Beispiel #1
0
 def get(self, *args, **kwargs):
     tid = kwargs.get('tid')
     task = Task.get(id=tid)
     return self.render('comment.html',
                        errors={},
                        auth=self.auth,
                        task=task)
Beispiel #2
0
def incomplete_tasks():
    # If the visitor is not logged in as a user:
    # Then redirect them to the login page
    if 'username' not in session:
        return redirect(url_for('login'))

    # if the request method is post
    if request.method == 'POST':
        # Then retrieve the username from the session and find its user
        user = User.get(User.name == session['username'])
        # Retrieve the task_id from the form submission
        # and use it to find the associated task
        task = Task.get(request.form['task_id'] == Task.id)
        # Update the task to indicate that it has been completed
        # at datetime.now() by the current user.
        # update is a peewee function
        task.update(performed_by=user.name, performed=datetime.now())
        #task.execute() # throws an error
        print(type(task))
        Task.update(performed=datetime.now(), performed_by=user)\
            .where(Task.id == request.form['task_id'])\
            .execute()

    # Retrieve a list of all incomplete tasks & pass to renderer
    incomplete = Task.select().where(Task.performed.is_null())
    return render_template('incomplete.jinja2', tasks=incomplete)
Beispiel #3
0
    def create_org_tasks(self, user, cohort_date=datetime.datetime.today()):
        org = Organization.create(name='Org Foo')
        org.put()

        org.tasklist.open(user)

        return (org, Task.get(ancestor=org, order='ordinal'))
Beispiel #4
0
 def get(self, *args, **kwargs):
     tid = kwargs.get('tid')
     mode = kwargs.get('mode')
     if not tid:
         raise HTTPError(404)
     p_users = Auth.find_project_users(pid=self.pid)
     self.p_users = [{'id': auth.user_id, 'name': auth.user_name} for auth in p_users]
     self.json_p_users = json.dumps(self.p_users)
     task = Task.get(id=tid)
     if not mode:  # 任务详细信息
         # get comment
         task_comments = Comment.find(task_id=task.id, order_by='created')
         # get change log
         task_logs = TaskLog.find(task_id=task.id, order_by='created desc')
         # focus
         focus = TaskFocus.check_focus(task_id=task.id, user_id=self.user.id)
         return self.render('task.html',
                            task=task,
                            auth=self.auth,
                            logs=task_logs,
                            comments=task_comments,
                            focus=focus)
     if mode == 'solve':  # 标记解决任务
         if not task.is_done:
             task.status = Task._status_solved
             task.save()
             TaskLog.new(
                 task_id=task.id,
                 desc=json.dumps([]),
                 note=u'标记为解决',
                 updater_id=self.user.id,
                 updater_name=self.user.name,
             )
         return self.redirect('/%s/%s/%s' % (self.pid, 'task', task.id))
     if mode == 'edit':  # 编辑任务
         # 用户列表去除已经分配的用户
         users = [u for u in self.p_users if u['id'] not in task.assigned_ids]
         json_p_users = json.dumps(users)
         task_data = task.dictify()
         task_data['assigneds'] = json.dumps(task.assigned_users)
         return self.render(
             'task-new.html',
             task=task_data,
             auth=self.auth,
             json_users=json_p_users,
             statuses=self.statuses,
             types=self.types,
             priorities=self.priorities,
             errors={},
             update=True)
     if mode == 'focus':  # 关注任务
         TaskFocus.focus(
             task=task,
             user=self.user,
             pid=self.pid,
             pname=self.auth.project_name,
         )
         return self.redirect('/%s/%s/%s' % (self.pid, 'task', task.id))
Beispiel #5
0
 def test_task_creation(self):
     project = Project.create(program_label='demo-program',
                              organization_id='Organization_Foo')
     project.put()
     tasks = Task.get(ancestor=project)
     program_config = Program.get_config(project.program_label)
     template = program_config['project_tasklist_template']
     num_tasks = sum([len(checkpoint['tasks']) for checkpoint in template])
     self.assertEqual(len(tasks), num_tasks)
Beispiel #6
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
Beispiel #7
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
Beispiel #8
0
 def post(self, *args, **kwargs):
     tid = kwargs.get('tid')
     if not tid:
         raise HTTPError(404)
     task = Task.get(id=tid)
     form = CommentForm(self.request.arguments)
     # set form data
     form.from_user_id.data = self.user.id
     form.from_user_name.data = self.user.name
     form.to_user_id.data = task.creator_id
     form.to_user_name.data = task.creator_name
     form.task_id.data = task.id
     form.task_title.data = task.title
     # 分析content 识别链接, 识别@
     # 链接 <a>url</a>
     content, at_users = analyse_content(form.content.data)
     print '****************content: ', repr(content)
     form.type.data = Comment._type_at if at_users else Comment._type_reply
     form.content.data = content
     if form.validate():
         comment = Comment.new(**form.data)
         # 评论消息 自己回复自己或者自己@自己不发消息
         if int(self.user.id) != int(task.creator_id):
             Message.set(
                 user_id=task.creator_id,
                 from_user=self.user,
                 task=task,
                 pid=self.pid,
                 pname=self.auth.project_name,
                 type='apply',
                 content=content,
             )
         # @消息
         for name in at_users:
             user = User.get(name=name, status=User._status_ok)
             if user and user.id != int(self.user.id):
                 Message.set(
                     user_id=user.id,
                     from_user=self.user,
                     task=task,
                     pid=self.pid,
                     pname=self.auth.project_name,
                     type='@',
                     content=content,
                 )
         return self.redirect('/%s/task/%s' % (self.pid, task.id))
     else:
         return self.render('comment.html',
                            errors=form.errors,
                            auth=self.auth,
                            task=task)
Beispiel #9
0
 def test_task_creation(self):
     program_label = 'demo-program'
     program_config = Program.get_config(program_label)
     template = program_config['surveys'][0]['survey_tasklist_template']
     survey = Survey.create(
         template,
         program_label=program_label,
         organization_id='Organization_Foo',
         ordinal=1,
     )
     survey.put()
     tasks = Task.get(ancestor=survey)
     num_tasks = sum([len(checkpoint['tasks']) for checkpoint in template])
     self.assertEqual(len(tasks), num_tasks)
Beispiel #10
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)
Beispiel #11
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)
Beispiel #12
0
 def post(self, *args, **kwargs):
     tid = kwargs.get('tid')
     if not tid:
         raise HTTPError(404)
     task = Task.get(id=tid)
     form = CommentForm(self.request.arguments)
     # set form data
     form.from_user_id.data = self.user.id
     form.from_user_name.data = self.user.name
     form.to_user_id.data = task.creator_id
     form.to_user_name.data = task.creator_name
     form.task_id.data = task.id
     form.task_title.data = task.title
     # 分析content 识别链接, 识别@
     # 链接 <a>url</a>
     content, at_users = analyse_content(form.content.data)
     print '****************content: ', repr(content)
     form.type.data = Comment._type_at if at_users else Comment._type_reply
     form.content.data = content
     if form.validate():
         comment = Comment.new(**form.data)
         # 评论消息 自己回复自己或者自己@自己不发消息
         if int(self.user.id) != int(task.creator_id):
             Message.set(
                 user_id=task.creator_id,
                 from_user=self.user,
                 task=task,
                 pid=self.pid,
                 pname=self.auth.project_name,
                 type='apply',
                 content=content,
             )
         # @消息
         for name in at_users:
             user = User.get(name=name, status=User._status_ok)
             if user and user.id != int(self.user.id):
                 Message.set(
                     user_id=user.id,
                     from_user=self.user,
                     task=task,
                     pid=self.pid,
                     pname=self.auth.project_name,
                     type='@',
                     content=content,
                 )
         return self.redirect('/%s/task/%s' % (self.pid, task.id))
     else:
         return self.render('comment.html', errors=form.errors, auth=self.auth, task=task)
    def tasklist_query_expected(self, liaison, org, project, pc, surveys):
        org.tasklist.open()
        project.tasklist.open()
        for s in surveys:
            s.tasklist.open()

        unexpected_props = ('survey_ids', )
        pc_items = [(k, v) for k, v in pc.to_client_dict().items()
                    if k not in unexpected_props]

        # Assemble the result we expect, being careful to put everything in an
        # explicit order, since that's how the client will see it.
        expected = {
            "project_cohort":
            OrderedDict(pc_items + [
                ('surveys', [s.to_client_dict() for s in surveys]),
                ('checkpoints', [
                    OrderedDict(
                        list(c.to_client_dict().items()) + [
                            ('tasks', [
                                t.to_client_dict() for t in Task.get(
                                    ancestor=DatastoreModel.id_to_key(
                                        c.parent_id),
                                    checkpoint_id=c.uid,
                                    order='ordinal',
                                )
                            ]),
                        ]) for c in Checkpoint.for_tasklist(pc)
                ]),
                ("liaison", liaison.to_client_dict()),
                ("organization",
                 OrderedDict(
                     list(org.to_client_dict().items()) + [
                         ("liaison", liaison.to_client_dict()),
                         ("users", [
                             liaison.to_client_dict(),
                         ]),
                     ])),
                ("program_cohort", self.cohort),
                ("project", project.to_client_dict()),
            ]),
        }

        return graphql_queries.single_tasklist, expected
Beispiel #14
0
    def get(self):
        program_label = 'cg17'
        cohort = Program.get_current_cohort(program_label)

        url = '{protocol}://{domain}/api/scripts/cg'.format(
            protocol='http' if util.is_localhost() else 'https',
            domain=('localhost:9080'
                    if util.is_localhost() else os.environ['RSERVE_DOMAIN']),
        )

        # Look up all the valid project cohorts
        pc_ids = [
            pc_key.id() for pc_key in ProjectCohort.get(
                program_label=program_label,
                cohort_label=cohort['label'],
                status='open',
                keys_only=True,
                n=float('inf'),
            )
        ]

        # To match up the right report tasks, we'll need tasks and checkpoints.
        checkpoints = [
            c for c in Checkpoint.get(
                label='cg17_survey__monitor_1',
                cohort_label=cohort['label'],
                n=float('inf'),
            ) if c.project_cohort_id in pc_ids
        ]
        checkpoint_ids = [c.uid for c in checkpoints]
        tasks = [
            t for t in Task.get(
                label='cg17_survey__report_1',
                n=float('inf'),
            ) if t.checkpoint_id in checkpoint_ids
        ]

        # Alternate way to get tasks, via surveys, which may or may not be
        # more efficient. My current assumption is, for large result sets,
        # SQL-back checkpoints are faster.
        #
        # survey_keys = [s.key for s in Survey.get(
        #     program_label=program_label,
        #     cohort_label=cohort['label'],
        #     n=float('inf'),
        # ) if s.project_cohort_id in pc_ids]
        # tasks = [t for t in Task.get(
        #     label='cg17_survey__report_1',
        #     n=float('inf'),
        # ) if t.key.parent() in survey_keys]

        payload = {
            'reporting_units': [
                self.build_reporting_unit(uid, checkpoints, tasks)
                for uid in pc_ids
            ],
        }

        secrets = ('neptune_sql_credentials', 'big_pipe_credentials',
                   'qualtrics_credentials')
        for s in secrets:
            payload[s] = SecretValue.get(s, None)

        result = urlfetch.fetch(url=url,
                                payload=json.dumps(payload),
                                method=urlfetch.POST,
                                headers={
                                    'Authorization': 'Bearer ' + rserve_jwt(),
                                    'Content-Type': 'application/json',
                                })

        if not result or result.status_code >= 300:
            logging.error("Non-successful response from RServe: {} {}".format(
                result.status_code, result.content))
        else:
            logging.info("response status: {}".format(result.status_code))
            try:
                json.loads(result.content)
                # ok, it's valid
                # logging.info(util.truncate_json(result.content))
                logging.info(result.content)
            except:
                # just log as text
                logging.info(result.content)
Beispiel #15
0
 def get(self, *args, **kwargs):
     tid = kwargs.get('tid')
     task = Task.get(id=tid)
     return self.render('comment.html', errors={}, auth=self.auth, task=task)
Beispiel #16
0
 def post(self, *args, **kwargs):
     """ 编辑任务 并记录更新历史
     """
     tid = kwargs.get('tid')
     mode = kwargs.get('mode')
     if not tid or mode != 'edit':
         raise HTTPError(404)
     p_users = Auth.find_project_users(pid=self.pid)
     self.p_users = [{'id': auth.user_id, 'name': auth.user_name} for auth in p_users]
     self.json_p_users = json.dumps(self.p_users)
     task = Task.get(id=tid)
     post_data = self.request.arguments
     # log note
     log_note = post_data['note'][0].decode('utf8')
     form = TaskForm(self, post_data)
     # redefine task message
     form.creator_id.data = task.creator_id
     form.creator_name.data = task.creator_name
     form.project_id.data = self.pid
     form.created.data = task.created
     # 旧的指派者
     assigned_users = task.assigned_users
     if form.validate():
         task = task.update_and_log(
             data=form.data,
             actor_id=self.user.id,
             actor_name=self.user.name,
             note=log_note)
         if task:
             # 指派用户, 记录消息
             for ud in task.assigned_users:
                 Message.set(user_id=ud['id'],
                             from_user=self.user,
                             task=task,
                             pid=self.pid,
                             pname=self.auth.project_name,
                             type='assigned')
             # 删除更新 未指派用户的消息 为获取用户消息提供服务 物理删除记录
             del_msg_user_ids = [u['id'] for u in assigned_users if u['id'] not in task.assigned_ids]
             for duid in del_msg_user_ids:
                 Message.delete(
                     user_id=duid,
                     type=Message._type_assigned,
                     task_id=task.id,
                     project_id=self.pid
                 )
             # 任务更新消息
             if task.creator_id != self.user.id:
                 Message.set(
                     user_id=task.creator_id,
                     from_user=self.user,
                     task=task,
                     pid=self.pid,
                     pname=self.auth.project_name,
                     type='edit'
                 )
             return self.redirect('/%s/task/%s' % (self.pid, task.id))
         self.add_message(u'更新任务失败, 请重试')
         return self.render('failed.html')
     else:
         # 去除已经填写的用户
         assigneds = json.loads(form.assigneds.data)
         aids = set([ud['id'] for ud in assigneds])
         json_users = json.dumps([ud for ud in self.p_users if ud['id'] not in aids])
         return self.render(
             'task-new.html',
             task=form.data,
             auth=self.auth,
             json_users=json_users,
             statuses=self.statuses,
             types=self.types,
             priorities=self.priorities,
             errors=form.errors,
             update=True)
Beispiel #17
0
 def post(self, *args, **kwargs):
     """ 编辑任务 并记录更新历史
     """
     tid = kwargs.get('tid')
     mode = kwargs.get('mode')
     if not tid or mode != 'edit':
         raise HTTPError(404)
     p_users = Auth.find_project_users(pid=self.pid)
     self.p_users = [{
         'id': auth.user_id,
         'name': auth.user_name
     } for auth in p_users]
     self.json_p_users = json.dumps(self.p_users)
     task = Task.get(id=tid)
     post_data = self.request.arguments
     # log note
     log_note = post_data['note'][0].decode('utf8')
     form = TaskForm(self, post_data)
     # redefine task message
     form.creator_id.data = task.creator_id
     form.creator_name.data = task.creator_name
     form.project_id.data = self.pid
     form.created.data = task.created
     # 旧的指派者
     assigned_users = task.assigned_users
     if form.validate():
         task = task.update_and_log(data=form.data,
                                    actor_id=self.user.id,
                                    actor_name=self.user.name,
                                    note=log_note)
         if task:
             # 指派用户, 记录消息
             for ud in task.assigned_users:
                 Message.set(user_id=ud['id'],
                             from_user=self.user,
                             task=task,
                             pid=self.pid,
                             pname=self.auth.project_name,
                             type='assigned')
             # 删除更新 未指派用户的消息 为获取用户消息提供服务 物理删除记录
             del_msg_user_ids = [
                 u['id'] for u in assigned_users
                 if u['id'] not in task.assigned_ids
             ]
             for duid in del_msg_user_ids:
                 Message.delete(user_id=duid,
                                type=Message._type_assigned,
                                task_id=task.id,
                                project_id=self.pid)
             # 任务更新消息
             if task.creator_id != self.user.id:
                 Message.set(user_id=task.creator_id,
                             from_user=self.user,
                             task=task,
                             pid=self.pid,
                             pname=self.auth.project_name,
                             type='edit')
             return self.redirect('/%s/task/%s' % (self.pid, task.id))
         self.add_message(u'更新任务失败, 请重试')
         return self.render('failed.html')
     else:
         # 去除已经填写的用户
         assigneds = json.loads(form.assigneds.data)
         aids = set([ud['id'] for ud in assigneds])
         json_users = json.dumps(
             [ud for ud in self.p_users if ud['id'] not in aids])
         return self.render('task-new.html',
                            task=form.data,
                            auth=self.auth,
                            json_users=json_users,
                            statuses=self.statuses,
                            types=self.types,
                            priorities=self.priorities,
                            errors=form.errors,
                            update=True)
Beispiel #18
0
 def get(self, *args, **kwargs):
     tid = kwargs.get('tid')
     mode = kwargs.get('mode')
     if not tid:
         raise HTTPError(404)
     p_users = Auth.find_project_users(pid=self.pid)
     self.p_users = [{
         'id': auth.user_id,
         'name': auth.user_name
     } for auth in p_users]
     self.json_p_users = json.dumps(self.p_users)
     task = Task.get(id=tid)
     if not mode:  # 任务详细信息
         # get comment
         task_comments = Comment.find(task_id=task.id, order_by='created')
         # get change log
         task_logs = TaskLog.find(task_id=task.id, order_by='created desc')
         # focus
         focus = TaskFocus.check_focus(task_id=task.id,
                                       user_id=self.user.id)
         return self.render('task.html',
                            task=task,
                            auth=self.auth,
                            logs=task_logs,
                            comments=task_comments,
                            focus=focus)
     if mode == 'solve':  # 标记解决任务
         if not task.is_done:
             task.status = Task._status_solved
             task.save()
             TaskLog.new(
                 task_id=task.id,
                 desc=json.dumps([]),
                 note=u'标记为解决',
                 updater_id=self.user.id,
                 updater_name=self.user.name,
             )
         return self.redirect('/%s/%s/%s' % (self.pid, 'task', task.id))
     if mode == 'edit':  # 编辑任务
         # 用户列表去除已经分配的用户
         users = [
             u for u in self.p_users if u['id'] not in task.assigned_ids
         ]
         json_p_users = json.dumps(users)
         task_data = task.dictify()
         task_data['assigneds'] = json.dumps(task.assigned_users)
         return self.render('task-new.html',
                            task=task_data,
                            auth=self.auth,
                            json_users=json_p_users,
                            statuses=self.statuses,
                            types=self.types,
                            priorities=self.priorities,
                            errors={},
                            update=True)
     if mode == 'focus':  # 关注任务
         TaskFocus.focus(
             task=task,
             user=self.user,
             pid=self.pid,
             pname=self.auth.project_name,
         )
         return self.redirect('/%s/%s/%s' % (self.pid, 'task', task.id))
Beispiel #19
0
def show_task(identifier):
    task = Task.get(Task.uuid == identifier)
    response = task.json
    return Response(response=json.dumps(response),
                    status=200,
                    mimetype="application/json")