Skip to content

Commit c502584

Browse files
committedNov 28, 2017
herokuify
1 parent 33e6e3c commit c502584

9 files changed

+786
-93
lines changed
 

‎Pipfile

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
[[source]]
2+
3+
url = "https://pypi.python.org/simple"
4+
verify_ssl = true
5+
name = "pypi"
6+
7+
[requires]
8+
python_version = "2.7"
9+
10+
11+
[dev-packages]
12+
13+
14+
15+
[packages]
16+
17+
Flask = "*"
18+
SQLAlchemy = "*"
19+
bcrypt = "*"
20+
"psycopg2" = "*"
21+
itsdangerous = "*"
22+
sendgrid = "*"
23+
bleach = "*"
24+
"markdown2" = "*"
25+
simplejson = "*"
26+
pandas = "*"
27+
gensim = "*"
28+
python-dateutil = "*"
29+
requests = {extras = ["security"]}
30+
pytz = "*"
31+
gevent = "*"
32+
pytest = "*"
33+
mock = "*"
34+
pytest-cov = "*"
35+
gunicorn = "*"
36+
raven = {extras = ["flask"]}

‎Pipfile.lock

+679
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Procfile

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
web: gunicorn app:app --worker-class gevent -b 0.0.0.0:$PORT --log-level=info

‎app.py

+39-39
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
app = Flask(__name__)
2222
app.secret_key = os.environ['FLASK_SECRET_KEY']
2323

24-
app.register_blueprint(bp_admin, url_prefix='/progcom/admin')
24+
app.register_blueprint(bp_admin, url_prefix='/admin')
2525

2626
if 'SENTRY_DSN' in os.environ:
2727
sentry = Sentry(app)
@@ -81,32 +81,32 @@ def security_check():
8181
return redirect(url_for('login'))
8282

8383
path = request.path
84-
if (request.user and path.startswith('/progcom/admin')
84+
if (request.user and path.startswith('/admin')
8585
and request.user.email not in _ADMIN_EMAILS):
8686
abort(403)
8787

88-
if path.startswith('/progcom/screening') and THIS_IS_BATCH:
88+
if path.startswith('/screening') and THIS_IS_BATCH:
8989
abort(403)
9090

91-
if path.startswith('/progcom/batch') and not THIS_IS_BATCH:
91+
if path.startswith('/batch') and not THIS_IS_BATCH:
9292
if request.user and request.user.email not in _ADMIN_EMAILS:
9393
abort(403)
9494

9595
if request.user:
9696
return
9797

98-
safe_prefixes = ('/progcom/static', '/progcom/user', '/progcom/feedback', '/progcom/confirmation')
98+
safe_prefixes = ('/static', '/user', '/feedback', '/confirmation')
9999
for prefix in safe_prefixes:
100100
if path.startswith(prefix):
101101
return
102102

103103
return redirect(url_for('login'))
104104

105-
@app.route('/progcom/user/login/')
105+
@app.route('/user/login/')
106106
def login():
107107
return render_template('user/login.html')
108108

109-
@app.route('/progcom/user/login/', methods=['POST'])
109+
@app.route('/user/login/', methods=['POST'])
110110
def login_post():
111111
uid = l.check_pw(request.values.get('email'),
112112
request.values.get('pw'))
@@ -118,13 +118,13 @@ def login_post():
118118
flash('You have not yet been approved.')
119119
return redirect(url_for('login'))
120120
session['userid'] = uid
121-
return redirect('/progcom/')
121+
return redirect('/')
122122

123-
@app.route('/progcom/user/new/')
123+
@app.route('/user/new/')
124124
def new_user():
125125
return render_template('user/new_user.html')
126126

127-
@app.route('/progcom/user/new/', methods=['POST'])
127+
@app.route('/user/new/', methods=['POST'])
128128
def new_user_post():
129129
email = request.values.get('email')
130130
name = request.values.get('name')
@@ -140,24 +140,24 @@ def new_user_post():
140140
flash('You will be able to log in after your account is approved!')
141141
return redirect(url_for('login'))
142142

143-
@app.route('/progcom/user/logout/')
143+
@app.route('/user/logout/')
144144
def logout():
145145
session.clear()
146146
return redirect(url_for('login'))
147147

148-
@app.route('/progcom/user/email_login/')
148+
@app.route('/user/email_login/')
149149
def request_reset():
150150
return render_template('user/request_reset.html')
151151

152-
@app.route('/progcom/user/email_login/', methods=['POST'])
152+
@app.route('/user/email_login/', methods=['POST'])
153153
def request_reset_post():
154154
if l.send_login_email(request.values.get('email')):
155155
flash('Reset sent')
156156
else:
157157
flash('Reset failed; perhaps a bad email address?')
158158
return redirect(url_for('request_reset'))
159159

160-
@app.route('/progcom/user/login/<key>/')
160+
@app.route('/user/login/<key>/')
161161
def view_reset_key(key):
162162
uid = l.test_login_string(key)
163163
if not uid:
@@ -167,36 +167,36 @@ def view_reset_key(key):
167167
flash('Logged in!')
168168
return redirect(url_for('reset_password'))
169169

170-
@app.route('/progcom/me/change_password/')
170+
@app.route('/me/change_password/')
171171
def reset_password():
172172
return render_template('user/reset_password.html')
173173

174174

175-
@app.route('/progcom/me/change_password/', methods=['POST'])
175+
@app.route('/me/change_password/', methods=['POST'])
176176
def reset_password_post():
177177
l.change_pw(request.user.id, request.values.get('pw'))
178178
flash('Password changed')
179-
return redirect('/progcom/')
179+
return redirect('/')
180180

181181
"""
182182
User State
183183
"""
184-
@app.route('/progcom/votes/')
184+
@app.route('/votes/')
185185
def show_votes():
186186
votes = l.get_my_votes(request.user.id)
187187
votes = [x._replace(updated_on=l._js_time(x.updated_on)) for x in votes]
188188
percent = l.get_vote_percentage(request.user.email, request.user.id)
189189
return render_template('my_votes.html', votes=votes, percent=percent,
190190
standards = l.get_standards())
191191

192-
@app.route('/progcom/unread/')
192+
@app.route('/unread/')
193193
def show_unread():
194194
return render_template('unread.html', unread=l.get_unread(request.user.id))
195195

196196
"""
197197
Batch Actions
198198
"""
199-
@app.route('/progcom/batch/')
199+
@app.route('/batch/')
200200
def batch_splash_page():
201201
groups = [x._asdict() for x in l.list_groups(request.user.id)]
202202
unread = l.get_unread_batches(request.user.id)
@@ -207,20 +207,20 @@ def batch_splash_page():
207207
percent = int( 100.0*sum(1.0 for x in groups if x['voted']) / len(groups))
208208
return render_template('batch/batch.html', groups=groups, percent=percent)
209209

210-
@app.route('/progcom/batch/full/<int:id>/')
210+
@app.route('/batch/full/<int:id>/')
211211
def view_single_proposals(id):
212212
proposal = l.get_proposal(id)
213213
if request.user.email in [x.email for x in proposal.authors]:
214214
abort(404)
215215
return render_template('batch/single_proposal.html', proposal=proposal,
216216
discussion=l.get_discussion(id))
217217

218-
@app.route('/progcom/batch/full/')
218+
@app.route('/batch/full/')
219219
def full_list():
220220
return render_template('batch/full_list.html',
221221
proposals=l.full_proposal_list(request.user.email))
222222

223-
@app.route('/progcom/batch/<int:id>/')
223+
@app.route('/batch/<int:id>/')
224224
def batch_view(id):
225225
l.l('batch_view', uid=request.user.id, gid=id)
226226
group = l.get_group(id)
@@ -252,7 +252,7 @@ def batch_view(id):
252252
all_votes=votes,
253253
vote = vote._asdict() if vote else None)
254254

255-
@app.route('/progcom/batch/<int:id>/vote/', methods=['POST'])
255+
@app.route('/batch/<int:id>/vote/', methods=['POST'])
256256
def batch_vote(id):
257257
group = l.get_group(id)
258258
if request.user.email in group.author_emails or group.locked:
@@ -263,7 +263,7 @@ def batch_vote(id):
263263
l.vote_group(id, request.user.id, accept)
264264
return redirect(url_for('batch_view', id=id))
265265

266-
@app.route('/progcom/batch/<int:id>/comment/', methods=['POST'])
266+
@app.route('/batch/<int:id>/comment/', methods=['POST'])
267267
def batch_discussion(id):
268268
group = l.get_group(id)
269269
if request.user.email in group.author_emails or group.locked:
@@ -274,20 +274,20 @@ def batch_discussion(id):
274274
return render_template('batch/batch_discussion_snippet.html',
275275
msgs=l.get_batch_messages(id))
276276

277-
@app.route('/progcom/batch/nominations/')
277+
@app.route('/batch/nominations/')
278278
def my_nominations():
279279
return render_template('batch/my_pycon.html',
280280
proposals=l.get_my_pycon(request.user.id))
281281

282282
"""
283283
Screening Actions
284284
"""
285-
@app.route('/progcom/activity_buttons/')
285+
@app.route('/activity_buttons/')
286286
def activity_buttons():
287287
return render_template('activity_button_fragment.html')
288288

289289

290-
@app.route('/progcom/screening/stats/')
290+
@app.route('/screening/stats/')
291291
def screening_stats():
292292
users = [x for x in l.list_users() if x.votes]
293293
users.sort(key=lambda x:-x.votes)
@@ -305,7 +305,7 @@ def screening_stats():
305305
active_discussions=active_discussions,
306306
votes_when=votes_when)
307307

308-
@app.route('/progcom/screening/<int:id>/')
308+
@app.route('/screening/<int:id>/')
309309
def screening(id):
310310
l.l('screening_view', uid=request.user.id, id=id)
311311
proposal = l.get_proposal(id)
@@ -333,7 +333,7 @@ def screening(id):
333333
unread=unread,
334334
percent=percent)
335335

336-
@app.route('/progcom/screening/<int:id>/vote/', methods=['POST'])
336+
@app.route('/screening/<int:id>/vote/', methods=['POST'])
337337
def vote(id):
338338
standards = l.get_standards()
339339
scores = {}
@@ -346,7 +346,7 @@ def vote(id):
346346
votes = l.get_votes(id),
347347
existing_vote=l.get_user_vote(request.user.id, id))
348348

349-
@app.route('/progcom/screening/<int:id>/comment/', methods=['POST'])
349+
@app.route('/screening/<int:id>/comment/', methods=['POST'])
350350
def comment(id):
351351
comment = request.values.get('comment').strip()
352352
if comment:
@@ -355,7 +355,7 @@ def comment(id):
355355
unread = l.is_unread(request.user.id, id),
356356
discussion = l.get_discussion(id))
357357

358-
@app.route('/progcom/screening/<int:id>/feedback/', methods=['POST'])
358+
@app.route('/screening/<int:id>/feedback/', methods=['POST'])
359359
def feedback(id):
360360
if CUTOFF_FEEDBACK:
361361
abort(404)
@@ -366,14 +366,14 @@ def feedback(id):
366366
unread = l.is_unread(request.user.id, id),
367367
discussion = l.get_discussion(id))
368368

369-
@app.route('/progcom/screening/<int:id>/mark_read/', methods=['POST'])
369+
@app.route('/screening/<int:id>/mark_read/', methods=['POST'])
370370
def mark_read(id):
371371
l.mark_read(request.user.id, id)
372372
return render_template('discussion_snippet.html',
373373
unread = l.is_unread(request.user.id, id),
374374
discussion = l.get_discussion(id))
375375

376-
@app.route('/progcom/screening/<int:id>/mark_read/next/', methods=['POST'])
376+
@app.route('/screening/<int:id>/mark_read/next/', methods=['POST'])
377377
def mark_read_read_next(id):
378378
l.mark_read(request.user.id, id)
379379
unread = l.get_unread(request.user.id)
@@ -387,7 +387,7 @@ def mark_read_read_next(id):
387387
Author Feedback
388388
"""
389389

390-
@app.route('/progcom/feedback/<key>')
390+
@app.route('/feedback/<key>')
391391
def author_feedback(key):
392392
name, id = l.check_author_key(key)
393393
if not name:
@@ -397,7 +397,7 @@ def author_feedback(key):
397397
proposal=proposal, messages=l.get_discussion(id))
398398

399399

400-
@app.route('/progcom/feedback/<key>', methods=['POST'])
400+
@app.route('/feedback/<key>', methods=['POST'])
401401
def author_post_feedback(key):
402402
if CUTOFF_FEEDBACK:
403403
abort(404)
@@ -416,15 +416,15 @@ def author_post_feedback(key):
416416
Observer View
417417
"""
418418

419-
@app.route('/progcom/schedule/')
419+
@app.route('/schedule/')
420420
def view_schedule():
421421
return render_template('admin/schedule.html', schedule=l.get_schedule(),
422422
talks=l.get_accepted(), read_only=True)
423423

424424
"""
425425
Confirmation
426426
"""
427-
@app.route('/progcom/confirmation/<key>/')
427+
@app.route('/confirmation/<key>/')
428428
def confirmation(key):
429429
id = l.acknowledge_confirmation(key)
430430
if not id:
@@ -435,7 +435,7 @@ def confirmation(key):
435435
"""
436436
Default Action
437437
"""
438-
@app.route('/progcom/')
438+
@app.route('/')
439439
def pick():
440440
if THIS_IS_BATCH:
441441
return redirect(url_for('batch_splash_page'))

‎logic.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def l(key, **data):
3636
"""
3737
Some DB wrapper stuff
3838
"""
39-
_e = create_engine(os.environ['PSQL_CONNECTION_STRING'])
39+
_e = create_engine(os.environ['DATABASE_URL'])
4040

4141
__TUPLE_CACHE = {}
4242
def build_tuple(keys):
@@ -705,8 +705,8 @@ def add_to_discussion(userid, proposal, body, feedback=False, name=None):
705705
full_proposal = get_proposal(proposal)
706706
email = _JINJA.get_template('email/feedback_notice.txt')
707707
for to, key in generate_author_keys(proposal).items():
708-
url = 'http://{}/feedback/{}'.format(_WEB_HOST, key)
709-
edit_url = 'https://us.pycon.org/2018/proposals/{}/'.format(proposal)
708+
url = 'https://{}/feedback/{}'.format(_WEB_HOST, key)
709+
edit_url = 'httpss://us.pycon.org/2018/proposals/{}/'.format(proposal)
710710
rendered = email.render(proposal=full_proposal, body=body,
711711
url=url, edit_url=edit_url)
712712
msg = {
@@ -777,7 +777,7 @@ def send_login_email(email):
777777

778778
body = _JINJA.get_template('email/login_email.txt')
779779
key = _LOGIN_EMAIL_ITSD.dumps(user.id)
780-
url = 'http://{}/progcom/user/login/{}/'.format(_WEB_HOST, key)
780+
url = 'https://{}/user/login/{}/'.format(_WEB_HOST, key)
781781
body = body.render(url=url)
782782

783783
msg = {
@@ -814,7 +814,7 @@ def test_login_string(s):
814814
def email_approved(id):
815815
user = get_user(id)
816816

817-
url = 'http://{}/progcom'.format(_WEB_HOST)
817+
url = 'https://{}'.format(_WEB_HOST)
818818
msg = {
819819
"personalizations": [
820820
{
@@ -1092,7 +1092,7 @@ def send_emails():
10921092
VALUES (%s, %s) RETURNING id'''
10931093
id = scalar(q, p.id, email)
10941094
key = _CONFIRMATION_ITSD.dumps(id)
1095-
url = 'http://{}/confirmation/{}/'.format(_WEB_HOST, key)
1095+
url = 'https://{}/confirmation/{}/'.format(_WEB_HOST, key)
10961096
text = accepted.render(name=name, title=p.data['title'], url=url)
10971097
msg = {
10981098
"personalizations": [

0 commit comments

Comments
 (0)
Please sign in to comment.