Example #1
0
def load_fixtures():
    """Load some fixture data into the database."""
    from maproulette.models import Task, Challenge, User
    from random import randrange, random

    # Create a user
    u = User()
    u.osm_id = 8909
    u.osm_username = '******'
    session.add(u)

    for x in range(1, 11):
        c = Challenge()
        c.name = "Challenge {}".format(x)
        c.instruction = "Challenge {} Instruction".format(x)
        session.add(c)

    for x in range(1, 10000):
        t = Task()
        t.challenge_id = randrange(1, 11)
        t.geometry = 'POINT({lon} {lat})'.format(lon=random() * 360 - 180,
                                                 lat=random() * 180 - 90)
        session.add(t)

    session.commit()
Example #2
0
def create_testdata(challenges=10, tasks=100, users=10):
    """Creates test data in the database"""
    import uuid
    import random
    from maproulette import db
    from maproulette.models import User, Challenge, Task, TaskGeometry, Action
    from shapely.geometry import Point, LineString, box

    # statuses to use
    statuses = ['available',
                'skipped',
                'fixed',
                'deleted',
                'alreadyfixed',
                'falsepositive']

    # challenge default strings
    challenge_help_test = "Sample challenge *help* text"
    challenge_instruction_test = "Challenge instruction text"
    task_instruction_text = "Task instruction text"

    # delete old tasks and challenges
    db.session.query(TaskGeometry).delete()
    db.session.query(Action).delete()
    db.session.query(Task).delete()
    db.session.query(Challenge).delete()
    db.session.query(User).delete()
    db.session.commit()

    # create users
    for uid in range(int(users)):
        user = User()
        user.id = uid
        user.display_name = 'Test User {uid}'.format(uid=uid)
        db.session.add(user)
    db.session.commit()

    # create ten challenges
    for i in range(1, int(challenges) + 1):
        print "Generating Test Challenge #%d" % i
        minx = -120
        maxx = -40
        miny = 20
        maxy = 50
        challengepoly = None
        slug = "test%d" % i
        title = "Test Challenge %d" % i
        challenge = Challenge(slug, title)
        challenge.difficulty = random.choice([1, 2, 3])
        challenge.active = True
        challenge.blurb = "This is test challenge number %d" % i
        challenge.description = "This describes challenge %d in detail" % i
        challenge.help = challenge_help_test
        challenge.instruction = challenge_instruction_test
        # have bounding boxes for all but the first two challenges.
        if i > 2:
            minx = random.randrange(-120, -40)
            miny = random.randrange(20, 50)
            maxx = minx + 1
            maxy = miny + 1
            challengepoly = box(minx, miny, maxx, maxy)
            print "\tChallenge has a bounding box of ", challengepoly
            challenge.polygon = challengepoly
        db.session.add(challenge)

        # add some tasks to the challenge
        print "\tGenerating %i tasks for challenge %i" % (int(tasks), i)
        # generate NUM_TASKS random tasks
        for j in range(int(tasks)):
            # generate a unique identifier
            identifier = str(uuid.uuid4())
            # create two random points not too far apart
            task_geometries = []
            p1 = Point(
                random.randrange(minx, maxx) + random.random(),
                random.randrange(miny, maxy) + random.random())
            p2 = Point(
                p1.x + (random.random() * random.choice((1, -1)) * 0.01),
                p1.y + (random.random() * random.choice((1, -1)) * 0.01))
            # create a linestring connecting the two points
            # no constructor for linestring from points?
            l1 = LineString([(p1.x, p1.y), (p2.x, p2.y)])
            # add the first point and the linestring to the task's geometries
            task_geometries.append(TaskGeometry(p1))
            # set a linestring for every other challenge
            if not j % 2:
                task_geometries.append(TaskGeometry(l1))
            # instantiate the task and register it with challenge 'test'
            # Initialize a task with its challenge slug and persistent ID
            task = Task(challenge.slug, identifier, task_geometries)
            # because we are not using the API, we need to call set_location
            # explicitly to set the task's location
            task.set_location()
            # generate random string for the instruction
            task.instruction = task_instruction_text
            # set a status
            action = Action(random.choice(statuses),
                            user_id=random.choice(range(int(users))))
            task.append_action(action)
            # add the task to the session
            db.session.add(task)

    # commit the generated tasks and the challenge to the database.
    db.session.commit()
Example #3
0
def retrieve_osm_data():
    """Get and store the user data from OSM"""

    # FIXME this is a messy function.
    data = osm.get('user/details').data
    app.logger.debug('received data: {}'.format(data))
    if not data or not data.find('user'):
        app.logger.debug('could not authenticate user')
        return False
    userxml = data.find('user')
    osmid = userxml.attrib['id']
    # query for existing user
    if bool(User.query.filter(User.id == osmid).count()):
        app.logger.debug('user exists, getting from database')
        user = User.query.filter(User.id == osmid).first()
    else:
        app.logger.debug('user is new, create local account')
        user = User()
        user.id = osmid
        user.display_name = userxml.attrib['display_name']
        user.osm_account_created = userxml.attrib['account_created']
        homexml = userxml.find('home')
        if homexml is not None:
            lon = float(homexml.attrib['lon'])
            # this is to work around a bug in OSM where the set user longitude
            # can be outside of the -180 ... 180 range if the user panned the
            # map across the 180 / -180 meridian
            lon = abs(lon) % 180 * (lon / abs(lon))
            lat = homexml.attrib['lat']
            user.home_location = WKTElement(
                'POINT(%s %s)' %
                (lon, lat))
            app.logger.debug('setting user home location')
        else:
            app.logger.debug('no home for this user')
        # languages = userxml.find('languages')
        # FIXME parse languages and add to user.languages string field
        user.changeset_count = userxml.find('changesets').attrib['count']
        # get last changeset info
        changesetdata = get_latest_changeset(user.id)
        try:
            lastchangeset = changesetdata.find('changeset')
            if 'min_lon' in lastchangeset.attrib:
                wktbbox = 'POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))' % (
                    lastchangeset.attrib['min_lon'],
                    lastchangeset.attrib['min_lat'],
                    lastchangeset.attrib['min_lon'],
                    lastchangeset.attrib['max_lat'],
                    lastchangeset.attrib['max_lon'],
                    lastchangeset.attrib['max_lat'],
                    lastchangeset.attrib['max_lon'],
                    lastchangeset.attrib['min_lat'],
                    lastchangeset.attrib['min_lon'],
                    lastchangeset.attrib['min_lat'])
                user.last_changeset_bbox = WKTElement(wktbbox)
                user.last_changeset_date = lastchangeset.attrib['created_at']
                user.last_changeset_id = lastchangeset.attrib['id']
        except:
            app.logger.debug('could not get changeset data from OSM')
        db.session.add(user)
        db.session.commit()
        app.logger.debug('user created')
    # we need to convert the GeoAlchemy object to something picklable
    if user.home_location is not None:
        point = to_shape(user.home_location)
        session['home_location'] = [point.x, point.y] or None
    session['display_name'] = user.display_name
    app.logger.debug('session now has display name: %s' %
                     (session['display_name']))
    session['osm_id'] = user.id
    session['difficulty'] = user.difficulty
Example #4
0
def retrieve_osm_data():
    """Get and store the user data from OSM"""

    # FIXME this is a messy function.
    data = osm.get('user/details').data
    app.logger.debug("getting user data from osm")
    if not data:
        # FIXME this requires handling
        return False
    userxml = data.find('user')
    osmid = userxml.attrib['id']
    # query for existing user
    if bool(User.query.filter(User.id == osmid).count()):
        app.logger.debug('user exists, getting from database')
        user = User.query.filter(User.id == osmid).first()
    else:
        app.logger.debug('user is new, create local account')
        user = User()
        user.id = osmid
        user.display_name = userxml.attrib['display_name']
        user.osm_account_created = userxml.attrib['account_created']
        homexml = userxml.find('home')
        if homexml is not None:
            lon = float(homexml.attrib['lon'])
            # this is to work around a bug in OSM where the set user longitude
            # can be outside of the -180 ... 180 range if the user panned the
            # map across the 180 / -180 meridian
            lon = abs(lon) % 180 * (lon / abs(lon))
            lat = homexml.attrib['lat']
            user.home_location = WKTElement('POINT(%s %s)' % (lon, lat))
            app.logger.debug('setting user home location')
        else:
            app.logger.debug('no home for this user')
        # languages = userxml.find('languages')
        # FIXME parse languages and add to user.languages string field
        user.changeset_count = userxml.find('changesets').attrib['count']
        # get last changeset info
        changesetdata = get_latest_changeset(user.id)
        try:
            lastchangeset = changesetdata.find('changeset')
            if 'min_lon' in lastchangeset.attrib:
                wktbbox = 'POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))' % (
                    lastchangeset.attrib['min_lon'],
                    lastchangeset.attrib['min_lat'],
                    lastchangeset.attrib['min_lon'],
                    lastchangeset.attrib['max_lat'],
                    lastchangeset.attrib['max_lon'],
                    lastchangeset.attrib['max_lat'],
                    lastchangeset.attrib['max_lon'],
                    lastchangeset.attrib['min_lat'],
                    lastchangeset.attrib['min_lon'],
                    lastchangeset.attrib['min_lat'])
                user.last_changeset_bbox = WKTElement(wktbbox)
                user.last_changeset_date = lastchangeset.attrib['created_at']
                user.last_changeset_id = lastchangeset.attrib['id']
        except:
            app.logger.debug('could not get changeset data from OSM')
        db.session.add(user)
        db.session.commit()
        app.logger.debug('user created')
    # we need to convert the GeoAlchemy object to something picklable
    if user.home_location is not None:
        point = to_shape(user.home_location)
        session['home_location'] = [point.x, point.y] or None
    session['display_name'] = user.display_name
    app.logger.debug('session now has display name: %s' %
                     (session['display_name']))
    session['osm_id'] = user.id
    session['difficulty'] = user.difficulty
Example #5
0
def create_testdata(challenges=10, tasks=100, users=10):
    """Creates test data in the database"""
    import uuid
    import random
    from maproulette import db
    from maproulette.models import User, Challenge, Task, TaskGeometry, Action
    from shapely.geometry import Point, LineString, box

    # statuses to use
    statuses = ['available',
                'skipped',
                'fixed',
                'deleted',
                'alreadyfixed',
                'falsepositive']

    # challenge default strings
    challenge_help_test = "Sample challenge *help* text"
    challenge_instruction_test = "Challenge instruction text"
    task_instruction_text = "Task instruction text"

    # delete old tasks and challenges
    db.session.query(TaskGeometry).delete()
    db.session.query(Action).delete()
    db.session.query(Task).delete()
    db.session.query(Challenge).delete()
    db.session.query(User).delete()
    db.session.commit()

    # create users
    for uid in range(int(users)):
        user = User()
        user.id = uid
        user.display_name = 'Test User {uid}'.format(uid=uid)
        db.session.add(user)
    db.session.commit()

    # create ten challenges
    for i in range(1, int(challenges) + 1):
        print "Generating Test Challenge #%d" % i
        minx = -120
        maxx = -40
        miny = 20
        maxy = 50
        challengepoly = None
        slug = "test%d" % i
        title = "Test Challenge %d" % i
        challenge = Challenge(slug, title)
        challenge.difficulty = random.choice([1, 2, 3])
        challenge.active = True
        challenge.blurb = "This is test challenge number %d" % i
        challenge.description = "This describes challenge %d in detail" % i
        challenge.help = challenge_help_test
        challenge.instruction = challenge_instruction_test
        # have bounding boxes for all but the first two challenges.
        if i > 2:
            minx = random.randrange(-120, -40)
            miny = random.randrange(20, 50)
            maxx = minx + 1
            maxy = miny + 1
            challengepoly = box(minx, miny, maxx, maxy)
            print "\tChallenge has a bounding box of ", challengepoly
            challenge.polygon = challengepoly
        db.session.add(challenge)

        # add some tasks to the challenge
        print "\tGenerating %i tasks for challenge %i" % (int(tasks), i)
        # generate NUM_TASKS random tasks
        for j in range(int(tasks)):
            # generate a unique identifier
            identifier = str(uuid.uuid4())
            # create two random points not too far apart
            task_geometries = []
            p1 = Point(
                random.randrange(minx, maxx) + random.random(),
                random.randrange(miny, maxy) + random.random())
            p2 = Point(
                p1.x + (random.random() * random.choice((1, -1)) * 0.01),
                p1.y + (random.random() * random.choice((1, -1)) * 0.01))
            # create a linestring connecting the two points
            # no constructor for linestring from points?
            l1 = LineString([(p1.x, p1.y), (p2.x, p2.y)])
            # generate some random 'osm ids'
            osmids = [random.randrange(1000000, 1000000000) for _ in range(2)]
            # add the first point and the linestring to the task's geometries
            task_geometries.append(TaskGeometry(osmids[0], p1))
            # set a linestring for every other challenge
            if not j % 2:
                task_geometries.append(TaskGeometry(osmids[1], l1))
            # instantiate the task and register it with challenge 'test'
            # Initialize a task with its challenge slug and persistent ID
            task = Task(challenge.slug, identifier, task_geometries)
            # because we are not using the API, we need to call set_location
            # explicitly to set the task's location
            task.set_location()
            # generate random string for the instruction
            task.instruction = task_instruction_text
            # set a status
            action = Action(random.choice(statuses),
                            user_id=random.choice(range(int(users))))
            task.append_action(action)
            # add the task to the session
            db.session.add(task)

    # commit the generated tasks and the challenge to the database.
    db.session.commit()