def get(self, slug):
        """Returns a task for specified challenge"""
        challenge = get_challenge_or_404(slug, True)
        parser = reqparse.RequestParser()
        parser.add_argument('lon', type=float,
                            help='longitude could not be parsed')
        parser.add_argument('lat', type=float,
                            help='longitude could not be parsed')
        parser.add_argument('assign', type=int, default=1,
                            help='Assign could not be parsed')
        args = parser.parse_args()
        osmid = session.get('osm_id')
        assign = args['assign']
        lon = args['lon']
        lat = args['lat']

        task = None
        if lon and lat:
            coordWKT = 'POINT(%s %s)' % (lat, lon)
            task = Task.query.filter(Task.location.ST_Intersects(
                ST_Buffer(coordWKT, app.config["NEARBUFFER"]))).first()
        if task is None:  # we did not get a lon/lat or there was no task close
            # If no location is specified, or no tasks were found, gather
            # random tasks
            task = get_random_task(challenge)
            app.logger.debug('got task %s' % task.id)
            # If no tasks are found with this method, then this challenge
            # is complete
        if task is None:
            # Send a mail to the challenge admin
            requests.post(
                "https://api.mailgun.net/v2/maproulette.org/messages",
                auth=("api", app.config["MAILGUN_API_KEY"]),
                data={"from": "MapRoulette <*****@*****.**>",
                      "to": ["*****@*****.**"],
                      "subject":
                      "Challenge {} is complete".format(challenge.slug),
                      "text":
                      "{challenge} has no remaining tasks on server {server}".format(
                          challenge=challenge.title,
                          server=url_for('index', _external=True))})
            # Deactivate the challenge
            challenge.active = False
            db.session.add(challenge)
            db.session.commit()
            # Is this the right error?
            return osmerror("ChallengeComplete",
                            "Challenge {} is complete".format(challenge.title))
        if assign:
            task.append_action(Action("assigned", osmid))
            db.session.add(task)

        db.session.commit()
        return marshal(task, task_fields)
Beispiel #2
0
    def get(self, slug):
        """Returns a task for specified challenge"""
        challenge = get_challenge_or_404(slug, True)
        parser = reqparse.RequestParser()
        parser.add_argument('lon', type=float,
                            help='longitude could not be parsed')
        parser.add_argument('lat', type=float,
                            help='longitude could not be parsed')
        parser.add_argument('assign', type=int, default=1,
                            help='Assign could not be parsed')
        args = parser.parse_args()
        osmid = session.get('osm_id')
        assign = args['assign']
        lon = args['lon']
        lat = args['lat']

        task = None
        if lon and lat:
            coordWKT = 'POINT(%s %s)' % (lat, lon)
            task = Task.query.filter(Task.location.ST_Intersects(
                ST_Buffer(coordWKT, app.config["NEARBUFFER"]))).first()
        if task is None:  # we did not get a lon/lat or there was no task close
            # If no location is specified, or no tasks were found, gather
            # random tasks
            task = get_random_task(challenge)
            # If no tasks are found with this method, then this challenge
            # is complete
        if task is None:
            if not user_area_is_defined():
                # send email and deactivate challenge only when
                # there are no more tasks for the entire challenge,
                # not if the user has defined an area to work on.
                subject = "Challenge {} is complete".format(challenge.slug)
                body = "{challenge} has no remaining tasks"
                " on server {server}".format(
                    challenge=challenge.title,
                    server=url_for('index', _external=True))
                send_email("*****@*****.**", subject, body)

                # Deactivate the challenge
                challenge.active = False
                db.session.add(challenge)
                db.session.commit()

            # Is this the right error?
            return osmerror("ChallengeComplete",
                            "Challenge {} is complete".format(challenge.title))
        if assign:
            task.append_action(Action("assigned", osmid))
            db.session.add(task)

        db.session.commit()
        return marshal(task, task_fields)
Beispiel #3
0
def challenge_tasks(challenge_slug):
    "Returns a task for specified challenge"
    challenge = get_challenge_or_404(challenge_slug, True)
    parser = reqparse.RequestParser()
    parser.add_argument('num', type=int, default=1,
                        help='Number of return results cannot be parsed')
    parser.add_argument('near', type=GeoPoint,
                        help='Near argument could not be parsed')
    parser.add_argument('assign', type=int, default=1,
                        help='Assign could not be parsed')
    args = parser.parse_args()
    osmid = session.get('osm_id')
    # By default, we return a single task, but no more than 10
    num = min(args['num'], 10)
    assign = args['assign']
    near = args['near']
    logging.info("{user} requesting {num} tasks from {challenge} near {near} assiging: {assign}".format(user=osmid, num=num, challenge=challenge_slug, near=near, assign=assign))
    task_list = []
    if near:
        coordWKT = 'POINT(%s %s)' % (near.lat, near.lon)
        task_query = Task.query.filter(Task.location.ST_Intersects(
                ST_Buffer(coordWKT, app.config["NEARBUFFER"]))).limit(num)
        task_list = [task for task in task_query
                     if challenge.task_available(task, osmid)]
    if not near or not task_list:
        # If no location is specified, or no tasks were found, gather
        # random tasks
        task_list = [get_random_task(challenge) for _ in range(num)]
        task_list = filter(None, task_list)
        # If no tasks are found with this method, then this challenge
        # is complete
    if not task_list:
        # Is this the right error?
        osmerror("ChallengeComplete",
                 "Challenge {} is complete".format(challenge_slug))
    if assign:
        for task in task_list:
            action = Action(task.id, "assigned", osmid)
            task.current_state = action
            db.session.add(action)
            db.session.add(task)
        db.session.commit()
    logging.info(
        "{num} tasks found matching criteria".format(num=len(task_list)))
    tasks = [marshal(task, task_fields) for task in task_list]
    for query in get_debug_queries():
        app.logger.debug(query)
    return jsonify(tasks=tasks)
Beispiel #4
0
    def get(self, slug):
        """Returns a task for specified challenge"""
        challenge = get_challenge_or_404(slug, True)
        parser = reqparse.RequestParser()
        parser.add_argument('lon', type=float,
                            help='longitude could not be parsed')
        parser.add_argument('lat', type=float,
                            help='longitude could not be parsed')
        parser.add_argument('assign', type=int, default=1,
                            help='Assign could not be parsed')
        args = parser.parse_args()
        osmid = session.get('osm_id')
        assign = args['assign']
        lon = args['lon']
        lat = args['lat']

        app.logger.info(
            "{user} requesting task from {challenge} near\
             ({lon}, {lat}) assiging: {assign}".format(
            user=osmid,
            challenge=slug,
            lon=lon,
            lat=lat,
            assign=assign))

        task = None
        if lon and lat:
            coordWKT = 'POINT(%s %s)' % (lat, lon)
            task = Task.query.filter(Task.location.ST_Intersects(
                ST_Buffer(coordWKT, app.config["NEARBUFFER"]))).first()
        if task is None:  # we did not get a lon/lat or there was no task close
            # If no location is specified, or no tasks were found, gather
            # random tasks
            app.logger.debug('getting random task')
            task = get_random_task(challenge)
            # If no tasks are found with this method, then this challenge
            # is complete
        if task is None:
            # Is this the right error?
            return osmerror("ChallengeComplete",
                            "Challenge {} is complete".format(slug))
        if assign:
            task.append_action(Action("assigned", osmid))
            db.session.add(task)

        db.session.commit()
        return marshal(task, task_fields)
Beispiel #5
0
    def get(self, slug):
        """Returns a task for specified challenge"""
        challenge = get_challenge_or_404(slug, True)
        parser = reqparse.RequestParser()
        parser.add_argument('lon', type=float,
                            help='longitude could not be parsed')
        parser.add_argument('lat', type=float,
                            help='longitude could not be parsed')
        parser.add_argument('assign', type=int, default=1,
                            help='Assign could not be parsed')
        args = parser.parse_args()
        osmid = session.get('osm_id')
        assign = args['assign']
        lon = args['lon']
        lat = args['lat']

        task = None
        if lon and lat:
            coordWKT = 'POINT(%s %s)' % (lat, lon)
            task = Task.query.filter(Task.location.ST_Intersects(
                ST_Buffer(coordWKT, app.config["NEARBUFFER"]))).first()
        if task is None:  # we did not get a lon/lat or there was no task close
            # If no location is specified, or no tasks were found, gather
            # random tasks
            task = get_random_task(challenge)
            # If no tasks are found with this method, then this challenge
            # is complete
        if task is None:
            if not user_area_is_defined():
                # send email and deactivate challenge only when
                # there are no more tasks for the entire challenge,
                # not if the user has defined an area to work on.
                subject = "Challenge {} is complete".format(challenge.slug)
                body = "{challenge} has no remaining tasks"
                " on server {server}".format(
                    challenge=challenge.title,
                    server=url_for('index', _external=True))
                send_email("*****@*****.**", subject, body)

                # Deactivate the challenge
                challenge.active = False
                merged_c = db.session.merge(challenge)
                db.session.add(merged_c)
                db.session.commit()

            # Is this the right error?
            return osmerror("ChallengeComplete",
                            "Challenge {} is complete".format(challenge.title))
        if assign:
            task.append_action(Action("assigned", osmid))
            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 marshal(task, task_fields)