def put(self, slug, identifier): """Update the task identified by 'identifier' from the challenge identified by 'slug'""" # initialize the parser parser = reqparse.RequestParser() parser.add_argument('action', type=str, help='action cannot be parsed') parser.add_argument('editor', type=str, help="editor cannot be parsed") args = parser.parse_args() # get the task task = get_task_or_404(slug, identifier) # append the latest action to it. task.append_action(Action(args.action, session.get('osm_id'), args.editor)) merged_t = db.session.merge(task) db.session.add(merged_t) try: db.session.commit() except Exception as e: if type(e) == IntegrityError: app.logger.warn(e) db.session.rollback() abort(409, message='The session and the database did not agree for task identifier {identifier}: {message}'.format(id=task.identifier, message=e)) else: app.logger.warn(e) abort(500, message=message_internal_server_error) return {}, 200
def task_by_id(challenge_slug, task_id): "Either displays a task (assigning it) or else posts the commit" # make sure we're authenticated challenge = get_challenge_or_404(challenge_slug, True) task = get_task_or_404(challenge, task_id) osmid = session.get('osm_id') if request.method == 'GET': try: assign = int(request.args.get('assign', 1)) except ValueError: abort(400) if assign: action = Action(task.id, "assigned", osmid) task.current_state = action db.session.add(action) db.session.add(task) return jsonify(marshal(task, task_fields)) elif request.method == 'POST': valid_actions = [button.action for button in challenge.dlg['buttons']] action = None for key in valid_actions: if request.form.get(key): action = Action(task.id, key, osmid) task.current_action = action db.session.add(action) break if not action: abort(400) new_state = challenge.task_status(task) action = Action(task.id, new_state, osmid) task.current_action = action db.session.add(action) db.session.add(task) db.commit()
def delete(self, slug, identifier): """Delete a task""" task = get_task_or_404(slug, identifier) task.append_action(Action('deleted')) db.session.add(task) db.session.commit()
def put(self, slug, identifier): """Update the task identified by 'identifier' from the challenge identified by 'slug'""" # initialize the parser parser = reqparse.RequestParser() parser.add_argument('action', type=str, help='action cannot be parsed') parser.add_argument('editor', type=str, help="editor cannot be parsed") args = parser.parse_args() # get the task task = get_task_or_404(slug, identifier) # append the latest action to it. task.append_action(Action(args.action, session.get('osm_id'), args.editor)) merged_t = db.session.merge(task) db.session.add(merged_t) try: db.session.commit() except Exception as e: if type(e) == IntegrityError: app.logger.warn(e.message) db.session.rollback() abort(409, message='The session and the database did not agree for task identifier {identifier}: {message}'.format(id=task.identifier, message=e.message)) else: app.logger.warn(e.message) abort(500, message=message_internal_server_error) return {}, 200
def get(self, slug, identifier): """Returns the geometries for the task identified by 'identifier' from the challenge identified by 'slug'""" task = get_task_or_404(slug, identifier) geometries = [geojson.Feature( geometry=g.geometry, properties={ 'selected': True, 'osmid': g.osmid}) for g in task.geometries] return geojson.FeatureCollection(geometries)
def put(self, slug, identifier): """Create or update one task. By default, the geometry must be supplied as WKB, but this can be overridden by adding ?geoformat=geojson to the URL""" task_geometries = [] # Get the posted data taskdata = json.loads(request.data) exists = task_exists(slug, identifier) app.logger.debug("taskdata: %s" % (taskdata,)) # abort if the taskdata does not contain geometries and it's a new task if not 'geometries' in taskdata: if not exists: abort(400) else: # extract the geometries geometries = taskdata.pop('geometries') app.logger.debug("geometries: %s" % (geometries,)) app.logger.debug("features: %s" % (geometries['features'],)) # parse the geometries for feature in geometries['features']: app.logger.debug(feature) osmid = feature['properties'].get('osmid') shape = asShape(feature['geometry']) t = TaskGeometry(osmid, shape) task_geometries.append(t) # there's two possible scenarios: # 1. An existing task gets an update, in that case # we only need the identifier # 2. A new task is inserted, in this case we need at # least an identifier and encoded geometries. # now we check if the task exists if exists: # if it does, update it app.logger.debug('existing task') task = get_task_or_404(slug, identifier) if not task.update(taskdata, task_geometries): abort(400) else: # if it does not, create it app.logger.debug('new task') new_task = Task(slug, identifier) new_task.update(taskdata, task_geometries) return {}
def delete(self, slug, identifier): """Delete a task""" t = get_task_or_404(slug, identifier) t.append_action(Action('deleted')) merged_t = db.session.merge(t) db.session.add(merged_t) try: db.session.commit() except Exception as e: if type(e) == IntegrityError: app.logger.warn(e) db.session.rollback() abort(409, message='the session and the database did not agree: {}'.format(e)) else: app.logger.warn(e) abort(500, message=message_internal_server_error) return {}, 204
def delete(self, slug, identifier): """Delete a task""" t = get_task_or_404(slug, identifier) t.append_action(Action('deleted')) merged_t = db.session.merge(t) db.session.add(merged_t) try: db.session.commit() except Exception as e: if type(e) == IntegrityError: app.logger.warn(e.message) db.session.rollback() abort(409, message='the session and the database did not agree: {}'.format(e.message)) else: app.logger.warn(e.message) abort(500, message=message_internal_server_error) return {}, 204
def put(self, slug, identifier): """update one task.""" # Parse the posted data t = json_to_task( slug, json.loads(request.data), task=get_task_or_404(slug, identifier)) db.session.add(t) try: db.session.commit() except Exception as e: if type(e) == IntegrityError: app.logger.warn(e) db.session.rollback() abort(409, message='The session and the database did not agree: {}'.format(e)) else: app.logger.warn(e) abort(500, message='something unexpected happened') return {}, 200
def post(self, slug, identifier): """Update the task identified by 'identifier' from the challenge identified by 'slug'""" # initialize the parser parser = reqparse.RequestParser() parser.add_argument('action', type=str, help='action cannot be parsed') parser.add_argument('editor', type=str, help="editor cannot be parsed") args = parser.parse_args() # get the task task = get_task_or_404(slug, identifier) # append the latest action to it. task.append_action(Action(args.action, session.get('osm_id'), args.editor)) db.session.add(task) db.session.commit() return {}
def put(self, slug, identifier): """update one task.""" # Parse the posted data t = json_to_task( slug, json.loads(request.data), task=get_task_or_404(slug, identifier)) db.session.add(t) try: db.session.commit() except Exception as e: if type(e) == IntegrityError: app.logger.warn(e.message) db.session.rollback() abort(409, message='The session and the database did not agree: {}'.format(e.message)) else: app.logger.warn(e.message) abort(500, message='something unexpected happened') return {}, 200
def put(self, slug): """bulk update""" # Get the data data = json.loads(request.data) # debug output number of tasks being put app.logger.debug('putting {number} tasks...'.format(number=len(data))) if len(data) > app.config['MAX_TASKS_BULK_UPDATE']: abort(400, 'more than 5000 tasks in bulk update') for task in data: if not 'identifier' in task: abort(400, 'task must have identifier') if not isinstance(task['identifier'], basestring): abort(400, 'task identifier must be string') if not re.match("^[\w\d_-]+$", task['identifier']): abort(400, 'identifier should contain only a-z, A-Z, 0-9, _, -') t = json_to_task(slug, task, task=get_task_or_404(slug, task['identifier'])) db.session.add(t) # commit all dirty tasks at once. try: db.session.commit() except Exception as e: if type(e) == IntegrityError: app.logger.warn(e.message) db.session.rollback() abort( 409, 'the session and the database did not agree: {}'.format( e.message)) else: app.logger.warn(e.message) abort(500, 'something unexpected happened') return {}, 200
def put(self, slug): """bulk update""" # Get the data data = json.loads(request.data) # debug output number of tasks being put app.logger.debug('putting {number} tasks...'.format(number=len(data))) if len(data) > app.config['MAX_TASKS_BULK_UPDATE']: abort(400, 'more than 5000 tasks in bulk update') for task in data: if not 'identifier' in task: abort(400, 'task must have identifier') if not isinstance(task['identifier'], basestring): abort(400, 'task identifier must be string') if not re.match("^[\w\d_-]+$", task['identifier']): abort(400, 'identifier should contain only a-z, A-Z, 0-9, _, -') t = json_to_task(slug, task, task=get_task_or_404(slug, task['identifier'])) db.session.add(t) # commit all dirty tasks at once. try: db.session.commit() except Exception as e: if type(e) == IntegrityError: app.logger.warn(e.message) db.session.rollback() abort(409, 'the session and the database did not agree: {}'.format(e.message)) else: app.logger.warn(e.message) abort(500, 'something unexpected happened') return {}, 200
def get(self, slug, identifier): """Returns the geometries for the task identified by 'identifier' from the challenge identified by 'slug'""" task = get_task_or_404(slug, identifier) return task.geometries
def get(self, slug, identifier): """Returns current status for the task identified by 'identifier' from the challenge identified by 'slug'""" task = get_task_or_404(slug, identifier) return {'status': task.status}
def get(self, slug, identifier): """Returns non-geo details for the task identified by 'identifier' from the challenge identified by 'slug'""" task = get_task_or_404(slug, identifier) return marshal(task, task_fields)