-
Notifications
You must be signed in to change notification settings - Fork 27
/
manage.py
executable file
·203 lines (172 loc) · 6.73 KB
/
manage.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#!/usr/bin/env python
import os
import sys
import subprocess
from flask_runner import Manager
from maproulette import app, db
from flask_migrate import MigrateCommand, Migrate
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
@manager.command
def clean_pyc():
"""Removes all *.pyc files from the project folder"""
clean_command = "find . -name *.pyc -delete".split()
subprocess.call(clean_command)
@manager.command
def drop_db():
"""Creates the database tables"""
db.drop_all()
@manager.command
def create_db():
"""Creates the database tables"""
db.create_all()
@manager.command
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()
@manager.command
def clean_stale_tasks():
from maproulette import db
from maproulette.models import Task, Action
from sqlalchemy.sql.functions import max
from datetime import datetime, timedelta
import pytz
current_time = datetime.now(pytz.utc)
stale_threshold = current_time - timedelta(hours=1)
counter = 0
for task in db.session.query(Task).filter(
Task.status.in_(['assigned', 'editing'])).join(
Task.actions).group_by(
Task.identifier, Task.challenge_slug).having(max(Action.timestamp) < stale_threshold).all():
task.append_action(Action("available"))
db.session.add(task)
print("setting task %s to available" % (task.identifier))
counter += 1
db.session.commit()
print('done. %i tasks made available' % counter)
@manager.command
def populate_task_location():
"""This command populates the new location field for each task"""
from maproulette import db
from maproulette.models import Task, Challenge
for challenge in db.session.query(Challenge):
counter = 0
for task in db.session.query(Task).filter_by(
challenge_slug=challenge.slug):
task.set_location()
counter += 1
# commit every 1000
if not counter % 1000:
db.session.commit()
db.session.commit()
print('done. Location for %i tasks in challenge %s set' %\
(counter, challenge.title))
@manager.command
def clean_sessions():
"""Remove all stored sessions"""
session_dir = './sessiondata'
for f in os.listdir(session_dir):
file_path = os.path.join(session_dir, f)
try:
if os.path.isfile(file_path):
os.unlink(file_path)
except Exception as e:
print(e)
if __name__ == "__main__":
manager.run()