def handle(self, *args, **options): date_string = datetime.datetime.now().strftime("%d_%m_%Y-%H_%M_%S") default_filename = f"backup_{date_string}.tar" full_backup = options.get('full_backup') username = options.get('user') location = options.get('location') or default_filename try: user = User.objects.get(username=username) except User.DoesNotExist: logger.error(f"Username {username} not found.") return # consider the case when user provides directory location i.e. # ./manage.py backup /backup/papermerge/ if os.path.isdir(location): # in case location is a non existing directory path e.g. "blah/" # os.path.isdir will return False backup_location = os.path.join(location, default_filename) else: backup_location = location try: with open(backup_location, 'wb') as backup_file: backup_documents(backup_file=backup_file, user=user, full_backup=full_backup) except IsADirectoryError: logger.error( "Provided location is a directory which does not exist." "Please create it first and try again.")
def test_backup_single_document(self): document_path = os.path.join( BASE_DIR, "data", "berlin.pdf" ) doc = Document.create_document( user=self.testcase_user, title='berlin.pdf', size=os.path.getsize(document_path), lang='deu', file_name='berlin.pdf', parent_id=None, page_count=3 ) default_storage.copy_doc( src=document_path, dst=doc.path.url(), ) with io.BytesIO() as memoryfile: backup_documents(memoryfile, self.testcase_user) memoryfile.seek(0) self.assertTrue( _can_restore(memoryfile), 'generated backup.tar is not valid' ) memoryfile.seek(0) backup_file = tarfile.open(fileobj=memoryfile, mode='r') backup_json = backup_file.extractfile('backup.json') backup_info = json.loads(backup_json.read()) self.assertIsNotNone( backup_info.get('documents'), 'backup.json did not have a key "documents"' ) self.assertIs( len(backup_info.get('documents')), 1, 'backup.json key documents had more or less than one entry' ) self.assertIs( len(backup_file.getnames()), 2, 'backup.tar had more or less than 2 entries' ) self.assertTrue( 'berlin.pdf' in backup_file.getnames(), 'berlin.pdf was not in the backup.tar' )
def test_backup_document_hierachy(self): folder_1 = Folder.objects.create(title='1', parent=None, user=self.testcase_user) folder_2 = Folder.objects.create(title='2', parent=folder_1, user=self.testcase_user) folder_3 = Folder.objects.create(title='3', parent=folder_1, user=self.testcase_user) Folder.objects.create(title='4', parent=None, user=self.testcase_user) document_path = os.path.join(BASE_DIR, "data", "berlin.pdf") doc_1 = Document.create_document(user=self.testcase_user, title='berlin.pdf', size=os.path.getsize(document_path), lang='deu', file_name='berlin.pdf', parent_id=folder_2.id, page_count=3) default_storage.copy_doc( src=document_path, dst=doc_1.path.url(), ) doc_2 = Document.create_document(user=self.testcase_user, title='berlin.pdf', size=os.path.getsize(document_path), lang='deu', file_name='berlin.pdf', parent_id=folder_3.id, page_count=3) default_storage.copy_doc( src=document_path, dst=doc_2.path.url(), ) with io.BytesIO() as memoryfile: backup_documents(memoryfile, self.testcase_user) memoryfile.seek(0) self.assertTrue(_can_restore(memoryfile), 'generated backup.tar is not valid') memoryfile.seek(0) backup_file = tarfile.open(fileobj=memoryfile, mode='r') backup_json = backup_file.extractfile('backup.json') backup_info = json.loads(backup_json.read()) self.assertIsNotNone(backup_info.get('documents'), 'backup.json did not have a key "documents"') self.assertIs( len(backup_info.get('documents')), 2, 'backup.json key documents had more or less than two entry') self.assertIs(len(backup_file.getnames()), 3, 'backup.tar had more or less than 2 entries') self.assertTrue( f"1/2/berlin.pdf__{doc_1.id}" in backup_file.getnames(), 'berlin.pdf was not in the backup.tar at folder 1/2/') self.assertTrue( f"1/3/berlin.pdf__{doc_2.id}" in backup_file.getnames(), 'berlin.pdf was not in the backup.tar at folder 1/3/') self.assertFalse( '4' in backup_file.getnames(), 'Folder 4 was in backup.tar but should have been ignored')