Skip to content

Commit

Permalink
glamr: add backup_users management command
Browse files Browse the repository at this point in the history
This can be used as a cron job on the production deployment to extract
backups of the user data.
  • Loading branch information
robert102 committed Dec 2, 2024
1 parent f88c295 commit 2700299
Showing 1 changed file with 63 additions and 0 deletions.
63 changes: 63 additions & 0 deletions mibios/glamr/management/commands/backup_users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from datetime import datetime
from pathlib import Path
import shutil
import tempfile

from django.core.management import call_command
from django.core.management.base import BaseCommand, CommandError


class Command(BaseCommand):
help = 'Save backup of user data if data has changed since earlier backup.'

BACKUP_BASE = 'user_backup_'
BACKUP_SUFFIX = '.json'

def add_arguments(self, parser):
parser.add_argument(
'--outdir',
default=None,
help='Directory to which backups get written.'
)

def handle(self, *args, outdir=None, **options):
if outdir is None:
outdir = Path()
else:
outdir = Path(outdir)

if not outdir.is_dir():
raise CommandError(f'no such directory: {outdir}')

# get most recent backup
old = None
for i in outdir.glob(f'{self.BACKUP_BASE}*{self.BACKUP_SUFFIX}'):
if old is None or old.name < i.name:
old = i

today = datetime.now().date() # prints as YYYY-MM-DD
fname = self.BACKUP_BASE + str(today) + self.BACKUP_SUFFIX
with tempfile.TemporaryDirectory() as tmpd:
new = Path(tmpd) / fname
call_command(
'dumpdata',
'auth.User',
format='json',
indent=4,
database='default',
natural_foreign=True,
natural_primary=True,
output=new,
)

if old and old.read_text() == new.read_text():
self.stdout.write(f'No changes, {old} is already up-to-date\n')
return

dst = outdir / new.name
shutil.copyfile(new, dst)
self.stdout.write(f'Backup written to {dst}\n')
if old and old.name == new.name:
# multiple backups for same day
self.stdout.write('[WARNING] File with same name existed and '
'got overwritten!')

0 comments on commit 2700299

Please sign in to comment.