def liberate(user_id, options): """ Get set for liberation, expects User object """ options['user'] = user_id user = get_user_model().objects.get(id=user_id) lib_status = user.liberation tar_type = TAR_TYPES[options.get('compression_type', '0')] rstr = get_random_string(7, string.ascii_letters) username = user.username + rstr username = username.encode("utf-8") basename = "%s_%s_%s_%s" % (time.time(), os.getpid(), rstr, hashlib.sha256(username).hexdigest()[:50]) path = os.path.join(settings.LIBERATION_PATH, basename) tarname = "%s.%s" % (basename, tar_type["ext"]) # Is this safe enough? try: os.mkdir(path, 0o700) except (IOError, OSError) as error: log.info("Couldn't create dir at %s", path) raise liberate.retry(exc=error) try: lib_status.path = tarname lib_status.save() except IntegrityError: os.rmdir(path) raise options["path"] = path options["tarname"] = tarname mail_path = os.path.join(path, 'emails') # make maildir mailbox.Maildir(mail_path, factory=None) inbox_tasks = [liberate_inbox.s(mail_path, inbox.id) for inbox in Inbox.objects.filter(user=user, deleted=False).only('id').iterator()] if len(inbox_tasks) > 0: tasks = chord( inbox_tasks, liberate_collect_emails.s(mail_path, options) ) else: options["noEmails"] = True data = {"results": []} tasks = chain( liberate_fetch_info.s(data, options), liberate_tarball.s(options), liberation_finish.s(options) ) async_result = tasks.apply_async() lib_status.async_result = async_result.id lib_status.save()
inbox_tasks = [liberate_inbox.s(mail_path, inbox.id) for inbox in Inbox.objects.filter(user=user, flags=~Inbox.flags.deleted).only('id').iterator()] if len(inbox_tasks) > 0: tasks = chord( inbox_tasks, liberate_collect_emails.s(mail_path, options) ) else: options["noEmails"] = True data = {"results": []} tasks = chain( liberate_fetch_info.s(data, options), liberate_tarball.s(options), liberation_finish.s(options) ) async_result = tasks.apply_async() lib_status.async_result = async_result.id lib_status.save() @app.task(rate_limit='100/m') def liberate_inbox(mail_path, inbox_id): """ Gather email IDs """ inbox = Inbox.objects.get(id=inbox_id, flags=~Inbox.flags.deleted) maildir = mailbox.Maildir(mail_path, factory=None) maildir.add_folder(str(inbox)) return { 'folder': str(inbox), 'ids': [email.id for email in Email.objects.filter(inbox=inbox, flags=~Email.flags.deleted).only('id').iterator()]