Browse Source

Add DataArchive utility class

Rafał Pitoń 7 years ago
parent
commit
bbe0303ab9

+ 8 - 8
misago/threads/signals.py

@@ -124,32 +124,32 @@ def delete_user_threads(sender, **kwargs):
 
 
 
 
 @receiver(archive_user_data)
 @receiver(archive_user_data)
-def archive_user_attachments(sender, data_archiver=None, **kwargs):
-    collection = data_archiver.create_collection('attachment')
+def archive_user_attachments(sender, archive=None, **kwargs):
+    collection = archive.create_collection('attachment')
     queryset = sender.attachment_set.order_by('id')
     queryset = sender.attachment_set.order_by('id')
     for attachment in chunk_queryset(queryset):
     for attachment in chunk_queryset(queryset):
         collection.write_model_file(attachment.image or attachment.file)
         collection.write_model_file(attachment.image or attachment.file)
 
 
 
 
 @receiver(archive_user_data)
 @receiver(archive_user_data)
-def archive_user_posts(sender, data_archiver=None, **kwargs):
-    collection = data_archiver.create_collection('post')
+def archive_user_posts(sender, archive=None, **kwargs):
+    collection = archive.create_collection('post')
     queryset = sender.post_set.order_by('id')
     queryset = sender.post_set.order_by('id')
     for post in chunk_queryset(queryset):
     for post in chunk_queryset(queryset):
         collection.write_data_file(post.posted_on, post.parsed)
         collection.write_data_file(post.posted_on, post.parsed)
 
 
 
 
 @receiver(archive_user_data)
 @receiver(archive_user_data)
-def archive_user_posts_edits(sender, data_archiver=None, **kwargs):
-    collection = data_archiver.create_collection('post_edit')
+def archive_user_posts_edits(sender, archive=None, **kwargs):
+    collection = archive.create_collection('post_edit')
     queryset = sender.postedit_set.order_by('id')
     queryset = sender.postedit_set.order_by('id')
     for post_edit in chunk_queryset(queryset):
     for post_edit in chunk_queryset(queryset):
         collection.write_data_file(post_edit.edited_on, post_edit.edited_from)
         collection.write_data_file(post_edit.edited_on, post_edit.edited_from)
 
 
 
 
 @receiver(archive_user_data)
 @receiver(archive_user_data)
-def archive_user_polls(sender, data_archiver=None, **kwargs):
-    collection = data_archiver.create_collection('poll')
+def archive_user_polls(sender, archive=None, **kwargs):
+    collection = archive.create_collection('poll')
     queryset = sender.poll_set.order_by('id')
     queryset = sender.poll_set.order_by('id')
     for poll in chunk_queryset(queryset):
     for poll in chunk_queryset(queryset):
         collection.write_data_file(poll.posted_on, {
         collection.write_data_file(poll.posted_on, {

+ 123 - 0
misago/users/dataarchive.py

@@ -0,0 +1,123 @@
+import os
+import shutil
+
+from django.core.files import File
+from django.utils import timezone
+from django.utils.crypto import get_random_string
+from django.utils import six
+
+from misago.core.utils import slugify
+
+
+class DataArchive(object):
+    def __init__(self, user, working_dir_path):
+        self.user = user
+        self.working_dir_path = working_dir_path
+
+        self.tmp_dir_path = None
+        self.data_dir_path = None
+
+        self.file_path = None
+        self.file = None
+
+    def __enter__(self):
+        self.tmp_dir_path = self.create_tmp_dir()
+        self.data_dir_path = self.create_data_dir()
+
+        return self
+
+    def __exit__(self, *args):
+        self.delete_file()
+        self.delete_tmp_dir()
+
+    def create_tmp_dir(self):
+        tmp_dir_name = get_tmp_filename(self.user)
+        tmp_dir_path = os.path.join(self.working_dir_path, tmp_dir_name)
+
+        os.mkdir(tmp_dir_path)
+
+        return tmp_dir_path
+
+    def create_data_dir(self):
+        data_dir_name = get_tmp_filename(self.user)
+        data_dir_path = os.path.join(self.tmp_dir_path, data_dir_name)
+
+        os.mkdir(data_dir_path)
+
+        return data_dir_path
+
+    def delete_tmp_dir(self):
+        if self.tmp_dir_path:
+            shutil.rmtree(self.tmp_dir_path)
+            self.tmp_dir_path = None
+            self.data_dir_path = None
+            
+    def get_file(self):
+        file_name = get_tmp_filename(self.user)
+        file_path = os.path.join(self.working_dir_path, file_name)
+
+        self.file_path = shutil.make_archive(file_path, 'zip', self.tmp_dir_path)
+        self.file = open(self.file_path, 'rb')
+
+        return File(self.file)
+
+    def delete_file(self):
+        if self.file:
+            self.file.close()
+            self.file = None
+
+        if self.file_path:
+            os.remove(self.file_path)
+            self.file_path = None
+
+    def add_text(self, name, value, path=None):
+        clean_filename = slugify(str(name))
+        file_dir_path = self.make_path(path)
+        file_path = os.path.join(file_dir_path, '{}.txt'.format(clean_filename))
+        with open(file_path, 'w+') as fp:
+            fp.write(six.text_type(value))
+            return file_path
+
+    def add_dict(self, name, value, path=None):
+        text_lines = []
+        for key, value in value.items():
+            text_lines.append(u"{}: {}".format(key, value))
+        text = u'\n'.join(text_lines)
+        return self.add_text(name, text, path)
+
+    def add_model_file(self, model_file, path=None):
+        if not model_file:
+            return None
+
+        clean_filename = model_file.name.split('/')[-1]
+        target_dir_path = self.make_path(path)
+        target_path = os.path.join(target_dir_path, clean_filename)
+
+        with open(target_path, 'wb') as fp:
+            for chunk in model_file.chunks():
+                fp.write(chunk)
+
+        return target_path
+
+    def make_path(self, path):
+        # fixme: this can be simplified in py37k
+        final_path = self.data_dir_path
+
+        if not path:
+            return final_path
+
+        for path_item in path:
+            final_path = os.path.join(final_path, path_item)
+            if not os.path.isdir(final_path):
+                os.mkdir(final_path)
+        return final_path
+
+
+def get_tmp_filename(user):
+    filename_bits = [
+        user.slug,
+        timezone.now().strftime('%Y%m%d-%H%M%S'),
+        get_random_string(6),
+    ]
+
+    return '-'.join(filename_bits)

+ 0 - 0
misago/users/dataarchiver.py → misago/users/datacollector.py


+ 10 - 12
misago/users/management/commands/prepareuserdatadownloads.py

@@ -5,9 +5,9 @@ from django.core.management.base import BaseCommand
 
 
 from misago.conf import settings
 from misago.conf import settings
 from misago.core.pgutils import chunk_queryset
 from misago.core.pgutils import chunk_queryset
-from misago.users.dataarchiver import DataArchiver
+from misago.users.dataarchive import DataArchive
 from misago.users.models import DataDownload
 from misago.users.models import DataDownload
-from misago.users.signals import archive_user_data
+from misago.users.signals import archive_user_personal_data
 
 
 
 
 logger = logging.getLogger('misago.users.datadownloads')
 logger = logging.getLogger('misago.users.datadownloads')
@@ -31,16 +31,14 @@ class Command(BaseCommand):
         queryset = queryset.filter(status=DataDownload.STATUS_PENDING)
         queryset = queryset.filter(status=DataDownload.STATUS_PENDING)
         for data_download in chunk_queryset(queryset):
         for data_download in chunk_queryset(queryset):
             user = data_download.user
             user = data_download.user
-            data_archiver = DataArchiver(user, working_dir)
-            try:
-                archive_user_data.send(user, data_archiver=data_archiver)
-                data_archiver.create_archive()
-                #data_download.save()
-            except Exception as e:
-                print(e)
-                logger.exception(e)
-            # data_archiver.delete_archive()
-            data_archiver.delete_tmp_dir()
+            with DataArchive(user, working_dir) as archive:
+                try:
+                    archive_user_personal_data.send(user, archive=archive)
+                    data_download.file = archive.get_file()
+                    #data_download.save()
+                except Exception as e:
+                    print(e)
+                    logger.exception(e)
 
 
             downloads_prepared += 1
             downloads_prepared += 1
 
 

+ 10 - 10
misago/users/signals.py

@@ -23,8 +23,8 @@ username_changed = Signal()
 
 
 
 
 @receiver(archive_user_data)
 @receiver(archive_user_data)
-def archive_user_details(sender, data_archiver=None, **kwargs):
-    data_archiver.write_data_file('details', {
+def archive_user_details(sender, archive=None, **kwargs):
+    archive.write_data_file('details', {
         _('Username'): sender.username,
         _('Username'): sender.username,
         _('E-mail'): sender.email,
         _('E-mail'): sender.email,
         _('Joined on'): sender.joined_on,
         _('Joined on'): sender.joined_on,
@@ -33,7 +33,7 @@ def archive_user_details(sender, data_archiver=None, **kwargs):
 
 
 
 
 @receiver(archive_user_data)
 @receiver(archive_user_data)
-def archive_user_profile_fields(sender, data_archiver=None, **kwargs):
+def archive_user_profile_fields(sender, archive=None, **kwargs):
     clean_profile_fields = {}
     clean_profile_fields = {}
     for profile_fields_group in profilefields.get_fields_groups():
     for profile_fields_group in profilefields.get_fields_groups():
         for profile_field in profile_fields_group['fields']:
         for profile_field in profile_fields_group['fields']:
@@ -42,12 +42,12 @@ def archive_user_profile_fields(sender, data_archiver=None, **kwargs):
                 clean_profile_fields[str(profile_field.label)] = field_value
                 clean_profile_fields[str(profile_field.label)] = field_value
                 
                 
     if clean_profile_fields:
     if clean_profile_fields:
-        data_archiver.write_data_file('profile_fields', clean_profile_fields)
+        archive.write_data_file('profile_fields', clean_profile_fields)
 
 
 
 
 @receiver(archive_user_data)
 @receiver(archive_user_data)
-def archive_user_avatar(sender, data_archiver=None, **kwargs):
-    collection = data_archiver.create_collection('avatar')
+def archive_user_avatar(sender, archive=None, **kwargs):
+    collection = archive.create_collection('avatar')
     collection.write_model_file(sender.avatar_tmp)
     collection.write_model_file(sender.avatar_tmp)
     collection.write_model_file(sender.avatar_src)
     collection.write_model_file(sender.avatar_src)
     for avatar in sender.avatar_set.iterator():
     for avatar in sender.avatar_set.iterator():
@@ -55,16 +55,16 @@ def archive_user_avatar(sender, data_archiver=None, **kwargs):
 
 
 
 
 @receiver(archive_user_data)
 @receiver(archive_user_data)
-def archive_user_audit_trail(sender, data_archiver=None, **kwargs):
-    collection = data_archiver.create_collection('audit_trail')
+def archive_user_audit_trail(sender, archive=None, **kwargs):
+    collection = archive.create_collection('audit_trail')
     queryset = sender.audittrail_set.order_by('id')
     queryset = sender.audittrail_set.order_by('id')
     for audit_trail in chunk_queryset(queryset):
     for audit_trail in chunk_queryset(queryset):
         collection.write_data_file(audit_trail.created_at, audit_trail.ip_address)
         collection.write_data_file(audit_trail.created_at, audit_trail.ip_address)
 
 
 
 
 @receiver(archive_user_data)
 @receiver(archive_user_data)
-def archive_user_name_history(sender, data_archiver=None, **kwargs):
-    collection = data_archiver.create_collection('name_history')
+def archive_user_name_history(sender, archive=None, **kwargs):
+    collection = archive.create_collection('name_history')
     for name_change in sender.namechanges.order_by('id').iterator():
     for name_change in sender.namechanges.order_by('id').iterator():
         collection.write_data_file(name_change.changed_on, {
         collection.write_data_file(name_change.changed_on, {
             _("New username"): name_change.new_username,
             _("New username"): name_change.new_username,

+ 198 - 0
misago/users/tests/test_dataarchive.py

@@ -0,0 +1,198 @@
+# -*- coding: utf-8 -*-
+import os
+from collections import OrderedDict
+
+from django.core.files import File
+
+from misago.conf import settings
+from misago.users.dataarchive import DataArchive
+from misago.users.testutils import AuthenticatedUserTestCase
+
+
+TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'testfiles')
+TEST_AVATAR_PATH = os.path.join(TESTFILES_DIR, 'avatar.png')
+
+DATA_DOWNLOADS_WORKING_DIR = settings.MISAGO_USER_DATA_DOWNLOADS_WORKING_DIR
+
+
+class DataArchiveTests(AuthenticatedUserTestCase):
+    def test_enter_without_dirs(self):
+        """data archive doesn't touch filesystem on init"""
+        archive = DataArchive(self.user, DATA_DOWNLOADS_WORKING_DIR)
+
+        self.assertEqual(archive.user, self.user)
+        self.assertEqual(archive.working_dir_path, DATA_DOWNLOADS_WORKING_DIR)
+
+        self.assertIsNone(archive.tmp_dir_path)
+        self.assertIsNone(archive.data_dir_path)
+
+    def test_context_life_cycle(self):
+        """object creates valid tmp directory on enter and cleans on exit"""
+        tmp_dir_path = None
+        data_dir_path = None
+
+        with DataArchive(self.user, DATA_DOWNLOADS_WORKING_DIR) as archive:
+            self.assertTrue(os.path.exists(archive.tmp_dir_path))
+            self.assertTrue(os.path.exists(archive.data_dir_path))
+
+            working_dir = str(DATA_DOWNLOADS_WORKING_DIR)
+            tmp_dir_path = str(archive.tmp_dir_path)
+            data_dir_path = str(archive.data_dir_path)
+            
+            self.assertTrue(tmp_dir_path.startswith(working_dir))
+            self.assertTrue(data_dir_path.startswith(working_dir))
+
+            self.assertTrue(data_dir_path.startswith(working_dir))
+            self.assertTrue(data_dir_path.startswith(tmp_dir_path))
+
+        self.assertIsNone(archive.tmp_dir_path)
+        self.assertIsNone(archive.data_dir_path)
+
+        self.assertFalse(os.path.exists(tmp_dir_path))
+        self.assertFalse(os.path.exists(data_dir_path))
+
+    def test_add_text_str(self):
+        """add_dict method creates text file with string"""
+        with DataArchive(self.user, DATA_DOWNLOADS_WORKING_DIR) as archive:
+            data_to_write = u"Hello, łorld!"
+            file_path = archive.add_text('testfile', data_to_write)
+            self.assertTrue(os.path.isfile(file_path))
+
+            valid_output_path = os.path.join(archive.data_dir_path, 'testfile.txt')
+            self.assertEqual(file_path, valid_output_path)
+
+            with open(file_path, 'r', encoding="utf-8") as fp:
+                saved_data = fp.read().strip()
+                self.assertEqual(saved_data, data_to_write)
+
+    def test_add_text_int(self):
+        """add_dict method creates text file with int"""
+        with DataArchive(self.user, DATA_DOWNLOADS_WORKING_DIR) as archive:
+            data_to_write = 1234
+            file_path = archive.add_text('testfile', data_to_write)
+            self.assertTrue(os.path.isfile(file_path))
+
+            valid_output_path = os.path.join(archive.data_dir_path, 'testfile.txt')
+            self.assertEqual(file_path, valid_output_path)
+
+            with open(file_path, 'r', encoding="utf-8") as fp:
+                saved_data = fp.read().strip()
+                self.assertEqual(saved_data, str(data_to_write))
+
+    def test_add_text_path(self):
+        """add_dict method creates text file under path"""
+        with DataArchive(self.user, DATA_DOWNLOADS_WORKING_DIR) as archive:
+            data_to_write = u"Hello, łorld!"
+            file_path = archive.add_text(
+                'testfile', data_to_write, path=['avatars', 'tmp'])
+            self.assertTrue(os.path.isfile(file_path))
+
+            valid_output_path = os.path.join(archive.data_dir_path, 'testfile.txt')
+            self.assertEqual(file_path, valid_output_path)
+
+            data_dir_path = str(archive.data_dir_path)
+            self.assertTrue(str(valid_output_path).startswith(data_dir_path))
+            self.assertIn('/avatars/tmp/', str(valid_output_path))
+
+    def test_add_dict(self):
+        """add_dict method creates text file from dict"""
+        with DataArchive(self.user, DATA_DOWNLOADS_WORKING_DIR) as archive:
+            data_to_write = {'first': u"łorld!", 'second': u"łup!"}
+            file_path = archive.add_dict('testfile', data_to_write)
+            self.assertTrue(os.path.isfile(file_path))
+
+            valid_output_path = os.path.join(archive.data_dir_path, 'testfile.txt')
+            self.assertEqual(file_path, valid_output_path)
+
+            with open(file_path, 'r', encoding="utf-8") as fp:
+                saved_data = fp.read().strip()
+                self.assertEqual(saved_data, u"first: łorld!\nsecond: łup!")
+
+    def test_add_dict_ordered(self):
+        """add_dict method creates text file form ordered dict"""
+        with DataArchive(self.user, DATA_DOWNLOADS_WORKING_DIR) as archive:
+            data_to_write = OrderedDict((('first', u"łorld!"), ('second', u"łup!")))
+            file_path = archive.add_dict('testfile', data_to_write)
+            self.assertTrue(os.path.isfile(file_path))
+
+            valid_output_path = os.path.join(archive.data_dir_path, 'testfile.txt')
+            self.assertEqual(file_path, valid_output_path)
+
+            with open(file_path, 'r', encoding="utf-8") as fp:
+                saved_data = fp.read().strip()
+                self.assertEqual(saved_data, u"first: łorld!\nsecond: łup!")
+
+    def test_add_dict_path(self):
+        """add_dict method creates text file under path"""
+        with DataArchive(self.user, DATA_DOWNLOADS_WORKING_DIR) as archive:
+            data_to_write = {'first': u"łorld!", 'second': u"łup!"}
+            file_path = archive.add_dict(
+                'testfile', data_to_write, path=['avatars', 'tmp']))
+            self.assertTrue(os.path.isfile(file_path))
+
+            valid_output_path = os.path.join(archive.data_dir_path, 'testfile.txt')
+            self.assertEqual(file_path, valid_output_path)
+
+            data_dir_path = str(archive.data_dir_path)
+            self.assertTrue(str(valid_output_path).startswith(data_dir_path))
+            self.assertIn('/avatars/tmp/', str(valid_output_path))
+
+    def test_add_model_file(self):
+        """add_model_file method adds model file"""
+        with open(TEST_AVATAR_PATH, 'rb') as avatar:
+            self.user.avatar_tmp = File(avatar)
+            self.user.save()
+
+        with DataArchive(self.user, DATA_DOWNLOADS_WORKING_DIR) as archive:
+            file_path = archive.add_model_file(self.user.avatar_tmp)
+
+            self.assertTrue(os.path.isfile(file_path))
+    
+            data_dir_path = str(archive.data_dir_path)
+            self.assertTrue(str(file_path).startswith(data_dir_path))
+
+    def test_add_model_file_empty(self):
+        """add_model_file method is noop if model field is empty"""
+        with DataArchive(self.user, DATA_DOWNLOADS_WORKING_DIR) as archive:
+            file_path = archive.add_model_file(self.user.avatar_tmp)
+
+            self.assertIsNone(file_path)
+            self.assertFalse(os.listdir(archive.data_dir_path))
+
+    def test_add_model_file_path(self):
+        """add_model_file method adds model file under path"""
+        with open(TEST_AVATAR_PATH, 'rb') as avatar:
+            self.user.avatar_tmp = File(avatar)
+            self.user.save()
+
+        with DataArchive(self.user, DATA_DOWNLOADS_WORKING_DIR) as archive:
+            file_path = archive.add_model_file(
+                self.user.avatar_tmp, path=['avatars', 'tmp'])
+
+            self.assertTrue(os.path.isfile(file_path))
+    
+            data_dir_path = str(archive.data_dir_path)
+            self.assertTrue(str(file_path).startswith(data_dir_path))
+            self.assertIn('/avatars/tmp/', str(file_path))
+
+    def test_get_file(self):
+        """get_file returns django file"""
+        django_file = None
+        
+        with open(TEST_AVATAR_PATH, 'rb') as avatar:
+            self.user.avatar_tmp = File(avatar)
+            self.user.save()
+
+        with DataArchive(self.user, DATA_DOWNLOADS_WORKING_DIR) as archive:
+            archive.add_model_file(self.user.avatar_tmp)
+
+            django_file = archive.get_file()
+            archive_path = archive.file_path
+
+            self.assertIsNotNone(archive_path)
+            self.assertEqual(django_file.name, archive.file_path)
+            self.assertFalse(django_file.closed)
+
+        self.assertIsNone(archive.file)
+        self.assertIsNone(archive.file_path)
+        self.assertTrue(django_file.closed)

+ 38 - 38
misago/users/tests/test_dataarchiver.py → misago/users/tests/test_datacollector.py

@@ -4,7 +4,7 @@ import os
 from django.core.files import File
 from django.core.files import File
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.users.dataarchiver import DataArchiver
+from misago.users.datacollector import DataCollector
 from misago.users.testutils import AuthenticatedUserTestCase
 from misago.users.testutils import AuthenticatedUserTestCase
 
 
 
 
@@ -17,13 +17,13 @@ DATA_DOWNLOADS_WORKING_DIR = settings.MISAGO_USER_DATA_DOWNLOADS_WORKING_DIR
 class DataArchiverTests(AuthenticatedUserTestCase):
 class DataArchiverTests(AuthenticatedUserTestCase):
     def test_init_with_dirs(self):
     def test_init_with_dirs(self):
         """data collector initializes with valid tmp directories"""
         """data collector initializes with valid tmp directories"""
-        data_archiver = DataArchiver(self.user, DATA_DOWNLOADS_WORKING_DIR)
-        self.assertTrue(os.path.exists(data_archiver.tmp_dir_path))
-        self.assertTrue(os.path.exists(data_archiver.data_dir_path))
+        data_collector = DataCollector(self.user, DATA_DOWNLOADS_WORKING_DIR)
+        self.assertTrue(os.path.exists(data_collector.tmp_dir_path))
+        self.assertTrue(os.path.exists(data_collector.data_dir_path))
 
 
         data_downloads_working_dir = str(DATA_DOWNLOADS_WORKING_DIR)
         data_downloads_working_dir = str(DATA_DOWNLOADS_WORKING_DIR)
-        tmp_dir_path = str(data_archiver.tmp_dir_path)
-        data_dir_path = str(data_archiver.data_dir_path)
+        tmp_dir_path = str(data_collector.tmp_dir_path)
+        data_dir_path = str(data_collector.data_dir_path)
         
         
         self.assertTrue(tmp_dir_path.startswith(data_downloads_working_dir))
         self.assertTrue(tmp_dir_path.startswith(data_downloads_working_dir))
         self.assertTrue(data_dir_path.startswith(data_downloads_working_dir))
         self.assertTrue(data_dir_path.startswith(data_downloads_working_dir))
@@ -33,13 +33,13 @@ class DataArchiverTests(AuthenticatedUserTestCase):
 
 
     def test_write_data_file(self):
     def test_write_data_file(self):
         """write_data_file creates new data file in data_dir_path"""
         """write_data_file creates new data file in data_dir_path"""
-        data_archiver = DataArchiver(self.user, DATA_DOWNLOADS_WORKING_DIR)
+        data_collector = DataCollector(self.user, DATA_DOWNLOADS_WORKING_DIR)
 
 
         data_to_write = {'hello': "I am test!", 'nice': u"łał!"}
         data_to_write = {'hello': "I am test!", 'nice': u"łał!"}
-        data_file_path = data_archiver.write_data_file("testfile", data_to_write)
+        data_file_path = data_collector.write_data_file("testfile", data_to_write)
         self.assertTrue(os.path.isfile(data_file_path))
         self.assertTrue(os.path.isfile(data_file_path))
 
 
-        valid_output_path = os.path.join(data_archiver.data_dir_path, 'testfile.txt')
+        valid_output_path = os.path.join(data_collector.data_dir_path, 'testfile.txt')
         self.assertEqual(data_file_path, valid_output_path)
         self.assertEqual(data_file_path, valid_output_path)
 
 
         with open(data_file_path, 'r') as fp:
         with open(data_file_path, 'r') as fp:
@@ -52,28 +52,28 @@ class DataArchiverTests(AuthenticatedUserTestCase):
             self.user.avatar_tmp = File(avatar)
             self.user.avatar_tmp = File(avatar)
             self.user.save()
             self.user.save()
 
 
-        data_archiver = DataArchiver(self.user, DATA_DOWNLOADS_WORKING_DIR)
-        file_path = data_archiver.write_model_file(self.user.avatar_tmp)
+        data_collector = DataCollector(self.user, DATA_DOWNLOADS_WORKING_DIR)
+        file_path = data_collector.write_model_file(self.user.avatar_tmp)
         
         
         self.assertTrue(os.path.isfile(file_path))
         self.assertTrue(os.path.isfile(file_path))
     
     
-        data_dir_path = str(data_archiver.data_dir_path)
+        data_dir_path = str(data_collector.data_dir_path)
         self.assertTrue(str(file_path).startswith(data_dir_path))
         self.assertTrue(str(file_path).startswith(data_dir_path))
 
 
     def test_write_model_file_empty(self):
     def test_write_model_file_empty(self):
         """write_model_file is noop if model file field is none"""
         """write_model_file is noop if model file field is none"""
-        data_archiver = DataArchiver(self.user, DATA_DOWNLOADS_WORKING_DIR)
-        file_path = data_archiver.write_model_file(self.user.avatar_tmp)
+        data_collector = DataCollector(self.user, DATA_DOWNLOADS_WORKING_DIR)
+        file_path = data_collector.write_model_file(self.user.avatar_tmp)
         
         
         self.assertIsNone(file_path)
         self.assertIsNone(file_path)
-        self.assertFalse(os.listdir(data_archiver.data_dir_path))
+        self.assertFalse(os.listdir(data_collector.data_dir_path))
 
 
     def test_create_collection(self):
     def test_create_collection(self):
         """create_collection creates new directory for collection"""
         """create_collection creates new directory for collection"""
-        data_archiver = DataArchiver(self.user, DATA_DOWNLOADS_WORKING_DIR)
-        collection = data_archiver.create_collection('collection')
+        data_collector = DataCollector(self.user, DATA_DOWNLOADS_WORKING_DIR)
+        collection = data_collector.create_collection('collection')
 
 
-        data_dir_path = str(data_archiver.data_dir_path)
+        data_dir_path = str(data_collector.data_dir_path)
         collection_dir_path = str(collection.data_dir_path)
         collection_dir_path = str(collection.data_dir_path)
         self.assertNotEqual(data_dir_path, collection_dir_path)
         self.assertNotEqual(data_dir_path, collection_dir_path)
         self.assertTrue(collection_dir_path.startswith(data_dir_path))
         self.assertTrue(collection_dir_path.startswith(data_dir_path))
@@ -82,8 +82,8 @@ class DataArchiverTests(AuthenticatedUserTestCase):
 
 
     def test_collection_write_data_file(self):
     def test_collection_write_data_file(self):
         """write_data_file creates new data file in collection data_dir_path"""
         """write_data_file creates new data file in collection data_dir_path"""
-        data_archiver = DataArchiver(self.user, DATA_DOWNLOADS_WORKING_DIR)
-        collection = data_archiver.create_collection('collection')
+        data_collector = DataCollector(self.user, DATA_DOWNLOADS_WORKING_DIR)
+        collection = data_collector.create_collection('collection')
 
 
         data_to_write = {'hello': "I am test!", 'nice': u"łał!"}
         data_to_write = {'hello': "I am test!", 'nice': u"łał!"}
         data_file_path = collection.write_data_file("testfile", data_to_write)
         data_file_path = collection.write_data_file("testfile", data_to_write)
@@ -102,8 +102,8 @@ class DataArchiverTests(AuthenticatedUserTestCase):
             self.user.avatar_tmp = File(avatar)
             self.user.avatar_tmp = File(avatar)
             self.user.save()
             self.user.save()
 
 
-        data_archiver = DataArchiver(self.user, DATA_DOWNLOADS_WORKING_DIR)
-        collection = data_archiver.create_collection('collection')
+        data_collector = DataCollector(self.user, DATA_DOWNLOADS_WORKING_DIR)
+        collection = data_collector.create_collection('collection')
 
 
         file_path = collection.write_model_file(self.user.avatar_tmp)
         file_path = collection.write_model_file(self.user.avatar_tmp)
         
         
@@ -114,8 +114,8 @@ class DataArchiverTests(AuthenticatedUserTestCase):
 
 
     def test_collection_write_model_file_empty(self):
     def test_collection_write_model_file_empty(self):
         """write_model_file is noop if model file field is none"""
         """write_model_file is noop if model file field is none"""
-        data_archiver = DataArchiver(self.user, DATA_DOWNLOADS_WORKING_DIR)
-        collection = data_archiver.create_collection('collection')
+        data_collector = DataCollector(self.user, DATA_DOWNLOADS_WORKING_DIR)
+        collection = data_collector.create_collection('collection')
 
 
         file_path = collection.write_model_file(self.user.avatar_tmp)
         file_path = collection.write_model_file(self.user.avatar_tmp)
         
         
@@ -124,36 +124,36 @@ class DataArchiverTests(AuthenticatedUserTestCase):
 
 
     def test_create_archive(self):
     def test_create_archive(self):
         """create_archive creates zip file from collected data"""
         """create_archive creates zip file from collected data"""
-        data_archiver = DataArchiver(self.user, DATA_DOWNLOADS_WORKING_DIR)
+        data_collector = DataCollector(self.user, DATA_DOWNLOADS_WORKING_DIR)
         
         
         data_to_write = {'hello': "I am test!", 'nice': u"łał!"}
         data_to_write = {'hello': "I am test!", 'nice': u"łał!"}
-        data_archiver.write_data_file("testfile", data_to_write)
+        data_collector.write_data_file("testfile", data_to_write)
 
 
         with open(TEST_AVATAR_PATH, 'rb') as avatar:
         with open(TEST_AVATAR_PATH, 'rb') as avatar:
             self.user.avatar_tmp = File(avatar)
             self.user.avatar_tmp = File(avatar)
             self.user.save()
             self.user.save()
-        data_archiver.write_model_file(self.user.avatar_tmp)
+        data_collector.write_model_file(self.user.avatar_tmp)
 
 
-        archive_path = data_archiver.create_archive()
-        self.assertEqual(data_archiver.archive_path, archive_path)
+        archive_path = data_collector.create_archive()
+        self.assertEqual(data_collector.archive_path, archive_path)
         self.assertTrue(os.path.isfile(archive_path))
         self.assertTrue(os.path.isfile(archive_path))
 
 
     def test_delete_archive(self):
     def test_delete_archive(self):
         """delete_archive deletes zip file"""
         """delete_archive deletes zip file"""
-        data_archiver = DataArchiver(self.user, DATA_DOWNLOADS_WORKING_DIR)
-        archive_path = data_archiver.create_archive()
-        data_archiver.delete_archive()
+        data_collector = DataCollector(self.user, DATA_DOWNLOADS_WORKING_DIR)
+        archive_path = data_collector.create_archive()
+        data_collector.delete_archive()
         self.assertFalse(os.path.isfile(archive_path))
         self.assertFalse(os.path.isfile(archive_path))
 
 
     def test_delete_archive_none(self):
     def test_delete_archive_none(self):
         """delete_archive is noop if zip file doesnt exist"""
         """delete_archive is noop if zip file doesnt exist"""
-        data_archiver = DataArchiver(self.user, DATA_DOWNLOADS_WORKING_DIR)
-        self.assertIsNone(data_archiver.archive_path)
-        data_archiver.delete_archive()
+        data_collector = DataCollector(self.user, DATA_DOWNLOADS_WORKING_DIR)
+        self.assertIsNone(data_collector.archive_path)
+        data_collector.delete_archive()
 
 
     def test_delete_tmp_dir(self):
     def test_delete_tmp_dir(self):
         """delete_tmp_dir delete's directory but leaves archive"""
         """delete_tmp_dir delete's directory but leaves archive"""
-        data_archiver = DataArchiver(self.user, DATA_DOWNLOADS_WORKING_DIR)
-        tmp_dir_path = data_archiver.tmp_dir_path
-        data_archiver.delete_tmp_dir()
+        data_collector = DataCollector(self.user, DATA_DOWNLOADS_WORKING_DIR)
+        tmp_dir_path = data_collector.tmp_dir_path
+        data_collector.delete_tmp_dir()
         self.assertFalse(os.path.exists(tmp_dir_path))
         self.assertFalse(os.path.exists(tmp_dir_path))