Hide keyboard shortcuts

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 

6 

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 

11 

12 

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 ) 

24 

25 try: 

26 serie_data = SerieBase.loads(series) 

27 

28 return pagination_resp( 

29 message="Serie data sent", 

30 content=serie_data, 

31 page=page, 

32 total_pages=total_pages 

33 ) 

34 

35 except Exception as error: 

36 current_app.logger.error(error) 

37 return internal_err_resp() 

38 

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) 

43 

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 ) 

50 

51 try: 

52 serie_data = SerieItem.loads(series) 

53 

54 return pagination_resp( 

55 message="Most popular serie data sent", 

56 content=serie_data, 

57 page=page, 

58 total_pages=total_pages 

59 ) 

60 

61 except Exception as error: 

62 current_app.logger.error(error) 

63 return internal_err_resp() 

64 

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) 

69 

70 filters = [RecommendedContentModel.user_id == user.user_id] 

71 if reco_engine is not None: 

72 filters.append(RecommendedContentModel.engine == reco_engine) 

73 

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 ) 

87 

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 

94 

95 serie_data = list(map(c_load, series)) 

96 

97 return pagination_resp( 

98 message="Most popular serie data sent", 

99 content=serie_data, 

100 page=page, 

101 total_pages=total_pages 

102 ) 

103 

104 except Exception as error: 

105 current_app.logger.error(error) 

106 return internal_err_resp() 

107 

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) 

112 

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 ] 

118 

119 filters = [RecommendedContentForGroupModel.group_id.in_(groups_ids)] 

120 if reco_engine is not None: 

121 filters.append(RecommendedContentModel.engine == reco_engine) 

122 

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 ) 

136 

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 

143 

144 serie_data = list(map(c_load, series)) 

145 

146 return pagination_resp( 

147 message="Most popular serie data sent", 

148 content=serie_data, 

149 page=page, 

150 total_pages=total_pages 

151 ) 

152 

153 except Exception as error: 

154 current_app.logger.error(error) 

155 return internal_err_resp() 

156 

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() 

163 

164 try: 

165 genres_data = GenreBase.loads(genres) 

166 

167 resp = message(True, "Serie genres data sent") 

168 resp["content"] = genres_data 

169 return resp, 200 

170 

171 except Exception as error: 

172 current_app.logger.error(error) 

173 return internal_err_resp() 

174 

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) 

179 

180 try: 

181 episodes_data = EpisodeBase.loads(episodes) 

182 

183 resp = message(True, "Series episodes data sent") 

184 resp["content"] = episodes_data 

185 return resp, 200 

186 

187 except Exception as error: 

188 current_app.logger.error(error) 

189 return internal_err_resp() 

190 

191 except Exception as error: 

192 current_app.logger.error(error) 

193 return internal_err_resp() 

194 

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) 

200 

201 if not (serie := SerieModel.query.filter_by(content_id=content_id).first()): 

202 return err_resp("Serie not found!", 404) 

203 

204 try: 

205 for type, value in data.items(): 

206 if type in REASON_CATEGORIES['serie']: 

207 for r in value: 

208 

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 ) 

215 

216 db.session.add(new_bad_reco) 

217 db.session.flush() 

218 db.session.commit() 

219 

220 resp = message(True, "Bad recommendation has been registered.") 

221 return resp, 201 

222 

223 except Exception as error: 

224 current_app.logger.error(error) 

225 return internal_err_resp() 

226 

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) 

232 

233 # Check permissions 

234 permissions = get_jwt_claims()['permissions'] 

235 if "add_content" not in permissions: 

236 return err_resp("Permission missing", 403) 

237 

238 try: 

239 

240 new_additional_serie = SerieAdditionalModel( 

241 title=data['title'], 

242 ) 

243 

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'] 

258 

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) 

264 

265 db.session.add(new_additional_serie) 

266 db.session.flush() 

267 

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 ) 

274 

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'] 

283 

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) 

289 

290 db.session.add(new_additional_episode) 

291 

292 db.session.commit() 

293 

294 resp = message(True, "Serie have been added to validation.") 

295 return resp, 201 

296 

297 except Exception as error: 

298 import traceback 

299 traceback.print_exc() 

300 current_app.logger.error(error) 

301 return internal_err_resp() 

302 

303 

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) 

308 

309 # Check permissions 

310 permissions = get_jwt_claims()['permissions'] 

311 if "add_content" not in permissions: 

312 return err_resp("Permission missing", 403) 

313 

314 series, total_pages = Paginator.get_from( 

315 SerieAdditionalModel.query, 

316 page, 

317 ) 

318 

319 try: 

320 serie_data = SerieAdditionalBase.loads(series) 

321 

322 return pagination_resp( 

323 message="Additional series data sent", 

324 content=serie_data, 

325 page=page, 

326 total_pages=total_pages 

327 ) 

328 

329 except Exception as error: 

330 current_app.logger.error(error) 

331 return internal_err_resp() 

332 

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) 

337 

338 # Check permissions 

339 permissions = get_jwt_claims()['permissions'] 

340 if "validate_added_content" not in permissions: 

341 return err_resp("Permission missing", 403) 

342 

343 if not (serie := SerieAdditionalModel.query.filter_by(serie_id=serie_id).first()): 

344 return err_resp("Additional series not found!", 404) 

345 

346 try: 

347 content = ContentModel(rating=None, genres=serie.genres) 

348 db.session.add(content) 

349 db.session.flush() 

350 

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) 

364 

365 for episode in serie.episodes : 

366 content_episode = ContentModel(rating=None, genres=episode.genres) 

367 db.session.add(content) 

368 db.session.flush() 

369 

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 ) 

379 

380 db.session.add(new_serie) 

381 db.session.delete(episode) 

382 

383 db.session.delete(serie) 

384 db.session.commit() 

385 

386 resp = message( 

387 True, "Additional series data successfully validated") 

388 return resp, 201 

389 

390 except Exception as error: 

391 current_app.logger.error(error) 

392 return internal_err_resp() 

393 

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) 

398 

399 # Check permissions 

400 permissions = get_jwt_claims()['permissions'] 

401 if "delete_content" not in permissions: 

402 return err_resp("Permission missing", 403) 

403 

404 if not (serie := SerieAdditionalModel.query.filter_by(serie_id=serie_id).first()): 

405 return err_resp("Additional series not found!", 404) 

406 

407 try: 

408 for episode in serie.episodes : 

409 db.session.delete(episode) 

410 db.session.delete(serie) 

411 db.session.commit() 

412 

413 resp = message(True, "Additional series successfully deleted") 

414 return resp, 201 

415 

416 except Exception as error: 

417 current_app.logger.error(error) 

418 return internal_err_resp()