forked from IanMulvany/sage-bridge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
basic.py
268 lines (230 loc) · 8.01 KB
/
basic.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
265
266
267
268
from flask import Flask, render_template, jsonify, request, json
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from flask.ext.autodoc import Autodoc
from flask_basicauth import BasicAuth
import moodle_api
import os
import logging
from datetime import datetime
from datetime import date
# from logging.config import fileConfig
import requests as r
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter(
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
app = Flask(__name__)
auto = Autodoc(app)
Bootstrap(app)
admin = Admin(app, name='SageBridge', template_mode='bootstrap3')
app.config.from_object(os.environ['APP_SETTINGS'])
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
from models import CourseId, SSTransaction, BridgeUser, MoodleUser
admin.add_view(ModelView(CourseId, db.session))
admin.add_view(ModelView(SSTransaction, db.session))
admin.add_view(ModelView(BridgeUser, db.session))
admin.add_view(ModelView(MoodleUser, db.session))
basic_auth = BasicAuth(app)
class InvalidUsage(Exception):
status_code = 400
def __init__(self, message, status_code=None, payload=None):
Exception.__init__(self)
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
@app.errorhandler(InvalidUsage)
def handle_invalid_usage(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
class ProcessingError(Exception):
status_code = 500
def __init__(self, message, status_code=None, payload=None):
Exception.__init__(self)
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
@app.errorhandler(ProcessingError)
def handle_processing_error(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
def get_moodle_courses():
"""
ping moodle and get a list of courses
store course name and course id in local DB
store course run date in local db
"""
return True
@app.route('/get_courses')
@auto.doc()
def get_courses():
courses = get_moodle_courses()
logger.info(courses)
return "hola!"
@app.route('/list_courses')
@auto.doc()
def list_courses():
"""
show moodle courses that we have gotten info about
"""
logger.info("george, we are home")
return "hola!"
@app.route('/')
@auto.doc()
def index():
return render_template("index.html")
@app.route('/homepage')
@auto.doc()
def homepage():
return render_template("homepage.html")
@app.route('/list_bridge_users')
@auto.doc()
def bridge_users():
"""
show a list of bridge users, and the
transactions that they have been associated with
"""
bridge_users = BridgeUser.query.all()
return render_template("bridge_users.html", users=bridge_users)
"show a list of squarespace transactions that we have processed"
return render_template("homepage.html")
@app.route('/list_ss_transactions', methods=['GET'])
@auto.doc()
def show_transactions():
"test pulling data from the db about users"
users = SSTransaction.query.all()
return render_template("purchasers.html", users=users)
# @app.route('/from_gdocs', methods=['POST'])
# @basic_auth.required
# def gdocs():
# name = request.form.get("name")
# email = request.form.get("email")
# interest = request.form.get("interest")
# submitted = request.form.get("submitted") # e.g. 5/11/2017 6:47:19
# user = SSUser(name, interest, email, submitted)
# db.session.add(user)
# db.session.commit()
# return("{'I got your back'}")
def create_or_get_bridge_user(email):
"""
given an email
return a bridge user object from the DB if it exists
else create it and return it
"""
bridge_user = BridgeUser.query.filter_by(email=email).first()
logger.info(bridge_user)
if bridge_user == None:
bridge_user = BridgeUser(email)
db.session.add(bridge_user)
db.session.commit()
logger.info(bridge_user)
return bridge_user
def associate_bridge_user_transaction(bridge_user, ss_transaction):
bridge_user.squarespace.append(ss_transaction)
db.session.add(bridge_user)
db.session.commit()
return True
@app.route('/create_ss_transaction', methods=['POST'])
# @basic_auth.required
@auto.doc()
def create_ss_transaction():
"""
create a record of a squarespace transation in the brige app.
"""
# try:
name = request.form.get("name")
email = request.form.get("email")
interest = request.form.get("interest")
submitted = request.form.get("submitted") # e.g. 5/11/2017 6:47:19
ss_transaction = SSTransaction(name, interest, email, submitted)
# check if bridge user exists with this email
bridge_user = create_or_get_bridge_user(email)
associate_bridge_user_transaction(bridge_user, ss_transaction)
db.session.add(ss_transaction)
db.session.commit()
return jsonify("transaction created in the bridge app", 200)
# except:
# message = "something failed in the function"
# logger.info(message)
# raise ProcessingError(message)
def create_moodle_user_if_nonexistent(email):
"""
given an email
check if we have a moodle user record for this email locally
check if moodle already has a user with the email
if so check for potential problems, re name drift
if neither above occurs, then create this new user in moodle
"""
bridge_user = create_or_get_bridge_user(email)
moodle_user = create_or_get_moodle_user(email)
associate_bridge_user_moodle_user(bridge_user, moodle_user)
# check if there is already a moodle user with this email.
criteria = [{
'key':'email', 'value':email
}]
users = moodle_api.call("core_user_get_users", criteria=criteria)
if uses == None:
api_call = "core_user_create_users"
users = [{
'username': 'username5', # username must be unique
'password': 'P-assword5',
'firstname': 'firstname5',
'lastname': 'lastname5',
'email': email,
'customfields': [{'type':'institution', 'value':'harvard'}]
}]
new_user = moodle_api.call("core_user_create_users", users=users)
criteria = [{
'key':'email', 'value':email
}]
users = moodle_api.call("core_user_get_users", criteria=criteria)
url = users[0].url
moodle_id = users[0].moodle_id
# TODO: unfuck this function
moodle_user = MoodleUser(email, moodle_id, moodle_url)
return True
@app.route('/create_moodle_users', methods=['POST'])
# @basic_auth.required
@auto.doc()
def create_moodle_users():
"""
create a record of a squarespace transation in the brige app.
"""
emails = request.form.getlist("cb[]")
for email in emails:
create_moodle_user_if_nonexistent(email.rstrip("\")): #noticed that there is a trailing backslask on form data?
return jsonify("got emails", 200)
@app.route('/create_moodle_users_view', methods=['GET'])
# @basic_auth.required
def create_moodle_users_view():
"""
show all bridge uses
allow the admin to select bridge users
create moodle users based on the selected brdige users
"""
bridge_users = BridgeUser.query.all()
return render_template("create_moodle_users.html", users=bridge_users)
@app.route('/documentation')
def documentation():
return auto.html()
if __name__ == "__main__":
port = int(os.environ.get("PORT", 5000))
app.run(host='0.0.0.0', port=port, threaded=True)