Guest User

Untitled

a guest
Oct 22nd, 2017
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.07 KB | None | 0 0
  1. import os
  2. import tarfile
  3. import progressbar
  4. import django.apps
  5. from datetime import datetime
  6. from django.core.management.base import BaseCommand
  7. from django.utils.encoding import smart_str
  8.  
  9.  
  10. class Command(BaseCommand):
  11. help = 'Backup item images'
  12.  
  13. def add_arguments(self, parser):
  14. parser.add_argument(
  15. '--show-bar',
  16. action='store_true',
  17. dest='show_bar',
  18. default=False,
  19. help='Show progressbar'
  20. )
  21. parser.add_argument(
  22. '--print-paths',
  23. action='store_true',
  24. dest='print_paths',
  25. default=False,
  26. help='Print files paths'
  27. )
  28.  
  29. def handle(self, *args, **options):
  30. backuper = BackupFiles(
  31. 'project-name',
  32. show_bar=options['show_bar'],
  33. print_paths=options['print_paths']
  34. )
  35. archive_path = backuper.start()
  36. print(archive_path)
  37.  
  38.  
  39. class BackupFiles(object):
  40. _media_folder_name = None
  41.  
  42. def __init__(self,
  43. project_name,
  44. archive_folder='/tmp',
  45. default_media_folder_name='media',
  46. show_bar=False,
  47. print_paths=False):
  48. self.show_bar = show_bar
  49. self.print_paths = print_paths
  50.  
  51. self.project_name = project_name
  52. self.archive_folder = archive_folder
  53. self._default_media_folder_name = default_media_folder_name
  54.  
  55. def start(self):
  56. archive_path = self._get_archive_path()
  57. tar = tarfile.open(archive_path, 'w:gz')
  58.  
  59. files_path = []
  60. models_list = django.apps.apps.get_models()
  61. for model_class in models_list:
  62. for instance in model_class.objects.all():
  63. file_field_names = self._get_file_fields(instance)
  64. for field_name in file_field_names:
  65. cur_path = self._get_file_field(instance, field_name)
  66. if cur_path:
  67. files_path.append(cur_path)
  68.  
  69. if self.print_paths:
  70. message = '{}.{} {} :: {}'.format(
  71. model_class._meta.app_label,
  72. model_class._meta.model_name,
  73. field_name,
  74. cur_path['full_path']
  75. )
  76. print(message)
  77.  
  78. bar = None
  79. if self.show_bar:
  80. bar = progressbar.ProgressBar(max_value=len(files_path)).start()
  81.  
  82. for i, cur_path in enumerate(files_path):
  83. tar.add(
  84. cur_path['full_path'],
  85. arcname=cur_path['arc_name']
  86. )
  87.  
  88. if bar:
  89. bar.update(i + 1)
  90.  
  91. if bar:
  92. bar.finish()
  93.  
  94. tar.close()
  95.  
  96. return archive_path
  97.  
  98. def _get_archive_path(self):
  99. file_name = '{}-{}-{}.tar.gz'.format(
  100. self.project_name,
  101. self.media_folder_name,
  102. datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
  103. )
  104. archive_path = '{}/{}'.format(
  105. self.archive_folder,
  106. file_name
  107. )
  108. return archive_path
  109.  
  110. @property
  111. def media_folder_name(self):
  112. if self._media_folder_name:
  113. return self._media_folder_name
  114. return self._default_media_folder_name
  115.  
  116. @media_folder_name.setter
  117. def media_folder_name(self, value):
  118. self._media_folder_name = value
  119.  
  120. @staticmethod
  121. def _get_file_fields(instance):
  122. names = []
  123. for field in instance._meta.fields:
  124. if field.get_internal_type() == 'FileField':
  125. names.append(field.name)
  126. return names
  127.  
  128. def _get_file_field(self, instance, field_name):
  129. field = getattr(instance, field_name)
  130. if not field:
  131. return {}
  132.  
  133. full_path = smart_str(field.path)
  134. arc_name = '{}/{}/{}'.format(
  135. self.media_folder_name,
  136. field.field.upload_to,
  137. os.path.basename(full_path)
  138. )
  139. return {
  140. 'arc_name': arc_name,
  141. 'full_path': full_path,
  142. }
Add Comment
Please, Sign In to add comment