Caches pms images to disk

This commit is contained in:
JonnyWong16 2016-05-02 22:08:06 -07:00
parent 5ddd4d045e
commit 7be651f5cf
3 changed files with 79 additions and 37 deletions

View file

@ -17,6 +17,8 @@ import base64
import datetime import datetime
import fnmatch import fnmatch
from functools import wraps from functools import wraps
import hashlib
import imghdr
from IPy import IP from IPy import IP
import json import json
import math import math
@ -563,4 +565,38 @@ def uploadToImgur(imgPath, imgTitle=''):
except (urllib2.HTTPError, urllib2.URLError) as e: except (urllib2.HTTPError, urllib2.URLError) as e:
logger.warn(u"PlexPy Helpers :: Unable to upload image to Imgur: %s" % e) logger.warn(u"PlexPy Helpers :: Unable to upload image to Imgur: %s" % e)
return img_url return img_url
def cache_image(url, image=None):
"""
Saves an image to the cache directory.
If no image is provided, tries to return the image from the cach directory.
"""
from plexpy import logger
# Create image directory if it doesn't exist
imgdir = os.path.join(plexpy.CONFIG.CACHE_DIR, 'images/')
if not os.path.exists(imgdir):
logger.debug(u"PlexPy Helpers :: Creating image cache directory at %s" % imgdir)
os.makedirs(imgdir)
# Create a hash of the path to use as filename
imghash = hashlib.md5(url).hexdigest()
imagefile = os.path.join(imgdir, imghash)
# If an image was provided, save it to the cache directory
if image:
try:
with open(imagefile, 'wb') as cache_file:
cache_file.write(image)
except IOError as e:
logger.error(u"PlexPy Helpers :: Failed to cache image %s: %s" % (imagefile, e))
# Try to return the image from the cache directory
if os.path.isfile(imagefile):
imagetype = 'image/' + imghdr.what(os.path.abspath(imagefile))
else:
imagefile = None
imagetype = 'image/jpeg'
return imagefile, imagetype

View file

@ -1886,7 +1886,7 @@ class PmsConnect(object):
return labels_list return labels_list
def get_image(self, img=None, width=None, height=None): def get_image(self, img=None, width=None, height=None, fallback=None):
""" """
Return image data as array. Return image data as array.
Array contains the image content type and image binary Array contains the image content type and image binary
@ -1896,21 +1896,51 @@ class PmsConnect(object):
height { the image height } height { the image height }
Output: array Output: array
""" """
if img: if not img:
logger.error(u"PlexPy Pmsconnect :: Image proxy queried but no input received.")
return None
# Remove the timestamp from PMS image uri
image_uri = img.rsplit('/', 1)[0]
# Try to retrieve the image from cache if it isn't a bif index.
if not 'indexes' in image_uri:
image_path, content_type = helpers.cache_image(image_uri)
if image_path and content_type:
return [open(image_path, 'rb'), content_type]
try:
if width.isdigit() and height.isdigit(): if width.isdigit() and height.isdigit():
uri = '/photo/:/transcode?url=http://127.0.0.1:32400' + img + '&width=' + width + '&height=' + height uri = '/photo/:/transcode?url=http://127.0.0.1:32400' + img + '&width=' + width + '&height=' + height
else: else:
uri = '/photo/:/transcode?url=http://127.0.0.1:32400' + img logger.error(u"PlexPy Pmsconnect :: Image proxy queried but no width or height specified.")
raise Exception
request, content_type = self.request_handler.make_request(uri=uri, request, content_type = self.request_handler.make_request(uri=uri,
proto=self.protocol, proto=self.protocol,
request_type='GET', request_type='GET',
return_type=True) return_type=True)
# Save the image to cache if it isn't a bif index.
if not 'indexes' in image_uri:
helpers.cache_image(image_uri, request)
return [request, content_type] return [request, content_type]
else:
logger.error(u"PlexPy Pmsconnect :: Image proxy queries but no input received.") except Exception as e:
return None if fallback:
logger.debug(u"PlexPy Pmsconnect :: Trying fallback %s image." % fallback)
try:
if fallback == 'poster':
return [open(common.DEFAULT_POSTER_THUMB, 'rb'), 'image/png']
elif fallback == 'cover':
return [open(common.DEFAULT_COVER_THUMB, 'rb'), 'image/png']
elif fallback == 'art':
return [open(common.DEFAULT_ART, 'rb'), 'image/png']
except IOError as e:
logger.error(u"PlexPy Pmsconnect :: Unable to read fallback %s image: %s" % (fallback, e))
return None
def get_search_results(self, query=''): def get_search_results(self, query=''):
""" """

View file

@ -1887,38 +1887,14 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def pms_image_proxy(self, img='', width='0', height='0', fallback=None, **kwargs): def pms_image_proxy(self, img='', width='0', height='0', fallback=None, **kwargs):
try:
pms_connect = pmsconnect.PmsConnect() pms_connect = pmsconnect.PmsConnect()
result = pms_connect.get_image(img, width, height) result = pms_connect.get_image(img, width, height, fallback)
if result:
cherrypy.response.headers['Content-type'] = result[1] cherrypy.response.headers['Content-type'] = result[1]
return result[0] return result[0]
except: else:
logger.warn(u"Image proxy queried but errors occurred.")
if fallback == 'poster':
logger.info(u"Trying fallback image...")
try:
fallback_image = open(self.interface_dir + common.DEFAULT_POSTER_THUMB, 'rb')
cherrypy.response.headers['Content-type'] = 'image/png'
return fallback_image
except IOError, e:
logger.error(u"Unable to read fallback %s image: %s" % (fallback, e))
elif fallback == 'cover':
logger.info(u"Trying fallback image...")
try:
fallback_image = open(self.interface_dir + common.DEFAULT_COVER_THUMB, 'rb')
cherrypy.response.headers['Content-type'] = 'image/png'
return fallback_image
except IOError, e:
logger.error(u"Unable to read fallback %s image: %s" % (fallback, e))
elif fallback == 'art':
logger.info(u"Trying fallback image...")
try:
fallback_image = open(self.interface_dir + common.DEFAULT_ART, 'rb')
cherrypy.response.headers['Content-type'] = 'image/png'
return fallback_image
except IOError, e:
logger.error(u"Unable to read fallback %s image: %s" % (fallback, e))
return None return None
@cherrypy.expose @cherrypy.expose