2021-12-04 03:49:20 +00:00
|
|
|
# coding=utf-8
|
|
|
|
|
|
|
|
import json
|
|
|
|
import requests
|
|
|
|
import os
|
2022-03-28 16:25:09 +00:00
|
|
|
import logging
|
2021-12-04 03:49:20 +00:00
|
|
|
|
2022-09-22 03:51:34 +00:00
|
|
|
from flask_restx import Resource, Namespace, reqparse
|
2021-12-04 03:49:20 +00:00
|
|
|
from bs4 import BeautifulSoup as bso
|
|
|
|
|
2023-07-26 23:34:49 +00:00
|
|
|
from app.database import TableEpisodes, TableShows, TableMovies, database, select
|
2022-05-01 12:00:20 +00:00
|
|
|
from subtitles.mass_download import episode_download_subtitles, movies_download_subtitles
|
|
|
|
|
2021-12-04 03:49:20 +00:00
|
|
|
from ..utils import authenticate
|
|
|
|
|
|
|
|
|
2022-09-22 03:51:34 +00:00
|
|
|
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')
|
2021-12-04 03:49:20 +00:00
|
|
|
class WebHooksPlex(Resource):
|
2022-09-22 03:51:34 +00:00
|
|
|
post_request_parser = reqparse.RequestParser()
|
|
|
|
post_request_parser.add_argument('payload', type=str, required=True, help='Webhook payload')
|
|
|
|
|
2021-12-04 03:49:20 +00:00
|
|
|
@authenticate
|
2022-09-22 03:51:34 +00:00
|
|
|
@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')
|
2021-12-04 03:49:20 +00:00
|
|
|
def post(self):
|
2022-09-22 03:51:34 +00:00
|
|
|
"""Trigger subtitles search on play media event in Plex"""
|
|
|
|
args = self.post_request_parser.parse_args()
|
|
|
|
json_webhook = args.get('payload')
|
2021-12-04 03:49:20 +00:00
|
|
|
parsed_json_webhook = json.loads(json_webhook)
|
2022-12-14 17:56:33 +00:00
|
|
|
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
|
2021-12-04 03:49:20 +00:00
|
|
|
|
|
|
|
event = parsed_json_webhook['event']
|
|
|
|
if event not in ['media.play']:
|
2022-09-22 03:51:34 +00:00
|
|
|
return 'Unhandled event', 204
|
2021-12-04 03:49:20 +00:00
|
|
|
|
|
|
|
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:
|
2022-08-24 01:13:06 +00:00
|
|
|
return 'No GUID found', 400
|
2021-12-04 03:49:20 +00:00
|
|
|
|
|
|
|
if media_type == 'episode':
|
|
|
|
try:
|
|
|
|
episode_imdb_id = [x['imdb'] for x in ids if 'imdb' in x][0]
|
2023-10-18 03:24:26 +00:00
|
|
|
r = requests.get(f'https://imdb.com/title/{episode_imdb_id}',
|
2021-12-04 03:49:20 +00:00
|
|
|
headers={"User-Agent": os.environ["SZ_USER_AGENT"]})
|
|
|
|
soup = bso(r.content, "html.parser")
|
2022-03-28 16:25:09 +00:00
|
|
|
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']
|
2022-01-03 03:59:30 +00:00
|
|
|
except Exception:
|
2022-03-28 16:25:09 +00:00
|
|
|
logging.debug('BAZARR is unable to get series IMDB id.')
|
2022-08-24 01:13:06 +00:00
|
|
|
return 'IMDB series ID not found', 404
|
2021-12-04 03:49:20 +00:00
|
|
|
else:
|
2023-07-26 23:34:49 +00:00
|
|
|
sonarrEpisodeId = database.execute(
|
|
|
|
select(TableEpisodes.sonarrEpisodeId)
|
|
|
|
.select_from(TableEpisodes)
|
|
|
|
.join(TableShows)
|
2021-12-04 03:49:20 +00:00
|
|
|
.where(TableShows.imdbId == series_imdb_id,
|
|
|
|
TableEpisodes.season == season,
|
2023-07-26 23:34:49 +00:00
|
|
|
TableEpisodes.episode == episode)) \
|
|
|
|
.first()
|
2021-12-04 03:49:20 +00:00
|
|
|
|
|
|
|
if sonarrEpisodeId:
|
2023-07-26 23:34:49 +00:00
|
|
|
episode_download_subtitles(no=sonarrEpisodeId.sonarrEpisodeId, send_progress=True)
|
2021-12-04 03:49:20 +00:00
|
|
|
else:
|
|
|
|
try:
|
|
|
|
movie_imdb_id = [x['imdb'] for x in ids if 'imdb' in x][0]
|
2022-01-03 03:59:30 +00:00
|
|
|
except Exception:
|
2022-08-24 01:13:06 +00:00
|
|
|
logging.debug('BAZARR is unable to get movie IMDB id.')
|
|
|
|
return 'IMDB movie ID not found', 404
|
2021-12-04 03:49:20 +00:00
|
|
|
else:
|
2023-07-26 23:34:49 +00:00
|
|
|
radarrId = database.execute(
|
|
|
|
select(TableMovies.radarrId)
|
|
|
|
.where(TableMovies.imdbId == movie_imdb_id)) \
|
|
|
|
.first()
|
2022-02-11 15:59:09 +00:00
|
|
|
|
2021-12-04 03:49:20 +00:00
|
|
|
if radarrId:
|
2023-07-26 23:34:49 +00:00
|
|
|
movies_download_subtitles(no=radarrId.radarrId)
|
2021-12-04 03:49:20 +00:00
|
|
|
|
|
|
|
return '', 200
|