app/soc/tasks/helper/decorators.py
changeset 2995 5931e6d6056f
parent 2993 e412510746dc
equal deleted inserted replaced
2994:24db4afbc82e 2995:5931e6d6056f
    25 
    25 
    26 import logging
    26 import logging
    27 
    27 
    28 from functools import wraps
    28 from functools import wraps
    29 
    29 
       
    30 from google.appengine.ext import db
       
    31 
    30 from soc.tasks import responses as task_responses
    32 from soc.tasks import responses as task_responses
    31 
    33 
    32 
    34 
    33 def task(func):
    35 def task(func):
    34   """Task decorator wrapper method
    36   """Task decorator wrapper method
    49       return task_responses.repeatTask()
    51       return task_responses.repeatTask()
    50 
    52 
    51   return wrapper
    53   return wrapper
    52 
    54 
    53 
    55 
    54 def iterative_task(func):
    56 def iterative_task(logic, **task_default):
    55   """Iterative wrapper method
    57   """Iterative wrapper method
       
    58 
       
    59   Args:
       
    60     logic: the Logic instance to get entities for
       
    61     task_default: keyword arguments which can contain the following options:
       
    62       fields: dictionary to filter the entities on
       
    63       start_key: the default key where to start this iterative task
    56   """
    64   """
    57 
    65 
    58   @wraps(func)
    66   def wrapper(func):
    59   def wrapper(request, *args, **kwargs):
    67     def iterative_wrapped(request, *args, **kwargs):
    60     """Decorator wrapper method
    68       """Decorator wrapper method
    61 
    69 
    62     Params usage:
    70       Args:
    63       logic: name of the logic for the data model to iterate through
    71         request: Django HTTP Request object
    64       filter: a dict for the properties that the entities should have
       
    65       order: a list with the sort order
       
    66       json: json object with additional parameters
       
    67 
    72 
    68     Returns:
    73       request.POST usage:
    69       Standard http django response
    74         fields: a JSON dict for the properties that the entities should have.
    70     """
    75           This updates values from the task_default entry.
       
    76         start_key: the key of the next entity to fetch
    71 
    77 
    72     post_dict = request.POST
    78       Returns:
       
    79         Standard HTTP Django response
       
    80       """
    73 
    81 
    74     if 'logic' not in post_dict:
    82       post_dict = request.POST
    75        return task_responses.terminateTask()
       
    76 
    83 
    77     _temp = __import__(post_dict['logic'], globals(), locals(), ['logic'], -1)
    84       fields = task_default.get('fields', {})
    78     logic = _temp.logic
    85       if 'fields' in post_dict:
       
    86         fields.update(simplejson.loads(post_dict['fields']))
    79 
    87 
    80     filter = None
    88       start_key = task_default.get('start_key', None)
    81     if 'filter' in post_dict:
    89       if 'start_key' in post_dict:
    82       filter = simplejson.loads(post_dict['filter'])
    90         # get the key where to start this iteration
       
    91         start_key = post_dict['start_key']
       
    92       if start_key:
       
    93         start_key = db.Key(start_key)
    83 
    94 
    84     order = None
    95       # get the entities for this iteration
    85     if 'order' in post_dict:
    96       entities, next_start_key = logic.getBatchOfData(filter=fields,
    86       order = simplejson.loads(post_dict['order'])
    97                                                       start_key=start_key)
    87 
    98 
    88     start_key = None
    99       # copy the post_dict so that the wrapped function can edit what it needs
    89     if 'start_key' in post_dict:
       
    90       start_key = db.Key(post_dict['start_key'])
       
    91 
       
    92     json = None
       
    93     if 'json' in post_dict:
       
    94       json = post_dict['json']
       
    95 
       
    96     entities, next_start_key = logic.getBatchOfData(filter, order, start_key)
       
    97 
       
    98     try:
       
    99       new_json = func(request, entities=entities, json=json, *args, **kwargs)
       
   100     except task_responses.FatalTaskError, error:
       
   101       logging.error(error)
       
   102       return task_responses.terminateTask()
       
   103     except Exception, exception:
       
   104       logging.error(exception)
       
   105       return task_responses.repeatTask()
       
   106 
       
   107     if next_start_key:
       
   108       context = post_dict.copy()
   100       context = post_dict.copy()
   109 
   101 
   110       if 'json' in context:
   102       try:
   111         del context['json']
   103         func(request, entities=entities, context=context, *args, **kwargs)
       
   104       except task_responses.FatalTaskError, error:
       
   105         logging.error(error)
       
   106         return task_responses.terminateTask()
       
   107       except Exception, exception:
       
   108         logging.error(exception)
       
   109         return task_responses.repeatTask()
   112 
   110 
   113       context.update({'start_key': next_start_key})
   111       if next_start_key:
       
   112         # set the key to use for the next iteration
       
   113         context.update({'start_key': next_start_key})
   114 
   114 
   115       if new_json is not None:
   115         task_responses.startTask(url=request.path, context=context)
   116         context.update({'json': new_json})
       
   117 
   116 
   118       task_responses.startTask(url=request.path, context=context)
   117       return task_responses.terminateTask()
   119 
   118 
   120     return task_responses.terminateTask()
   119     return iterative_wrapped
   121 
       
   122   return wrapper
   120   return wrapper