Offload image processing to the Plex server

This commit is contained in:
JonnyWong16 2018-03-17 14:03:27 -07:00
parent 003e890844
commit 1f7be7a4d5
10 changed files with 96 additions and 158 deletions

View file

@ -2,7 +2,6 @@
<%!
import json
from plexpy import helpers, notifiers
from plexpy.notification_handler import PILLOW
email_notifiers = [n for n in notifiers.get_notifiers() if n['agent_name'] == 'email']
sorted(email_notifiers, key=lambda k: (k['agent_label'], k['friendly_name'], k['id']))

View file

@ -1,6 +1,5 @@
% if data:
<%
from plexpy.notification_handler import PILLOW
recently_added = data['recently_added']
%>
<!doctype html>
@ -351,26 +350,11 @@
margin: 3px auto !important;
}
.card-background {
background-color: #3F4245;
background-position: center;
background-size: cover;
width: 100%;
height: 100%;
}
.card-background-preview {
background-color: #3F4245;
background-position: center;
background-size: cover;
opacity: 0.25;
-webkit-filter: blur(3px);
filter: blur(3px);
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 0;
}
.card-poster-container {
width: 150px;
margin: 3px;
@ -387,7 +371,7 @@
height: 150px;
}
.card-poster {
background-color: #3F4245;
background-color: #282828;
background-position: center;
background-size: cover;
height: 100%;
@ -617,19 +601,14 @@
% else:
<div class="card-instance movie" style="float: left;width: 500px;margin: 3px;border: 1px solid rgba(255,255,255,.1);-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;font-size: 12px;overflow: hidden;position: relative;height: 235px;">
% endif
% if PILLOW:
% if preview:
<div class="card-background" style="background-color: #3F4245;background-position: center;background-size: cover;width: 100%;height: 100%;">
<div class="card-background-preview" style="background-image: url(${'pms_image_proxy?img=' + movie['art'] + '&width=500&height=280&fallback=art&refresh=true'});background-color: #3F4245;background-position: center;background-size: cover;opacity: 0.25;-webkit-filter: blur(3px);filter: blur(3px);position: absolute;top: 0;right: 0;bottom: 0;left: 0;z-index: 0;"></div>
<div class="card-background" style="background-image: url(${'pms_image_proxy?img=' + movie['art'] + '&width=500&height=280&opacity=25&background=282828&blur=3&fallback=art&refresh=true'});background-position: center;background-size: cover;width: 100%;height: 100%;">
% else:
<div class="card-background" style="background-image: url(${movie['art_url']});background-color: #3F4245;background-position: center;background-size: cover;width: 100%;height: 100%;">
% endif
% else:
<div class="card-background" style="background-color: #3F4245;background-position: center;background-size: cover;width: 100%;height: 100%;">
<div class="card-background" style="background-image: url(${movie['art_url']});background-position: center;background-size: cover;width: 100%;height: 100%;">
% endif
<div class="card-poster-container" style="width: 150px;margin: 3px;border: 1px solid rgba(255,255,255,.1);float: left;position: relative;z-index: 1;height: 225px;">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${movie['rating_key']}" title="${movie['title']}" target="_blank" style="color: #3498db;text-decoration: underline;">
<div class="card-poster" style="background-image: url(${'pms_image_proxy?img=' + movie['thumb'] + '&width=300&height=450&fallback=poster&refresh=true' if preview else movie['poster_url']});background-color: #3F4245;background-position: center;background-size: cover;height: 100%;width: 100%;">
<div class="card-poster" style="background-image: url(${'pms_image_proxy?img=' + movie['thumb'] + '&width=300&height=450&fallback=poster&refresh=true' if preview else movie['poster_url']});background-color: #282828;background-position: center;background-size: cover;height: 100%;width: 100%;">
<div class="card-poster-overlay" style="background: url(https://cdn.discordapp.com/attachments/334355557706235906/401064397780287489/newsletter-view-on-plex-flat.png) bottom right no-repeat;width: 100%;height: 100%;"></div>
</div>
</a>
@ -705,19 +684,14 @@
% else:
<div class="card-instance show" style="float: left;width: 500px;margin: 3px;border: 1px solid rgba(255,255,255,.1);-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;font-size: 12px;overflow: hidden;position: relative;height: 235px;">
% endif
% if PILLOW:
% if preview:
<div class="card-background" style="background-color: #3F4245;background-position: center;background-size: cover;width: 100%;height: 100%;">
<div class="card-background-preview" style="background-image: url(${'pms_image_proxy?img=' + show['art'] + '&width=500&height=280&fallback=art&refresh=true'});background-color: #3F4245;background-position: center;background-size: cover;opacity: 0.25;-webkit-filter: blur(3px);filter: blur(3px);position: absolute;top: 0;right: 0;bottom: 0;left: 0;z-index: 0;"></div>
<div class="card-background" style="background-image: url(${'pms_image_proxy?img=' + show['art'] + '&width=500&height=280&opacity=25&background=282828&blur=3&fallback=art&refresh=true'});background-position: center;background-size: cover;width: 100%;height: 100%;">
% else:
<div class="card-background" style="background-image: url(${show['art_url']});background-color: #3F4245;background-position: center;background-size: cover;width: 100%;height: 100%;">
% endif
% else:
<div class="card-background" style="background-color: #3F4245;background-position: center;background-size: cover;width: 100%;height: 100%;">
<div class="card-background" style="background-image: url(${show['art_url']});background-position: center;background-size: cover;width: 100%;height: 100%;">
% endif
<div class="card-poster-container" style="width: 150px;margin: 3px;border: 1px solid rgba(255,255,255,.1);float: left;position: relative;z-index: 1;height: 225px;">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${link_rating_key}" title="${link_title}" target="_blank" style="color: #3498db;text-decoration: underline;">
<div class="card-poster" style="background-image: url(${'pms_image_proxy?img=' + show['thumb'] + '&width=300&height=450&fallback=poster&refresh=true' if preview else show['poster_url']});background-color: #3F4245;background-position: center;background-size: cover;height: 100%;width: 100%;">
<div class="card-poster" style="background-image: url(${'pms_image_proxy?img=' + show['thumb'] + '&width=300&height=450&fallback=poster&refresh=true' if preview else show['poster_url']});background-color: #282828;background-position: center;background-size: cover;height: 100%;width: 100%;">
<div class="card-poster-overlay" style="background: url(https://cdn.discordapp.com/attachments/334355557706235906/401064397780287489/newsletter-view-on-plex-flat.png) bottom right no-repeat;width: 100%;height: 100%;"></div>
</div>
</a>
@ -815,19 +789,14 @@
% else:
<div class="card-instance album" style="float: left;width: 500px;margin: 3px;border: 1px solid rgba(255,255,255,.1);-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;font-size: 12px;overflow: hidden;position: relative;height: 160px;">
% endif
% if PILLOW:
% if preview:
<div class="card-background" style="background-color: #3F4245;background-position: center;background-size: cover;width: 100%;height: 100%;">
<div class="card-background-preview" style="background-image: url(${'pms_image_proxy?img=' + album['art'] + '&width=500&height=280&fallback=art&refresh=true'});background-color: #3F4245;background-position: center;background-size: cover;opacity: 0.25;-webkit-filter: blur(3px);filter: blur(3px);position: absolute;top: 0;right: 0;bottom: 0;left: 0;z-index: 0;"></div>
<div class="card-background-preview" style="background-image: url(${'pms_image_proxy?img=' + album['art'] + '&width=500&height=280&opacity=25&background=282828&blur=3&fallback=art&refresh=true'});">
% else:
<div class="card-background" style="background-image: url(${album['art_url']});background-color: #3F4245;background-position: center;background-size: cover;width: 100%;height: 100%;">
% endif
% else:
<div class="card-background" style="background-color: #3F4245;background-position: center;background-size: cover;width: 100%;height: 100%;">
<div class="card-background" style="background-image: url(${album['art_url']});background-position: center;background-size: cover;width: 100%;height: 100%;">
% endif
<div class="card-poster-container" style="width: 150px;margin: 3px;border: 1px solid rgba(255,255,255,.1);float: left;position: relative;z-index: 1;height: 150px;">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${album['rating_key']}" title="${album['title']}" target="_blank" style="color: #3498db;text-decoration: underline;">
<div class="card-poster" style="background-image: url(${'pms_image_proxy?img=' + album['thumb'] + '&width=300&height=450&fallback=poster&refresh=true' if preview else album['poster_url']});background-color: #3F4245;background-position: center;background-size: cover;height: 100%;width: 100%;">
<div class="card-poster" style="background-image: url(${'pms_image_proxy?img=' + album['thumb'] + '&width=300&height=450&fallback=poster&refresh=true' if preview else album['poster_url']});background-color: #282828;background-position: center;background-size: cover;height: 100%;width: 100%;">
<div class="card-poster-overlay" style="background: url(https://cdn.discordapp.com/attachments/334355557706235906/401064397780287489/newsletter-view-on-plex-flat.png) bottom right no-repeat;width: 100%;height: 100%;"></div>
</div>
</a>

View file

@ -1,6 +1,5 @@
% if data:
<%
from plexpy.notification_handler import PILLOW
recently_added = data['recently_added']
%>
<!doctype html>
@ -351,26 +350,11 @@
margin: 3px auto !important;
}
.card-background {
background-color: #3F4245;
background-position: center;
background-size: cover;
width: 100%;
height: 100%;
}
.card-background-preview {
background-color: #3F4245;
background-position: center;
background-size: cover;
opacity: 0.25;
-webkit-filter: blur(3px);
filter: blur(3px);
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 0;
}
.card-poster-container {
width: 150px;
margin: 3px;
@ -617,15 +601,10 @@
% else:
<div class="card-instance movie">
% endif
% if PILLOW:
% if preview:
<div class="card-background">
<div class="card-background-preview" style="background-image: url(${'pms_image_proxy?img=' + movie['art'] + '&width=500&height=280&fallback=art&refresh=true'});"></div>
<div class="card-background" style="background-image: url(${'pms_image_proxy?img=' + movie['art'] + '&width=500&height=280&opacity=25&background=282828&blur=3&fallback=art&refresh=true'});">
% else:
<div class="card-background" style="background-image: url(${movie['art_url']});">
% endif
% else:
<div class="card-background">
% endif
<div class="card-poster-container">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${movie['rating_key']}" title="${movie['title']}" target="_blank">
@ -705,15 +684,10 @@
% else:
<div class="card-instance show">
% endif
% if PILLOW:
% if preview:
<div class="card-background">
<div class="card-background-preview" style="background-image: url(${'pms_image_proxy?img=' + show['art'] + '&width=500&height=280&fallback=art&refresh=true'});"></div>
<div class="card-background" style="background-image: url(${'pms_image_proxy?img=' + show['art'] + '&width=500&height=280&opacity=25&background=282828&blur=3&fallback=art&refresh=true'});">
% else:
<div class="card-background" style="background-image: url(${show['art_url']});">
% endif
% else:
<div class="card-background">
% endif
<div class="card-poster-container">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${link_rating_key}" title="${link_title}" target="_blank">
@ -815,15 +789,10 @@
% else:
<div class="card-instance album">
% endif
% if PILLOW:
% if preview:
<div class="card-background">
<div class="card-background-preview" style="background-image: url(${'pms_image_proxy?img=' + album['art'] + '&width=500&height=280&fallback=art&refresh=true'});"></div>
<div class="card-background-preview" style="background-image: url(${'pms_image_proxy?img=' + album['art'] + '&width=500&height=280&opacity=25&background=282828&blur=3&fallback=art&refresh=true'});">
% else:
<div class="card-background" style="background-image: url(${album['art_url']});">
% endif
% else:
<div class="card-background">
% endif
<div class="card-poster-container">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${album['rating_key']}" title="${album['title']}" target="_blank">

View file

@ -649,7 +649,7 @@ def dbcheck():
# art_urls table :: This table keeps record of the notification art urls
c_db.execute(
'CREATE TABLE IF NOT EXISTS art_urls (id INTEGER PRIMARY KEY AUTOINCREMENT, '
'rating_key INTEGER, art_title TEXT, art_url TEXT, blur_art_url TEXT)'
'rating_key INTEGER, art_title TEXT, art_url TEXT, delete_hash TEXT, blur INTEGER DEFAULT 0)'
)
# recently_added table :: This table keeps record of recently added items

View file

@ -1106,7 +1106,7 @@ class DataFactory(object):
return ip_address
def get_poster_info(self, rating_key='', metadata=None, art=False):
def get_poster_info(self, rating_key='', metadata=None, art=False, blur=None):
monitor_db = database.MonitorDatabase()
poster_key = ''
@ -1125,31 +1125,31 @@ class DataFactory(object):
if poster_key:
try:
if art:
query = 'SELECT art_title, art_url, blur_art_url FROM art_urls ' \
'WHERE rating_key = ?'
query = 'SELECT art_title, art_url, blur FROM art_urls ' \
'WHERE rating_key = ? AND blur = ?'
args = [poster_key, int(blur is not None)]
else:
query = 'SELECT poster_title, poster_url FROM poster_urls ' \
'WHERE rating_key = ?'
poster_info = monitor_db.select_single(query, args=[poster_key])
args = [poster_key]
poster_info = monitor_db.select_single(query, args=args)
except Exception as e:
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_poster_url: %s." % e)
return poster_info
def set_poster_url(self, rating_key='', poster_title='', poster_url='', delete_hash='', art=False, blur=False):
def set_poster_url(self, rating_key='', poster_title='', poster_url='', delete_hash='', art=False, blur=None):
monitor_db = database.MonitorDatabase()
if str(rating_key).isdigit():
keys = {'rating_key': int(rating_key)}
if art:
keys['blur'] = int(blur is not None)
table = 'art_urls'
values = {'art_title': poster_title,
'art_url': poster_url,
'delete_hash': delete_hash}
if blur:
values['blur_art_url'] = poster_url
else:
values['art_url'] = poster_url
else:
table = 'poster_urls'
values = {'poster_title': poster_title,

View file

@ -30,7 +30,7 @@ import logger
import newsletter_handler
import notification_handler
import pmsconnect
from notification_handler import PILLOW, get_poster_info
from notification_handler import get_poster_info
from notifiers import send_notification, EMAIL
@ -542,16 +542,16 @@ class RecentlyAdded(Newsletter):
if poster_info:
item['poster_url'] = poster_info['poster_url'] or common.ONLINE_POSTER_THUMB
art_info = {}
if PILLOW:
art_info = get_poster_info(poster_thumb=item['art'],
poster_key=item['rating_key'],
poster_title=item['title'],
art=True,
width='500',
height='280',
blur=True)
item['art_url'] = art_info.get('blur_art_url', '')
opacity='25',
background='282828',
blur='3')
item['art_url'] = art_info.get('art_url', '')
self.data['recently_added'] = recently_added
@ -600,19 +600,4 @@ class RecentlyAdded(Newsletter):
}
]
if not PILLOW:
pillow_message = {
'label': 'Background Art',
'description': 'The Pillow library is missing. '
'Background art on the newsletter media cards will not be included.<br>'
'Install the Pillow library to add background art. '
'Instructions can be found in the '
'<a href="' + helpers.anon_url('https://github.com/%s/plexpy/wiki/'
'Frequently-Asked-Questions-(FAQ)#notifications-pillow'
% plexpy.CONFIG.GIT_USER) + '" target="_blank">FAQ</a>.',
'name': 'recently_added_pillow',
'input_type': 'help'
}
config_option.insert(0, pillow_message)
return config_option

View file

@ -26,12 +26,6 @@ from string import Formatter
import threading
import time
try:
from PIL import Image, ImageFilter
PILLOW = True
except ImportError:
PILLOW = False
import plexpy
import activity_processor
import common
@ -1071,53 +1065,42 @@ def format_group_index(group_keys):
return ','.join(num) or '0', ','.join(num00) or '00'
def get_poster_info(poster_thumb='', poster_key='', poster_title='', art=False, width='', height='', blur=False):
def get_poster_info(poster_thumb='', poster_key='', poster_title='', art=False,
width='', height='', opacity=None, background=None, blur=None):
default_poster_info = {'poster_title': '', 'poster_url': ''}
default_art_info = {'art_title': '', 'art_url': ''}
# Try to retrieve poster info from the database
data_factory = datafactory.DataFactory()
poster_info = data_factory.get_poster_info(rating_key=poster_key, art=art)
poster_info = data_factory.get_poster_info(rating_key=poster_key, art=art, blur=blur)
# If no previous poster info
if not poster_info and poster_thumb:
try:
thread_name = str(threading.current_thread().ident)
poster_file = os.path.join(plexpy.CONFIG.CACHE_DIR, 'cache-image-%s.jpg' % thread_name)
poster_file = os.path.join(plexpy.CONFIG.CACHE_DIR, 'cache-image-%s.png' % thread_name)
# Retrieve the poster from Plex and cache to file
pms_connect = pmsconnect.PmsConnect()
result = pms_connect.get_image(img=poster_thumb, width=width, height=height)
result = pms_connect.get_image(img=poster_thumb,
width=width,
height=height,
opacity=opacity,
background=background,
blur=blur)
if result and result[0]:
with open(poster_file, 'wb') as f:
f.write(result[0])
else:
raise Exception(u'PMS image request failed')
if blur and PILLOW:
img = Image.open(poster_file)
img = img.convert("RGBA")
img = img.filter(ImageFilter.GaussianBlur(3)) # 3px blur
img.putalpha(64) # 40% opacity
# Save as a png
poster_file_blur = os.path.join(plexpy.CONFIG.CACHE_DIR, 'cache-image-%s.png' % thread_name)
img.save(poster_file_blur)
# Upload poster_thumb to Imgur and get link
if blur:
poster_url, delete_hash = helpers.upload_to_imgur(poster_file_blur, poster_title)
else:
poster_url, delete_hash = helpers.upload_to_imgur(poster_file, poster_title)
if poster_url:
# Create poster info
if art:
poster_info = {'art_title': poster_title}
if blur:
poster_info['blur_art_url'] = poster_url
else:
poster_info['art_url'] = poster_url
poster_info = {'art_title': poster_title, 'art_url': poster_url}
else:
poster_info = {'poster_title': poster_title, 'poster_url': poster_url}
@ -1131,8 +1114,6 @@ def get_poster_info(poster_thumb='', poster_key='', poster_title='', art=False,
# Delete the cached poster
os.remove(poster_file)
if blur:
os.remove(poster_file_blur)
except Exception as e:
logger.error(u"Tautulli NotificationHandler :: Unable to retrieve poster for rating_key %s: %s."
% (poster_key, e))

View file

@ -1656,7 +1656,7 @@ class GROUPME(Notifier):
if poster_content:
headers = {'X-Access-Token': self.config['access_token'],
'Content-Type': 'image/jpeg'}
'Content-Type': 'image/png'}
r = requests.post('https://image.groupme.com/pictures', headers=headers, data=poster_content)
@ -2643,9 +2643,9 @@ class PUSHBULLET(Notifier):
logger.error(u"Tautulli Notifiers :: Unable to retrieve image for {name}.".format(name=self.NAME))
if poster_content:
poster_filename = 'poster_{}.jpg'.format(pretty_metadata.parameters['rating_key'])
file_json = {'file_name': poster_filename, 'file_type': 'image/jpeg'}
files = {'file': (poster_filename, poster_content, 'image/jpeg')}
poster_filename = 'poster_{}.png'.format(pretty_metadata.parameters['rating_key'])
file_json = {'file_name': poster_filename, 'file_type': 'image/png'}
files = {'file': (poster_filename, poster_content, 'image/png')}
r = requests.post('https://api.pushbullet.com/v2/upload-request', headers=headers, json=file_json)
@ -2799,8 +2799,8 @@ class PUSHOVER(Notifier):
logger.error(u"Tautulli Notifiers :: Unable to retrieve image for {name}.".format(name=self.NAME))
if poster_content:
poster_filename = 'poster_{}.jpg'.format(pretty_metadata.parameters['rating_key'])
files = {'attachment': (poster_filename, poster_content, 'image/jpeg')}
poster_filename = 'poster_{}.png'.format(pretty_metadata.parameters['rating_key'])
files = {'attachment': (poster_filename, poster_content, 'image/png')}
headers = {}
return self.make_request('https://api.pushover.net/1/messages.json', headers=headers, data=data, files=files)
@ -3327,8 +3327,8 @@ class TELEGRAM(Notifier):
logger.error(u"Tautulli Notifiers :: Unable to retrieve image for {name}.".format(name=self.NAME))
if poster_content:
poster_filename = 'poster_{}.jpg'.format(pretty_metadata.parameters['rating_key'])
files = {'photo': (poster_filename, poster_content, 'image/jpeg')}
poster_filename = 'poster_{}.png'.format(pretty_metadata.parameters['rating_key'])
files = {'photo': (poster_filename, poster_content, 'image/png')}
data['caption'] = text
return self.make_request('https://api.telegram.org/bot{}/sendPhoto'.format(self.config['bot_token']),

View file

@ -2425,7 +2425,8 @@ class PmsConnect(object):
return labels_list
def get_image(self, img=None, width='1000', height='1500', clip=False):
def get_image(self, img=None, width='1000', height='1500', opacity=None, background=None, blur=None, img_format='png',
clip=False):
"""
Return image data as array.
Array contains the image content type and image binary
@ -2433,6 +2434,9 @@ class PmsConnect(object):
Parameters required: img { Plex image location }
Optional parameters: width { the image width }
height { the image height }
opacity { the image opacity 0-100 }
background { the image background HEX }
blur { the image blur 0-100 }
Output: array
"""
@ -2447,6 +2451,14 @@ class PmsConnect(object):
params['width'] = width
params['height'] = height
params['format'] = img_format
if opacity:
params['opacity'] = opacity
if background:
params['background'] = background
if blur:
params['blur'] = blur
uri = '/photo/:/transcode?%s' % urllib.urlencode(params)
result = self.request_handler.make_request(uri=uri,

View file

@ -3816,6 +3816,7 @@ class WebInterface(object):
@addtoapi('pms_image_proxy')
def real_pms_image_proxy(self, img='', rating_key=None, width='0', height='0',
opacity=None, background=None, blur=None, img_format='png',
fallback=None, refresh=False, clip=False, **kwargs):
""" Gets an image from the PMS and saves it to the image cache directory.
@ -3826,8 +3827,12 @@ class WebInterface(object):
rating_key (str): 54321
Optional parameters:
width (str): 150
height (str): 255
width (str): 300
height (str): 450
opacity (str): 25
background (str): 282828
blur (str): 3
img_format (str): png
fallback (str): "poster", "cover", "art"
refresh (bool): True or False whether to refresh the image cache
@ -3843,9 +3848,20 @@ class WebInterface(object):
img = '/library/metadata/%s/thumb/1337' % rating_key
img_string = img.rsplit('/', 1)[0] if '/library/metadata' in img else img
img_string += '%s%s' % (width, height)
if width:
img_string += width
if height:
img_string += height
if opacity:
img_string += opacity
if background:
img_string += background
if blur:
img_string += blur
fp = hashlib.md5(img_string).hexdigest()
fp += '.jpg' # we want to be able to preview the thumbs
fp += '.%s' % img_format # we want to be able to preview the thumbs
c_dir = os.path.join(plexpy.CONFIG.CACHE_DIR, 'images')
ffp = os.path.join(c_dir, fp)
@ -3858,13 +3874,20 @@ class WebInterface(object):
if not plexpy.CONFIG.CACHE_IMAGES or refresh or 'indexes' in img:
raise NotFound
return serve_file(path=ffp, content_type='image/jpeg')
return serve_file(path=ffp, content_type='image/png')
except NotFound:
# the image does not exist, download it from pms
try:
pms_connect = pmsconnect.PmsConnect()
result = pms_connect.get_image(img, width, height, clip=clip)
result = pms_connect.get_image(img=img,
width=width,
height=height,
opacity=opacity,
background=background,
blur=blur,
img_format=img_format,
clip=clip)
if result and result[0]:
cherrypy.response.headers['Content-type'] = result[1]