Redo newsletter template using tables

This commit is contained in:
JonnyWong16 2018-03-24 00:02:31 -07:00
parent e1035a49fd
commit 3f7edc3635
6 changed files with 780 additions and 620 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View file

@ -1,6 +1,7 @@
% if data:
<%
import plexpy
from helpers import grouper
recently_added = data['recently_added']
if plexpy.CONFIG.NEWSLETTER_SELF_HOSTED and plexpy.CONFIG.NEWSLETTER_BASE_URL:
@ -73,7 +74,7 @@
box-sizing: border-box;
display: block;
margin: 0 auto;
max-width: 1042px;
max-width: 1037px;
padding: 10px;
}
@ -139,10 +140,8 @@
ul,
ol {
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
font-size: 14px;
font-weight: 400;
margin: 0;
margin-bottom: 15px;
}
p li,
@ -245,6 +244,8 @@
.nowrap {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.clear {
clear: both;
@ -335,150 +336,135 @@
MEDIA CARDS
------------------------------------- */
.card-instance {
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;
padding: 3px;
width: 502px;
min-width: 502px;
max-width: 502px;
}
.card-instance.movie,
.card-instance.show {
height: 235px;
height: 233px;
}
.card-instance.album {
height: 160px;
}
.card-instance.odd {
float: none !important;
margin: 3px auto !important;
height: 158px;
}
.card-background {
background-position: center;
background-size: cover;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-clip: padding-box;
border: 1px solid rgba(255,255,255,.1);
}
.card-poster-container {
width: 150px;
margin: 3px;
border: 1px solid rgba(255,255,255,.1);
float: left;
position: relative;
z-index: 1;
width: 152px;
min-width: 152px;
}
.card-instance.movie .card-poster-container,
.card-instance.show .card-poster-container{
height: 225px;
height: 227px;
}
.card-instance.album .card-poster-container {
height: 150px;
height: 152px;
}
.card-poster {
background-color: #3F4245;
background-position: center;
background-size: cover;
height: 100%;
width: 100%;
background-repeat: no-repeat;
background-clip: padding-box;
border: 1px solid rgba(255,255,255,.1);
}
.card-poster-overlay {
background-repeat: no-repeat;
background-position: bottom right;
width: 100%;
height: 100%;
display: block;
}
.card-info-container {
margin: 4px;
width: 332px;
float: left;
position: relative;
z-index: 1;
padding-left: 4px;
}
.card-instance.movie .card-info-container,
.card-instance.show .card-info-container{
height: 225px;
height: 227px;
}
.card-instance.album .card-info-container {
height: 150px;
height: 152px;
}
.card-info-container > div {
padding: 5px;
text-overflow: ellipsis;
overflow: hidden;
.card-info-container > table {
height: 100%;
}
.card-info-title {
border-bottom: 1px solid rgba(255, 255, 255, .1);
line-height: 20px;
font-size: 15px;
line-height: 1.2rem;
font-size: 0.9rem;
padding: 5px;
}
.card-info-title a {
text-decoration: none;
color: #ffffff;
}
.card-info-body > div {
color: #ffffff;
font-size: 12px;
text-overflow: ellipsis;
overflow: hidden;
.card-info-body {
font-size: 0.75rem;
padding: 5px;
height: 100%;
}
.card-info-body > p {
max-width: 325px;
}
.card-instance.movie .card-info-body,
.card-instance.show .card-info-body {
min-height: 157px;
}
.card-instance.album .card-info-body {
height: 82px;
min-height: 82px;
}
.card-info-footer {
font-size: 10px;
font-size: 0.6rem;
padding-top: 0px;
padding-right: 5px;
padding-bottom: 5px;
padding-left: 5px;
}
.card-info-footer .star-rating-container {
vertical-align: bottom;
padding-right: 5px;
}
.card-info-footer .star-rating {
width: 60px;
font-size: 14px;
line-height: 17px;
float: right;
}
.star-rating-full {
color: #E5A00D;
direction: ltr;
padding: 0;
overflow: hidden;
float: left;
}
.star-rating-empty {
color: #aaaaaa;
direction: rtl;
padding: 0;
overflow: hidden;
float: left;
}
.star-rating span {
font-size: 0.8rem;
line-height: 1rem;
width: 0.5rem;
display: inline-block;
text-align: center;
width: 12px;
}
.star-rating.full {
color: #E5A00D;
}
.star-rating.empty {
color: #aaaaaa;
}
.badge {
display: inline-block;
min-width: 10px;
padding: 3px 7px;
font-size: 11px;
font-style: normal;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: middle;
background-color: rgba(0, 0, 0, .25);
border-radius: 2px;
max-width: 75px;
text-overflow: ellipsis;
overflow: hidden;
}
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 620px) {
@media only screen and (max-width: 1040px) {
.card-instance {
display: block !important;
margin: 0 auto;
}
table[class=body] .header {
background-position: center !important;
}
@ -510,11 +496,6 @@
font-size: 14px !important;
}
table[class=body] .card-instance {
margin: 3px auto;
float: none;
}
table[class=body] .content {
padding: 0 !important;
}
@ -573,12 +554,12 @@
<table border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;">
<tr>
<td class="container" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;display: block;max-width: 1042px;padding: 10px;width: 1042px;margin: 0 auto !important;">
<div class="content" style="box-sizing: border-box;display: block;margin: 0 auto;max-width: 1042px;padding: 10px;">
<div class="content" style="box-sizing: border-box;display: block;margin: 0 auto;max-width: 1037px;padding: 10px;">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader" style="color: transparent;display: none;height: 0;max-height: 0;max-width: 0;opacity: 0;overflow: hidden;mso-hide: all;visibility: hidden;width: 0;">Tautulli card-backbro - ${title}</span>
<span class="preheader" style="color: transparent;display: none;height: 0;max-height: 0;max-width: 0;opacity: 0;overflow: hidden;mso-hide: all;visibility: hidden;width: 0;">Tautulli Newsletter - ${title}</span>
<table border="0" cellpadding="0" cellspacing="0" class="main" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;background: #282A2D;border-radius: 3px;color: #ffffff;">
<table border="0" cellpadding="3" cellspacing="0" class="main" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;background: #282A2D;border-radius: 3px;color: #ffffff;">
<!-- START MAIN CONTENT AREA -->
<tr>
@ -588,9 +569,9 @@
<div class="dates" style="color: #aaaaaa;font-size: 20px;text-align: center;">${parameters['start_date']} - ${parameters['end_date']}</div>
</td>
</tr>
% if recently_added.get('movie'):
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
% if recently_added.get('movie'):
<div class="wrapper" style="box-sizing: border-box;padding: 5px;overflow: auto;">
<div class="sub-header">
<div class="sub-header-bar" style="width: 200px;border-top: 1px solid #E5A00D;margin-top: 15px;margin-bottom: 25px;margin-left: auto;margin-right: auto;font-size: 30px;text-align: center;"></div>
@ -602,67 +583,106 @@
</div>
</div>
</div>
<div class="wrapper" style="box-sizing: border-box;padding: 5px;overflow: auto;">
% for movie in recently_added['movie']:
<%
if loop.index == len(recently_added['movie'])-1 and loop.index % 2 == 0:
clear = '<div style="clear: both;"></div>'
odd = 'odd'
else:
clear = odd = ''
%>
${clear | n}
<div class="card-instance movie ${odd}" 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;">
<div class="card-background" style="background-image: url(${(base_url + movie['art_hash']) if base_url else movie['art_url']});background-position: center;background-size: cover;width: 100%;height: 100%;">
<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;">
</td>
</tr>
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;">
<tbody>
% for movie_a, movie_b in grouper(recently_added['movie'], 2):
<tr>
% for movie in (movie_a, movie_b):
% if movie:
<td align="center" valign="top" class="card-instance movie" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 12px;vertical-align: top;overflow: hidden;padding: 3px;width: 502px;min-width: 502px;max-width: 502px;height: 233px;">
<table border="0" cellpadding="0" cellspacing="3" width="100%" class="card-background" style="background-image: url(${(base_url + movie['art_hash']) if base_url else movie['art_url']});border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;background-position: center;background-size: cover;background-repeat: no-repeat;background-clip: padding-box;border: 1px solid rgba(255,255,255,.1);">
<tbody>
<tr>
<td class="card-poster-container" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;width: 152px;min-width: 152px;height: 227px;">
<table border="0" cellpadding="0" cellspacing="0" class="card-poster" style="background-image: url(${(base_url + movie['thumb_hash']) if base_url else movie['poster_url']});border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;background-color: #3F4245;background-position: center;background-size: cover;background-repeat: no-repeat;background-clip: padding-box;border: 1px solid rgba(255,255,255,.1);">
<tbody>
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
<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(${(base_url + movie['thumb_hash']) if base_url else movie['poster_url']});background-color: #3F4245;background-position: center;background-size: cover;height: 100%;width: 100%;">
<div class="card-poster-overlay" style="background-image: url(${base_url + 'images/newsletter/view-on-plex.png' if base_url else 'https://i.imgur.com/NSV7q16.png'});background-repeat: no-repeat;background-position: bottom right;width: 100%;height: 100%;"></div>
</div>
<img class="card-poster-overlay" src="${base_url + 'images/newsletter/view-on-plex-poster.png' if base_url else 'https://i.imgur.com/AeyPvJ4.png'}" width="150" height="225" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;display: block;">
</a>
</div>
<div class="card-info-container" style="margin: 4px;width: 332px;float: left;position: relative;z-index: 1;height: 225px;">
<div class="card-info-title nowrap" style="white-space: nowrap;border-bottom: 1px solid rgba(255, 255, 255, .1);line-height: 20px;font-size: 15px;padding: 5px;text-overflow: ellipsis;overflow: hidden;">
</td>
</tr>
</tbody>
</table>
</td>
<td class="card-info-container" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;padding-left: 4px;height: 227px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;height: 100%;">
<tbody>
<tr>
<td class="card-info-title nowrap" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 0.9rem;vertical-align: top;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;border-bottom: 1px solid rgba(255, 255, 255, .1);line-height: 1.2rem;padding: 5px;">
<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: #ffffff;text-decoration: none;">${movie['title']}</a>
</div>
<div class="card-info-body" style="padding: 5px;text-overflow: ellipsis;overflow: hidden;min-height: 157px;">
</td>
</tr>
<tr>
<td class="card-info-body" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 0.75rem;vertical-align: top;padding: 5px;height: 100%;">
% if movie['tagline']:
<div class="nowrap mb5" style="margin-bottom: 5px;white-space: nowrap;color: #ffffff;font-size: 12px;text-overflow: ellipsis;overflow: hidden;">
<p class="nowrap mb5" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-weight: 400;margin: 0;margin-bottom: 5px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;max-width: 325px;">
<em>${movie['tagline']}</em>
</div>
</p>
% endif
<div style="color: #ffffff;font-size: 12px;text-overflow: ellipsis;overflow: hidden;">
<p style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-weight: 400;margin: 0;max-width: 325px;">
${movie['summary'][:450] + (movie['summary'][450:] and '...')}
</div>
</div>
<div class="card-info-footer nowrap" style="white-space: nowrap;font-size: 10px;padding: 5px;text-overflow: ellipsis;overflow: hidden;">
</p>
</td>
</tr>
<tr>
<td class="card-info-footer nowrap" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 0.6rem;vertical-align: top;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;padding-top: 0px;padding-right: 5px;padding-bottom: 5px;padding-left: 5px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;">
<tbody>
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
% if movie['year']:
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;font-style: normal;line-height: 1;color: #fff;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;">${movie['year']}</span>
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;line-height: 1;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;max-width: 75px;text-overflow: ellipsis;overflow: hidden;">${movie['year']}</span>
% endif
% if movie['content_rating']:
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;font-style: normal;line-height: 1;color: #fff;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;">${movie['content_rating']}</span>
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;line-height: 1;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;max-width: 75px;text-overflow: ellipsis;overflow: hidden;">${movie['content_rating']}</span>
% endif
% if movie['duration']:
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;font-style: normal;line-height: 1;color: #fff;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;">${int(int(movie['duration'])/60000)} mins</span>
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;line-height: 1;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;max-width: 75px;text-overflow: ellipsis;overflow: hidden;">${int(int(movie['duration'])/60000)} mins</span>
% endif
</td>
% if movie['rating']:
<span class="star-rating" title="${int(float(movie['rating'])/0.1)}%" style="width: 60px;font-size: 14px;line-height: 17px;float: right;">
<div class="star-rating-full nowrap" style="width: ${float(movie['rating'])/0.1}%;white-space: nowrap;color: #E5A00D;direction: ltr;padding: 0;overflow: hidden;float: left;">
<span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span>
</div>
<div class="star-rating-empty" style="width: ${100-float(movie['rating'])/0.1}%;color: #aaaaaa;direction: rtl;padding: 0;overflow: hidden;float: left;">
<span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span>
</div>
</span>
% endif
</div>
</div>
</div>
</div>
<% rating = int(round(float(movie['rating']) / 2)) %>
<td class="star-rating-container" title="${int(float(movie['rating'])/0.1)}%" align="right" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: bottom;padding-right: 5px;">
% for _ in range(rating):
<span class="star-rating full" style="font-size: 0.8rem;line-height: 1rem;width: 0.5rem;display: inline-block;color: #E5A00D;">&#9733;</span>
% endfor
</div>
% for _ in range(5-rating):
<span class="star-rating empty" style="font-size: 0.8rem;line-height: 1rem;width: 0.5rem;display: inline-block;color: #aaaaaa;">&#9734;</span>
% endfor
</td>
% endif
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
% else:
<td align="center" valign="top" class="card-instance" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 12px;vertical-align: top;overflow: hidden;padding: 3px;width: 502px;min-width: 502px;max-width: 502px;"></td>
% endif
% endfor
</tr>
% endfor
</tbody>
</table>
</td>
</tr>
% endif
% if recently_added.get('show'):
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
<div class="wrapper" style="box-sizing: border-box;padding: 5px;overflow: auto;">
<div class="sub-header">
<div class="sub-header-bar" style="width: 200px;border-top: 1px solid #E5A00D;margin-top: 15px;margin-bottom: 25px;margin-left: auto;margin-right: auto;font-size: 30px;text-align: center;"></div>
@ -676,45 +696,47 @@
</div>
</div>
</div>
<div class="wrapper" style="box-sizing: border-box;padding: 5px;overflow: auto;">
% for show in recently_added['show']:
<%
if show['season_count'] == 1 and show['season'][0]['episode_count'] == 1:
link_rating_key = show['season'][0]['episode'][0]['rating_key']
link_title = show['title'] + " - " + show['season'][0]['episode'][0]['title']
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 = '<div style="clear: both;"></div>'
odd = 'odd'
else:
clear = odd = ''
%>
${clear | n}
<div class="card-instance show ${odd}" 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;">
<div class="card-background" style="background-image: url(${(base_url + show['art_hash']) if base_url else show['art_url']});background-position: center;background-size: cover;width: 100%;height: 100%;">
<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(${(base_url + show['thumb_hash']) if base_url else show['poster_url']});background-color: #3F4245;background-position: center;background-size: cover;height: 100%;width: 100%;">
<div class="card-poster-overlay" style="background-image: url(${base_url + 'images/newsletter/view-on-plex.png' if base_url else 'https://i.imgur.com/NSV7q16.png'});background-repeat: no-repeat;background-position: bottom right;width: 100%;height: 100%;"></div>
</div>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;">
<tbody>
% for show_a, show_b in grouper(recently_added['show'], 2):
<tr>
% for show in (show_a, show_b):
% if show:
<td align="center" valign="top" class="card-instance show" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 12px;vertical-align: top;overflow: hidden;padding: 3px;width: 502px;min-width: 502px;max-width: 502px;height: 233px;">
<table border="0" cellpadding="0" cellspacing="3" width="100%" class="card-background" style="background-image: url(${(base_url + show['art_hash']) if base_url else show['art_url']});border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;background-position: center;background-size: cover;background-repeat: no-repeat;background-clip: padding-box;border: 1px solid rgba(255,255,255,.1);">
<tbody>
<tr>
<td class="card-poster-container" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;width: 152px;min-width: 152px;height: 227px;">
<table border="0" cellpadding="0" cellspacing="0" class="card-poster" style="background-image: url(${(base_url + show['thumb_hash']) if base_url else show['poster_url']});border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;background-color: #3F4245;background-position: center;background-size: cover;background-repeat: no-repeat;background-clip: padding-box;border: 1px solid rgba(255,255,255,.1);">
<tbody>
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${show['rating_key']}" title="${show['title']}" target="_blank" style="color: #3498db;text-decoration: underline;">
<img class="card-poster-overlay" src="${base_url + 'images/newsletter/view-on-plex-poster.png' if base_url else 'https://i.imgur.com/AeyPvJ4.png'}" width="150" height="225" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;display: block;">
</a>
</div>
<div class="card-info-container" style="margin: 4px;width: 332px;float: left;position: relative;z-index: 1;height: 225px;">
<div class="card-info-title nowrap" style="white-space: nowrap;border-bottom: 1px solid rgba(255, 255, 255, .1);line-height: 20px;font-size: 15px;padding: 5px;text-overflow: ellipsis;overflow: hidden;">
<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: #ffffff;text-decoration: none;">${show['title']}</a>
</div>
<div class="card-info-body" style="padding: 5px;text-overflow: ellipsis;overflow: hidden;min-height: 157px;">
<div class="nowrap mb5" style="margin-bottom: 5px;white-space: nowrap;color: #ffffff;font-size: 12px;text-overflow: ellipsis;overflow: hidden;">
</td>
</tr>
</tbody>
</table>
</td>
<td class="card-info-container" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;padding-left: 4px;height: 227px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;height: 100%;">
<tbody>
<tr>
<td class="card-info-title nowrap" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 0.9rem;vertical-align: top;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;border-bottom: 1px solid rgba(255, 255, 255, .1);line-height: 1.2rem;padding: 5px;">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${show['rating_key']}" title="${show['title']}" target="_blank" style="color: #ffffff;text-decoration: none;">${show['title']}</a>
</td>
</tr>
<tr>
<td class="card-info-body" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 0.75rem;vertical-align: top;padding: 5px;height: 100%;">
<p class="nowrap mb5" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-weight: 400;margin: 0;margin-bottom: 5px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;max-width: 325px;">
% if show['season_count'] > 1:
<em>${show['season_count']} seasons /</em>
% endif
<% total_show_episodes = sum(s['episode_count'] for s in show['season']) %>
<em>${total_show_episodes} episode${'s' if total_show_episodes > 1 else ''}</em>
</div>
<div class="nowrap mb5" style="margin-bottom: 5px;white-space: nowrap;color: #ffffff;font-size: 12px;text-overflow: ellipsis;overflow: hidden;">
</p>
<p class="nowrap mb5" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-weight: 400;margin: 0;margin-bottom: 5px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;max-width: 325px;">
% for i, season in enumerate(show['season'][:8]):
Season ${season['media_index']} &middot;
% if season['episode_count'] == 1:
@ -728,8 +750,8 @@
...plus ${show['season_count'] - 8} more seasons!
% endif
% endfor
</div>
<div style="color: #ffffff;font-size: 12px;text-overflow: ellipsis;overflow: hidden;">
</p>
<p style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-weight: 400;margin: 0;max-width: 325px;">
% if show['season_count'] == 1 and show['season'][0]['episode_count'] == 1:
${show['season'][0]['episode'][0]['summary'][:350] + (show['season'][0]['episode'][0]['summary'][350:] and '...')}
% else:
@ -738,39 +760,65 @@
${show['summary'][:length] + (show['summary'][length:] and '...')}
% endif
% endif
</div>
</div>
<div class="card-info-footer nowrap" style="white-space: nowrap;font-size: 10px;padding: 5px;text-overflow: ellipsis;overflow: hidden;">
</p>
</td>
</tr>
<tr>
<td class="card-info-footer nowrap" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 0.6rem;vertical-align: top;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;padding-top: 0px;padding-right: 5px;padding-bottom: 5px;padding-left: 5px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;">
<tbody>
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
% if show['studio']:
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;font-style: normal;line-height: 1;color: #fff;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;">${show['studio']}</span>
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;line-height: 1;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;max-width: 75px;text-overflow: ellipsis;overflow: hidden;">${show['studio']}</span>
% endif
% if show['year']:
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;font-style: normal;line-height: 1;color: #fff;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;">${show['year']}</span>
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;line-height: 1;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;max-width: 75px;text-overflow: ellipsis;overflow: hidden;">${show['year']}</span>
% endif
% if show['content_rating']:
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;font-style: normal;line-height: 1;color: #fff;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;">${show['content_rating']}</span>
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;line-height: 1;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;max-width: 75px;text-overflow: ellipsis;overflow: hidden;">${show['content_rating']}</span>
% endif
% if show['duration']:
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;font-style: normal;line-height: 1;color: #fff;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;">${int(int(show['duration'])/60000)} mins</span>
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;line-height: 1;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;max-width: 75px;text-overflow: ellipsis;overflow: hidden;">${int(int(show['duration'])/60000)} mins</span>
% endif
</td>
% if show['rating']:
<span class="star-rating" title="${int(float(show['rating'])/0.1)}%" style="width: 60px;font-size: 14px;line-height: 17px;float: right;">
<div class="star-rating-full nowrap" style="width: ${float(show['rating'])/0.1}%;white-space: nowrap;color: #E5A00D;direction: ltr;padding: 0;overflow: hidden;float: left;">
<span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span>
</div>
<div class="star-rating-empty" style="width: ${100-float(show['rating'])/0.1}%;color: #aaaaaa;direction: rtl;padding: 0;overflow: hidden;float: left;">
<span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span>
</div>
</span>
% endif
</div>
</div>
</div>
</div>
<% rating = int(round(float(show['rating']) / 2)) %>
<td class="star-rating-container" title="${int(float(show['rating'])/0.1)}%" align="right" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: bottom;padding-right: 5px;">
% for _ in range(rating):
<span class="star-rating full" style="font-size: 0.8rem;line-height: 1rem;width: 0.5rem;display: inline-block;color: #E5A00D;">&#9733;</span>
% endfor
</div>
% for _ in range(5-rating):
<span class="star-rating empty" style="font-size: 0.8rem;line-height: 1rem;width: 0.5rem;display: inline-block;color: #aaaaaa;">&#9734;</span>
% endfor
</td>
% endif
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
% else:
<td align="center" valign="top" class="card-instance" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 12px;vertical-align: top;overflow: hidden;padding: 3px;width: 502px;min-width: 502px;max-width: 502px;"></td>
% endif
% endfor
</tr>
% endfor
</tbody>
</table>
</td>
</tr>
% endif
% if recently_added.get('artist'):
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
<div class="wrapper" style="box-sizing: border-box;padding: 5px;overflow: auto;">
<div class="sub-header">
<div class="sub-header-bar" style="width: 200px;border-top: 1px solid #E5A00D;margin-top: 15px;margin-bottom: 25px;margin-left: auto;margin-right: auto;font-size: 30px;text-align: center;"></div>
@ -784,71 +832,100 @@
</div>
</div>
</div>
<div class="wrapper" style="box-sizing: border-box;padding: 5px;overflow: auto;">
<% 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:
clear = '<div style="clear: both;"></div>'
odd = 'odd'
else:
clear = odd = ''
%>
${clear | n}
<div class="card-instance album ${odd}" 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;">
<div class="card-background" style="background-image: url(${(base_url + album['art_hash']) if base_url else album['art_url']});background-position: center;background-size: cover;width: 100%;height: 100%;">
<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;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;">
<tbody>
% for album_a, album_b in grouper([a for artist in recently_added['artist'] for a in artist['album']], 2):
<tr>
% for album in (album_a, album_b):
% if album:
<td align="center" valign="top" class="card-instance album" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 12px;vertical-align: top;overflow: hidden;padding: 3px;width: 502px;min-width: 502px;max-width: 502px;height: 158px;">
<table border="0" cellpadding="0" cellspacing="3" width="100%" class="card-background" style="background-image: url(${(base_url + album['art_hash']) if base_url else album['art_url']});border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;background-position: center;background-size: cover;background-repeat: no-repeat;background-clip: padding-box;border: 1px solid rgba(255,255,255,.1);">
<tbody>
<tr>
<td class="card-poster-container" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;width: 152px;min-width: 152px;height: 152px;">
<table border="0" cellpadding="0" cellspacing="0" class="card-poster" style="background-image: url(${(base_url + album['thumb_hash']) if base_url else album['poster_url']});border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;background-color: #3F4245;background-position: center;background-size: cover;background-repeat: no-repeat;background-clip: padding-box;border: 1px solid rgba(255,255,255,.1);">
<tbody>
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
<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(${(base_url + album['thumb_hash']) if base_url else album['poster_url']});background-color: #3F4245;background-position: center;background-size: cover;height: 100%;width: 100%;">
<div class="card-poster-overlay" style="background-image: url(${base_url + 'images/newsletter/view-on-plex.png' if base_url else 'https://i.imgur.com/NSV7q16.png'});background-repeat: no-repeat;background-position: bottom right;width: 100%;height: 100%;"></div>
</div>
<img class="card-poster-overlay" src="${base_url + 'images/newsletter/view-on-plex-cover.png' if base_url else 'https://i.imgur.com/ObC1NeY.png'}" width="150" height="150" style="border: none;-ms-interpolation-mode: bicubic;max-width: 100%;display: block;">
</a>
</div>
<div class="card-info-container" style="margin: 4px;width: 332px;float: left;position: relative;z-index: 1;height: 150px;">
<div class="card-info-title nowrap" style="white-space: nowrap;border-bottom: 1px solid rgba(255, 255, 255, .1);line-height: 20px;font-size: 15px;padding: 5px;text-overflow: ellipsis;overflow: hidden;">
</td>
</tr>
</tbody>
</table>
</td>
<td class="card-info-container" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;padding-left: 4px;height: 152px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;height: 100%;">
<tbody>
<tr>
<td class="card-info-title nowrap" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 0.9rem;vertical-align: top;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;border-bottom: 1px solid rgba(255, 255, 255, .1);line-height: 1.2rem;padding: 5px;">
<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: #ffffff;text-decoration: none;">${album['title']}</a>
</div>
<div class="card-info-body" style="padding: 5px;text-overflow: ellipsis;overflow: hidden;min-height: 82px;">
<div class="nowrap mb5" style="margin-bottom: 5px;white-space: nowrap;color: #ffffff;font-size: 12px;text-overflow: ellipsis;overflow: hidden;">
<em>${artist['title']} &middot; ${album['track_count']} track${'s' if album['track_count'] > 1 else ''}</em>
</div>
</td>
</tr>
<tr>
<td class="card-info-body" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 0.75rem;vertical-align: top;padding: 5px;height: 82px;min-height: 82px;">
<p class="nowrap mb5" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-weight: 400;margin: 0;margin-bottom: 5px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;max-width: 325px;">
<em>${album['parent_title']} &middot; ${album['track_count']} track${'s' if album['track_count'] > 1 else ''}</em>
</p>
% if artist['title'].lower() != 'various artists':
<div style="color: #ffffff;font-size: 12px;text-overflow: ellipsis;overflow: hidden;">
<p style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-weight: 400;margin: 0;max-width: 325px;">
${album['summary'][:200] + (album['summary'][200:] and '...')}
</div>
</p>
% endif
</div>
<div class="card-info-footer nowrap" style="white-space: nowrap;font-size: 10px;padding: 5px;text-overflow: ellipsis;overflow: hidden;">
</td>
</tr>
<tr>
<td class="card-info-footer nowrap" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 0.6rem;vertical-align: top;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;padding-top: 0px;padding-right: 5px;padding-bottom: 5px;padding-left: 5px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;">
<tbody>
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
% if album['year']:
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;font-style: normal;line-height: 1;color: #fff;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;">${album['year']}</span>
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;line-height: 1;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;max-width: 75px;text-overflow: ellipsis;overflow: hidden;">${album['year']}</span>
% endif
% if album['genres']:
% for genre in album['genres'][:2]:
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;font-style: normal;line-height: 1;color: #fff;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;">${genre}</span>
<span class="badge" style="display: inline-block;min-width: 10px;padding: 3px 7px;font-size: 11px;line-height: 1;text-align: center;white-space: nowrap;vertical-align: middle;background-color: rgba(0, 0, 0, .25);border-radius: 2px;max-width: 75px;text-overflow: ellipsis;overflow: hidden;">${genre}</span>
% endfor
% endif
</td>
% if album['rating']:
<span class="star-rating" title="${int(float(album['rating'])/0.1)}%" style="width: 60px;font-size: 14px;line-height: 17px;float: right;">
<div class="star-rating-full nowrap" style="width: ${float(album['rating'])/0.1}%;white-space: nowrap;color: #E5A00D;direction: ltr;padding: 0;overflow: hidden;float: left;">
<span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9733;</span>
</div>
<div class="star-rating-empty" style="width: ${100-float(album['rating'])/0.1}%;color: #aaaaaa;direction: rtl;padding: 0;overflow: hidden;float: left;">
<span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span><span style="display: inline-block;text-align: center;width: 12px;">&#9734;</span>
</div>
</span>
% endif
</div>
</div>
</div>
</div>
<% rating = int(round(float(album['rating']) / 2)) %>
<td class="star-rating-container" title="${int(float(album['rating'])/0.1)}%" align="right" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: bottom;padding-right: 5px;">
% for _ in range(rating):
<span class="star-rating full" style="font-size: 0.8rem;line-height: 1rem;width: 0.5rem;display: inline-block;color: #E5A00D;">&#9733;</span>
% endfor
% for _ in range(5-rating):
<span class="star-rating empty" style="font-size: 0.8rem;line-height: 1rem;width: 0.5rem;display: inline-block;color: #aaaaaa;">&#9734;</span>
% endfor
</div>
</td>
% endif
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
% else:
<td align="center" valign="top" class="card-instance" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 12px;vertical-align: top;overflow: hidden;padding: 3px;width: 502px;min-width: 502px;max-width: 502px;"></td>
% endif
% endfor
</tr>
% endfor
</tbody>
</table>
</td>
</tr>
% endif
<tr>
<td style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;">
<!-- START FOOTER -->
<div class="footer" style="clear: both;margin-top: 10px;text-align: center;width: 100%;font-size: 12px;">
<div class="footer-bar" style="margin-left: auto;margin-right: auto;width: 200px;border-top: 1px solid #E5A00D;margin-top: 25px;"></div>
@ -857,7 +934,6 @@
</div>
</div>
<!-- END FOOTER -->
</td>
</tr>

View file

@ -1,6 +1,7 @@
% if data:
<%
import plexpy
from helpers import grouper
recently_added = data['recently_added']
if plexpy.CONFIG.NEWSLETTER_SELF_HOSTED and plexpy.CONFIG.NEWSLETTER_BASE_URL:
@ -73,7 +74,7 @@
box-sizing: border-box;
display: block;
margin: 0 auto;
max-width: 1042px;
max-width: 1037px;
padding: 10px;
}
@ -139,10 +140,8 @@
ul,
ol {
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
font-size: 14px;
font-weight: 400;
margin: 0;
margin-bottom: 15px;
}
p li,
@ -245,6 +244,8 @@
.nowrap {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.clear {
clear: both;
@ -335,150 +336,135 @@
MEDIA CARDS
------------------------------------- */
.card-instance {
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;
padding: 3px;
width: 502px;
min-width: 502px;
max-width: 502px;
}
.card-instance.movie,
.card-instance.show {
height: 235px;
height: 233px;
}
.card-instance.album {
height: 160px;
}
.card-instance.odd {
float: none !important;
margin: 3px auto !important;
height: 158px;
}
.card-background {
background-position: center;
background-size: cover;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-clip: padding-box;
border: 1px solid rgba(255,255,255,.1);
}
.card-poster-container {
width: 150px;
margin: 3px;
border: 1px solid rgba(255,255,255,.1);
float: left;
position: relative;
z-index: 1;
width: 152px;
min-width: 152px;
}
.card-instance.movie .card-poster-container,
.card-instance.show .card-poster-container{
height: 225px;
height: 227px;
}
.card-instance.album .card-poster-container {
height: 150px;
height: 152px;
}
.card-poster {
background-color: #3F4245;
background-position: center;
background-size: cover;
height: 100%;
width: 100%;
background-repeat: no-repeat;
background-clip: padding-box;
border: 1px solid rgba(255,255,255,.1);
}
.card-poster-overlay {
background-repeat: no-repeat;
background-position: bottom right;
width: 100%;
height: 100%;
display: block;
}
.card-info-container {
margin: 4px;
width: 332px;
float: left;
position: relative;
z-index: 1;
padding-left: 4px;
}
.card-instance.movie .card-info-container,
.card-instance.show .card-info-container{
height: 225px;
height: 227px;
}
.card-instance.album .card-info-container {
height: 150px;
height: 152px;
}
.card-info-container > div {
padding: 5px;
text-overflow: ellipsis;
overflow: hidden;
.card-info-container > table {
height: 100%;
}
.card-info-title {
border-bottom: 1px solid rgba(255, 255, 255, .1);
line-height: 20px;
font-size: 15px;
line-height: 1.2rem;
font-size: 0.9rem;
padding: 5px;
}
.card-info-title a {
text-decoration: none;
color: #ffffff;
}
.card-info-body > div {
color: #ffffff;
font-size: 12px;
text-overflow: ellipsis;
overflow: hidden;
.card-info-body {
font-size: 0.75rem;
padding: 5px;
height: 100%;
}
.card-info-body > p {
max-width: 325px;
}
.card-instance.movie .card-info-body,
.card-instance.show .card-info-body {
min-height: 157px;
}
.card-instance.album .card-info-body {
height: 82px;
min-height: 82px;
}
.card-info-footer {
font-size: 10px;
font-size: 0.6rem;
padding-top: 0px;
padding-right: 5px;
padding-bottom: 5px;
padding-left: 5px;
}
.card-info-footer .star-rating-container {
vertical-align: bottom;
padding-right: 5px;
}
.card-info-footer .star-rating {
width: 60px;
font-size: 14px;
line-height: 17px;
float: right;
}
.star-rating-full {
color: #E5A00D;
direction: ltr;
padding: 0;
overflow: hidden;
float: left;
}
.star-rating-empty {
color: #aaaaaa;
direction: rtl;
padding: 0;
overflow: hidden;
float: left;
}
.star-rating span {
font-size: 0.8rem;
line-height: 1rem;
width: 0.5rem;
display: inline-block;
text-align: center;
width: 12px;
}
.star-rating.full {
color: #E5A00D;
}
.star-rating.empty {
color: #aaaaaa;
}
.badge {
display: inline-block;
min-width: 10px;
padding: 3px 7px;
font-size: 11px;
font-style: normal;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: middle;
background-color: rgba(0, 0, 0, .25);
border-radius: 2px;
max-width: 75px;
text-overflow: ellipsis;
overflow: hidden;
}
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 620px) {
@media only screen and (max-width: 1040px) {
.card-instance {
display: block !important;
margin: 0 auto;
}
table[class=body] .header {
background-position: center !important;
}
@ -510,11 +496,6 @@
font-size: 14px !important;
}
table[class=body] .card-instance {
margin: 3px auto;
float: none;
}
table[class=body] .content {
padding: 0 !important;
}
@ -576,9 +557,9 @@
<div class="content">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader">Tautulli card-backbro - ${title}</span>
<span class="preheader">Tautulli Newsletter - ${title}</span>
<table border="0" cellpadding="0" cellspacing="0" class="main">
<table border="0" cellpadding="3" cellspacing="0" class="main">
<!-- START MAIN CONTENT AREA -->
<tr>
@ -588,9 +569,9 @@
<div class="dates">${parameters['start_date']} - ${parameters['end_date']}</div>
</td>
</tr>
% if recently_added.get('movie'):
<tr>
<td>
% if recently_added.get('movie'):
<div class="wrapper">
<div class="sub-header">
<div class="sub-header-bar"></div>
@ -602,40 +583,59 @@
</div>
</div>
</div>
<div class="wrapper">
% for movie in recently_added['movie']:
<%
if loop.index == len(recently_added['movie'])-1 and loop.index % 2 == 0:
clear = '<div style="clear: both;"></div>'
odd = 'odd'
else:
clear = odd = ''
%>
${clear | n}
<div class="card-instance movie ${odd}">
<div class="card-background" style="background-image: url(${(base_url + movie['art_hash']) if base_url else movie['art_url']});">
<div class="card-poster-container">
</td>
</tr>
<tr>
<td>
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
% for movie_a, movie_b in grouper(recently_added['movie'], 2):
<tr>
% for movie in (movie_a, movie_b):
% if movie:
<td align="center" valign="top" class="card-instance movie">
<table border="0" cellpadding="0" cellspacing="3" width="100%" class="card-background" style="background-image: url(${(base_url + movie['art_hash']) if base_url else movie['art_url']});">
<tbody>
<tr>
<td class="card-poster-container">
<table border="0" cellpadding="0" cellspacing="0" class="card-poster" style="background-image: url(${(base_url + movie['thumb_hash']) if base_url else movie['poster_url']})">
<tbody>
<tr>
<td>
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${movie['rating_key']}" title="${movie['title']}" target="_blank">
<div class="card-poster" style="background-image: url(${(base_url + movie['thumb_hash']) if base_url else movie['poster_url']})">
<div class="card-poster-overlay" style="background-image: url(${base_url + 'images/newsletter/view-on-plex.png' if base_url else 'https://i.imgur.com/NSV7q16.png'})"></div>
</div>
<img class="card-poster-overlay" src="${base_url + 'images/newsletter/view-on-plex-poster.png' if base_url else 'https://i.imgur.com/AeyPvJ4.png'}" width="150" height="225">
</a>
</div>
<div class="card-info-container">
<div class="card-info-title nowrap">
</td>
</tr>
</tbody>
</table>
</td>
<td class="card-info-container">
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td class="card-info-title nowrap">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${movie['rating_key']}" title="${movie['title']}" target="_blank">${movie['title']}</a>
</div>
<div class="card-info-body">
</td>
</tr>
<tr>
<td class="card-info-body">
% if movie['tagline']:
<div class="nowrap mb5">
<p class="nowrap mb5">
<em>${movie['tagline']}</em>
</div>
</p>
% endif
<div>
<p>
${movie['summary'][:450] + (movie['summary'][450:] and '...')}
</div>
</div>
<div class="card-info-footer nowrap">
</p>
</td>
</tr>
<tr>
<td class="card-info-footer nowrap">
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
% if movie['year']:
<span class="badge">${movie['year']}</span>
% endif
@ -645,24 +645,44 @@
% if movie['duration']:
<span class="badge">${int(int(movie['duration'])/60000)} mins</span>
% endif
</td>
% if movie['rating']:
<span class="star-rating" title="${int(float(movie['rating'])/0.1)}%">
<div class="star-rating-full nowrap" style="width: ${float(movie['rating'])/0.1}%">
<span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span>
</div>
<div class="star-rating-empty" style="width: ${100-float(movie['rating'])/0.1}%">
<span>&#9734;</span><span>&#9734;</span><span>&#9734;</span><span>&#9734;</span><span>&#9734;</span>
</div>
</span>
% endif
</div>
</div>
</div>
</div>
<% rating = int(round(float(movie['rating']) / 2)) %>
<td class="star-rating-container" title="${int(float(movie['rating'])/0.1)}%" align="right">
% for _ in range(rating):
<span class="star-rating full">&#9733;</span>
% endfor
</div>
% for _ in range(5-rating):
<span class="star-rating empty">&#9734;</span>
% endfor
</td>
% endif
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
% else:
<td align="center" valign="top" class="card-instance"></td>
% endif
% endfor
</tr>
% endfor
</tbody>
</table>
</td>
</tr>
% endif
% if recently_added.get('show'):
<tr>
<td>
<div class="wrapper">
<div class="sub-header">
<div class="sub-header-bar"></div>
@ -676,45 +696,47 @@
</div>
</div>
</div>
<div class="wrapper">
% for show in recently_added['show']:
<%
if show['season_count'] == 1 and show['season'][0]['episode_count'] == 1:
link_rating_key = show['season'][0]['episode'][0]['rating_key']
link_title = show['title'] + " - " + show['season'][0]['episode'][0]['title']
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 = '<div style="clear: both;"></div>'
odd = 'odd'
else:
clear = odd = ''
%>
${clear | n}
<div class="card-instance show ${odd}">
<div class="card-background" style="background-image: url(${(base_url + show['art_hash']) if base_url else show['art_url']});">
<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">
<div class="card-poster" style="background-image: url(${(base_url + show['thumb_hash']) if base_url else show['poster_url']});">
<div class="card-poster-overlay" style="background-image: url(${base_url + 'images/newsletter/view-on-plex.png' if base_url else 'https://i.imgur.com/NSV7q16.png'})"></div>
</div>
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
% for show_a, show_b in grouper(recently_added['show'], 2):
<tr>
% for show in (show_a, show_b):
% if show:
<td align="center" valign="top" class="card-instance show">
<table border="0" cellpadding="0" cellspacing="3" width="100%" class="card-background" style="background-image: url(${(base_url + show['art_hash']) if base_url else show['art_url']});">
<tbody>
<tr>
<td class="card-poster-container">
<table border="0" cellpadding="0" cellspacing="0" class="card-poster" style="background-image: url(${(base_url + show['thumb_hash']) if base_url else show['poster_url']})">
<tbody>
<tr>
<td>
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${show['rating_key']}" title="${show['title']}" target="_blank">
<img class="card-poster-overlay" src="${base_url + 'images/newsletter/view-on-plex-poster.png' if base_url else 'https://i.imgur.com/AeyPvJ4.png'}" width="150" height="225">
</a>
</div>
<div class="card-info-container">
<div class="card-info-title nowrap">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${link_rating_key}" title="${link_title}" target="_blank">${show['title']}</a>
</div>
<div class="card-info-body">
<div class="nowrap mb5">
</td>
</tr>
</tbody>
</table>
</td>
<td class="card-info-container">
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td class="card-info-title nowrap">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${show['rating_key']}" title="${show['title']}" target="_blank">${show['title']}</a>
</td>
</tr>
<tr>
<td class="card-info-body">
<p class="nowrap mb5">
% if show['season_count'] > 1:
<em>${show['season_count']} seasons /</em>
% endif
<% total_show_episodes = sum(s['episode_count'] for s in show['season']) %>
<em>${total_show_episodes} episode${'s' if total_show_episodes > 1 else ''}</em>
</div>
<div class="nowrap mb5">
</p>
<p class="nowrap mb5">
% for i, season in enumerate(show['season'][:8]):
Season ${season['media_index']} &middot;
% if season['episode_count'] == 1:
@ -728,8 +750,8 @@
...plus ${show['season_count'] - 8} more seasons!
% endif
% endfor
</div>
<div>
</p>
<p>
% if show['season_count'] == 1 and show['season'][0]['episode_count'] == 1:
${show['season'][0]['episode'][0]['summary'][:350] + (show['season'][0]['episode'][0]['summary'][350:] and '...')}
% else:
@ -738,9 +760,15 @@
${show['summary'][:length] + (show['summary'][length:] and '...')}
% endif
% endif
</div>
</div>
<div class="card-info-footer nowrap">
</p>
</td>
</tr>
<tr>
<td class="card-info-footer nowrap">
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
% if show['studio']:
<span class="badge">${show['studio']}</span>
% endif
@ -753,24 +781,44 @@
% if show['duration']:
<span class="badge">${int(int(show['duration'])/60000)} mins</span>
% endif
</td>
% if show['rating']:
<span class="star-rating" title="${int(float(show['rating'])/0.1)}%">
<div class="star-rating-full nowrap" style="width: ${float(show['rating'])/0.1}%">
<span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span>
</div>
<div class="star-rating-empty" style="width: ${100-float(show['rating'])/0.1}%">
<span>&#9734;</span><span>&#9734;</span><span>&#9734;</span><span>&#9734;</span><span>&#9734;</span>
</div>
</span>
% endif
</div>
</div>
</div>
</div>
<% rating = int(round(float(show['rating']) / 2)) %>
<td class="star-rating-container" title="${int(float(show['rating'])/0.1)}%" align="right">
% for _ in range(rating):
<span class="star-rating full">&#9733;</span>
% endfor
</div>
% for _ in range(5-rating):
<span class="star-rating empty">&#9734;</span>
% endfor
</td>
% endif
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
% else:
<td align="center" valign="top" class="card-instance"></td>
% endif
% endfor
</tr>
% endfor
</tbody>
</table>
</td>
</tr>
% endif
% if recently_added.get('artist'):
<tr>
<td>
<div class="wrapper">
<div class="sub-header">
<div class="sub-header-bar"></div>
@ -784,44 +832,55 @@
</div>
</div>
</div>
<div class="wrapper">
<% 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:
clear = '<div style="clear: both;"></div>'
odd = 'odd'
else:
clear = odd = ''
%>
${clear | n}
<div class="card-instance album ${odd}">
<div class="card-background" style="background-image: url(${(base_url + album['art_hash']) if base_url else album['art_url']});">
<div class="card-poster-container">
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
% for album_a, album_b in grouper([a for artist in recently_added['artist'] for a in artist['album']], 2):
<tr>
% for album in (album_a, album_b):
% if album:
<td align="center" valign="top" class="card-instance album">
<table border="0" cellpadding="0" cellspacing="3" width="100%" class="card-background" style="background-image: url(${(base_url + album['art_hash']) if base_url else album['art_url']});">
<tbody>
<tr>
<td class="card-poster-container">
<table border="0" cellpadding="0" cellspacing="0" class="card-poster" style="background-image: url(${(base_url + album['thumb_hash']) if base_url else album['poster_url']})">
<tbody>
<tr>
<td>
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${album['rating_key']}" title="${album['title']}" target="_blank">
<div class="card-poster" style="background-image: url(${(base_url + album['thumb_hash']) if base_url else album['poster_url']});">
<div class="card-poster-overlay" style="background-image: url(${base_url + 'images/newsletter/view-on-plex.png' if base_url else 'https://i.imgur.com/NSV7q16.png'})"></div>
</div>
<img class="card-poster-overlay" src="${base_url + 'images/newsletter/view-on-plex-cover.png' if base_url else 'https://i.imgur.com/ObC1NeY.png'}" width="150" height="150">
</a>
</div>
<div class="card-info-container">
<div class="card-info-title nowrap">
</td>
</tr>
</tbody>
</table>
</td>
<td class="card-info-container">
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td class="card-info-title nowrap">
<a href="${parameters['pms_web_url']}#!/server/${parameters['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${album['rating_key']}" title="${album['title']}" target="_blank">${album['title']}</a>
</div>
<div class="card-info-body">
<div class="nowrap mb5">
<em>${artist['title']} &middot; ${album['track_count']} track${'s' if album['track_count'] > 1 else ''}</em>
</div>
</td>
</tr>
<tr>
<td class="card-info-body">
<p class="nowrap mb5">
<em>${album['parent_title']} &middot; ${album['track_count']} track${'s' if album['track_count'] > 1 else ''}</em>
</p>
% if artist['title'].lower() != 'various artists':
<div>
<p>
${album['summary'][:200] + (album['summary'][200:] and '...')}
</div>
</p>
% endif
</div>
<div class="card-info-footer nowrap">
</td>
</tr>
<tr>
<td class="card-info-footer nowrap">
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
% if album['year']:
<span class="badge">${album['year']}</span>
% endif
@ -830,25 +889,43 @@
<span class="badge">${genre}</span>
% endfor
% endif
</td>
% if album['rating']:
<span class="star-rating" title="${int(float(album['rating'])/0.1)}%">
<div class="star-rating-full nowrap" style="width: ${float(album['rating'])/0.1}%">
<span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span><span>&#9733;</span>
</div>
<div class="star-rating-empty" style="width: ${100-float(album['rating'])/0.1}%">
<span>&#9734;</span><span>&#9734;</span><span>&#9734;</span><span>&#9734;</span><span>&#9734;</span>
</div>
</span>
% endif
</div>
</div>
</div>
</div>
<% rating = int(round(float(album['rating']) / 2)) %>
<td class="star-rating-container" title="${int(float(album['rating'])/0.1)}%" align="right">
% for _ in range(rating):
<span class="star-rating full">&#9733;</span>
% endfor
% for _ in range(5-rating):
<span class="star-rating empty">&#9734;</span>
% endfor
</div>
</td>
% endif
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
% else:
<td align="center" valign="top" class="card-instance"></td>
% endif
% endfor
</tr>
% endfor
</tbody>
</table>
</td>
</tr>
% endif
<tr>
<td>
<!-- START FOOTER -->
<div class="footer">
<div class="footer-bar"></div>
@ -857,7 +934,6 @@
</div>
</div>
<!-- END FOOTER -->
</td>
</tr>

View file

@ -20,6 +20,7 @@ import geoip2.database, geoip2.errors
import gzip
import hashlib
import imghdr
from itertools import izip_longest
import ipwhois, ipwhois.exceptions, ipwhois.utils
from IPy import IP
import json
@ -974,3 +975,10 @@ def momentjs_to_arrow(format, duration=False):
for f in invalid_formats:
format = format.replace(f, '')
return format
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)

View file

@ -413,7 +413,7 @@ class Newsletter(object):
os.makedirs(newsletter_folder)
try:
with open(newsletter_file_fp, 'w') as n_file:
with open(newsletter_file_fp, 'wb') as n_file:
n_file.write(self.newsletter.encode('utf-8'))
logger.info(u"Tautulli Newsletters :: %s newsletter saved to %s" % (self.NAME, newsletter_file))
@ -661,8 +661,8 @@ class RecentlyAdded(Newsletter):
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,
width=150,
height=225,
fallback='poster')
item['art_hash'] = set_hash_image_info(img=item['art'],
width=500,