def order_tasks(params, tasks): """ Apply ordering to tasks """ ordering = params.tab.get('ordering', []) # ordering = ['id', 'completed_at', ...] if not check_order_enabled(params): return tasks # remove 'tasks:' prefix for tasks api, for annotations it will be 'annotations:' ordering = [o.replace(TASKS, '') for o in ordering if o.startswith(TASKS) or o.startswith('-' + TASKS)] order = 'id' if not ordering else ordering[0] # we support only one column ordering right now # ascending or descending ascending = order[0] == '-' order = order[1:] if order[0] == '-' else order # id if order == 'id': ordered = sorted(tasks, key=lambda x: x['id'], reverse=ascending) # cancelled: for cancelled_completions use two keys ordering elif order == 'cancelled_completions': ordered = sorted(tasks, key=lambda x: (DirectionSwitch(x.get('cancelled_completions', None), not ascending), DirectionSwitch(x.get('completed_at', None), False))) # another orderings else: ordered = sorted(tasks, key=lambda x: DirectionSwitch(resolve_task_field(x, order), not ascending)) return ordered
def api_all_tasks(): """ Get full tasks with pagination, completions and predictions """ project = project_get_or_create() page, page_size = int(request.args.get('page', 1)), int( request.args.get('page_size', 10)) order = request.args.get('order', 'id') if page < 1 or page_size < 1: return make_response( jsonify({'detail': 'Incorrect page or page_size'}), 422) order_inverted = order[0] == '-' order = order[1:] if order_inverted else order if order not in ['id', 'completed_at', 'has_skipped_completions']: return make_response(jsonify({'detail': 'Incorrect order'}), 422) # get task ids and sort them by completed time task_ids = project.source_storage.ids() completed_at = project.get_completed_at() skipped_status = project.get_skipped_status() # ordering pre_order = [{ 'id': i, 'completed_at': completed_at[i] if i in completed_at else None, 'has_skipped_completions': skipped_status[i] if i in completed_at else None, } for i in task_ids] # for has_skipped_completions use two keys ordering if order == 'has_skipped_completions': ordered = sorted( pre_order, key=lambda x: (DirectionSwitch(x['has_skipped_completions'], order_inverted), DirectionSwitch(x['completed_at'], False))) else: ordered = sorted(pre_order, key=lambda x: (DirectionSwitch(x[order], order_inverted))) paginated = ordered[(page - 1) * page_size:page * page_size] # get tasks with completions tasks = [] for item in paginated: i = item['id'] task = project.get_task_with_completions(i) if task is None: # no completion at task task = project.source_storage.get(i) else: task['completed_at'] = item['completed_at'] task['has_skipped_completions'] = item['has_skipped_completions'] task = resolve_task_data_uri(task) tasks.append(task) return make_response(jsonify(tasks), 200)
def api_all_tasks(): """ Get full tasks with pagination, completions and predictions """ page, page_size = int(request.args.get('page', 1)), int(request.args.get('page_size', 10)) order = request.args.get('order', 'id') if page < 1 or page_size < 1: return make_response(jsonify({'detail': 'Incorrect page or page_size'}), 422) order_inverted = order[0] == '-' order = order[1:] if order_inverted else order if order not in ['id', 'completed_at', 'has_skipped_completions']: return make_response(jsonify({'detail': 'Incorrect order'}), 422) # get task ids and sort them by completed time task_ids = g.project.source_storage.ids() completed_at = g.project.get_completed_at() skipped_status = g.project.get_skipped_status() # ordering pre_order = ({ 'id': i, 'completed_at': completed_at[i] if i in completed_at else None, 'has_skipped_completions': skipped_status[i] if i in completed_at else None, } for i in task_ids) if order == 'id': ordered = sorted(pre_order, key=lambda x: x['id'], reverse=order_inverted) else: # for has_skipped_completions use two keys ordering if order == 'has_skipped_completions': ordered = sorted(pre_order, key=lambda x: (DirectionSwitch(x['has_skipped_completions'], not order_inverted), DirectionSwitch(x['completed_at'], False))) # another orderings else: ordered = sorted(pre_order, key=lambda x: (DirectionSwitch(x[order], not order_inverted))) paginated = ordered[(page - 1) * page_size:page * page_size] # get tasks with completions tasks = [] for item in paginated: if item['completed_at'] != 'undefined' and item['completed_at'] is not None: item['completed_at'] = timestamp_to_local_datetime(item['completed_at']).strftime('%Y-%m-%d %H:%M:%S') i = item['id'] task = g.project.get_task_with_completions(i) if task is None: # no completion at task task = g.project.source_storage.get(i) else: task['completed_at'] = item['completed_at'] task['has_skipped_completions'] = item['has_skipped_completions'] task = resolve_task_data_uri(task, project=g.project) tasks.append(task) return make_response(jsonify(tasks), 200)
def prepare_tasks(project, params): order, page, page_size = params.order, params.page, params.page_size fields = params.fields ascending = order[0] == "-" order = order[1:] if order[0] == "-" else order if order not in ["id", "completed_at", "has_cancelled_completions"]: raise DataManagerException("Incorrect order") # get task ids and sort them by completed time task_ids = project.source_storage.ids() completed_at = ( project.get_completed_at() ) # task can have multiple completions, get the last of completed cancelled_status = project.get_cancelled_status() # ordering pre_order = ({ "id": i, "completed_at": completed_at[i] if i in completed_at else None, "has_cancelled_completions": cancelled_status[i] if i in completed_at else None, } for i in task_ids) if order == "id": ordered = sorted(pre_order, key=lambda x: x["id"], reverse=ascending) else: # for has_cancelled_completions use two keys ordering if order == "has_cancelled_completions": ordered = sorted( pre_order, key=lambda x: ( DirectionSwitch(x["has_cancelled_completions"], not ascending), DirectionSwitch(x["completed_at"], False), ), ) # another orderings else: ordered = sorted(pre_order, key=lambda x: (DirectionSwitch(x[order], not ascending))) paginated = ordered[(page - 1) * page_size:page * page_size] # get tasks with completions tasks = [] for item in paginated: i = item["id"] task = project.get_task_with_completions(i) # no completions at task, get task without completions if task is None: task = project.source_storage.get(i) else: # evaluate completed_at time completed_at = item["completed_at"] if completed_at != "undefined" and completed_at is not None: completed_at = timestamp_to_local_datetime( completed_at).strftime("%Y-%m-%d %H:%M:%S") task["completed_at"] = completed_at task["has_cancelled_completions"] = item[ "has_cancelled_completions"] # don't resolve data (s3/gcs is slow) if it's not in fields if "all" in fields or "data" in fields: task = resolve_task_data_uri(task, project=project) # leave only chosen fields if "all" not in fields: task = {field: task[field] for field in fields} tasks.append(task) return tasks