-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.py
181 lines (162 loc) · 7.11 KB
/
server.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
# Dom Parise - 4/13/14
# Response handling server module
# To install dependencies: sudo pip install Flask
#
# submit new user screen refresh back to submit new user
# write tutorial / walkthrough
# comment code
import config_vars
from database import Database
from participant import Participant
from datetime import datetime
from random import random
def is_valid_response(s):
# make sure time is numeric text within 1-100 inclusive
try:
n = int(s)
if n >= 1 and n <= 100 and not n%5 == 0:
return True
else: return False
except:
return False
def valid_time(date_text):
try:
return datetime.strptime(date_text, '%Y-%m-%d')
except:
return False
def valid_number(number):
if len(str(number)) == 11:
return int(number)
return False
db = Database()
participants = dict()
participant_tuples = db.load_participants()
for p in participant_tuples:
participants[p[0]] = Participant(p[0],p[1],p[2],valid_time(p[3]),p[4],p[5])
participants[p[0]].next_message()
from flask import Flask, request, Response, render_template
app = Flask(__name__)
@app.route('/receiver', methods=['POST'])
def respond_to_text():
number = valid_number(request.form['From'][1:])
request_text = request.form['Body']
if number:
db.log(number, 'received', request_text)
if number in participants: # message received from a number we've recently messaged
if participants[number].expecting:
if is_valid_response(request_text): # valid response
participants[number].num_today += 1
update_participant(number,'num_today',participants[number].num_today)
participants[number].next_message()
else: # invalid response, ask for a valid answer
return str('<?xml version="1.0" encoding="UTF-8"?><Response><Message><Body>'+config_vars.invalid_sms_response+'</Body></Message></Response>')
elif participants[number].expectingVerification:
if is_valid_response(request_text):
participants[number].expectingVerification = False
participants[number].next_message()
else:
participants[number].send_verification()
return
@app.route('/new-participant', methods=['GET','POST'])
# display participant, and handle post new participant
def new_participant():
if request.method == 'GET':
return render_template('new-participant.html')
else: # password = economics
if request.form['pwd'] == config_vars.interface_pwd:
# create new participant
lab_day = (valid_time(request.form['lab_day']) - datetime.now()).days
money_day = (valid_time(request.form['money_day']) - datetime.now()).days
phone_number = valid_number(request.form['phone'])
twilio_number = valid_number(request.form['twilio'])
if lab_day and money_day and phone_number and twilio_number:
participants[phone_number] = Participant(phone_number,twilio_number,0,datetime.now(),lab_day,money_day)
db = Database()
db.new_participant(phone_number,twilio_number,lab_day,money_day)
participants[phone_number].send_verification()
return render_template('new-participant.html')
return 'invalid input'
@app.route('/participants', methods=['POST'])
def display_participants():
if request.form['pwd'] == config_vars.interface_pwd:
csv = 'phone_number, twilio_number, current_day <br>'
for number in participants:
p = participants[number]
csv += str(number) + ', ' + str(p.txt.from_number[1:]) +', '+ str(p.day) + '<br>'
return csv
else:
return 'incorrect password'
## need to implement showing current data
@app.route('/participant/<int:number>', methods=['POST'])
def display_participant(number):
if request.form['pwd'] == config_vars.interface_pwd:
if 'edit' in request.form: # show the edit form
return render_template('edit-participant.html', number=number,num_today=participants[number].num_today, current_twilio=participants[number].txt.from_number, current_lab_day=participants[number].lab_day, current_money_day=participants[number].money_day)
elif 'target' in request.form: # begin on target day
today = datetime.today()
time = datetime.strptime(request.form['target_time'],'%H:%M')
when = datetime(year=today.year, month=today.month, day=today.day, hour=time.hour, minute=time.minute)
participants[number].set_next_msg(when)
else:
field = ''
val = None
if 'twilio_number' in request.form:
field = 'twilio_number'
val = request.form['twilio_number_val']
participants[number].txt = TextMessenger(val)
elif 'lab_day' in request.form:
field = 'lab_day'
val = request.form['lab_day_val']
participants[number].lab_day = valid_time(val)
elif 'money_day' in request.form:
field = 'money_day'
val = request.form['money_day_val']
participants[number].money_day = valid_time(val)
db.update_participant(number, field, val)
return 'success'
else:
return 'invalid password'
# tested
@app.route('/email', methods=['GET','POST'])
def handle_email():
if request.method == 'GET':
return render_template('input-email.html')
else:
rand = random()
amt = ''
if rand < 0.25:
amt = '$1'
elif rand >= 0.25 and rand < 0.50:
amt = '$5'
elif rand >= 0.50 and rand < 0.75:
amt = '$25'
elif rand >= 0.75:
amt = '$125'
db.log_email(request.form['email'],amt)
return render_template('amount.html', amount=amt)
@app.route('/data', methods=['GET'])
def display_all_data():
return render_template('data.html')
@app.route('/data/sms', methods=['POST']) #tested
def display_sms_data():
if request.form['pwd'] == config_vars.interface_pwd:
# display the main table
data = db.fetch_logs()
csv = 'time, phone_number, event, content\n'
for datum in data:
csv += str(datum['timestamp']) + ', ' + str(datum['phone']) + ', ' + str(datum['event']) + ', ' + str(datum['content']) + '\n'
return Response(csv,mimetype="text/plain",headers={"Content-Disposition":"attachment;filename=sms.txt"})
else:
return 'incorrect password'
@app.route('/data/email', methods=['POST']) #tested
def display_email():
if request.form['pwd'] == config_vars.interface_pwd:
data = db.fetch_email()
csv = 'time, email, amount_seen\n'
for datum in data:
csv += str(datum['timestamp']) + ', ' + str(datum['email']) + ', ' + str(datum['amount_seen']) + '\n'
return Response(csv,mimetype="text/plain",headers={"Content-Disposition":"attachment;filename=email.txt"})
else:
return 'incorrect password'
if __name__ == "__main__":
app.run(debug=True,host='0.0.0.0',threaded=True)