Ejemplo n.º 1
0
 def txn():
     task = api.get_task(domain_identifier, task_identifier)
     if not task:
         logging.error("Task '%s/%s' does not exist", domain_identifier, task_identifier)
         return
     index = TaskIndex.get_by_key_name(task_identifier, parent=task)
     if not index:
         index = TaskIndex(parent=task, key_name=task_identifier)
     # Get all subtasks. The ancestor queries are strongly
     # consistent, so when propagating upwards through the
     # hierarchy the changes are reflected.
     subtasks = list(Task.all().ancestor(domain_key).filter("parent_task =", task.key()))
     if not subtasks:  # atomic task
         task.derived_completed = task.completed
         task.derived_size = 1
         task.derived_atomic_task_count = 1
         task.derived_has_open_tasks = task.open()
         assignee_identifier = task.assignee_identifier()
         if assignee_identifier:
             index.assignees = [assignee_identifier]
             if not DEV_SERVER:
                 # Uses a multi entity group transaction to get the name
                 # of the assignee. This is cached in the record for
                 # quick descriptions.
                 assignee = api.get_user(assignee_identifier)
                 name = assignee.name if assignee else "<Missing>"
             else:
                 name = "temp"
             task.derived_assignees[task.assignee_identifier()] = {
                 "id": task.assignee_identifier(),
                 "name": name,
                 "completed": int(task.is_completed()),
                 "all": 1,
             }
     else:  # composite task
         task.derived_completed = all(t.is_completed() for t in subtasks)
         task.derived_size = 1 + sum(t.derived_size for t in subtasks)
         task.derived_atomic_task_count = sum(t.atomic_task_count() for t in subtasks)
         task.derived_has_open_tasks = any(t.has_open_tasks() for t in subtasks)
         # Compute derived assignees, and sum the total of all
         # their assigned and completed subtasks.
         assignees = {}
         for subtask in subtasks:
             subtask_assignees = subtask.derived_assignees
             for id, record in subtask_assignees.iteritems():
                 if not id in assignees:
                     assignees[id] = {"id": id, "name": record["name"], "completed": 0, "all": 0}
                 assignees[id]["completed"] += record["completed"]
                 assignees[id]["all"] += record["all"]
         task.derived_assignees = assignees
         index.assignees = list(assignees.iterkeys())
     task.put()
     index.completed = task.is_completed()
     index.has_open_tasks = task.has_open_tasks()
     index.atomic = task.atomic()
     index.put()
     # Propagate further upwards
     if task.parent_task_identifier():
         UpdateTaskCompletion.enqueue(domain_identifier, task.parent_task_identifier(), transactional=True)
Ejemplo n.º 2
0
 def txn():
     task = api.get_task(domain_identifier, task_identifier)
     if not task:
         logging.error("Task '%s/%s' does not exist", domain_identifier,
                       task_identifier)
         return None
     parent_task = api.get_task(domain_identifier,
                                task.parent_task_identifier())
     if parent_task:
         parent_index = TaskIndex.get_by_key_name(
             parent_task.identifier(), parent=parent_task.key())
         if not parent_index:
             logging.error("Missing index for parent task '%s/%s'",
                           domain_identifier, parent_identifier)
             self.error(400)  # Retry later
             return None
         hierarchy = list(parent_index.hierarchy)
         hierarchy.append(parent_task.identifier())
         level = parent_task.derived_level + 1
     else:  # root task
         hierarchy = []
         level = 0
     index = TaskIndex.get_by_key_name(task_identifier, parent=task)
     if not index:
         index = TaskIndex(parent=task, key_name=task_identifier)
     index.hierarchy = hierarchy
     index.put()
     task.derived_level = level
     task.put()
     return task
Ejemplo n.º 3
0
Archivo: api.py Proyecto: wadevries/sps
 def txn():
     level = root_task.hierarchy_level() + 1 if root_task else 0
     query = TaskIndex.all(keys_only=True).\
         ancestor(Domain.key_from_name(domain_identifier)).\
         filter('assignees =', user.identifier()).\
         filter('level =', level)
     if root_task:
         query.filter('hierarchy =', root_task.identifier())
     fetched = query.fetch(limit)
     tasks = Task.get([key.parent() for key in fetched])
     return tasks
Ejemplo n.º 4
0
 def txn():
     level = root_task.hierarchy_level() + 1 if root_task else 0
     query = TaskIndex.all(keys_only=True).\
         ancestor(Domain.key_from_name(domain_identifier)).\
         filter('assignees =', user.identifier()).\
         filter('level =', level)
     if root_task:
         query.filter('hierarchy =', root_task.identifier())
     fetched = query.fetch(limit)
     tasks = Task.get([key.parent() for key in fetched])
     return tasks
Ejemplo n.º 5
0
 def txn():
     task = api.get_task(domain_identifier, task_identifier)
     if not task:
         logging.error("Task '%s/%s' does not exist",
                       domain_identifier, task_identifier)
         return None
     parent_task = api.get_task(domain_identifier,
                                task.parent_task_identifier())
     if parent_task:
         parent_index = TaskIndex.get_by_key_name(
             parent_task.identifier(),
             parent=parent_task.key())
         if not parent_index:
             logging.error("Missing index for parent task '%s/%s'",
                           domain_identifier, parent_identifier)
             self.error(400) # Retry later
             return None
         hierarchy = list(parent_index.hierarchy)
         hierarchy.append(parent_task.identifier())
         level = parent_task.derived_level + 1
     else:               # root task
         hierarchy = []
         level = 0
     index = TaskIndex.get_by_key_name(task_identifier, parent=task)
     if not index:
         index = TaskIndex(parent=task, key_name=task_identifier)
     index.hierarchy = hierarchy
     index.put()
     task.derived_level = level
     task.put()
     return task
Ejemplo n.º 6
0
def get_all_subtasks(domain, task, limit=50, depth_limit=None):
    """
    Returns a list of all subtasks of the given task, in the order
    as a pre-order traversal through the task hierarchy.

    This function will perform one query for each level of the subtask
    hierarchy.

    Args:
        domain: The domain identifier string.
        task: An instance of the Task model.
        limit: The maximum number of subtasks to return.
        depth_limit: The maximum depth of subtasks in the task
            hierarchy.

    Returns:
        A list with all subtasks of the given task.

    Raises:
        ValueError: The depth_limit or limit are not positive integers
    """
    if not depth_limit:
        #  ListProperties cannot contain more than 5000 elements anyway
        depth_limit = 5000
    if depth_limit < 0 or limit < 0:
        raise ValueError("Invalid limits")

    task_level = task.level
    tasks = []
    for depth in range(depth_limit):
        query = TaskIndex.all(keys_only=True).\
            ancestor(Domain.key_from_name(domain)).\
            filter('level = ', task_level + depth + 1).\
            filter('hierarchy = ', task.identifier())
        fetched = query.fetch(limit)
        tasks.extend(Task.get([key.parent() for key in fetched]))
        limit = limit - len(fetched)
        if not fetched or limit < 1:
            break  # stop

    # Sort the tasks on completion status and then on time, as this is
    # not possible in the query.
    def task_cmp(t1, t2):
        if t1.completed != t2.completed:
            return cmp(t1.completed, t2.completed)
        return -cmp(t1.time, t2.time)

    tasks.sort(cmp=task_cmp)
    return _group_tasks(tasks)
Ejemplo n.º 7
0
Archivo: api.py Proyecto: edrijver/sps
def get_all_subtasks(domain, task, limit=50, depth_limit=None):
    """
    Returns a list of all subtasks of the given task, in the order
    as a pre-order traversal through the task hierarchy.

    This function will perform one query for each level of the subtask
    hierarchy.

    Args:
        domain: The domain identifier string.
        task: An instance of the Task model.
        limit: The maximum number of subtasks to return.
        depth_limit: The maximum depth of subtasks in the task
            hierarchy.

    Returns:
        A list with all subtasks of the given task.

    Raises:
        ValueError: The depth_limit or limit are not positive integers
    """
    if not depth_limit:
        #  ListProperties cannot contain more than 5000 elements anyway
        depth_limit = 5000
    if depth_limit < 0 or limit < 0:
        raise ValueError("Invalid limits")

    task_level = task.level
    tasks = []
    for depth in range(depth_limit):
        query = TaskIndex.all(keys_only=True).\
            ancestor(Domain.key_from_name(domain)).\
            filter('level = ', task_level + depth + 1).\
            filter('hierarchy = ', task.identifier())
        fetched = query.fetch(limit)
        tasks.extend(Task.get([key.parent() for key in fetched]))
        limit = limit - len(fetched)
        if not fetched or limit < 1:
            break               # stop

    # Sort the tasks on completion status and then on time, as this is
    # not possible in the query.
    def task_cmp(t1, t2):
        if t1.completed != t2.completed:
            return cmp(t1.completed, t2.completed)
        return -cmp(t1.time, t2.time)

    tasks.sort(cmp=task_cmp)
    return _group_tasks(tasks)
Ejemplo n.º 8
0
        def txn():
            # Returns (task, changed) tuple, where changed is set if
            # the task index was updated.
            task = api.get_task(domain_identifier, task_identifier)
            if not task:
                logging.error("Task '%s/%s' does not exist", domain_identifier,
                              task_identifier)
                return None, False
            index = TaskIndex.get_by_key_name(task_identifier, parent=task)
            new_index = False
            if not index:
                index = TaskIndex(parent=task,
                                  key_name=task_identifier,
                                  hierarchy=[],
                                  level=0)
                new_index = True
            parent_identifier = task.parent_task_identifier()
            parent_hierarchy = []
            if parent_identifier:
                parent_key = task.parent_task_key()
                parent_index = TaskIndex.get_by_key_name(parent_identifier,
                                                         parent=parent_key)
                if not parent_index:
                    logging.error("Missing index for parent task '%s/%s'",
                                  domain_identifier, parent_identifier)
                    self.error(500)  # Retry
                    return None, False
                parent_hierarchy = parent_index.hierarchy

            hierarchy = parent_hierarchy
            if parent_identifier:
                hierarchy.append(parent_identifier)
            if (force_update or new_index
                    or set(index.hierarchy) ^ set(hierarchy)):
                index.hierarchy = hierarchy
                index.level = len(hierarchy)
                index.put()
                return task, True
            return task, False
Ejemplo n.º 9
0
        def txn():
            # Returns (task, changed) tuple, where changed is set if
            # the task index was updated.
            task = api.get_task(domain_identifier, task_identifier)
            if not task:
                logging.error("Task '%s/%s' does not exist",
                              domain_identifier, task_identifier)
                return None, False
            index = TaskIndex.get_by_key_name(task_identifier, parent=task)
            new_index = False
            if not index:
                index = TaskIndex(parent=task,
                                  key_name=task_identifier,
                                  hierarchy=[],
                                  level=0)
                new_index = True
            parent_identifier = task.parent_task_identifier()
            parent_hierarchy = []
            if parent_identifier:
                parent_key = task.parent_task_key()
                parent_index = TaskIndex.get_by_key_name(parent_identifier,
                                                         parent=parent_key)
                if not parent_index:
                    logging.error("Missing index for parent task '%s/%s'",
                                  domain_identifier, parent_identifier)
                    self.error(500) # Retry
                    return None, False
                parent_hierarchy = parent_index.hierarchy

            hierarchy = parent_hierarchy
            if parent_identifier:
                hierarchy.append(parent_identifier)
            if (force_update
                or new_index
                or set(index.hierarchy) ^ set(hierarchy)):
                index.hierarchy = hierarchy
                index.level = len(hierarchy)
                index.put()
                return task, True
            return task, False
Ejemplo n.º 10
0
 def txn():
     task = api.get_task(domain_identifier, task_identifier)
     if not task:
         logging.error("Task '%s/%s' does not exist", domain_identifier,
                       task_identifier)
         return
     index = TaskIndex.get_by_key_name(task_identifier, parent=task)
     if not index:
         index = TaskIndex(parent=task, key_name=task_identifier)
     # Get all subtasks. The ancestor queries are strongly
     # consistent, so when propagating upwards through the
     # hierarchy the changes are reflected.
     subtasks = list(Task.all().ancestor(domain_key).filter(
         'parent_task =', task.key()))
     if not subtasks:  # atomic task
         task.derived_completed = task.completed
         task.derived_size = 1
         task.derived_atomic_task_count = 1
         task.derived_has_open_tasks = task.open()
         assignee_identifier = task.assignee_identifier()
         if assignee_identifier:
             index.assignees = [assignee_identifier]
             if not DEV_SERVER:
                 # Uses a multi entity group transaction to get the name
                 # of the assignee. This is cached in the record for
                 # quick descriptions.
                 assignee = api.get_user(assignee_identifier)
                 name = assignee.name if assignee else '<Missing>'
             else:
                 name = 'temp'
             task.derived_assignees[task.assignee_identifier()] = {
                 'id': task.assignee_identifier(),
                 'name': name,
                 'completed': int(task.is_completed()),
                 'all': 1
             }
     else:  # composite task
         task.derived_completed = all(t.is_completed()
                                      for t in subtasks)
         task.derived_size = 1 + sum(t.derived_size for t in subtasks)
         task.derived_atomic_task_count = sum(t.atomic_task_count()
                                              for t in subtasks)
         task.derived_has_open_tasks = any(t.has_open_tasks()
                                           for t in subtasks)
         # Compute derived assignees, and sum the total of all
         # their assigned and completed subtasks.
         assignees = {}
         for subtask in subtasks:
             subtask_assignees = subtask.derived_assignees
             for id, record in subtask_assignees.iteritems():
                 if not id in assignees:
                     assignees[id] = {
                         'id': id,
                         'name': record['name'],
                         'completed': 0,
                         'all': 0
                     }
                 assignees[id]['completed'] += record['completed']
                 assignees[id]['all'] += record['all']
         task.derived_assignees = assignees
         index.assignees = list(assignees.iterkeys())
     task.put()
     index.completed = task.is_completed()
     index.has_open_tasks = task.has_open_tasks()
     index.atomic = task.atomic()
     index.put()
     # Propagate further upwards
     if task.parent_task_identifier():
         UpdateTaskCompletion.enqueue(domain_identifier,
                                      task.parent_task_identifier(),
                                      transactional=True)