-
Notifications
You must be signed in to change notification settings - Fork 1
/
helpers.py
251 lines (171 loc) · 7.14 KB
/
helpers.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
from model import Account, User
from base64 import b64encode, b64decode
from werkzeug.contrib.cache import SimpleCache
import requests
import datetime
cache = SimpleCache()
#==================================
# terrible form validation goes here
#==================================
def email_is_valid(email):
""" Checks user submitted email against db and returns a Boolean. """
try:
Account.query.filter_by(email=email).one()
except:
return False
return True
def pass_is_valid(password, email):
""" Checks user submitted password against db and returns a Boolean. """
if not email_is_valid(email):
return False
acct = Account.query.filter_by(email=email).one()
if acct.password != password:
return False
return True
def make_datetime(date):
""" Takes in data from a form input and returns a datetime object. """
date_list = date.split("-")
db_date = datetime.date(int(date_list[0]), int(date_list[1]), int(date_list[2]))
return db_date
def review_is_private(privacy):
""" Takes in user form input about a review and returns a boolean for submission
to db. """
if privacy == "t":
return True
return False
#====================
# db getter functions
#====================
def get_current_account(acct_id):
""" Takes in an account id, and returns an account object. """
acct = Account.query.get(acct_id)
return acct
def get_user_by_acct(acct):
""" Takes in an Account object and returns the corresponding User object. """
return acct.user
def get_user_by_gr_id(gr_id):
""" Takes in a goodreads id number and returns the corresponding User object."""
user = User.query.filter_by(gr_id=gr_id).one()
return user
#=============
# clean up xml
#=============
def date_is_valid(xml):
""" Takes in a piece of XML and returns an int/default value to be used as
part of a book's publishing date. """
try:
date = int(xml)
except:
date = 1
return date
def valid_isbn(xml):
""" Takes in an ISBN xml value and returns an int, or None if no ISBN was found. """
try:
isbn = int(xml)
except:
isbn = None
return isbn
def valid_page_count(xml):
""" Takes in page count and returns an int or default value. """
try:
page_count = int(xml)
except:
page_count = 0
return page_count
#===================================
# Overdrive helpers - Setup requests
#===================================
def request_ovr_tkn(key, secret):
""" Requests a temporary authorization token from Overdrive API """
dev_keys = key + ":" + secret
b64_keys = b64encode(dev_keys)
params = {"grant_type": "client_credentials"}
r = requests.post('https://oauth.overdrive.com/token',
headers={"Authorization": "Basic %s" % b64_keys,
"Content-Type": "application/x-www-form-urlencoded"},
data=params)
r = r.json()
# tkn_type = r["token_type"] # should always be type "bearer"
access_tkn = r["access_token"]
return access_tkn
def check_ovrdrv_token(key, secret):
""" Checks for valid auth token before submitting Overdrive requests -
refreshes and resets token with ~ 1hr time limit if not found, and returns
a valid token. """
token = cache.get('ovr_tkn')
if token is None:
token = request_ovr_tkn(key, secret)
cache.set('ovr_tkn', token, timeout=60 * 60) # set cache to expire in 1 hr.
return token
def get_lib_products(lib_id, key, secret):
""" """
token = check_ovrdrv_token(key, secret)
url = 'https://api.overdrive.com/v1/libraries/' + lib_id
response = requests.get(url,
headers={"User-Agent": "Readerboard",
"Authorization": "Bearer %s" % token,
"Content-Type": "application/json",
"X-Forwarded-For": "0.0.0.0:5000"})
r = response.json()
products_url = r["links"]["products"]["href"]
return products_url
#======================
# Challenge data graphs
#======================
def get_challenge_data(id, user):
""" Takes in a challenge id, and a user object, and returns a dictionary
of challenge information to populate a chart.js graph. """
data_dict = {"labels": ["Christmas Melon",
"Crenshaw", ],
"datasets": [{"data": [300, 50],
"backgroundColor": ["#FF6384",
"#36A2EB", ],
"hoverBackgroundColor": ["#FF6384",
"#36A2EB", ]}]}
#========================
# Set library preferences
#========================
def get_library_details(lib_id, key, secret):
""" Given a library id, and dev keys, returns the name of a given library. """
token = check_ovrdrv_token(key, secret)
url = 'https://api.overdrive.com/v1/libraries/' + lib_id
response = requests.get(url,
headers={"User-Agent": "Readerboard",
"Authorization": "Bearer %s" % token,
"Content-Type": "application/json"})
r = response.json()
return r["name"]
#==============================================
# Search and Availability Overdrive API helpers
#==============================================
def search_lib_for_copies(product_url, book, key, secret):
""" Accesses the Overdrive Search API endpoint with a query containing the ISBN
of the book selected by the user. Returns the Availability API endpoint and
calls the get_availability function. """
token = check_ovrdrv_token(key, secret)
url = product_url + "?limit=50&q=" + book['title'] + "&identifiers=" + str(book['edition']['isbn'])
response = requests.get(url,
headers={"User-Agent": "Readerboard",
"Authorization": "Bearer %s" % token,
"Content-Type": "application/json"})
response = response.json()
for product in response['products']:
if product['title'] == book['title']:
avail_url = product['links']['availability']['href']
availability = get_lib_availability(avail_url, key, secret)
return availability
return None
def get_lib_availability(url, key, secret):
""" Get availability information for a given book, if any copies are found
in the library collection. """
token = check_ovrdrv_token(key, secret)
response = requests.get(url,
headers={"User-Agent": "Readerboard",
"Authorization": "Bearer %s" % token,
"Content-Type": "application/json"})
response = response.json()
availability = {"copies": response['copiesOwned'],
"available": response['copiesAvailable'],
"holds": response['numberOfHolds'],
"avail_type": response['availabilityType']}
return availability