Exemple #1
0
    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
Exemple #2
0
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()
Exemple #3
0
    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()
Exemple #4
0
    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
Exemple #5
0
 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)
Exemple #6
0
 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)
Exemple #7
0
    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 {}
Exemple #8
0
    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
Exemple #9
0
    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
Exemple #10
0
    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
Exemple #11
0
    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 {}
Exemple #12
0
    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
Exemple #13
0
    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
Exemple #14
0
    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
Exemple #15
0
 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
Exemple #16
0
 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}
Exemple #17
0
 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)
Exemple #18
0
 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)
Exemple #19
0
 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}