# coding=utf-8 import json import requests import os import logging from flask_restx import Resource, Namespace, reqparse from bs4 import BeautifulSoup as bso from app.database import TableEpisodes, TableShows, TableMovies from subtitles.mass_download import episode_download_subtitles, movies_download_subtitles from ..utils import authenticate api_ns_webhooks_plex = Namespace('Webhooks Plex', description='Webhooks endpoint that can be configured in Plex to ' 'trigger a subtitles search when playback start.') @api_ns_webhooks_plex.route('webhooks/plex') class WebHooksPlex(Resource): post_request_parser = reqparse.RequestParser() post_request_parser.add_argument('payload', type=str, required=True, help='Webhook payload') @authenticate @api_ns_webhooks_plex.doc(parser=post_request_parser) @api_ns_webhooks_plex.response(200, 'Success') @api_ns_webhooks_plex.response(204, 'Unhandled event') @api_ns_webhooks_plex.response(400, 'No GUID found') @api_ns_webhooks_plex.response(401, 'Not Authenticated') @api_ns_webhooks_plex.response(404, 'IMDB series/movie ID not found') def post(self): """Trigger subtitles search on play media event in Plex""" args = self.post_request_parser.parse_args() json_webhook = args.get('payload') parsed_json_webhook = json.loads(json_webhook) if 'Guid' not in parsed_json_webhook['Metadata']: logging.debug('No GUID provided in Plex json payload. Probably a pre-roll video.') return "No GUID found in JSON request body", 200 event = parsed_json_webhook['event'] if event not in ['media.play']: return 'Unhandled event', 204 media_type = parsed_json_webhook['Metadata']['type'] if media_type == 'episode': season = parsed_json_webhook['Metadata']['parentIndex'] episode = parsed_json_webhook['Metadata']['index'] else: season = episode = None ids = [] for item in parsed_json_webhook['Metadata']['Guid']: splitted_id = item['id'].split('://') if len(splitted_id) == 2: ids.append({splitted_id[0]: splitted_id[1]}) if not ids: return 'No GUID found', 400 if media_type == 'episode': try: episode_imdb_id = [x['imdb'] for x in ids if 'imdb' in x][0] r = requests.get('https://imdb.com/title/{}'.format(episode_imdb_id), headers={"User-Agent": os.environ["SZ_USER_AGENT"]}) soup = bso(r.content, "html.parser") script_tag = soup.find(id='__NEXT_DATA__') script_tag_json = script_tag.string show_metadata_dict = json.loads(script_tag_json) series_imdb_id = show_metadata_dict['props']['pageProps']['aboveTheFoldData']['series']['series']['id'] except Exception: logging.debug('BAZARR is unable to get series IMDB id.') return 'IMDB series ID not found', 404 else: sonarrEpisodeId = TableEpisodes.select(TableEpisodes.sonarrEpisodeId) \ .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId)) \ .where(TableShows.imdbId == series_imdb_id, TableEpisodes.season == season, TableEpisodes.episode == episode) \ .dicts() \ .get_or_none() if sonarrEpisodeId: episode_download_subtitles(no=sonarrEpisodeId['sonarrEpisodeId'], send_progress=True) else: try: movie_imdb_id = [x['imdb'] for x in ids if 'imdb' in x][0] except Exception: logging.debug('BAZARR is unable to get movie IMDB id.') return 'IMDB movie ID not found', 404 else: radarrId = TableMovies.select(TableMovies.radarrId)\ .where(TableMovies.imdbId == movie_imdb_id)\ .dicts()\ .get_or_none() if radarrId: movies_download_subtitles(no=radarrId['radarrId']) return '', 200