Files
ACORE/ext-visit manager/files(1)/attendance_retention_settings.py
T
lokses 131cb27d16 Initial commit — ACORE pharmacy network management system
Django project: employees, locations, visit_manager, it_manager,
mattermost_connector and stub connectors (ad, mail, portal).
2026-05-31 14:21:47 +03:00

110 lines
4.0 KiB
Python

# ---------------------------------------------------------------------------
# management/commands/cleanup_old_photos.py
# ---------------------------------------------------------------------------
# python manage.py cleanup_old_photos --days 90
# ---------------------------------------------------------------------------
import os
from datetime import timedelta
from django.core.management.base import BaseCommand
from django.utils import timezone
from attendance.models import AttendanceLog
class Command(BaseCommand):
help = 'Удаляет оригиналы фото старше N дней (превью остаются в БД)'
def add_arguments(self, parser):
parser.add_argument('--days', type=int, default=90,
help='Retention period в днях (default: 90)')
parser.add_argument('--dry-run', action='store_true',
help='Только показать, что будет удалено')
def handle(self, *args, **options):
cutoff = timezone.now() - timedelta(days=options['days'])
qs = AttendanceLog.objects.filter(
timestamp__lt=cutoff,
photo__isnull=False,
).exclude(photo='')
self.stdout.write(f'Найдено записей: {qs.count()} (старше {cutoff.date()})')
if options['dry_run']:
self.stdout.write('[dry-run] Удаление не выполняется.')
return
deleted = 0
for log in qs.iterator(chunk_size=500):
if log.photo and os.path.isfile(log.photo.path):
os.remove(log.photo.path)
log.photo = ''
log.save(update_fields=['photo'])
deleted += 1
self.stdout.write(self.style.SUCCESS(f'Удалено файлов: {deleted}'))
# ---------------------------------------------------------------------------
# settings snippet
# ---------------------------------------------------------------------------
"""
MEDIA_ROOT = '/var/lib/acore-visits/media'
MEDIA_URL = '/media/'
# Retention (дней хранения оригиналов фото)
ATTENDANCE_PHOTO_RETENTION_DAYS = 90
# Celery beat task (если используется Celery)
CELERY_BEAT_SCHEDULE = {
'cleanup-old-photos': {
'task': 'attendance.tasks.cleanup_old_photos',
'schedule': crontab(hour=3, minute=0), # каждую ночь в 03:00
},
}
"""
# ---------------------------------------------------------------------------
# Структура директорий на сервере
# ---------------------------------------------------------------------------
"""
/var/lib/acore-visits/
media/
photos/
2026/
04/
24/
42/ ← employee_id
a3f1bc.jpg
d7e2ff.jpg
57/
...
25/
...
ВАЖНО:
- Директория принадлежит пользователю www-data (или acore)
- Монтировать как NFS/samba если несколько app-серверов
- В PBS делать отдельный job на /var/lib/acore-visits/media/
- Для PPOS: фото хранятся локально, путь тот же,
синк на центр — только метаданные AttendanceLog (без photo_thumb)
"""
# ---------------------------------------------------------------------------
# Индексы миграции (добавить в Migration.operations)
# ---------------------------------------------------------------------------
"""
migrations.AddIndex(
model_name='attendancelog',
index=models.Index(fields=['employee', 'timestamp'], name='att_emp_ts_idx'),
),
migrations.AddIndex(
model_name='attendancelog',
index=models.Index(fields=['location', 'timestamp'], name='att_loc_ts_idx'),
),
migrations.AddIndex(
model_name='attendancelog',
index=models.Index(fields=['synced'], name='att_synced_idx'),
),
"""