-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathdev_portal_api.py
155 lines (130 loc) · 5.14 KB
/
dev_portal_api.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
from algoliasearch import algoliasearch
from flask import Blueprint, jsonify, abort, request
from flask_cors import CORS
from werkzeug.exceptions import BadRequest
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm.exc import NoResultFound
from .utils import authed_request, demand_authed_request, get_uid
from .models import LockerEntry, UserLike, db, App, Developer
from .settings import config
parent_app = None
legacy_api = Blueprint('legacy_api', __name__)
CORS(legacy_api)
if config['ALGOLIA_ADMIN_API_KEY']:
algolia_client = algoliasearch.Client(config['ALGOLIA_APP_ID'], config['ALGOLIA_ADMIN_API_KEY'])
algolia_index = algolia_client.init_index(config['ALGOLIA_INDEX'])
else:
algolia_index = None
@legacy_api.route('/users/me')
def me():
result = demand_authed_request('GET', f"{config['REBBLE_AUTH_URL']}/api/v1/me/pebble/appstore")
me = result.json()
rebble_id = me['rebble_id']
added_ids = [x.app_id for x in LockerEntry.query.filter_by(user_id=rebble_id)]
voted_ids = [x.app_id for x in UserLike.query.filter_by(user_id=rebble_id)]
return jsonify({
'users': [{
'id': me['id'],
'uid': me['uid'],
'added_ids': added_ids,
'voted_ids': voted_ids,
'flagged_ids': [],
'applications': [],
'name': me['name'],
'href': request.url,
}],
})
@legacy_api.route('/users/me/developer', methods=['GET'])
def my_apps():
result = demand_authed_request('GET', f"{config['REBBLE_AUTH_URL']}/api/v1/me/pebble/appstore")
me = result.json()
developer_id = me['id']
# Get apps
my_apps = [x for x in App.query.filter_by(developer_id=developer_id)]
my_appdata = [{"id": a.id, "title": a.title} for a in my_apps]
# Get developer name
developer = Developer.query.filter_by(id=developer_id).one_or_none()
# Check if is wizard (Can we update auth to return this with /me/pebble/appstore?)
result = demand_authed_request('GET', f"{config['REBBLE_AUTH_URL']}/api/v1/me")
me_detailed = result.json()
me["is_wizard"] = me_detailed["is_wizard"]
if developer is None:
return jsonify({
'id': me["id"],
'userid': me["uid"],
'href': request.url,
'authName': me["name"],
'applications': [],
'needsSetup': True,
'w': me["is_wizard"],
})
else:
return jsonify({
'id': me["id"],
'userid': me["uid"],
'href': request.url,
'authName': me["name"],
'applications': my_appdata,
'name': developer.name,
'needsSetup': False,
'w': me["is_wizard"],
})
@legacy_api.route('/users/me/developer', methods=['POST'])
def update_my_developer():
permitted_fields = ["name"]
try:
req = request.json
except BadRequest as e:
print(e)
return jsonify(error="Invalid POST body. Expected JSON", e="body.invalid"), 400
if req is None:
return jsonify(error="Invalid POST body. Expected JSON and 'Content-Type: application/json'", e="request.invalid"), 400
for f in req:
if not f in permitted_fields:
return jsonify(error=f"Illegal field: {f}", e="illegal.field"), 400
if not "name" in req:
return jsonify(error=f"Missing required field: name", e="missing.field.name"), 400
# Resolve our auth token to our developer ID
result = demand_authed_request('GET', f"{config['REBBLE_AUTH_URL']}/api/v1/me/pebble/appstore")
me = result.json()
developer_id = me["id"]
developer = Developer.query.filter_by(id=developer_id).one()
print("Update developer from " + developer.name + " to " + req["name"])
developer.name = req["name"]
db.session.commit()
return jsonify(success=True, id=developer.id, name=developer.name)
@legacy_api.route('/applications/<app_id>/add_heart', methods=['POST'])
def add_heart(app_id):
uid = get_uid()
try:
app = App.query.filter_by(id=app_id).one()
like = UserLike(user_id=uid, app_id=app_id)
db.session.add(like)
App.query.filter_by(id=app_id).update({'hearts': App.hearts + 1})
db.session.commit()
except NoResultFound:
abort(404)
return
except IntegrityError:
return "already hearted", 400
if algolia_index:
algolia_index.partial_update_object({'objectID': app_id, 'hearts': app.hearts}, no_create=True)
return 'ok'
@legacy_api.route('/applications/<app_id>/remove_heart', methods=['POST'])
def remove_heart(app_id):
uid = get_uid()
try:
like = UserLike.query.filter_by(app_id=app_id, user_id=uid).one()
except NoResultFound:
return ''
app = like.app
db.session.delete(like)
App.query.filter_by(id=app_id).update({'hearts': App.hearts - 1})
db.session.commit()
if algolia_index:
algolia_index.partial_update_object({'objectID': app_id, 'hearts': app.hearts}, no_create=True)
return 'ok'
def init_app(app, url_prefix='/api/v0'):
global parent_app
parent_app = app
app.register_blueprint(legacy_api, url_prefix=url_prefix)