diff --git a/data/interfaces/default/newsletter_config.html b/data/interfaces/default/newsletter_config.html index fe957b36..cfbee655 100644 --- a/data/interfaces/default/newsletter_config.html +++ b/data/interfaces/default/newsletter_config.html @@ -156,10 +156,10 @@
- +
- % for notifier in email_notifiers: <% selected = 'selected' if notifier['id'] == newsletter['email_config']['notifier'] else '' %> % if notifier['friendly_name']: @@ -377,7 +377,7 @@ var incl_libraries = $incl_libraries[0].selectize; incl_libraries.setValue(${json.dumps(next((c['value'] for c in newsletter['config_options'] if c['name'] == 'newsletter_config_incl_libraries'), [])) | n}); - $('#email_notifier').change(function () { + $('#newsletter_email_notifier').change(function () { if ($(this).val() === "0") { $('#newsletter-email-config').show(); } else { diff --git a/data/interfaces/newsletters/recently_added.html b/data/interfaces/newsletters/recently_added.html index 631a12f1..8d154bd0 100644 --- a/data/interfaces/newsletters/recently_added.html +++ b/data/interfaces/newsletters/recently_added.html @@ -3,9 +3,12 @@ import plexpy recently_added = data['recently_added'] - base_url = '' - if self_hosted and plexpy.CONFIG.NEWSLETTER_BASE_URL: - base_url = plexpy.CONFIG.NEWSLETTER_BASE_URL + '/' + if plexpy.CONFIG.NEWSLETTER_SELF_HOSTED and plexpy.CONFIG.NEWSLETTER_BASE_URL: + base_url = plexpy.CONFIG.NEWSLETTER_BASE_URL + '/newsletter/image/' + elif plexpy.CONFIG.NEWSLETTER_SELF_HOSTED or preview: + base_url = 'newsletter/image/' + else: + base_url = '' %> @@ -600,20 +603,19 @@
% for movie in recently_added['movie']: - % if loop.index == len(recently_added['movie'])-1 and loop.index % 2 == 0: -
-
- % else: -
- % endif - % if self_hosted: -
- % else: -
- % endif + <% + if loop.index == len(recently_added['movie'])-1 and loop.index % 2 == 0: + clear = '
' + odd = 'odd' + else: + clear = odd = '' + %> + ${clear} +
+
-
+
@@ -682,21 +684,19 @@ else: link_rating_key = show['rating_key'] link_title = show['title'] + + if loop.index == len(recently_added['show'])-1 and loop.index % 2 == 0: + clear = '
' + odd = 'odd' + else: + clear = odd = '' %> - % if loop.index == len(recently_added['show'])-1 and loop.index % 2 == 0: -
-
- % else: -
- % endif - % if self_hosted: -
- % else: -
- % endif + ${clear} +
+
-
+
@@ -787,21 +787,21 @@ <% album_count = 0 %> % for artist in recently_added['artist']: % for album in artist['album']: - <% album_count += 1 %> - % if album_count == total_albums and album_count % 2 == 1: -
-
- % else: -
- % endif - % if self_hosted: -
- % else: -
- % endif + <% + album_count += 1 + + if album_count == total_albums and album_count % 2 == 1: + clear = '
' + odd = 'odd' + else: + clear = odd = '' + %> + ${clear} +
+
-
+
diff --git a/data/interfaces/newsletters/recently_added_master.html b/data/interfaces/newsletters/recently_added_master.html index be440475..245fbd79 100644 --- a/data/interfaces/newsletters/recently_added_master.html +++ b/data/interfaces/newsletters/recently_added_master.html @@ -3,9 +3,12 @@ import plexpy recently_added = data['recently_added'] - base_url = '' - if self_hosted and plexpy.CONFIG.NEWSLETTER_BASE_URL: - base_url = plexpy.CONFIG.NEWSLETTER_BASE_URL + '/' + if plexpy.CONFIG.NEWSLETTER_SELF_HOSTED and plexpy.CONFIG.NEWSLETTER_BASE_URL: + base_url = plexpy.CONFIG.NEWSLETTER_BASE_URL + '/newsletter/image/' + elif plexpy.CONFIG.NEWSLETTER_SELF_HOSTED or preview: + base_url = 'newsletter/image/' + else: + base_url = '' %> @@ -600,20 +603,19 @@
% for movie in recently_added['movie']: - % if loop.index == len(recently_added['movie'])-1 and loop.index % 2 == 0: -
-
- % else: -
- % endif - % if self_hosted: -
- % else: -
- % endif + <% + if loop.index == len(recently_added['movie'])-1 and loop.index % 2 == 0: + clear = '
' + odd = 'odd' + else: + clear = odd = '' + %> + ${clear} +
+
-
+
@@ -682,21 +684,19 @@ else: link_rating_key = show['rating_key'] link_title = show['title'] + + if loop.index == len(recently_added['show'])-1 and loop.index % 2 == 0: + clear = '
' + odd = 'odd' + else: + clear = odd = '' %> - % if loop.index == len(recently_added['show'])-1 and loop.index % 2 == 0: -
-
- % else: -
- % endif - % if self_hosted: -
- % else: -
- % endif + ${clear} +
+
-
+
@@ -787,21 +787,21 @@ <% album_count = 0 %> % for artist in recently_added['artist']: % for album in artist['album']: - <% album_count += 1 %> - % if album_count == total_albums and album_count % 2 == 1: -
-
- % else: -
- % endif - % if self_hosted: -
- % else: -
- % endif + <% + album_count += 1 + + if album_count == total_albums and album_count % 2 == 1: + clear = '
' + odd = 'odd' + else: + clear = odd = '' + %> + ${clear} +
+
-
+
diff --git a/plexpy/__init__.py b/plexpy/__init__.py index 907521b2..81cb12ca 100644 --- a/plexpy/__init__.py +++ b/plexpy/__init__.py @@ -690,6 +690,13 @@ def dbcheck(): 'themoviedb_id INTEGER, themoviedb_url TEXT, themoviedb_json TEXT)' ) + # image_hash_lookup table :: This table keeps record of the image hash lookups + c_db.execute( + 'CREATE TABLE IF NOT EXISTS image_hash_lookup (id INTEGER PRIMARY KEY AUTOINCREMENT, ' + 'img_hash TEXT, img TEXT, rating_key INTEGER, width INTEGER, height INTEGER, ' + 'opacity INTEGER, background TEXT, blur INTEGER, fallback TEXT)' + ) + # Upgrade sessions table from earlier versions try: c_db.execute('SELECT started FROM sessions') diff --git a/plexpy/newsletters.py b/plexpy/newsletters.py index f72d7127..ed5f7002 100644 --- a/plexpy/newsletters.py +++ b/plexpy/newsletters.py @@ -392,7 +392,7 @@ class Newsletter(object): title=self.subject_formatted, parameters=self.parameters, data=self.data, - self_hosted=self.is_preview or plexpy.CONFIG.NEWSLETTER_SELF_HOSTED + preview=self.is_preview ) def send(self): @@ -640,7 +640,7 @@ class RecentlyAdded(Newsletter): return recently_added def retrieve_data(self): - from notification_handler import get_poster_info + from notification_handler import get_poster_info, set_hash_image_info if not self.config['incl_libraries']: logger.warn(u"Tautulli Newsletters :: Failed to retrieve %s newsletter data: no libraries selected." % self.NAME) @@ -653,31 +653,50 @@ class RecentlyAdded(Newsletter): if media_type not in recently_added: recently_added[media_type] = self._get_recently_added(media_type) - if not self.is_preview: + movies = recently_added.get('movie', []) + shows = recently_added.get('show', []) + artists = recently_added.get('artist', []) + albums = [a for artist in artists for a in artist['album']] + + if self.is_preview or plexpy.CONFIG.NEWSLETTER_SELF_HOSTED: + for item in movies + shows + albums: + item['thumb_hash'] = set_hash_image_info(img=item['thumb'], + width=300, + height=450, + fallback='poster') + item['art_hash'] = set_hash_image_info(img=item['art'], + width=500, + height=280, + opacity=25, + background='282828', + blur=3, + fallback='art') + + item['poster_url'] = '' + item['art_url'] = '' + + else: # Upload posters and art to Imgur - movies = recently_added.get('movie', []) - shows = recently_added.get('show', []) - artists = recently_added.get('artist', []) - albums = [a for artist in artists for a in artist['album']] + for item in movies + shows + albums: + poster_info = get_poster_info(poster_thumb=item['thumb'], + poster_key=item['rating_key'], + poster_title=item['title']) + if poster_info: + item['poster_url'] = poster_info['poster_url'] or common.ONLINE_POSTER_THUMB - if not plexpy.CONFIG.NEWSLETTER_SELF_HOSTED: - for item in movies + shows + albums: - poster_info = get_poster_info(poster_thumb=item['thumb'], - poster_key=item['rating_key'], - poster_title=item['title']) - if poster_info: - item['poster_url'] = poster_info['poster_url'] or common.ONLINE_POSTER_THUMB + art_info = get_poster_info(poster_thumb=item['art'], + poster_key=item['rating_key'], + poster_title=item['title'], + art=True, + width='500', + height='280', + opacity='25', + background='282828', + blur='3') + item['art_url'] = art_info.get('art_url', '') - art_info = get_poster_info(poster_thumb=item['art'], - poster_key=item['rating_key'], - poster_title=item['title'], - art=True, - width='500', - height='280', - opacity='25', - background='282828', - blur='3') - item['art_url'] = art_info.get('art_url', '') + item['thumb_hash'] = '' + item['art_hash'] = '' self.data['recently_added'] = recently_added diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py index 627c1770..8fb866f6 100644 --- a/plexpy/notification_handler.py +++ b/plexpy/notification_handler.py @@ -17,6 +17,7 @@ import arrow import bleach from collections import Counter, defaultdict +import hashlib from itertools import groupby import json from operator import itemgetter @@ -1127,6 +1128,41 @@ def get_poster_info(poster_thumb='', poster_key='', poster_title='', art=False, return poster_info or default_poster_info +def set_hash_image_info(img=None, rating_key=None, width=600, height=1000, + opacity=100, background='000000', blur=0, fallback=None): + if rating_key and not img: + img = '/library/metadata/{}/thumb'.format(rating_key) + + img_split = img.split('/') + img = '/'.join(img_split[:5]) + rating_key = rating_key or img_split[3] + + img_string = '{}{}{}{}{}{}{}'.format(rating_key, width, height, opacity, background, blur, fallback) + img_hash = hashlib.sha256(img_string).hexdigest() + + keys = {'img_hash': img_hash} + values = {'img': img, + 'rating_key': rating_key, + 'width': width, + 'height': height, + 'opacity': opacity, + 'background': background, + 'blur': blur, + 'fallback': fallback} + + db = database.MonitorDatabase() + db.upsert('image_hash_lookup', key_dict=keys, value_dict=values) + + return img_hash + + +def get_hash_image_info(img_hash=None): + db = database.MonitorDatabase() + query = 'SELECT * FROM image_hash_lookup WHERE img_hash = ?' + result = db.select_single(query, args=[img_hash]) + return result + + def lookup_tvmaze_by_id(rating_key=None, thetvdb_id=None, imdb_id=None): db = database.MonitorDatabase() diff --git a/plexpy/pmsconnect.py b/plexpy/pmsconnect.py index 967fb8f4..203157cb 100644 --- a/plexpy/pmsconnect.py +++ b/plexpy/pmsconnect.py @@ -2425,8 +2425,8 @@ class PmsConnect(object): return labels_list - def get_image(self, img=None, width='1000', height='1500', opacity=None, background=None, blur=None, img_format='png', - clip=False): + def get_image(self, img=None, width=600, height=1000, 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 @@ -2440,8 +2440,8 @@ class PmsConnect(object): Output: array """ - width = width or '1000' - height = height or '1500' + width = width or 600 + height = height or 1000 if img: if clip: diff --git a/plexpy/webserve.py b/plexpy/webserve.py index 0624f613..acfc2b32 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -3893,7 +3893,6 @@ class WebInterface(object): return {'result': 'error', 'message': 'Notification failed.'} @cherrypy.expose - @requireAuth() def pms_image_proxy(self, **kwargs): """ See real_pms_image_proxy docs string""" @@ -3906,8 +3905,8 @@ class WebInterface(object): return self.real_pms_image_proxy(**kwargs) @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', + def real_pms_image_proxy(self, img='', rating_key=None, width=0, height=0, + opacity=100, background='000000', blur=0, img_format='png', fallback=None, refresh=False, clip=False, **kwargs): """ Gets an image from the PMS and saves it to the image cache directory. @@ -3939,17 +3938,7 @@ class WebInterface(object): img = '/library/metadata/%s/thumb/1337' % rating_key img_string = img.rsplit('/', 1)[0] if '/library/metadata' in img else img - - 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 + img_string = '{}{}{}{}{}{}'.format(img_string, width, height, opacity, background, blur) fp = hashlib.md5(img_string).hexdigest() fp += '.%s' % img_format # we want to be able to preview the thumbs @@ -4004,6 +3993,15 @@ class WebInterface(object): fp = os.path.join(plexpy.PROG_DIR, 'data', fbi) return serve_file(path=fp, content_type='image/png') + @cherrypy.expose + def image(self, *args, **kwargs): + if args: + img_hash = args[0] + img_info = notification_handler.get_hash_image_info(img_hash=img_hash) + kwargs.update(img_info) + return self.real_pms_image_proxy(**kwargs) + + return @cherrypy.expose @requireAuth(member_of("admin")) @@ -5603,6 +5601,9 @@ class WebInterface(object): @cherrypy.expose def newsletter(self, *args, **kwargs): if args: + if len(args) >= 2 and args[0] == 'image': + return self.image(args[1], refresh=True) + newsletter_uuid = args[0] newsletter = newsletter_handler.get_newsletter(newsletter_uuid=newsletter_uuid) return newsletter