forked from hedyorg/hedy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprograms.py
178 lines (151 loc) · 7.34 KB
/
programs.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
from website.auth import requires_login, current_user
import utils
import uuid
from flask import g, request, jsonify
def routes(app, database, achievements):
global DATABASE
global ACHIEVEMENTS
DATABASE = database
ACHIEVEMENTS = achievements
@app.route('/programs_list', methods=['GET'])
@requires_login
def list_programs(user):
return {'programs': DATABASE.programs_for_user(user['username']).records}
@app.route('/programs/delete/', methods=['POST'])
@requires_login
def delete_program(user):
body = request.json
if not isinstance(body.get('id'), str):
return 'program id must be a string', 400
result = DATABASE.program_by_id(body['id'])
if not result or result['username'] != user['username']:
return "", 404
DATABASE.delete_program_by_id(body['id'])
DATABASE.increase_user_program_count(user['username'], -1)
# This only happens in the situation were a user deletes their favourite program -> Delete from public profile
public_profile = DATABASE.get_public_profile_settings(current_user()['username'])
if public_profile and 'favourite_program' in public_profile and public_profile['favourite_program'] == body[
'id']:
DATABASE.set_favourite_program(user['username'], None)
achievement = ACHIEVEMENTS.add_single_achievement(user['username'], "do_you_have_copy")
if achievement:
return {'achievement': achievement}, 200
return {}, 200
@app.route('/programs/duplicate-check', methods=['POST'])
@requires_login
def check_duplicate_program(user):
body = request.json
if not isinstance(body, dict):
return 'body must be an object', 400
if not isinstance(body.get('name'), str):
return 'name must be a string', 400
programs = DATABASE.programs_for_user(user['username'])
for program in programs:
if program['name'] == body['name']:
return jsonify({'duplicate': True})
return jsonify({'duplicate': False})
@app.route('/programs', methods=['POST'])
@requires_login
def save_program(user):
body = request.json
if not isinstance(body, dict):
return 'body must be an object', 400
if not isinstance(body.get('code'), str):
return 'code must be a string', 400
if not isinstance(body.get('name'), str):
return 'name must be a string', 400
if not isinstance(body.get('level'), int):
return 'level must be an integer', 400
if 'adventure_name' in body:
if not isinstance(body.get('adventure_name'), str):
return 'if present, adventure_name must be a string', 400
# We check if a program with a name `xyz` exists in the database for the username.
# It'd be ideal to search by username & program name, but since DynamoDB doesn't allow searching for two indexes at the same time, this would require to create a special index to that effect, which is cumbersome.
# For now, we bring all existing programs for the user and then search within them for repeated names.
programs = DATABASE.programs_for_user(user['username']).records
program_id = uuid.uuid4().hex
program_public = 0
overwrite = False
for program in programs:
if program['name'] == body['name']:
overwrite = True
program_id = program['id']
program_public = program.get('public', 0)
break
stored_program = {
'id': program_id,
'session': utils.session_id(),
'date': utils.timems(),
'lang': g.lang,
'version': utils.version(),
'level': body['level'],
'code': body['code'],
'name': body['name'],
'username': user['username'],
'public': program_public
}
if 'adventure_name' in body:
stored_program['adventure_name'] = body['adventure_name']
DATABASE.store_program(stored_program)
if not overwrite:
DATABASE.increase_user_program_count(user['username'])
DATABASE.increase_user_save_count(user['username'])
ACHIEVEMENTS.increase_count("saved")
if ACHIEVEMENTS.verify_save_achievements(user['username'],
'adventure_name' in body and len(body['adventure_name']) > 2):
return jsonify(
{'name': body['name'], 'id': program_id, "achievements": ACHIEVEMENTS.get_earned_achievements()})
return jsonify({'name': body['name'], 'id': program_id})
@app.route('/programs/share', methods=['POST'])
@requires_login
def share_unshare_program(user):
body = request.json
if not isinstance(body, dict):
return 'body must be an object', 400
if not isinstance(body.get('id'), str):
return 'id must be a string', 400
if not isinstance(body.get('public'), bool):
return 'public must be a boolean', 400
result = DATABASE.program_by_id(body['id'])
if not result or result['username'] != user['username']:
return 'No such program!', 404
# This only happens in the situation were a user un-shares their favourite program -> Delete from public profile
public_profile = DATABASE.get_public_profile_settings(current_user()['username'])
if public_profile and 'favourite_program' in public_profile and public_profile['favourite_program'] == body[
'id']:
DATABASE.set_favourite_program(user['username'], None)
DATABASE.set_program_public_by_id(body['id'], bool(body['public']), bool(body['error']))
achievement = ACHIEVEMENTS.add_single_achievement(user['username'], "sharing_is_caring")
if achievement:
return jsonify({'achievement': achievement, 'id': body['id']})
return jsonify({'id': body['id']})
@app.route('/programs/submit', methods=['POST'])
@requires_login
def submit_program(user):
body = request.json
if not isinstance(body, dict):
return 'body must be an object', 400
if not isinstance(body.get('id'), str):
return 'id must be a string', 400
result = DATABASE.program_by_id(body['id'])
if not result or result['username'] != user['username']:
return 'No such program!', 404
DATABASE.submit_program_by_id(body['id'])
DATABASE.increase_user_submit_count(user['username'])
ACHIEVEMENTS.increase_count("submitted")
if ACHIEVEMENTS.verify_submit_achievements(user['username']):
return jsonify({"achievements": ACHIEVEMENTS.get_earned_achievements()})
return jsonify({})
@app.route('/programs/set_favourite', methods=['POST'])
@requires_login
def set_favourite_program(user):
body = request.json
if not isinstance(body, dict):
return 'body must be an object', 400
if not isinstance(body.get('id'), str):
return 'id must be a string', 400
result = DATABASE.program_by_id(body['id'])
if not result or result['username'] != user['username']:
return 'No such program!', 404
DATABASE.set_favourite_program(user['username'], body['id'])
return jsonify({})