Browse Source

add poster image caching and redirects

master
cinnaboot 6 years ago
parent
commit
ada3fe2683
  1. 63
      video_metadata/views/tmdb.py

63
video_metadata/views/tmdb.py

@ -4,6 +4,8 @@ from dataclasses import dataclass, field
from datetime import date, datetime
from enum import IntEnum
import json
import os
from pathlib import Path
import re
from sqlite3 import DatabaseError
import ssl
@ -12,8 +14,8 @@ from urllib.error import URLError, HTTPError
import urllib.parse
import urllib.request
from flask import Blueprint, current_app, flash, Flask, jsonify, request, redirect, \
render_template, Response, url_for
from flask import Blueprint, current_app, flash, Flask, jsonify, make_response, request, \
redirect, render_template, Response, url_for
from .. import util
from .. import db
@ -31,6 +33,7 @@ TMDB_TV_LINK_URL = 'https://www.themoviedb.org/tv/'
TMDB_POSTER_PREFIX = 'https://image.tmdb.org/t/p/w154'
VALID_IMAGE_EXTENSIONS = ('.jpg', '.png', '.svg')
DEFAULT_POSTER_IMAGE = 'no_poster_w154.jpg'
LOCAL_POSTER_PATH = 'image_cache'
####################
@ -78,7 +81,7 @@ class view_result:
overview: str = ''
genre_ids: List[int] = field(default_factory=list)
original_language: str = ''
poster_path: str = 'no_image.png'
poster_path: str = ''
tmdb_link: str = ''
# TODO: flask 1.1 adds support for JSON encoding dataclasses
@ -279,27 +282,55 @@ def create_path_mapping():
return jsonify({'errors':errors, 'message':message})
@bp.route('/images')
@bp.route('/images/<string:image_name>')
def cache_image(image_name:str = ''):
current_app.logger.debug(f'image_name: {image_name}')
# validate image name
if (image_name == ''
or re.search(r'[^ a-zA-z0-9./]', image_name)
or not Path(image_name).suffix in VALID_IMAGE_EXTENSIONS):
current_app.logger.error(f'invalid image name: {image_name}')
return redirect(url_for('static', filename=DEFAULT_POSTER_IMAGE))
if image_name != '':
s = re.sub(r'/', '', image_name)
ext = re.compile(r'.[a-zA-Z]{3}$').search(image_name).group(0)
print(f'ext: "{ext}"')
# look for image in cache folder
local_dir = Path(current_app.instance_path).joinpath(LOCAL_POSTER_PATH)
image = Path(image_name).name
p = local_dir.joinpath(image)
current_app.logger.debug(f'checking for local path: {p}')
if not ext in VALID_IMAGE_EXTENSIONS:
print('oops')
else:
print(f'seems okay: {ext}')
if not p.exists():
# make request for remote image
response = util.URLResponse
url = f'{TMDB_POSTER_PREFIX}/{s}'
if util.getURL(f'{TMDB_POSTER_PREFIX}/{image}', response, current_app.logger):
# store remote image
current_app.logger.debug(f'content-type for {image}: {response.content_type}')
try:
fp = open(p, 'wb')
fp.write(response.body)
fp.close()
except OSError as e:
current_app.logger.error(e)
return redirect(url_for('static', filename=DEFAULT_POSTER_IMAGE))
#res = Response(json.dumps(results, cls=result_encoder))
#res.headers.set('Content-Type', 'application/json')
#return str(f'image_name: {image_name}, url: {url}')
# redirect to saved image
try:
fp = open(p, 'rb')
image_bytes = fp.read()
except OSError as e:
current_app.logger.error(e)
return redirect(url_for('static', filename=DEFAULT_POSTER_IMAGE))
def getCType(s):
if s is '.jpg':
return 'image/jpeg'
elif s is '.png':
return 'image/png'
elif s is '.svg':
return 'image/svg+xml'
return make_response(tuple([image_bytes, {'Content-Type': getCType(p.suffix)} ]))
###################
# helpers

Loading…
Cancel
Save