|
|
|
|
@ -16,6 +16,7 @@ import urllib.request
|
|
|
|
|
|
|
|
|
|
from flask import Blueprint, current_app, flash, Flask, jsonify, make_response, request, \ |
|
|
|
|
redirect, render_template, Response, url_for |
|
|
|
|
from guessit import guessit |
|
|
|
|
|
|
|
|
|
from .. import util |
|
|
|
|
from .. import db |
|
|
|
|
@ -53,13 +54,17 @@ class media_type(IntEnum):
|
|
|
|
|
@dataclass |
|
|
|
|
class query_data: |
|
|
|
|
errors: List[str] = field(default_factory=list) |
|
|
|
|
full_url: str = '' |
|
|
|
|
movie_year: int = 0 |
|
|
|
|
is_valid:bool = True |
|
|
|
|
raw_query_str:str = '' |
|
|
|
|
parsed_query_str:str = '' |
|
|
|
|
query_params: str = '' |
|
|
|
|
title:str = '' |
|
|
|
|
media_type:media_type = media_type.UNKNOWN |
|
|
|
|
raw_query_str: str = '' |
|
|
|
|
rel_path:str = '' |
|
|
|
|
query_params:str = '' |
|
|
|
|
full_url:str = '' |
|
|
|
|
movie_year:int = 0 |
|
|
|
|
tv_season:str = '' |
|
|
|
|
tv_episode:str = '' |
|
|
|
|
|
|
|
|
|
@dataclass |
|
|
|
|
class response_data: |
|
|
|
|
@ -168,10 +173,11 @@ def tv_show_test():
|
|
|
|
|
@bp.route('/manual_query', methods=['GET', 'POST']) |
|
|
|
|
def manual_query(): |
|
|
|
|
query = query_data() |
|
|
|
|
view_results = [] |
|
|
|
|
errors = [] |
|
|
|
|
|
|
|
|
|
if 'query' in request.form: |
|
|
|
|
query.raw_query_str = request.form['query'] |
|
|
|
|
|
|
|
|
|
q_res = doQueryAlgorithm(query) |
|
|
|
|
errors = q_res['errors'] |
|
|
|
|
view_results = q_res['results'] |
|
|
|
|
@ -338,10 +344,9 @@ def cache_image(image_name:str = ''):
|
|
|
|
|
def doQueryAlgorithm(query:query_data) -> dict: |
|
|
|
|
errors, view_results = [], [] |
|
|
|
|
response = response_data() |
|
|
|
|
query = guessMedia(query) |
|
|
|
|
|
|
|
|
|
# TODO: if query_obj.media_type is still 'UNKNOWN' from parseQueryStr(), make queries to |
|
|
|
|
# both tmdb endpoints (movie and tv) |
|
|
|
|
if query.raw_query_str and parseQueryStr(query): |
|
|
|
|
if query.is_valid: |
|
|
|
|
if isQueryCached(query.parsed_query_str, query.movie_year): |
|
|
|
|
view_results = makeLocalQuery(query) |
|
|
|
|
current_app.logger.debug(f'view_results length: {len(view_results)}') |
|
|
|
|
@ -370,35 +375,25 @@ def doQueryAlgorithm(query:query_data) -> dict:
|
|
|
|
|
return {'errors': errors, 'results': view_results} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: need a way to correctly parse titles like: "2001: A Space Odyssey (1968)" |
|
|
|
|
# with legitimate dates in the title |
|
|
|
|
def parseQueryStr(query_obj): |
|
|
|
|
s = query_obj.raw_query_str.replace('.', ' ').strip().lower() |
|
|
|
|
s = re.sub('[(){}\[\]]', '', s).strip() # NOTE: remove some common characters |
|
|
|
|
current_year = date.today().year |
|
|
|
|
|
|
|
|
|
# NOTE: check for a string that looks like a tv show |
|
|
|
|
m = re.search(r's[0-9]{1,2}|season ?[0-9]{1,2}', s, re.IGNORECASE) |
|
|
|
|
|
|
|
|
|
if m: |
|
|
|
|
query_obj.parsed_query_str = s[0:m.start()].strip() |
|
|
|
|
query_obj.media_type = media_type.TV_SHOW |
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
# NOTE: find all 4 digit numbers to match the year of queries with 4 digit numbers in the title |
|
|
|
|
# ex) "2036.Origin.Unknown.2018" |
|
|
|
|
regex = re.compile('[0-9]{4}') |
|
|
|
|
def guessMedia(query:query_data) -> query_data: |
|
|
|
|
guess = guessit(query.raw_query_str) |
|
|
|
|
query.title = guess['title'] |
|
|
|
|
query.parsed_query_str = guess['title'].lower() |
|
|
|
|
|
|
|
|
|
for m in regex.finditer(s): |
|
|
|
|
i = int(m[0]) |
|
|
|
|
if i > 1878 and i <= current_year: |
|
|
|
|
query_obj.parsed_query_str = s[0:m.start()].strip() # NOTE: slice query string to year match |
|
|
|
|
query_obj.movie_year = i |
|
|
|
|
query_obj.media_type = media_type.MOVIE |
|
|
|
|
return True |
|
|
|
|
try: |
|
|
|
|
if guess['type'] == 'movie': |
|
|
|
|
query.media_type = media_type.MOVIE |
|
|
|
|
query.movie_year = guess['year'] |
|
|
|
|
else: # NOTE: 'type' has to be 'episode' here. guessit has no 'unknown' equivalent |
|
|
|
|
query.media_type = media_type.TV_SHOW |
|
|
|
|
query.tv_season = guess['season'] |
|
|
|
|
query.tv_episode = guess['episode'] |
|
|
|
|
except KeyError as e: |
|
|
|
|
query.is_valid = False |
|
|
|
|
current_app.logger.error(f'invalid key: {e}, for query: {query.raw_query_str}') |
|
|
|
|
|
|
|
|
|
current_app.logger.warning(f'unable to guess media type for "{query_obj.raw_query_str}"') |
|
|
|
|
return False |
|
|
|
|
current_app.logger.debug(f'query: {util.dumpObject(query)}') |
|
|
|
|
return query |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def isQueryCached(query_str:str, year) -> bool: |
|
|
|
|
@ -470,6 +465,8 @@ def buildViewResult(db_row):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: need to check response headers for rate limiting requests |
|
|
|
|
# TODO: if query_obj.media_type is still 'UNKNOWN' from parseQueryStr(), make queries to |
|
|
|
|
# both tmdb endpoints (movie and tv) |
|
|
|
|
def makeTMDBQuery(query_obj, response_obj): |
|
|
|
|
if query_obj.media_type == media_type.MOVIE: |
|
|
|
|
search_part = TMDB_SEARCH_MOVIE |
|
|
|
|
|