98 lines
3.1 KiB
Python
98 lines
3.1 KiB
Python
from pathlib import PosixPath
|
|
from django.conf import settings
|
|
from django.db import models
|
|
|
|
from app.form.file_with_img_preview import FileWithImagePreview, ImageValidator
|
|
from app.utils import encrypt, overwrite_upload, random_secret
|
|
|
|
import os
|
|
import uuid
|
|
import json
|
|
import base64
|
|
|
|
|
|
class Member(models.Model):
|
|
# auto-generated ids
|
|
uuid = models.UUIDField(
|
|
primary_key=True, default=uuid.uuid4, editable=False)
|
|
secret = models.CharField(
|
|
max_length=20, default=random_secret, editable=False)
|
|
|
|
# member info
|
|
organization = models.ForeignKey(
|
|
'Organization', on_delete=models.CASCADE, related_name='members')
|
|
member_id = models.CharField('Mitglieder-Nr.', max_length=20)
|
|
name = models.CharField('Name', max_length=100)
|
|
valid_since = models.DateField('Mitglied seit')
|
|
valid_until = models.DateField('Mitglied bis', blank=True, null=True)
|
|
image = FileWithImagePreview(
|
|
'Bild', blank=True, null=True,
|
|
upload_to=overwrite_upload, validators=[ImageValidator.validate],
|
|
help_text=ImageValidator.help_text)
|
|
additional = models.JSONField(
|
|
'Zusätzliche Daten (JSON)', blank=True, null=True)
|
|
|
|
class Meta:
|
|
verbose_name = 'Mitglied'
|
|
verbose_name_plural = 'Mitglieder'
|
|
|
|
def __str__(self) -> str:
|
|
return self.name
|
|
|
|
@property
|
|
def export_url(self) -> str:
|
|
return self.organization.exportBaseUrl + \
|
|
f"#{self.organization.slug}/{self.uuid}/{self.secret}"
|
|
|
|
@property
|
|
def export_os_path(self) -> PosixPath:
|
|
return settings.EXPORT_PATH / self.organization.slug / str(self.uuid)
|
|
|
|
@property
|
|
def image_save_url(self) -> str:
|
|
return f'{self.organization.slug}/{self.uuid}'
|
|
|
|
@property
|
|
def image_os_path(self) -> PosixPath:
|
|
return settings.MEDIA_ROOT / self.organization.slug / str(self.uuid)
|
|
|
|
@property
|
|
def json(self):
|
|
return json.dumps({
|
|
'name': self.name,
|
|
'org': self.organization.name,
|
|
'id': self.member_id,
|
|
'valid_since': str(self.valid_since or ''),
|
|
'valid_until': str(self.valid_until or ''),
|
|
'data': self.additional or '',
|
|
'img': base64.b64encode(self.image.read()).decode(
|
|
'utf-8') if self.image else None,
|
|
})
|
|
|
|
@property
|
|
def json_encrypted(self) -> bytes:
|
|
return encrypt(self.json, self.secret)
|
|
|
|
def export(self):
|
|
os.makedirs(self.export_os_path.parent, exist_ok=True)
|
|
with open(self.export_os_path, 'wb') as fp:
|
|
fp.write(self.json_encrypted)
|
|
|
|
def save(self, *args, **kwargs):
|
|
if self.pk:
|
|
try:
|
|
prev = Member.objects.get(pk=self.pk)
|
|
if prev.image != self.image:
|
|
prev.image.delete(save=False)
|
|
except Member.DoesNotExist:
|
|
pass
|
|
self.export()
|
|
return super().save(*args, **kwargs)
|
|
|
|
def delete(self, *args, **kwargs):
|
|
if self.image:
|
|
self.image.delete(save=False)
|
|
if os.path.isfile(self.export_os_path):
|
|
os.remove(self.export_os_path)
|
|
return super().delete(*args, **kwargs)
|