mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-12 08:16:06 -07:00
Caches pms images to disk
This commit is contained in:
parent
5ddd4d045e
commit
7be651f5cf
3 changed files with 79 additions and 37 deletions
|
@ -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
|
||||||
|
@ -564,3 +566,37 @@ def uploadToImgur(imgPath, imgTitle=''):
|
||||||
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
|
|
@ -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,20 +1896,50 @@ 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:
|
||||||
|
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
|
return None
|
||||||
|
|
||||||
def get_search_results(self, query=''):
|
def get_search_results(self, query=''):
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue