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)
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)
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)
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)
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)