# Path: djenga/celery/tasks.py
# class DetailTask(Task):
#     steps = None
# 
#     def __init__(self, steps=None):
#         super().__init__()
#         self.steps = self.steps or []
#         self.details = OrderedDict()
#         for key, description in self.steps:
#             self.details[key] = description
# 
#     def initialize_detail(self):
#         if not hasattr(self.request, 'details'):
#             self.request.details = OrderedDict([
#                 (key, TaskDetail(key, description),)
#                 for key, description in self.details.items()
#             ])
#             self.request.detail_stack = list()
#             self.request.current_detail = None
# 
#     def save_details(self):
#         if self.request.id:
#             self.backend.store_result(
#                 self.request.id,
#                 result=None,
#                 state=states.STARTED,
#                 details=self.request.details)
# 
#     def start_step(self, key, description=None, detail='in progress'):
#         self.initialize_detail()
#         r = self.request
#         if key not in r.details:
#             r.current_detail = r.details.setdefault(
#                 key, TaskDetail(key, description))
#         else:
#             r.current_detail = r.details[key]
#         r.current_detail.start_time()
#         r.current_detail.add_detail(detail)
#         r.detail_stack.append(r.current_detail)
#         logger.info(
#             '[%s/%s] %s', r.current_detail.key,
#             r.current_detail.description, detail)
#         self.save_details()
# 
#     def update_step(self, detail, *args):
#         self.initialize_detail()
#         r = self.request
#         if args:
#             try:
#                 detail = detail % args
#             except Exception as ex:  # pylint: disable=broad-except
#                 logger.exception('%s', ex)
#         r.current_detail.add_detail(detail)
#         logger.info(
#             '[%s/%s] %s', r.current_detail.key,
#             r.current_detail.description, detail)
#         self.save_details()
# 
#     def end_step(self, error=None, detail='done'):
#         self.initialize_detail()
#         r = self.request
#         if error:
#             r.current_detail.error = error
#             r.current_detail.add_detail(error)
#             logger.info(
#                 '[%s/%s] %s', r.current_detail.key,
#                 r.current_detail.description, error)
#         else:
#             r.current_detail.add_detail(detail)
#             logger.info(
#                 '[%s/%s] %s', r.current_detail.key,
#                 r.current_detail.description, detail)
#         r.current_detail.end_time()
#         r.detail_stack.pop()
#         if r.detail_stack:
#             r.current_detail = r.detail_stack[-1]
#         else:
#             r.current_detail = None
#         self.save_details()
# 
#     @abstractmethod
#     def run(self, *args, **kwargs):
#         pass
# 
# Path: djenga/celery/utils.py
# def auto_step(key, description=None,
#               start_detail='in progress', end_detail='done'):
#     """
#     Make sure to apply the `@auto_step` decorator **before** the `@app.task`
#     decorator.  e.g.
# 
#             @app.task(bind=True, name='my.cool_task',
#                       base='djenga.celery.tasks.DetailTask')
#             @auto_step(key=1, description='eat cookies')
#             def eat_cookies(self):
#                 pass
#     :param key:
#     :param description:
#     :param start_detail:
#     :param end_detail:
#     :return:
#     """
#     def decorator(fn):
#         @wraps(fn)
#         def decorated(self, *args, **kwargs):
#             error = None
#             self.start_step(key, description, start_detail)
#             try:
#                 result = fn(self, *args, **kwargs)
#                 return result
#             except Exception as ex:
#                 error = '%s' % (ex,)
#                 raise
#             finally:
#                 self.end_step(error, end_detail)
#         return decorated
#     return decorator


import os
    import logging
    import time
    import logging
from celery import Celery
from celery.signals import after_setup_logger
from celery.signals import worker_process_init
from djenga.celery.tasks import DetailTask
        from djenga.celery.tasks import DetailTask
        from djenga.celery.backends import patch_aliases
        from datetime import datetime
from djenga.celery.utils import auto_step
from __future__ import absolute_import, unicode_literals


# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djenga_tests.settings')


class DjengaCelery(Celery):
    def __init__(self, main=None, loader=None, backend=None,
                 amqp=None, events=None, log=None, control=None,
                 set_as_current=True, tasks=None, broker=None, include=None,
                 changes=None, config_source=None, fixups=None, task_cls=None,
                 autofinalize=True, namespace=None, strict_typing=True,
                 **kwargs):
        patch_aliases()
        super().__init__(main, loader, backend, amqp, events, log, control,
                         set_as_current, tasks, broker, include, changes,

# Path: djenga/celery/tasks.py
# class DetailTask(Task):
#     steps = None
# 
#     def __init__(self, steps=None):
#         super().__init__()
#         self.steps = self.steps or []
#         self.details = OrderedDict()
#         for key, description in self.steps:
#             self.details[key] = description
# 
#     def initialize_detail(self):
#         if not hasattr(self.request, 'details'):
#             self.request.details = OrderedDict([
#                 (key, TaskDetail(key, description),)
#                 for key, description in self.details.items()
#             ])
#             self.request.detail_stack = list()
#             self.request.current_detail = None
# 
#     def save_details(self):
#         if self.request.id:
#             self.backend.store_result(
#                 self.request.id,
#                 result=None,
#                 state=states.STARTED,
#                 details=self.request.details)
# 
#     def start_step(self, key, description=None, detail='in progress'):
#         self.initialize_detail()
#         r = self.request
#         if key not in r.details:
#             r.current_detail = r.details.setdefault(
#                 key, TaskDetail(key, description))
#         else:
#             r.current_detail = r.details[key]
#         r.current_detail.start_time()
#         r.current_detail.add_detail(detail)
#         r.detail_stack.append(r.current_detail)
#         logger.info(
#             '[%s/%s] %s', r.current_detail.key,
#             r.current_detail.description, detail)
#         self.save_details()
# 
#     def update_step(self, detail, *args):
#         self.initialize_detail()
#         r = self.request
#         if args:
#             try:
#                 detail = detail % args
#             except Exception as ex:  # pylint: disable=broad-except
#                 logger.exception('%s', ex)
#         r.current_detail.add_detail(detail)
#         logger.info(
#             '[%s/%s] %s', r.current_detail.key,
#             r.current_detail.description, detail)
#         self.save_details()
# 
#     def end_step(self, error=None, detail='done'):
#         self.initialize_detail()
#         r = self.request
#         if error:
#             r.current_detail.error = error
#             r.current_detail.add_detail(error)
#             logger.info(
#                 '[%s/%s] %s', r.current_detail.key,
#                 r.current_detail.description, error)
#         else:
#             r.current_detail.add_detail(detail)
#             logger.info(
#                 '[%s/%s] %s', r.current_detail.key,
#                 r.current_detail.description, detail)
#         r.current_detail.end_time()
#         r.detail_stack.pop()
#         if r.detail_stack:
#             r.current_detail = r.detail_stack[-1]
#         else:
#             r.current_detail = None
#         self.save_details()
# 
#     @abstractmethod
#     def run(self, *args, **kwargs):
#         pass
# 
# Path: djenga/celery/utils.py
# def auto_step(key, description=None,
#               start_detail='in progress', end_detail='done'):
#     """
#     Make sure to apply the `@auto_step` decorator **before** the `@app.task`
#     decorator.  e.g.
# 
#             @app.task(bind=True, name='my.cool_task',
#                       base='djenga.celery.tasks.DetailTask')
#             @auto_step(key=1, description='eat cookies')
#             def eat_cookies(self):
#                 pass
#     :param key:
#     :param description:
#     :param start_detail:
#     :param end_detail:
#     :return:
#     """
#     def decorator(fn):
#         @wraps(fn)
#         def decorated(self, *args, **kwargs):
#             error = None
#             self.start_step(key, description, start_detail)
#             try:
#                 result = fn(self, *args, **kwargs)
#                 return result
#             except Exception as ex:
#                 error = '%s' % (ex,)
#                 raise
#             finally:
#                 self.end_step(error, end_detail)
#         return decorated
#     return decorator


# Path: djenga_tests/celery.py
import os
    import logging
    import time
    import logging
from celery import Celery
from celery.signals import after_setup_logger
from celery.signals import worker_process_init
from djenga.celery.tasks import DetailTask
        from djenga.celery.tasks import DetailTask
        from djenga.celery.backends import patch_aliases
        from datetime import datetime
from djenga.celery.utils import auto_step

from __future__ import absolute_import, unicode_literals


# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djenga_tests.settings')


class DjengaCelery(Celery):
    def __init__(self, main=None, loader=None, backend=None,
                 amqp=None, events=None, log=None, control=None,
                 set_as_current=True, tasks=None, broker=None, include=None,
                 changes=None, config_source=None, fixups=None, task_cls=None,
                 autofinalize=True, namespace=None, strict_typing=True,
                 **kwargs):
        patch_aliases()
        super().__init__(main, loader, backend, amqp, events, log, control,
                         set_as_current, tasks, broker, include, changes,

                         config_source, fixups, task_cls=DetailTask,