mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-19 21:03:17 -07:00
Merge pull request #2191 from anojht/newsletterenhancement
Newsletter Enhancement
This commit is contained in:
commit
31231b4a06
8 changed files with 400 additions and 174 deletions
|
@ -68,7 +68,7 @@ namespace Ombi.Mapping.Profiles
|
|||
.ForMember(x => x.ReleaseDate, o => o.MapFrom(s => s.release_date))
|
||||
.ForMember(x => x.Type, o => o.MapFrom(s => s.Type));
|
||||
|
||||
CreateMap<Genre, GenreDto>();
|
||||
CreateMap<TheMovieDbApi.Models.Genre, GenreDto>();
|
||||
|
||||
CreateMap<MovieSearchResult, SearchMovieViewModel>().ReverseMap();
|
||||
CreateMap<MovieResponseDto, SearchMovieViewModel>().ReverseMap();
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
public abstract class TemplateBase
|
||||
{
|
||||
public abstract string TemplateLocation { get; }
|
||||
public virtual string OmbiLogo => "http://i.imgur.com/qQsN78U.png";
|
||||
public virtual string OmbiLogo => "http://i.imgur.com/7pqVq7W.png";
|
||||
}
|
||||
}
|
|
@ -4,57 +4,125 @@
|
|||
<meta name="viewport" content="width=device-width" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>Ombi</title>
|
||||
<style media="all" type="text/css">
|
||||
@media all {
|
||||
.btn-primary table td:hover {
|
||||
background-color: #34495e !important;
|
||||
}
|
||||
|
||||
.btn-primary a:hover {
|
||||
background-color: #34495e !important;
|
||||
border-color: #34495e !important;
|
||||
}
|
||||
<style type="text/css">
|
||||
img {
|
||||
border: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@media all {
|
||||
.btn-secondary a:hover {
|
||||
border-color: #34495e !important;
|
||||
color: #34495e !important;
|
||||
}
|
||||
body {
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 620px) {
|
||||
table {
|
||||
border-collapse: separate;
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table td {
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.body {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: block;
|
||||
margin: 0 auto !important;
|
||||
max-width: 1042px;
|
||||
padding: 10px;
|
||||
width: 1042px;
|
||||
}
|
||||
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-width: 1037px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.main {
|
||||
border-radius: 3px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
box-sizing: border-box;
|
||||
padding: 5px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.content-block {
|
||||
padding-bottom: 10px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
clear: both;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.footer td,
|
||||
.footer p,
|
||||
.footer span,
|
||||
.footer a {
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #ffffff;
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
font-weight: 400;
|
||||
margin: 0;
|
||||
color: #ff761b;
|
||||
}
|
||||
|
||||
p {
|
||||
font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
font-weight: 400;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p li,
|
||||
ul li {
|
||||
list-style-position: inside;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1040px) {
|
||||
.media-card {
|
||||
display: block !important;
|
||||
margin-top: 0 !important;
|
||||
margin-right: auto !important;
|
||||
margin-bottom: 10px !important;
|
||||
margin-left: auto !important;
|
||||
}
|
||||
|
||||
table[class=body] h1 {
|
||||
font-size: 28px !important;
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
|
||||
table[class=body] h2 {
|
||||
font-size: 22px !important;
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
|
||||
table[class=body] h3 {
|
||||
font-size: 16px !important;
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
|
||||
table[class=body] p,
|
||||
table[class=body] ul,
|
||||
table[class=body] ol,
|
||||
table[class=body] td,
|
||||
table[class=body] span,
|
||||
table[class=body] a {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
table[class=body] .wrapper,
|
||||
table[class=body] .article {
|
||||
padding: 10px !important;
|
||||
}
|
||||
|
||||
table[class=body] .content {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
table[class=body] .container {
|
||||
|
@ -62,60 +130,14 @@
|
|||
width: 100% !important;
|
||||
}
|
||||
|
||||
table[class=body] .header {
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
|
||||
table[class=body] .main {
|
||||
border-left-width: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
border-right-width: 0 !important;
|
||||
}
|
||||
|
||||
table[class=body] .btn table {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
table[class=body] .btn a {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
table[class=body] .img-responsive {
|
||||
height: auto !important;
|
||||
max-width: 100% !important;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
table[class=body] .alert td {
|
||||
border-radius: 0 !important;
|
||||
padding: 10px !important;
|
||||
}
|
||||
|
||||
table[class=body] .span-2,
|
||||
table[class=body] .span-3 {
|
||||
max-width: none !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
table[class=body] .receipt {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media all {
|
||||
.ExternalClass {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ExternalClass,
|
||||
.ExternalClass p,
|
||||
.ExternalClass span,
|
||||
.ExternalClass font,
|
||||
.ExternalClass td,
|
||||
.ExternalClass div {
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
.apple-link a {
|
||||
color: inherit !important;
|
||||
font-family: inherit !important;
|
||||
|
@ -127,16 +149,15 @@
|
|||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="" style="font-family: sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.4; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; background-color: #f6f6f6; margin: 0; padding: 0;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background-color: #f6f6f6;" width="100%" bgcolor="#f6f6f6">
|
||||
<body class="" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;font-size: 14px;line-height: 1.4;margin: 0;padding: 0;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%; background-color: #1f1f1f; color: #fff;">
|
||||
<tr>
|
||||
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;" valign="top"> </td>
|
||||
<td class="container" style="font-family: sans-serif; font-size: 14px; vertical-align: top; display: block; Margin: 0 auto !important; max-width: 580px; padding: 10px; width: 580px;" width="580" valign="top">
|
||||
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 580px; padding: 10px;">
|
||||
<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: 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;">Ombi Recently Added</span>
|
||||
<table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: #fff; border-radius: 3px;" width="100%">
|
||||
<table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; border-radius: 3px;" width="100%">
|
||||
|
||||
<!-- START MAIN CONTENT AREA -->
|
||||
<tr>
|
||||
|
@ -144,23 +165,24 @@
|
|||
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;" width="100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<img src="{@LOGO}" width="400px" text-align="center" />
|
||||
<img src="{@LOGO}" width="400px" text-align="center"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;" valign="top">
|
||||
<br />
|
||||
<br />
|
||||
<p style="font-family: sans-serif; font-size: 20px; font-weight: normal; margin: 0; Margin-bottom: 15px;">{@INTRO}</p>
|
||||
<p style="color: #fff; font-family: sans-serif; font-size: 20px; font-weight: normal; margin: 0; Margin-bottom: 15px; text-align: center;">{@INTRO}</p>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
{@RECENTLYADDED}
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{@RECENTLYADDED}
|
||||
|
||||
<!-- END MAIN CONTENT AREA -->
|
||||
</table>
|
||||
|
|
|
@ -4,43 +4,79 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
public abstract class HtmlTemplateGenerator
|
||||
{
|
||||
protected virtual void AddParagraph(StringBuilder stringBuilder, string text, int fontSize = 14, string fontWeight = "normal")
|
||||
protected virtual void AddBackgroundInsideTable(StringBuilder sb, string url)
|
||||
{
|
||||
stringBuilder.AppendFormat("<p style=\"font-family: sans-serif; font-size: {1}px; font-weight: {2}; margin: 0; Margin-bottom: 15px;\">{0}</p>", text, fontSize, fontWeight);
|
||||
sb.Append("<td align=\"center\" valign=\"top\" class=\"media-card\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 12px; vertical-align: top; padding: 3px; width: 502px; min-width: 500px; max-width: 500px; height: 235px; \">");
|
||||
sb.AppendFormat("<table class=\"card-bg\" style=\"background-image: url({0}); border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background-color: #1f1f1f; background-position: center; background-size: cover; background-repeat: no-repeat; background-clip: padding-box; border: 2px solid rgba(255,118,27,.4); \">", url);
|
||||
sb.Append("<tr>");
|
||||
sb.Append("<td>");
|
||||
sb.Append("<table class=\"bg-tint\" style=\"background-color: rgba(0, 0, 0, .6); position: absolute; width: 490px; height: 239px; \">");
|
||||
}
|
||||
|
||||
protected virtual void AddImageInsideTable(StringBuilder sb, string url, int size = 400)
|
||||
protected virtual void AddPosterInsideTable(StringBuilder sb, string url)
|
||||
{
|
||||
sb.Append("<tr>");
|
||||
sb.Append("<td align=\"center\">");
|
||||
sb.Append($"<img src=\"{url}\" width=\"{size}px\" text-align=\"center\" />");
|
||||
sb.Append("<td class=\"poster-container\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; width: 150px; min-width: 15px; height: 225px; \">");
|
||||
sb.AppendFormat("<table class=\"poster-img\" style=\"background-image: url({0}); border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background-color: transparent; background-position: center; background-size: cover; background-repeat: no-repeat; background-clip: padding-box; border: 1px solid rgba(255,255,255,.1); \">", url);
|
||||
}
|
||||
|
||||
protected virtual void AddMediaServerUrl(StringBuilder sb, string mediaurl, string url)
|
||||
{
|
||||
sb.Append("<tr>");
|
||||
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; \">");
|
||||
sb.AppendFormat("<a href=\"{0}\" target=\"_blank\">", mediaurl);
|
||||
sb.AppendFormat("<img class=\"poster-overlay\" src=\"{0}\" width=\"150\" height=\"225\" style=\"border: none;-ms-interpolation-mode: bicubic; max-width: 100%;display: block; visibility: hidden; \">", url);
|
||||
sb.Append("</a>");
|
||||
sb.Append("</td>");
|
||||
sb.Append("</tr>");
|
||||
sb.Append("</table>");
|
||||
sb.Append("</td>");
|
||||
}
|
||||
|
||||
protected virtual void AddInfoTable(StringBuilder sb)
|
||||
{
|
||||
sb.Append(
|
||||
"<td class=\"movie-info\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; padding-left: 4px; text-align: left; height: 227px; \">");
|
||||
sb.Append("<table style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; height: 100%; \">");
|
||||
}
|
||||
|
||||
protected virtual void AddTitle(StringBuilder sb, string url, string title)
|
||||
{
|
||||
sb.Append("<tr>");
|
||||
sb.Append("<td class=\"title\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 0.9rem; vertical-align: top; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; line-height: 1.2rem; padding: 5px; \">");
|
||||
sb.AppendFormat("<a href=\"{0}\" target=\"_blank\">", url);
|
||||
sb.AppendFormat("<h1 style=\"white-space: normal; line-height: 1;\" >{0}</h1>", title);
|
||||
sb.Append("</a>");
|
||||
sb.Append("</td>");
|
||||
sb.Append("</tr>");
|
||||
}
|
||||
|
||||
protected virtual void Href(StringBuilder sb, string url)
|
||||
protected virtual void AddParagraph(StringBuilder sb, string text)
|
||||
{
|
||||
sb.AppendFormat("<a href=\"{0}\">", url);
|
||||
sb.Append("<tr class=\"description\">");
|
||||
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 0.75rem; vertical-align: top; padding: 5px; height: 100%; \">");
|
||||
sb.AppendFormat("<p style=\"color: #fff; font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-weight: 400; margin: 0; max-width: 325px; text-align: justify; \">{0}</p>", text);
|
||||
sb.Append("</td>");
|
||||
sb.Append("</tr>");
|
||||
}
|
||||
|
||||
protected virtual void TableData(StringBuilder sb)
|
||||
protected virtual void AddTvParagraph(StringBuilder sb, string episodes, string summary)
|
||||
{
|
||||
sb.Append(
|
||||
"<td align=\"center\" style=\"font-family: sans-serif; font-size: 14px; vertical-align: top;\" valign=\"top\">");
|
||||
sb.Append("<tr class=\"description\">");
|
||||
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 0.75rem; vertical-align: top; padding: 5px; height: 100%; \">");
|
||||
sb.AppendFormat("<p style=\"color: #fff; font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-weight: 400; margin: 0; max-width: 325px; margin-bottom: 10px; \">{0}</p>", episodes);
|
||||
sb.AppendFormat("<div style=\"color: #fff; font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-weight: 400; margin: 0; max-width: 325px; overflow: hidden; text-align: justify; \">{0}</div>", summary);
|
||||
sb.Append("</td>");
|
||||
sb.Append("</tr>");
|
||||
}
|
||||
|
||||
protected virtual void EndTag(StringBuilder sb, string tag)
|
||||
protected virtual void AddGenres(StringBuilder sb, string text)
|
||||
{
|
||||
sb.AppendFormat("</{0}>", tag);
|
||||
sb.Append("<tr class=\"meta\">");
|
||||
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; max-width: 265px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; \">");
|
||||
sb.AppendFormat("<span 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(255, 118, 27, 0.5); color: #fff; border-radius: 2px; text-overflow: ellipsis; overflow: hidden; \">{0}</span>", text);
|
||||
sb.Append("</td>");
|
||||
sb.Append("</tr>");
|
||||
}
|
||||
|
||||
protected virtual void Header(StringBuilder sb, int size, string text, string fontWeight = "normal")
|
||||
{
|
||||
sb.AppendFormat(
|
||||
"<h{0} style=\"font-family: sans-serif; font-weight: {2}; margin: 0; Margin-bottom: 15px;\">{1}</h{0}>",
|
||||
size, text, fontWeight);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -306,16 +306,38 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
var embyMovies = embyContentToSend.Where(x => x.Type == EmbyMediaType.Movie);
|
||||
if ((plexMovies.Any() || embyMovies.Any()) && !settings.DisableMovies)
|
||||
{
|
||||
sb.Append("<h1>New Movies:</h1><br /><br />");
|
||||
sb.Append("<h1 style=\"text-align: center;\">New Movies</h1><br /><br />");
|
||||
sb.Append(
|
||||
"<table class=\"movies-table\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100 %; \">");
|
||||
sb.Append("<tr>");
|
||||
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; \">");
|
||||
sb.Append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100 %; \">");
|
||||
sb.Append("<tr>");
|
||||
await ProcessPlexMovies(plexMovies, sb);
|
||||
await ProcessEmbyMovies(embyMovies, sb);
|
||||
sb.Append("</tr>");
|
||||
sb.Append("</table>");
|
||||
sb.Append("</td>");
|
||||
sb.Append("</tr>");
|
||||
sb.Append("</table>");
|
||||
}
|
||||
|
||||
if ((plexEpisodes.Any() || embyEp.Any()) && !settings.DisableTv)
|
||||
{
|
||||
sb.Append("<h1>New Episodes:</h1><br /><br />");
|
||||
sb.Append("<br /><br /><h1 style=\"text-align: center;\">New TV</h1><br /><br />");
|
||||
sb.Append(
|
||||
"<table class=\"tv-table\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100 %; \">");
|
||||
sb.Append("<tr>");
|
||||
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; \">");
|
||||
sb.Append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100 %; \">");
|
||||
sb.Append("<tr>");
|
||||
await ProcessPlexTv(plexEpisodes, sb);
|
||||
await ProcessEmbyTv(embyEp, sb);
|
||||
sb.Append("</tr>");
|
||||
sb.Append("</table>");
|
||||
sb.Append("</td>");
|
||||
sb.Append("</tr>");
|
||||
sb.Append("</table>");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
|
@ -323,8 +345,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
|
||||
private async Task ProcessPlexMovies(IQueryable<PlexServerContent> plexContentToSend, StringBuilder sb)
|
||||
{
|
||||
sb.Append(
|
||||
"<table border=\"0\" cellpadding=\"0\" align=\"center\" cellspacing=\"0\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;\" width=\"100%\">");
|
||||
int count = 0;
|
||||
var ordered = plexContentToSend.OrderByDescending(x => x.AddedAt);
|
||||
foreach (var content in ordered)
|
||||
{
|
||||
|
@ -334,13 +355,15 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
continue;
|
||||
}
|
||||
var info = await _movieApi.GetMovieInformationWithExtraInfo(movieDbId);
|
||||
var mediaurl = content.Url;
|
||||
if (info == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
CreateMovieHtmlContent(sb, info);
|
||||
CreateMovieHtmlContent(sb, info, mediaurl);
|
||||
count += 1;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -350,13 +373,19 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
EndLoopHtml(sb);
|
||||
}
|
||||
|
||||
if (count == 2)
|
||||
{
|
||||
count = 0;
|
||||
sb.Append("</tr>");
|
||||
sb.Append("<tr>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ProcessEmbyMovies(IQueryable<EmbyContent> embyContent, StringBuilder sb)
|
||||
{
|
||||
sb.Append(
|
||||
"<table border=\"0\" cellpadding=\"0\" align=\"center\" cellspacing=\"0\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;\" width=\"100%\">");
|
||||
int count = 0;
|
||||
var ordered = embyContent.OrderByDescending(x => x.AddedAt);
|
||||
foreach (var content in ordered)
|
||||
{
|
||||
|
@ -374,6 +403,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
theMovieDbId = result.id.ToString();
|
||||
}
|
||||
|
||||
var mediaurl = content.Url;
|
||||
var info = await _movieApi.GetMovieInformationWithExtraInfo(StringHelper.IntParseLinq(theMovieDbId));
|
||||
if (info == null)
|
||||
{
|
||||
|
@ -381,7 +411,8 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
}
|
||||
try
|
||||
{
|
||||
CreateMovieHtmlContent(sb, info);
|
||||
CreateMovieHtmlContent(sb, info, mediaurl);
|
||||
count += 1;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -391,17 +422,24 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
EndLoopHtml(sb);
|
||||
}
|
||||
|
||||
if (count == 2)
|
||||
{
|
||||
count = 0;
|
||||
sb.Append("</tr>");
|
||||
sb.Append("<tr>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateMovieHtmlContent(StringBuilder sb, MovieResponseDto info)
|
||||
private void CreateMovieHtmlContent(StringBuilder sb, MovieResponseDto info, string mediaurl)
|
||||
{
|
||||
AddImageInsideTable(sb, $"https://image.tmdb.org/t/p/original{info.PosterPath}");
|
||||
AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w1280/{info.BackdropPath}");
|
||||
AddPosterInsideTable(sb, $"https://image.tmdb.org/t/p/original{info.PosterPath}");
|
||||
|
||||
sb.Append("<tr>");
|
||||
TableData(sb);
|
||||
AddMediaServerUrl(sb, mediaurl, $"https://image.tmdb.org/t/p/original{info.PosterPath}");
|
||||
AddInfoTable(sb);
|
||||
|
||||
Href(sb, $"https://www.imdb.com/title/{info.ImdbId}/");
|
||||
var releaseDate = string.Empty;
|
||||
try
|
||||
{
|
||||
|
@ -411,16 +449,15 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
// Swallow, couldn't parse the date
|
||||
}
|
||||
Header(sb, 3, $"{info.Title} {releaseDate}");
|
||||
EndTag(sb, "a");
|
||||
|
||||
AddTitle(sb, $"https://www.imdb.com/title/{info.ImdbId}/", $"{info.Title} {releaseDate}");
|
||||
AddParagraph(sb, info.Overview);
|
||||
|
||||
if (info.Genres.Any())
|
||||
{
|
||||
AddParagraph(sb,
|
||||
$"Genre: {string.Join(", ", info.Genres.Select(x => x.Name.ToString()).ToArray())}");
|
||||
AddGenres(sb,
|
||||
$"Genres: {string.Join(", ", info.Genres.Select(x => x.Name.ToString()).ToArray())}");
|
||||
}
|
||||
|
||||
AddParagraph(sb, info.Overview);
|
||||
}
|
||||
|
||||
private async Task ProcessPlexTv(HashSet<PlexEpisode> plexContent, StringBuilder sb)
|
||||
|
@ -444,9 +481,8 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
var orderedTv = series.OrderByDescending(x => x.AddedAt);
|
||||
sb.Append(
|
||||
"<table border=\"0\" cellpadding=\"0\" align=\"center\" cellspacing=\"0\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;\" width=\"100%\">");
|
||||
foreach (var t in orderedTv)
|
||||
{
|
||||
try
|
||||
|
@ -489,17 +525,23 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
banner = banner.Replace("http", "https"); // Always use the Https banners
|
||||
}
|
||||
AddImageInsideTable(sb, banner);
|
||||
|
||||
var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId);
|
||||
if (tvInfo != null && tvInfo.backdrop_path.HasValue())
|
||||
{
|
||||
|
||||
sb.Append("<tr>");
|
||||
sb.Append(
|
||||
"<td align=\"center\" style=\"font-family: sans-serif; font-size: 14px; vertical-align: top;\" valign=\"top\">");
|
||||
AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w500{tvInfo.backdrop_path}");
|
||||
}
|
||||
else
|
||||
{
|
||||
AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w1280/");
|
||||
}
|
||||
AddPosterInsideTable(sb, banner);
|
||||
AddMediaServerUrl(sb, t.Url, banner);
|
||||
AddInfoTable(sb);
|
||||
|
||||
var title = $"{t.Title} ({t.ReleaseYear})";
|
||||
|
||||
Href(sb, $"https://www.imdb.com/title/{info.externals.imdb}/");
|
||||
Header(sb, 3, title);
|
||||
EndTag(sb, "a");
|
||||
AddTitle(sb, $"https://www.imdb.com/title/{info.externals.imdb}/", title);
|
||||
|
||||
// Group by the season number
|
||||
var results = t.Episodes.GroupBy(p => p.SeasonNumber,
|
||||
|
@ -511,6 +553,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
);
|
||||
|
||||
// Group the episodes
|
||||
var finalsb = new StringBuilder();
|
||||
foreach (var epInformation in results.OrderBy(x => x.SeasonNumber))
|
||||
{
|
||||
var orderedEpisodes = epInformation.Episodes.OrderBy(x => x.EpisodeNumber).ToList();
|
||||
|
@ -528,15 +571,24 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
}
|
||||
|
||||
}
|
||||
AddParagraph(sb, $"Season: {epInformation.SeasonNumber}, Episode: {epSb}");
|
||||
finalsb.Append($"Season: {epInformation.SeasonNumber} - Episodes: {epSb}");
|
||||
finalsb.Append("<br />");
|
||||
}
|
||||
|
||||
var summary = info.summary;
|
||||
if (summary.Length > 280)
|
||||
{
|
||||
summary = summary.Remove(280);
|
||||
summary = summary + "...</p>";
|
||||
}
|
||||
AddTvParagraph(sb, finalsb.ToString(), summary);
|
||||
|
||||
if (info.genres.Any())
|
||||
{
|
||||
AddParagraph(sb, $"Genre: {string.Join(", ", info.genres.Select(x => x.ToString()).ToArray())}");
|
||||
AddGenres(sb, $"Genres: {string.Join(", ", info.genres.Select(x => x.ToString()).ToArray())}");
|
||||
}
|
||||
count += 1;
|
||||
|
||||
AddParagraph(sb, info.summary);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -546,9 +598,14 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
EndLoopHtml(sb);
|
||||
}
|
||||
}
|
||||
sb.Append("</table><br /><br />");
|
||||
|
||||
if (count == 2)
|
||||
{
|
||||
count = 0;
|
||||
sb.Append("</tr>");
|
||||
sb.Append("<tr>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ProcessEmbyTv(HashSet<EmbyEpisode> embyContent, StringBuilder sb)
|
||||
|
@ -570,9 +627,9 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
series.Add(episode.Series);
|
||||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
var orderedTv = series.OrderByDescending(x => x.AddedAt);
|
||||
sb.Append(
|
||||
"<table border=\"0\" cellpadding=\"0\" align=\"center\" cellspacing=\"0\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;\" width=\"100%\">");
|
||||
foreach (var t in orderedTv)
|
||||
{
|
||||
try
|
||||
|
@ -581,26 +638,34 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int.TryParse(t.TvDbId, out var tvdbId);
|
||||
var info = await _tvApi.ShowLookupByTheTvDbId(tvdbId);
|
||||
if (info == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var banner = info.image?.original;
|
||||
if (!string.IsNullOrEmpty(banner))
|
||||
{
|
||||
banner = banner.Replace("http", "https"); // Always use the Https banners
|
||||
}
|
||||
AddImageInsideTable(sb, banner);
|
||||
|
||||
sb.Append("<tr>");
|
||||
sb.Append(
|
||||
"<td align=\"center\" style=\"font-family: sans-serif; font-size: 14px; vertical-align: top;\" valign=\"top\">");
|
||||
var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId);
|
||||
if (tvInfo != null && tvInfo.backdrop_path.HasValue())
|
||||
{
|
||||
|
||||
Href(sb, $"https://www.imdb.com/title/{info.externals.imdb}/");
|
||||
Header(sb, 3, t.Title);
|
||||
EndTag(sb, "a");
|
||||
AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w500{tvInfo.backdrop_path}");
|
||||
}
|
||||
else
|
||||
{
|
||||
AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w1280/");
|
||||
}
|
||||
AddPosterInsideTable(sb, banner);
|
||||
AddMediaServerUrl(sb, t.Url, banner);
|
||||
AddInfoTable(sb);
|
||||
AddTitle(sb, $"https://www.imdb.com/title/{info.externals.imdb}/", $"{t.Title} ({info.premiered.Remove(4)})");
|
||||
|
||||
// Group by the season number
|
||||
var results = t.Episodes?.GroupBy(p => p.SeasonNumber,
|
||||
|
@ -612,6 +677,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
);
|
||||
|
||||
// Group the episodes
|
||||
var finalsb = new StringBuilder();
|
||||
foreach (var epInformation in results.OrderBy(x => x.SeasonNumber))
|
||||
{
|
||||
var orderedEpisodes = epInformation.Episodes.OrderBy(x => x.EpisodeNumber).ToList();
|
||||
|
@ -629,15 +695,24 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
}
|
||||
|
||||
}
|
||||
AddParagraph(sb, $"Season: {epInformation.SeasonNumber}, Episode: {epSb}");
|
||||
finalsb.Append($"Season: {epInformation.SeasonNumber} - Episodes: {epSb}");
|
||||
finalsb.Append("<br />");
|
||||
}
|
||||
|
||||
var summary = info.summary;
|
||||
if (summary.Length > 280)
|
||||
{
|
||||
summary = summary.Remove(280);
|
||||
summary = summary + "...</p>";
|
||||
}
|
||||
AddTvParagraph(sb, finalsb.ToString(), summary);
|
||||
|
||||
if (info.genres.Any())
|
||||
{
|
||||
AddParagraph(sb, $"Genre: {string.Join(", ", info.genres.Select(x => x.ToString()).ToArray())}");
|
||||
AddGenres(sb, $"Genres: {string.Join(", ", info.genres.Select(x => x.ToString()).ToArray())}");
|
||||
}
|
||||
count += 1;
|
||||
|
||||
AddParagraph(sb, info.summary);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -647,19 +722,28 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
EndLoopHtml(sb);
|
||||
}
|
||||
|
||||
if (count == 2)
|
||||
{
|
||||
count = 0;
|
||||
sb.Append("</tr>");
|
||||
sb.Append("<tr>");
|
||||
}
|
||||
}
|
||||
sb.Append("</table><br /><br />");
|
||||
}
|
||||
|
||||
private void EndLoopHtml(StringBuilder sb)
|
||||
{
|
||||
//NOTE: BR have to be in TD's as per html spec or it will be put outside of the table...
|
||||
//Source: http://stackoverflow.com/questions/6588638/phantom-br-tag-rendered-by-browsers-prior-to-table-tag
|
||||
sb.Append("<hr />");
|
||||
sb.Append("<br />");
|
||||
sb.Append("<br />");
|
||||
sb.Append("</table>");
|
||||
sb.Append("</td>");
|
||||
sb.Append("</tr>");
|
||||
sb.Append("</table>");
|
||||
sb.Append("</td>");
|
||||
sb.Append("</tr>");
|
||||
sb.Append("</table>");
|
||||
sb.Append("</td>");
|
||||
}
|
||||
|
||||
protected bool ValidateConfiguration(EmailNotificationSettings settings)
|
||||
|
|
|
@ -18,5 +18,6 @@ namespace Ombi.Api.TheMovieDb
|
|||
Task<List<MovieSearchResult>> SimilarMovies(int movieId);
|
||||
Task<FindResult> Find(string externalId, ExternalSource source);
|
||||
Task<TvExternals> GetTvExternals(int theMovieDbId);
|
||||
Task<TvInfo> GetTVInfo(string themoviedbid);
|
||||
}
|
||||
}
|
74
src/Ombi.TheMovieDbApi/Models/TvInfo.cs
Normal file
74
src/Ombi.TheMovieDbApi/Models/TvInfo.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
namespace Ombi.Api.TheMovieDb.Models
|
||||
{
|
||||
public class TvInfo
|
||||
{
|
||||
public string backdrop_path { get; set; }
|
||||
public Created_By[] created_by { get; set; }
|
||||
public int[] episode_run_time { get; set; }
|
||||
public string first_air_date { get; set; }
|
||||
public Genre[] genres { get; set; }
|
||||
public string homepage { get; set; }
|
||||
public int id { get; set; }
|
||||
public bool in_production { get; set; }
|
||||
public string[] languages { get; set; }
|
||||
public string last_air_date { get; set; }
|
||||
public string name { get; set; }
|
||||
public Network[] networks { get; set; }
|
||||
public int number_of_episodes { get; set; }
|
||||
public int number_of_seasons { get; set; }
|
||||
public string[] origin_country { get; set; }
|
||||
public string original_language { get; set; }
|
||||
public string original_name { get; set; }
|
||||
public string overview { get; set; }
|
||||
public float popularity { get; set; }
|
||||
public string poster_path { get; set; }
|
||||
public Production_Companies[] production_companies { get; set; }
|
||||
public Season[] seasons { get; set; }
|
||||
public string status { get; set; }
|
||||
public string type { get; set; }
|
||||
public float vote_average { get; set; }
|
||||
public int vote_count { get; set; }
|
||||
}
|
||||
|
||||
public class Created_By
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string name { get; set; }
|
||||
public int gender { get; set; }
|
||||
public string profile_path { get; set; }
|
||||
}
|
||||
|
||||
public class Genre
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string name { get; set; }
|
||||
}
|
||||
|
||||
public class Network
|
||||
{
|
||||
public string name { get; set; }
|
||||
public int id { get; set; }
|
||||
public string logo_path { get; set; }
|
||||
public string origin_country { get; set; }
|
||||
}
|
||||
|
||||
public class Production_Companies
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string logo_path { get; set; }
|
||||
public string name { get; set; }
|
||||
public string origin_country { get; set; }
|
||||
}
|
||||
|
||||
public class Season
|
||||
{
|
||||
public string air_date { get; set; }
|
||||
public int episode_count { get; set; }
|
||||
public int id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string overview { get; set; }
|
||||
public string poster_path { get; set; }
|
||||
public int season_number { get; set; }
|
||||
}
|
||||
|
||||
}
|
|
@ -129,6 +129,15 @@ namespace Ombi.Api.TheMovieDb
|
|||
var result = await Api.Request<TheMovieDbContainer<SearchResult>>(request);
|
||||
return Mapper.Map<List<MovieSearchResult>>(result.results);
|
||||
}
|
||||
|
||||
public async Task<TvInfo> GetTVInfo(string themoviedbid)
|
||||
{
|
||||
var request = new Request($"/tv/{themoviedbid}", BaseUri, HttpMethod.Get);
|
||||
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
|
||||
AddRetry(request);
|
||||
|
||||
return await Api.Request<TvInfo>(request);
|
||||
}
|
||||
private static void AddRetry(Request request)
|
||||
{
|
||||
request.Retry = true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue