Coverage for src/service/external_service.py : 14%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from src.utils import err_resp, message, internal_err_resp, Spotify, TMDB, GBooks, validation_error
2from src.model import UserModel, ExternalModel, TrackModel, MovieModel, SerieModel, BookModel, MetaUserContentModel, ContentModel
3from src import db
4from flask import current_app, session
5from flask_jwt_extended import decode_token
7from dateutil.parser import parse
10class ExternalService:
11 @staticmethod
12 def get_spotify_oauth(user_uuid):
13 """ Get spotify oauth url """
14 if not (user := UserModel.query.filter_by(uuid=user_uuid).first()):
15 return err_resp("User not found!", 404)
17 try:
18 if (ExternalModel.query.filter_by(user_id=user.user_id, service_name="Spotify").first()) is None:
19 resp = message(True, "Spotify oauth url sent")
20 resp["spotify_url"] = Spotify.oauth_url(user)
21 else:
22 resp = message(True, "Spotify is already linked")
23 resp["spotify_url"] = 'linked'
24 return resp, 201
25 except Exception as error:
26 current_app.logger.error(error)
27 return internal_err_resp()
29 @staticmethod
30 def spotify_callback(csrf, code, user_uuid):
31 """ Store Spotify access and refresh token """
32 if decode_token(csrf)['identity'] != user_uuid:
33 return err_resp("CSRF invalid!", 404)
34 if not (user := UserModel.query.filter_by(uuid=user_uuid).first()):
35 return err_resp("User not found!", 404)
36 # Check if the email is taken
37 if ExternalModel.query.filter_by(user_id=user.user_id, service_name="Spotify").first() is not None:
38 return validation_error(False, "Spotify Oauth is already done.")
39 try:
40 token_info = Spotify.get_tokens(code)
42 new_external = ExternalModel(
43 service_name='Spotify',
44 user_id=user.user_id,
45 access_token=token_info['access_token'],
46 refresh_token=token_info['refresh_token']
47 )
49 db.session.add(new_external)
50 db.session.flush()
52 # Commit changes to DB
53 db.session.commit()
55 resp = message(True, "Spotify tokens stored")
56 return resp, 201
57 except Exception as error:
58 current_app.logger.error(error)
59 return internal_err_resp()
61 @staticmethod
62 def get_spotify_data(user_uuid, app):
63 """ Get spotify data : """
64 with app.app_context():
65 if not (user := UserModel.query.filter_by(uuid=user_uuid).first()):
66 return err_resp("User not found!", 404)
67 if not (external := ExternalModel.query.filter_by(user_id=user.user_id, service_name="Spotify").first()):
68 return err_resp("External service not found!", 404)
69 try:
70 token_info = Spotify.refresh_token(external.refresh_token)
71 if "access_token" not in token_info.keys():
72 ExternalModel.query.filter_by(
73 user_id=user.user_id, service_name="Spotify").delete()
74 db.session.commit()
75 return err_resp("Spotify service oauth revoked!", 404)
76 external.access_token = token_info['access_token']
78 db.session.add(external)
80 db.session.commit()
81 data = []
83 data.append(Spotify.get_user_top_track(external.access_token))
84 data.append(Spotify.get_user_recently_played(
85 external.access_token))
86 for item in Spotify.get_user_playlist(external.access_token):
87 data.append(item['tracks'])
89 for d in data:
90 for line in d:
91 if TrackModel.query.filter_by(spotify_id=line['spotify_id']).first() is None:
92 content = ContentModel(rating=None)
93 db.session.add(content)
94 db.session.flush()
95 new_track = TrackModel(
96 artist_name=line['artist_name'],
97 title=line['title'],
98 year=line['year'],
99 release=line['release'],
100 spotify_id=line['spotify_id'],
101 covert_art_url=line['cover_art_url'],
102 content=content
103 )
104 db.session.add(new_track)
105 db.session.flush()
107 db.session.commit()
109 for d in data:
110 for line in d:
111 track = TrackModel.query.filter_by(
112 spotify_id=line['spotify_id']).first()
113 if ((meta := MetaUserContentModel.query.filter_by(content_id=track.content_id).first()) is None):
114 new_meta_user_track = MetaUserContentModel(
115 user_id=user.user_id,
116 content_id=track.content_id,
117 play_count=1,
118 last_played_date=line['played_at']
119 )
120 db.session.add(new_meta_user_track)
121 db.session.flush()
122 else:
123 if ((line['played_at'] is not None) and ((meta.last_count_increment is None) or (line['played_at'] > meta.last_count_increment))):
124 meta.last_count_increment = line['played_at']
125 db.session.commit()
127 except Exception as error:
128 current_app.logger.error(error)
129 return internal_err_resp()
131 @staticmethod
132 def get_tmdb_oauth(user_uuid):
133 """ Get TMDB oauth url """
134 if not (user := UserModel.query.filter_by(uuid=user_uuid).first()):
135 return err_resp("User not found!", 404)
137 try:
138 if (ExternalModel.query.filter_by(user_id=user.user_id, service_name="TMDB").first()) is None:
139 resp = message(True, "TMDB oauth url sent")
140 resp["tmdb_url"] = TMDB.oauth_url()
141 else:
142 resp = message(True, "TMDB is already linked")
143 resp["tmdb_url"] = 'linked'
144 return resp, 201
145 except Exception as error:
146 current_app.logger.error(error)
147 return internal_err_resp()
149 @staticmethod
150 def tmdb_callback(request_token, user_uuid):
151 """ Store tmdb access """
152 if not (user := UserModel.query.filter_by(uuid=user_uuid).first()):
153 return err_resp("User not found!", 404)
154 # Check if the email is taken
155 if ExternalModel.query.filter_by(user_id=user.user_id, service_name="TMDB").first() is not None:
156 return validation_error(False, "tmdb Oauth is already done.")
157 try:
158 token_info = TMDB.get_tokens(request_token)
160 new_external = ExternalModel(
161 service_name='TMDB',
162 user_id=user.user_id,
163 access_token=token_info['session_id'],
164 )
166 db.session.add(new_external)
167 db.session.flush()
169 # Commit changes to DB
170 db.session.commit()
172 resp = message(True, "TMDB token stored")
173 return resp, 201
174 except Exception as error:
175 current_app.logger.error(error)
176 return internal_err_resp()
178 @staticmethod
179 def get_tmdb_data(user_uuid, app):
180 """ Get tmdb data : """
181 with app.app_context():
182 if not (user := UserModel.query.filter_by(uuid=user_uuid).first()):
183 return err_resp("User not found!", 404)
184 if not (external := ExternalModel.query.filter_by(user_id=user.user_id, service_name="TMDB").first()):
185 return err_resp("External service not found!", 404)
186 try:
187 token = external.access_token
188 account_id = TMDB.get_account_id(token)
189 if 'success' in account_id.keys():
190 ExternalModel.query.filter_by(
191 user_id=user.user_id, service_name="TMDB").delete()
192 db.session.commit()
193 return err_resp("TMDB service oauth revoked!", 404)
194 data = TMDB.get_created_list(token, account_id)
195 movies = []
196 movies.append(TMDB.get_favorite_movies(token, account_id))
197 movies.append(TMDB.get_rated_movies(token, account_id))
198 movies.append(data['movies'])
200 series = []
201 series.append(TMDB.get_favorite_series(token, account_id))
202 series.append(TMDB.get_rated_series(token, account_id))
203 series.append(data['series'])
205 for movie in movies:
206 for line in movie:
207 if (movie_db := MovieModel.query.filter_by(imdbid=line['imdbid']).first()) is None:
208 content = ContentModel(rating=None)
209 db.session.add(content)
210 db.session.flush()
211 new_movie = MovieModel(
212 title=line['title'],
213 language=line['language'],
214 actors=line['actors'],
215 year=line['year'],
216 producers=line['producers'],
217 director=line['director'],
218 writer=line['writer'],
219 imdbid=line['imdbid'],
220 tmdbid=line['tmdbid'],
221 rating=line['rating'],
222 rating_count=line['rating_count'],
223 cover=line['cover'],
224 content=content
225 )
226 db.session.add(new_movie)
227 db.session.flush()
228 else:
229 if line['rating'] != movie_db.rating:
230 movie_db.rating = line['rating']
231 if line['rating_count'] != movie_db.rating_count:
232 movie_db.rating_count = line['rating_count']
233 db.session.commit()
235 for movie in movies:
236 for line in movie:
237 ext_movie = MovieModel.query.filter_by(
238 imdbid=line['imdbid']).first()
239 if ((meta := MetaUserContentModel.query.filter_by(content_id=ext_movie.content_id).first()) is None):
240 new_meta_user_track = MetaUserContentModel(
241 user_id=user.user_id,
242 content_id=ext_movie.content_id,
243 rating=line['user_rating'] if "user_rating" in line.keys(
244 ) else None,
245 watch_count=1,
246 review_see_count=1
247 )
248 db.session.add(new_meta_user_track)
249 db.session.flush()
250 else:
251 if line['rating'] != meta.rating:
252 meta.rating = line['rating']
253 db.session.commit()
255 for serie in series:
256 for line in serie:
257 if (s := SerieModel.query.filter_by(title=line['title'], start_year=line['start_year']).first()) is None:
258 content = ContentModel(rating=None)
259 db.session.add(content)
260 db.session.flush()
261 new_serie = SerieModel(
262 title=line['title'],
263 actors=line['actors'],
264 start_year=line['start_year'],
265 end_year=line['end_year'],
266 directors=line['directors'],
267 writers=line['writers'],
268 rating=line['rating'],
269 rating_count=line['rating_count'],
270 cover=line['cover'],
271 content=content,
272 )
273 db.session.add(new_serie)
274 db.session.flush()
275 else:
276 if line['rating'] != s.rating:
277 s.rating = line['rating']
278 if line['rating_count'] != s.rating_count:
279 s.rating_count = line['rating_count']
280 db.session.commit()
281 for serie in series:
282 for line in serie:
283 serie = SerieModel.query.filter_by(
284 title=line['title'], start_year=line['start_year']).first()
285 if ((serie_db := MetaUserContentModel.query.filter_by(serie_id=serie.serie_id).first()) is None):
286 new_meta_user_track = MetaUserContentModel(
287 user_id=user.user_id,
288 content_id=serie.content_id,
289 rating=line['user_rating'] if "user_rating" in line.keys(
290 ) else None,
291 review_see_count=1
292 )
293 db.session.add(new_meta_user_track)
294 db.session.flush()
295 else:
296 if line['rating'] != serie_db.rating:
297 serie_db.rating != line['rating']
298 db.session.commit()
299 except Exception as error:
300 current_app.logger.error(error)
301 return internal_err_resp()
303 @staticmethod
304 def get_gbooks_oauth(user_uuid):
305 """ Get GBooks oauth url """
306 if not (user := UserModel.query.filter_by(uuid=user_uuid).first()):
307 return err_resp("User not found!", 404)
309 try:
310 if (ExternalModel.query.filter_by(user_id=user.user_id, service_name="GBooks").first()) is None:
311 resp = message(True, "GBooks oauth url sent")
312 resp["gbooks_url"] = GBooks.oauth_url(user)
313 else:
314 resp = message(True, "GBooks is already linked")
315 resp["gbooks_url"] = 'linked'
316 return resp, 201
317 except Exception as error:
318 current_app.logger.error(error)
319 return internal_err_resp()
321 @staticmethod
322 def gbooks_callback(user_uuid, code, state):
323 """ Store gbooks access """
324 if decode_token(state)['identity'] != user_uuid:
325 return err_resp("CSRF invalid!", 404)
326 if not (user := UserModel.query.filter_by(uuid=user_uuid).first()):
327 return err_resp("User not found!", 404)
329 if ExternalModel.query.filter_by(user_id=user.user_id, service_name="GBooks").first() is not None:
330 return validation_error(False, "gbooks Oauth is already done.")
331 try:
332 token_info = GBooks.get_token(code, state)
334 new_external = ExternalModel(
335 service_name='GBooks',
336 user_id=user.user_id,
337 access_token=token_info['token'],
338 refresh_token=token_info['refresh_token']
339 )
341 db.session.add(new_external)
342 db.session.flush()
344 # Commit changes to DB
345 db.session.commit()
347 resp = message(True, "GBooks token stored")
348 return resp, 201
349 except Exception as error:
350 current_app.logger.error(error)
351 return internal_err_resp()
353 @staticmethod
354 def get_gbooks_data(user_uuid, app):
355 """ Get gbooks data : """
356 with app.app_context():
357 if not (user := UserModel.query.filter_by(uuid=user_uuid).first()):
358 return err_resp("User not found!", 404)
359 if not (external := ExternalModel.query.filter_by(user_id=user.user_id, service_name="GBooks").first()):
360 return err_resp("External service not found!", 404)
361 try:
362 token = external.access_token
363 refresh_token = external.refresh_token
365 books = GBooks.get_data(token, refresh_token)
366 if books == "revoked":
367 ExternalModel.query.filter_by(
368 user_id=user.user_id, service_name="GBooks").delete()
369 db.session.commit()
370 return err_resp("Google Books service oauth revoked!", 404)
372 for line in books:
373 if (book_db := BookModel.query.filter_by(isbn=line['isbn']).first()) is None:
374 content = ContentModel(rating=None)
375 db.session.add(content)
376 db.session.flush()
377 new_book = BookModel(
378 isbn=line['isbn'],
379 title=line['title'],
380 author=line['author'],
381 year_of_publication=line['year_of_publication'],
382 publisher=line['publisher'],
383 image_url_s=line['image_url_s'],
384 image_url_m=line['image_url_m'],
385 image_url_l=line['image_url_l'],
386 rating=line['rating'],
387 rating_count=line['rating_count'],
388 content=content,
389 )
390 db.session.add(new_book)
391 db.session.flush()
392 else:
393 if line['rating'] != book_db.rating:
394 book_db.rating = line['rating']
395 if line['rating_count'] != book_db.rating_count:
396 book_db.rating_count = line['rating_count']
397 db.session.commit()
399 for line in books:
400 if ((meta := MetaUserContentModel.query.filter_by(isbn=line['isbn']).first()) is None):
401 new_meta_user_track = MetaUserContentModel(
402 user_id=user.user_id,
403 isbn=line['isbn'],
404 rating=line['user_rating'],
405 purchase=line['purchase']
406 )
407 db.session.add(new_meta_user_track)
408 db.session.flush()
409 else:
410 if line['rating'] != meta.rating:
411 meta.rating = line['rating']
412 if line['purchase'] != meta.purchase:
413 meta.purchase = line['purchase']
414 db.session.commit()
415 except Exception as error:
416 current_app.logger.error(error)
417 return internal_err_resp()