-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
264 lines (217 loc) · 6.29 KB
/
app.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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
import datetime, re, sqlite3, requests, random
from flask import *
from tempfile import mkdtemp
from twilio.rest import Client
from twilio.twiml.messaging_response import MessagingResponse
from datetime import timedelta, date, datetime
from operator import itemgetter
from math import sqrt
from threading import Timer
# FLASK SETUP
app = Flask(__name__)
app.secret_key = 'nikhilrocks'
app.config['TEMPLATES_AUTO_RELOAD'] = True
app.config['SESSION_FILE_DIR'] = mkdtemp()
app.config['SESSION_PERMANENT'] = False
app.config['SESSION_TYPE'] = 'filesystem'
# DATABASE
conn = sqlite3.connect('data.db', check_same_thread=False)
db = conn.cursor()
# TWILIO
account_sid = '{INSERT_ACCOUNT_SID}'
auth_token = '{INSERT_AUTH_TOKEN}'
client = Client(account_sid, auth_token)
# GOOGLE MAPS
api_key = '{INSERT_API_KEY}'
# url =
# CHECK INT FUNCTION
def checkInt(i):
try:
int(i)
return True
except ValueError:
return False
# CALC DISTANCE BETWEEN 2 COORDINATE POINTS
def calc(p1, p2):
p1split = p1.split(',')
p2split = p2.split(',')
x1 = float(p1split[0])
y1 = float(p1split[1])
x2 = float(p2split[0])
y2 = float(p2split[1])
xdist = (x2 - x1) * 111.32
ydist = (y2 - y1) * 110.57
dist = sqrt(xdist**2 + ydist**2)*1000
return dist
reports = 0
score = 0
# SMS RESPONSE
@app.route('/sms', methods=['GET', 'POST'])
def sms():
# Retrieve data in database
data = []
db.execute('SELECT * FROM points')
temp = db.fetchall()
for point in temp:
data.append({
'phone': point[0],
'type': point[1],
'severity': point[2].upper(),
'location': point[3],
'time': point[4]
})
# Retrieve users data
users = {}
db.execute('SELECT * FROM users')
userstemp = db.fetchall()
for user in userstemp:
users[user[0]] = user[1]
# Retrieve SMS info
requested = request.form['Body']
requestedlist = requested.split(' ')
number = request.form['From']
'''
if requested.lower() == 'help':
resp = MessagingResponse()
resp.message('To report: report [type] [severity] [location]\n To query: query [location] [radius]')
return str(resp)
'''
if requestedlist[0].lower() == 'report':
if len(requestedlist) != 4:
resp = MessagingResponse()
resp.message('Invalid format. Proper: report [type] [severity] [location]')
return str(resp)
else:
entry = {
'type': requestedlist[1],
'severity': requestedlist[2],
'location': requestedlist[3]
}
global reports
reports += 1
global score
if entry['severity'] == 'LOW':
score += 8
elif entry['severity'] == 'MID' or 'severity' == 'MEDIUM':
score += 5
elif entry['severity'] == 'HIGH':
score += 2
db.execute('INSERT INTO points VALUES (?, ?, ?, ?, ?)', (number, entry['type'], entry['severity'], entry['location'], datetime.now()))
conn.commit()
resp = MessagingResponse()
resp.message('Added! {0} ({1} severity) at {2}'.format(entry['type'], entry['severity'], entry['location']))
t = Timer(300.0, delete)
t.start()
return str(resp)
elif requestedlist[0].lower() == 'query':
if len(requestedlist) != 3:
resp = MessagingResponse()
resp.message('Invalid format. Proper: query [location] [radius]')
return str(resp)
elif not checkInt(requestedlist[2]):
resp = MessagingResponse()
resp.message('Search radius must be numeric.')
return str(resp)
else:
sendMsg = ''
req = {
'location': requestedlist[1],
'radius': float(requestedlist[2])
}
db.execute('SELECT * FROM points')
points = db.fetchall()
validpoints = []
for point in points:
print(calc(req['location'], point[3]))
print(req['radius'])
distance = calc(req['location'], point[3])
if distance <= req['radius']:
validpoints.append({
'number': point[0],
'type': point[1],
'severity': point[2],
'location': point[3],
'dist': distance
})
for point in validpoints:
sendMsg += (u'\n\u2022' + ' ' + str(point['dist']) + ' m away at ' + point['location'] + ': ' + point['type'].title() + ', ' + point['severity'] + ' severity. Pinged by ' + users[point['number']])
if sendMsg == '':
sendMsg = 'No matching queries.'
'''
resp = MessagingResponse()
resp.message(sendMsg)
return str(resp)
'''
message = client.messages.create(
to = number,
from_ = 'FloodGate',
body = sendMsg)
else:
resp = MessagingResponse()
resp.message('Invalid command.')
return str(resp)
return redirect(url_for('/'))
@app.route('/delete')
def delete():
db.execute('SELECT * FROM points')
points = db.fetchall()
for point in points:
if datetime.now() - datetime.strptime(point[4], '%Y-%m-%d %H:%M:%S.%f') > timedelta(seconds=300):
db.execute('DELETE FROM points WHERE time = ?', (point[4],))
global reports
reports -= 1
global score
if point[2] == 'LOW':
score -= 8
elif point[2] == 'MEDIUM' or point[2] == 'MID':
score -= 5
elif point[2] == 'HIGH':
score -= 2
conn.commit()
@app.route('/')
def index():
# Retrieve users data
users = {}
db.execute('SELECT * FROM users')
userstemp = db.fetchall()
for user in userstemp:
users[user[0]] = user[1]
# Get data for map
markers = []
db.execute('SELECT * FROM points')
pointdata = db.fetchall()
for point in pointdata:
markers.append({
'coords': {'lat': float(point[3].split(',')[0]), 'lng': float(point[3].split(',')[1])},
'content': point[3] + ': ' + point[1].title() + ', ' + point[2] + ' severity. Pinged by user.'})
algae = round(random.random()*3+5, 1)
if reports != 0:
score2 = score/reports
else:
score2 = '-'
return render_template('index.html', score = score2, markerdata = markers, algae = algae)
@app.route('/map')
def map():
# Retrieve users data
users = {}
db.execute('SELECT * FROM users')
userstemp = db.fetchall()
for user in userstemp:
users[user[0]] = user[1]
# Get data for map
markers = []
db.execute('SELECT * FROM points')
pointdata = db.fetchall()
for point in pointdata:
markers.append({
'coords': {'lat': float(point[3].split(',')[0]), 'lng': float(point[3].split(',')[1])},
'content': point[3] + ': ' + point[1].title() + ', ' + point[2] + ' severity. Pinged by user.'})
return render_template('map.html', markerdata = markers)
@app.route('/contact')
def contact():
return render_template('contact.html')
@app.route('/howto')
def howto():
return render_template('howto.html')
if __name__ == '__main__':
app.run(debug=True)