Coverage for src/service/serie_service.py : 62%
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 settings import REASON_CATEGORIES
2from flask import current_app
3from flask_jwt_extended import get_jwt_claims
4from sqlalchemy import func, text, select, and_
5from sqlalchemy.sql.expression import null
7from src import db, settings
8from src.utils import pagination_resp, internal_err_resp, message, Paginator, err_resp
9from src.model import SerieModel, EpisodeModel, GenreModel, ContentType, UserModel, ContentModel, RecommendedContentModel, RecommendedContentForGroupModel, MetaUserContentModel, BadRecommendationContentModel, SerieAdditionalModel, EpisodeAdditionalModel
10from src.schemas import SerieBase, SerieItem, EpisodeBase, GenreBase, SerieExtra, MetaUserContentBase, SerieAdditionalBase, EpisodeAdditionalBase
13class SerieService:
14 @staticmethod
15 def search_serie_data(search_term, page, connected_user_uuid):
16 """ Search serie data by title """
17 if not (UserModel.query.filter_by(uuid=connected_user_uuid).first()):
18 return err_resp("User not found!", 404)
19 series, total_pages = Paginator.get_from(
20 SerieModel.query.filter(SerieModel.title.ilike(search_term+"%")).union(
21 SerieModel.query.filter(SerieModel.title.ilike("%"+search_term+"%"))),
22 page,
23 )
25 try:
26 serie_data = SerieBase.loads(series)
28 return pagination_resp(
29 message="Serie data sent",
30 content=serie_data,
31 page=page,
32 total_pages=total_pages
33 )
35 except Exception as error:
36 current_app.logger.error(error)
37 return internal_err_resp()
39 @staticmethod
40 def get_popular_series(page, connected_user_uuid):
41 if not (user := UserModel.query.filter_by(uuid=connected_user_uuid).first()):
42 return err_resp("User not found!", 404)
44 series, total_pages = Paginator.get_from(
45 SerieModel.query.join(SerieModel.content, aliased=True).order_by(
46 ContentModel.popularity_score.desc().nullslast(),
47 ),
48 page,
49 )
51 try:
52 serie_data = SerieItem.loads(series)
54 return pagination_resp(
55 message="Most popular serie data sent",
56 content=serie_data,
57 page=page,
58 total_pages=total_pages
59 )
61 except Exception as error:
62 current_app.logger.error(error)
63 return internal_err_resp()
65 @staticmethod
66 def get_recommended_series_for_user(page, connected_user_uuid, reco_engine):
67 if not (user := UserModel.query.filter_by(uuid=connected_user_uuid).first()):
68 return err_resp("User not found!", 404)
70 filters = [RecommendedContentModel.user_id == user.user_id]
71 if reco_engine is not None:
72 filters.append(RecommendedContentModel.engine == reco_engine)
74 series, total_pages = Paginator.get_from(
75 db.session.query(RecommendedContentModel, SerieModel)
76 .join(SerieModel.content)
77 .join(RecommendedContentModel, RecommendedContentModel.content_id == ContentModel.content_id)
78 .filter(
79 and_(*filters)
80 )
81 .order_by(
82 RecommendedContentModel.score.desc().nullslast(),
83 ContentModel.popularity_score.desc().nullslast(),
84 ),
85 page,
86 )
88 try:
89 def c_load(row):
90 serie = SerieExtra.load(row[1])
91 serie["reco_engine"] = row[0].engine
92 serie["reco_score"] = row[0].score
93 return serie
95 serie_data = list(map(c_load, series))
97 return pagination_resp(
98 message="Most popular serie data sent",
99 content=serie_data,
100 page=page,
101 total_pages=total_pages
102 )
104 except Exception as error:
105 current_app.logger.error(error)
106 return internal_err_resp()
108 @staticmethod
109 def get_recommended_series_for_group(page, connected_user_uuid, reco_engine):
110 if not (user := UserModel.query.filter_by(uuid=connected_user_uuid).first()):
111 return err_resp("User not found!", 404)
113 # Query for recommendation from group
114 groups_ids = [
115 *list(map(lambda x: x.group_id, user.groups)),
116 *list(map(lambda x: x.group_id, user.owned_groups))
117 ]
119 filters = [RecommendedContentForGroupModel.group_id.in_(groups_ids)]
120 if reco_engine is not None:
121 filters.append(RecommendedContentModel.engine == reco_engine)
123 series, total_pages = Paginator.get_from(
124 db.session.query(RecommendedContentForGroupModel, SerieModel)
125 .join(SerieModel.content)
126 .join(RecommendedContentForGroupModel, RecommendedContentForGroupModel.content_id == ContentModel.content_id)
127 .filter(
128 and_(*filters)
129 )
130 .order_by(
131 RecommendedContentModel.score.desc().nullslast(),
132 ContentModel.popularity_score.desc().nullslast(),
133 ),
134 page,
135 )
137 try:
138 def c_load(row):
139 serie = SerieExtra.load(row[1])
140 serie["reco_engine"] = row[0].engine
141 serie["reco_score"] = row[0].score
142 return serie
144 serie_data = list(map(c_load, series))
146 return pagination_resp(
147 message="Most popular serie data sent",
148 content=serie_data,
149 page=page,
150 total_pages=total_pages
151 )
153 except Exception as error:
154 current_app.logger.error(error)
155 return internal_err_resp()
157 @staticmethod
158 def get_ordered_genre(connected_user_uuid):
159 if not (UserModel.query.filter_by(uuid=connected_user_uuid).first()):
160 return err_resp("User not found!", 404)
161 genres = GenreModel.query.filter_by(
162 content_type=ContentType.SERIE).order_by(GenreModel.count.desc()).all()
164 try:
165 genres_data = GenreBase.loads(genres)
167 resp = message(True, "Serie genres data sent")
168 resp["content"] = genres_data
169 return resp, 200
171 except Exception as error:
172 current_app.logger.error(error)
173 return internal_err_resp()
175 @staticmethod
176 def get_episodes(content_id):
177 if not (episodes := EpisodeModel.query.filter_by(serie_id=content_id).order_by(EpisodeModel.season_number, EpisodeModel.episode_number).all()):
178 return err_resp("Serie not found!", 404)
180 try:
181 episodes_data = EpisodeBase.loads(episodes)
183 resp = message(True, "Series episodes data sent")
184 resp["content"] = episodes_data
185 return resp, 200
187 except Exception as error:
188 current_app.logger.error(error)
189 return internal_err_resp()
191 except Exception as error:
192 current_app.logger.error(error)
193 return internal_err_resp()
195 @staticmethod
196 def add_bad_recommendation(user_uuid, content_id, data):
197 """ Add bad user recommendation """
198 if not (user := UserModel.query.filter_by(uuid=user_uuid).first()):
199 return err_resp("User not found!", 404)
201 if not (serie := SerieModel.query.filter_by(content_id=content_id).first()):
202 return err_resp("Serie not found!", 404)
204 try:
205 for type, value in data.items():
206 if type in REASON_CATEGORIES['serie']:
207 for r in value:
209 new_bad_reco = BadRecommendationContentModel(
210 user_id=user.user_id,
211 content_id=serie.content_id,
212 reason_categorie=type,
213 reason=r
214 )
216 db.session.add(new_bad_reco)
217 db.session.flush()
218 db.session.commit()
220 resp = message(True, "Bad recommendation has been registered.")
221 return resp, 201
223 except Exception as error:
224 current_app.logger.error(error)
225 return internal_err_resp()
227 @staticmethod
228 def add_additional_serie(user_uuid, data):
229 """ Add additional serie"""
230 if not (user := UserModel.query.filter_by(uuid=user_uuid).first()):
231 return err_resp("User not found!", 404)
233 # Check permissions
234 permissions = get_jwt_claims()['permissions']
235 if "add_content" not in permissions:
236 return err_resp("Permission missing", 403)
238 try:
240 new_additional_serie = SerieAdditionalModel(
241 title=data['title'],
242 )
244 if 'imdbid' in data:
245 new_additional_serie.imdbid = data['imdbid']
246 if 'start_year' in data:
247 new_additional_serie.start_year = data['start_year']
248 if 'end_year' in data:
249 new_additional_serie.end_year = data['end_year']
250 if 'writers' in data:
251 new_additional_serie.writers = data['writers']
252 if 'directors' in data:
253 new_additional_serie.directors = data['directors']
254 if 'actors' in data:
255 new_additional_serie.actors = data['actors']
256 if 'cover' in data:
257 new_additional_serie.cover = data['cover']
259 for genre_id in data["genres"]:
260 if (ge := GenreModel.query.filter_by(genre_id=genre_id).first()):
261 new_additional_serie.genres.append(ge)
262 else:
263 return err_resp("Genre %s not found!" % genre_id, 404)
265 db.session.add(new_additional_serie)
266 db.session.flush()
268 if "episodes" in data:
269 for episode in data["episodes"]:
270 new_additional_episode = EpisodeAdditionalModel(
271 title=data['title'],
272 serie_id=new_additional_serie.serie_id
273 )
275 if 'imdbid' in data:
276 new_additional_episode.imdbid = data['imdbid']
277 if 'year' in data:
278 new_additional_episode.year = data['year']
279 if 'season_number' in data:
280 new_additional_episode.season_number = data['season_number']
281 if 'episode_number' in data:
282 new_additional_episode.episode_number = data['episode_number']
284 for genre_id in data["genres"]:
285 if (ge := GenreModel.query.filter_by(genre_id=genre_id).first()):
286 new_additional_episode.genres.append(ge)
287 else:
288 return err_resp("Genre %s not found!" % genre_id, 404)
290 db.session.add(new_additional_episode)
292 db.session.commit()
294 resp = message(True, "Serie have been added to validation.")
295 return resp, 201
297 except Exception as error:
298 import traceback
299 traceback.print_exc()
300 current_app.logger.error(error)
301 return internal_err_resp()
304 @staticmethod
305 def get_additional_serie(connected_user_uuid, page):
306 if not (user := UserModel.query.filter_by(uuid=connected_user_uuid).first()):
307 return err_resp("User not found!", 404)
309 # Check permissions
310 permissions = get_jwt_claims()['permissions']
311 if "add_content" not in permissions:
312 return err_resp("Permission missing", 403)
314 series, total_pages = Paginator.get_from(
315 SerieAdditionalModel.query,
316 page,
317 )
319 try:
320 serie_data = SerieAdditionalBase.loads(series)
322 return pagination_resp(
323 message="Additional series data sent",
324 content=serie_data,
325 page=page,
326 total_pages=total_pages
327 )
329 except Exception as error:
330 current_app.logger.error(error)
331 return internal_err_resp()
333 @staticmethod
334 def validate_additional_serie(connected_user_uuid, serie_id):
335 if not (user := UserModel.query.filter_by(uuid=connected_user_uuid).first()):
336 return err_resp("User not found!", 404)
338 # Check permissions
339 permissions = get_jwt_claims()['permissions']
340 if "validate_added_content" not in permissions:
341 return err_resp("Permission missing", 403)
343 if not (serie := SerieAdditionalModel.query.filter_by(serie_id=serie_id).first()):
344 return err_resp("Additional series not found!", 404)
346 try:
347 content = ContentModel(rating=None, genres=serie.genres)
348 db.session.add(content)
349 db.session.flush()
351 new_serie = SerieModel(
352 imdbid=serie.imdbid,
353 title=serie.title,
354 start_year=serie.start_year,
355 end_year=serie.end_year,
356 writers=serie.writers,
357 directors=serie.directors,
358 actors=serie.actors,
359 cover=serie.cover,
360 plot_outline=serie.plot_outline,
361 content=content
362 )
363 db.session.add(new_serie)
365 for episode in serie.episodes :
366 content_episode = ContentModel(rating=None, genres=episode.genres)
367 db.session.add(content)
368 db.session.flush()
370 new_episode = EpisodeModel(
371 imdbid=episode.imdbid,
372 title=episode.title,
373 year=episode.year,
374 season_number=episode.season_number,
375 episode_number=episode.episode_number,
376 serie_id=serie.serie_id,
377 content=content_episode
378 )
380 db.session.add(new_serie)
381 db.session.delete(episode)
383 db.session.delete(serie)
384 db.session.commit()
386 resp = message(
387 True, "Additional series data successfully validated")
388 return resp, 201
390 except Exception as error:
391 current_app.logger.error(error)
392 return internal_err_resp()
394 @staticmethod
395 def decline_additional_serie(connected_user_uuid, serie_id):
396 if not (user := UserModel.query.filter_by(uuid=connected_user_uuid).first()):
397 return err_resp("User not found!", 404)
399 # Check permissions
400 permissions = get_jwt_claims()['permissions']
401 if "delete_content" not in permissions:
402 return err_resp("Permission missing", 403)
404 if not (serie := SerieAdditionalModel.query.filter_by(serie_id=serie_id).first()):
405 return err_resp("Additional series not found!", 404)
407 try:
408 for episode in serie.episodes :
409 db.session.delete(episode)
410 db.session.delete(serie)
411 db.session.commit()
413 resp = message(True, "Additional series successfully deleted")
414 return resp, 201
416 except Exception as error:
417 current_app.logger.error(error)
418 return internal_err_resp()