Browse Source

add query_movie_json flask route

master
cinnaboot 7 years ago
parent
commit
7be03e5a77
  1. 122
      video_metadata/views/tmdb.py

122
video_metadata/views/tmdb.py

@ -12,7 +12,7 @@ from urllib.error import URLError, HTTPError
import urllib.parse
import urllib.request
from flask import Blueprint, current_app, flash, Flask, request, render_template
from flask import Blueprint, current_app, flash, Flask, jsonify, request, render_template, Response
from .. import util
from .. import db
@ -73,6 +73,18 @@ class view_result:
poster_path: str = 'no_image.png'
tmdb_link: str = ''
# NOTE: haven't found a better way to json encode dataclasses :(
class result_encoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, view_result):
return obj.__dict__
try:
ret = json.JSONEncoder.default(self, obj)
except TypeError:
return ''
return ret
####################
# flask routes
@ -102,11 +114,11 @@ def list_movie_test():
url_prefix = current_app.config['VIDEO_URL_PREFIX']
)
@bp.route('/query_movie', methods=['GET', 'POST'])
def query_movie():
errors = []
query = query_data()
response = response_data()
view_results = []
# NOTE: query string can be submitted from a link or form input
@ -118,32 +130,9 @@ def query_movie():
query.raw_query_str = request.args['query']
query.rel_path = request.args['rel_path']
# TODO: if query_obj.query_type is still 'UNKNOWN' from parseQueryStr(), make queries to
# both tmdb endpoints (movie and tv)
if query.raw_query_str and parseQueryStr(query):
if isQueryCached(query.parsed_query_str):
view_results = makeLocalQuery(query)
else:
makeTMDBQuery(query, response)
try:
response.parsed_response = json.loads(response.response_body)
except json.JSONDecodeError as e:
view_data.errors.append(e)
if 'total_results' in response.parsed_response:
response.result_count = response.parsed_response['total_results']
# TODO: it's possible for the query results to span multiple 'pages'
# see) https://developers.themoviedb.org/3/search/search-movies
if 'results' in response.parsed_response:
for result in response.parsed_response['results']:
view_results.append(parseTMDBResult(result, query.query_type))
storeTMDBQueryResults(query, view_results)
errors.extend(query.errors)
errors.extend(response.errors)
q_res = doQueryAlgorithm(query)
errors = q_res['errors']
view_results = q_res['results']
if errors:
view_results.clear()
@ -155,14 +144,40 @@ def query_movie():
'tmdb/query.html',
view_data = view_results,
rel_path = query.rel_path,
debug_str = '{} \n {} \n {} \n'.format(
debug_str = '{} \n {} \n'.format(
util.dumpObject(query),
util.dumpObject(response),
util.dumpObject(view_results)
)
)
@bp.route('/query_movie_json')
def query_movie_json():
query = query_data()
results = []
if 'query' in request.args and 'rel_path' in request.args:
query.raw_query_str = request.args['query']
query.rel_path = request.args['rel_path']
q_res = doQueryAlgorithm(query)
errors = q_res['errors']
results = q_res['results']
current_app.logger.debug(f'{util.getFunctionName()}, results length: {len(results)}')
else:
errors = ['required parameters: query, rel_path']
if errors:
for e in errors:
current_app.logger.error(e)
return jsonify(errors=errors)
res = Response(json.dumps(results, cls=result_encoder))
res.headers.set('Content-Type', 'application/json')
return res
# TODO: add option for tv shows
# TODO: this endpoint should be http POST only
@bp.route('/create_mapping')
def create_mapping():
movie_id = request.args.get('movie_id')
@ -197,6 +212,41 @@ def create_mapping():
###################
# helpers
def doQueryAlgorithm(query:query_data) -> list:
errors, view_results = [], []
response = response_data()
# TODO: if query_obj.query_type is still 'UNKNOWN' from parseQueryStr(), make queries to
# both tmdb endpoints (movie and tv)
if query.raw_query_str and parseQueryStr(query):
if isQueryCached(query.parsed_query_str):
view_results = makeLocalQuery(query)
current_app.logger.debug(f'{util.getFunctionName()}, view_results length: {len(view_results)}')
else:
makeTMDBQuery(query, response)
try:
response.parsed_response = json.loads(response.response_body)
except json.JSONDecodeError as e:
errors.append(e)
if 'total_results' in response.parsed_response:
response.result_count = response.parsed_response['total_results']
# TODO: it's possible for the query results to span multiple 'pages'
# see) https://developers.themoviedb.org/3/search/search-movies
if 'results' in response.parsed_response:
for result in response.parsed_response['results']:
view_results.append(parseTMDBResult(result, query.query_type))
storeTMDBQueryResults(query, view_results)
errors.extend(query.errors)
errors.extend(response.errors)
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):
@ -225,16 +275,19 @@ def parseQueryStr(query_obj):
return True
def isQueryCached(query_str):
conn = db.get_db()
cur = conn.cursor()
cur.execute('SELECT COUNT(*) FROM movie_queries WHERE query=?', (query_str,))
count = cur.fetchone()[0]
current_app.logger.debug('movie_queries count: "{}, query: {}"'.format(count, query_str))
current_app.logger.debug(
f'{util.getFunctionName()}, movie_queries count: {count}, query: "{query_str}"'
)
return (count > 0)
# NOTE: returns list of 'view_result' objects that match the query_obj.parsed_query_str
# stored in the local db cache
def makeLocalQuery(query_obj):
@ -256,6 +309,7 @@ def makeLocalQuery(query_obj):
return results
def buildViewResult(db_row):
vr = view_result()
vr.id = db_row['movie_id']
@ -270,6 +324,8 @@ def buildViewResult(db_row):
return vr
# TODO: add info and debug logging for network requests
def makeTMDBQuery(query_obj, response_obj):
if query_obj.query_type == query_type.MOVIE:
search_part = TMDB_SEARCH_MOVIE
@ -319,6 +375,7 @@ def makeTMDBQuery(query_obj, response_obj):
return True
# NOTE: @param result is parsed JSON object from tmdb API
def parseTMDBResult(result, query_type):
parsed = view_result()
@ -338,6 +395,7 @@ def parseTMDBResult(result, query_type):
return parsed
def storeTMDBQueryResults(query_obj, result_list):
conn = db.get_db()
cur = conn.cursor()

Loading…
Cancel
Save