diff --git a/src/Ombi.Notifications.Templates/Templates/NewsletterTemplate.html b/src/Ombi.Notifications.Templates/Templates/NewsletterTemplate.html index 67a632ee6..e9a2b7f29 100644 --- a/src/Ombi.Notifications.Templates/Templates/NewsletterTemplate.html +++ b/src/Ombi.Notifications.Templates/Templates/NewsletterTemplate.html @@ -123,7 +123,6 @@ table[class=body] h1 { font-size: 28px !important; - margin-bottom: 10px !important; } table[class=body] .container { diff --git a/src/Ombi.Schedule/Jobs/Ombi/HtmlTemplateGenerator.cs b/src/Ombi.Schedule/Jobs/Ombi/HtmlTemplateGenerator.cs index 61f4bd7c8..976af9cb4 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/HtmlTemplateGenerator.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/HtmlTemplateGenerator.cs @@ -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("

{0}

", text, fontSize, fontWeight); + sb.Append(""); + sb.AppendFormat("", url); + sb.Append(""); + sb.Append("
"); + sb.Append(""); } - protected virtual void AddImageInsideTable(StringBuilder sb, string url, int size = 400) + protected virtual void AddPosterInsideTable(StringBuilder sb, string url) { sb.Append(""); - sb.Append(""); + } + + protected virtual void AddInfoTable(StringBuilder sb) + { + sb.Append( + ""); + sb.Append(""); + } + } } private async Task ProcessEmbyTv(HashSet embyContent, StringBuilder sb) @@ -570,9 +623,10 @@ namespace Ombi.Schedule.Jobs.Ombi series.Add(episode.Series); } } + + int count = 0; + overlay = "https://emby.media/resources/logowhite_1881.png"; var orderedTv = series.OrderByDescending(x => x.AddedAt); - sb.Append( - "
"); - sb.Append($""); + sb.Append(""); + sb.AppendFormat("", url); + } + + protected virtual void AddMediaServerUrl(StringBuilder sb, string mediaurl, string overlay) + { + sb.Append(""); + sb.Append(""); + sb.Append(""); + sb.Append("
"); + sb.AppendFormat("", mediaurl); + sb.AppendFormat("", overlay); + sb.Append(""); + sb.Append("
"); + sb.Append("
"); + sb.Append(""); + } + + protected virtual void AddTitle(StringBuilder sb, string url, string title) + { + sb.Append(""); + sb.Append(""); sb.Append(""); } - protected virtual void Href(StringBuilder sb, string url) + protected virtual void AddParagraph(StringBuilder sb, string text) { - sb.AppendFormat("", url); + sb.Append(""); + sb.Append(""); + sb.Append(""); } - protected virtual void TableData(StringBuilder sb) + protected virtual void AddTvParagraph(StringBuilder sb, string episodes, string summary) { - sb.Append( - ""); + sb.Append(""); + sb.Append(""); } - protected virtual void EndTag(StringBuilder sb, string tag) + protected virtual void AddGenres(StringBuilder sb, string text) { - sb.AppendFormat("", tag); + sb.Append(""); + sb.Append(""); + sb.Append(""); } - - protected virtual void Header(StringBuilder sb, int size, string text, string fontWeight = "normal") - { - sb.AppendFormat( - "{1}", - size, text, fontWeight); - } - - } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs index 79731637b..add10ee04 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs @@ -60,6 +60,7 @@ namespace Ombi.Schedule.Jobs.Ombi private readonly ISettingsService _newsletterSettings; private readonly UserManager _userManager; private readonly ILogger _log; + private string overlay; public async Task Start(NewsletterSettings settings, bool test) { @@ -306,16 +307,38 @@ namespace Ombi.Schedule.Jobs.Ombi var embyMovies = embyContentToSend.Where(x => x.Type == EmbyMediaType.Movie); if ((plexMovies.Any() || embyMovies.Any()) && !settings.DisableMovies) { - sb.Append("

New Movies:



"); + sb.Append("

New Movies



"); + sb.Append( + "
"); + sb.AppendFormat("", url); + sb.AppendFormat("

{0}

", title); + sb.Append("
"); sb.Append("
"); + sb.AppendFormat("

{0}

", text); + sb.Append("
"); + sb.Append("
"); + sb.AppendFormat("

{0}

", episodes); + sb.AppendFormat("
{0}
", summary); + sb.Append("
"); + sb.AppendFormat("{0}", text); + sb.Append("
"); + sb.Append(""); + sb.Append(""); + sb.Append(""); + sb.Append("
"); + sb.Append(""); + sb.Append(""); await ProcessPlexMovies(plexMovies, sb); await ProcessEmbyMovies(embyMovies, sb); + sb.Append(""); + sb.Append("
"); + sb.Append("
"); } if ((plexEpisodes.Any() || embyEp.Any()) && !settings.DisableTv) { - sb.Append("

New Episodes:



"); + sb.Append("

New TV



"); + sb.Append( + ""); + sb.Append(""); + sb.Append(""); + sb.Append(""); + sb.Append("
"); + sb.Append(""); + sb.Append(""); await ProcessPlexTv(plexEpisodes, sb); await ProcessEmbyTv(embyEp, sb); + sb.Append(""); + sb.Append("
"); + sb.Append("
"); } return sb.ToString(); @@ -323,8 +346,8 @@ namespace Ombi.Schedule.Jobs.Ombi private async Task ProcessPlexMovies(IQueryable plexContentToSend, StringBuilder sb) { - sb.Append( - ""); + int count = 0; + overlay = "https://www.plex.tv/wp-content/themes/plex/img/plex-logo@2x.png"; var ordered = plexContentToSend.OrderByDescending(x => x.AddedAt); foreach (var content in ordered) { @@ -334,13 +357,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 +375,20 @@ namespace Ombi.Schedule.Jobs.Ombi { EndLoopHtml(sb); } + + if (count == 2) + { + count = 0; + sb.Append(""); + sb.Append(""); + } } } private async Task ProcessEmbyMovies(IQueryable embyContent, StringBuilder sb) { - sb.Append( - "
"); + int count = 0; + overlay = "https://emby.media/resources/logowhite_1881.png"; var ordered = embyContent.OrderByDescending(x => x.AddedAt); foreach (var content in ordered) { @@ -375,13 +407,15 @@ namespace Ombi.Schedule.Jobs.Ombi } var info = await _movieApi.GetMovieInformationWithExtraInfo(int.Parse(theMovieDbId)); + var mediaurl = content.Url; if (info == null) { continue; } try { - CreateMovieHtmlContent(sb, info); + CreateMovieHtmlContent(sb, info, mediaurl); + count += 1; } catch (Exception e) { @@ -391,17 +425,24 @@ namespace Ombi.Schedule.Jobs.Ombi { EndLoopHtml(sb); } + + if (count == 2) + { + count = 0; + sb.Append(""); + sb.Append(""); + } } } - 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(""); - TableData(sb); + AddMediaServerUrl(sb, mediaurl, overlay); + AddInfoTable(sb); - Href(sb, $"https://www.imdb.com/title/{info.ImdbId}/"); var releaseDate = string.Empty; try { @@ -411,16 +452,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 plexContent, StringBuilder sb) @@ -444,9 +484,9 @@ namespace Ombi.Schedule.Jobs.Ombi } } + int count = 0; + overlay = "https://www.plex.tv/wp-content/themes/plex/img/plex-logo@2x.png"; var orderedTv = series.OrderByDescending(x => x.AddedAt); - sb.Append( - "
"); foreach (var t in orderedTv) { try @@ -489,17 +529,15 @@ namespace Ombi.Schedule.Jobs.Ombi { banner = banner.Replace("http", "https"); // Always use the Https banners } - AddImageInsideTable(sb, banner); - sb.Append(""); - sb.Append( - "
"); + //GET BACKGROUND URL HERE AND CALL + AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w1280/"); + AddPosterInsideTable(sb, banner); + AddMediaServerUrl(sb, t.Url, overlay); + 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 +549,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 +567,24 @@ namespace Ombi.Schedule.Jobs.Ombi } } - AddParagraph(sb, $"Season: {epInformation.SeasonNumber}, Episode: {epSb}"); + finalsb.Append($"Season: {epInformation.SeasonNumber} - Episodes: {epSb}"); + finalsb.Append("
"); } + var summary = info.summary; + if (summary.Length > 280) + { + summary = summary.Remove(280); + summary = summary + "...

"; + } + 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 +594,14 @@ namespace Ombi.Schedule.Jobs.Ombi { EndLoopHtml(sb); } - } - sb.Append("


"); + if (count == 2) + { + count = 0; + sb.Append("
"); foreach (var t in orderedTv) { try @@ -581,26 +635,26 @@ 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(""); - sb.Append( - ""); + sb.Append(""); + } } - sb.Append("
"); - - Href(sb, $"https://www.imdb.com/title/{info.externals.imdb}/"); - Header(sb, 3, t.Title); - EndTag(sb, "a"); + //GET BACKGROUND URL HERE AND CALL + AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w1280/"); + AddPosterInsideTable(sb, banner); + AddMediaServerUrl(sb, t.Url, overlay); + 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 +666,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 +684,24 @@ namespace Ombi.Schedule.Jobs.Ombi } } - AddParagraph(sb, $"Season: {epInformation.SeasonNumber}, Episode: {epSb}"); + finalsb.Append($"Season: {epInformation.SeasonNumber} - Episodes: {epSb}"); + finalsb.Append("
"); } + var summary = info.summary; + if (summary.Length > 280) + { + summary = summary.Remove(280); + summary = summary + "...

"; + } + 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 +711,28 @@ namespace Ombi.Schedule.Jobs.Ombi { EndLoopHtml(sb); } + + if (count == 2) + { + count = 0; + sb.Append("


"); } 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("
"); - sb.Append("
"); - sb.Append("
"); + sb.Append("
"); sb.Append(""); sb.Append(""); + sb.Append(""); + sb.Append(""); + sb.Append(""); + sb.Append(""); + sb.Append(""); } protected bool ValidateConfiguration(EmailNotificationSettings settings)