@ -53,18 +53,19 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter
public RecentlyAddedNewsletter ( IPlexApi api , ISettingsService < PlexSettings > plexSettings ,
ISettingsService < EmailNotificationSettings > email , IJobRecord rec ,
ISettingsService < NewletterSettings > newsletter ,
IPlexReadOnlyDatabase db , IUserHelper userHelper , IEmbyAddedNewsletter embyNews ,
ISettingsService < EmbySettings > embyS )
IUserHelper userHelper , IEmbyAddedNewsletter embyNews ,
ISettingsService < EmbySettings > embyS ,
IPlexNewsletter plex )
{
JobRecord = rec ;
Api = api ;
PlexSettings = plexSettings ;
EmailSettings = email ;
NewsletterSettings = newsletter ;
PlexDb = db ;
UserHelper = userHelper ;
EmbyNewsletter = embyNews ;
EmbySettings = embyS ;
PlexNewsletter = plex ;
}
private IPlexApi Api { get ; }
@ -75,9 +76,9 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter
private ISettingsService < EmailNotificationSettings > EmailSettings { get ; }
private ISettingsService < NewletterSettings > NewsletterSettings { get ; }
private IJobRecord JobRecord { get ; }
private IPlexReadOnlyDatabase PlexDb { get ; }
private IUserHelper UserHelper { get ; }
private IEmbyAddedNewsletter EmbyNewsletter { get ; }
private IPlexNewsletter PlexNewsletter { get ; }
private static readonly Logger Log = LogManager . GetCurrentClassLogger ( ) ;
@ -144,331 +145,18 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter
}
else
{
var sb = new StringBuilder ( ) ;
var plexSettings = PlexSettings . GetSettings ( ) ;
Log . Debug ( "Got Plex Settings" ) ;
var libs = Api . GetLibrarySections ( plexSettings . PlexAuthToken , plexSettings . FullUri ) ;
Log . Debug ( "Getting Plex Library Sections" ) ;
var tvSections = libs . Directories . Where ( x = > x . type . Equals ( PlexMediaType . Show . ToString ( ) , StringComparison . CurrentCultureIgnoreCase ) ) ; // We could have more than 1 lib
Log . Debug ( "Filtered sections for TV" ) ;
var movieSection = libs . Directories . Where ( x = > x . type . Equals ( PlexMediaType . Movie . ToString ( ) , StringComparison . CurrentCultureIgnoreCase ) ) ; // We could have more than 1 lib
Log . Debug ( "Filtered sections for Movies" ) ;
var plexVersion = Api . GetStatus ( plexSettings . PlexAuthToken , plexSettings . FullUri ) . Version ;
var html = string . Empty ;
if ( plexVersion . StartsWith ( "1.3" ) )
{
var tvMetadata = new List < Metadata > ( ) ;
var movieMetadata = new List < Metadata > ( ) ;
foreach ( var tvSection in tvSections )
{
var item = Api . RecentlyAdded ( plexSettings . PlexAuthToken , plexSettings . FullUri ,
tvSection ? . Key ) ;
if ( item ? . MediaContainer ? . Metadata ! = null )
{
tvMetadata . AddRange ( item ? . MediaContainer ? . Metadata ) ;
}
}
Log . Debug ( "Got RecentlyAdded TV Shows" ) ;
foreach ( var movie in movieSection )
{
var recentlyAddedMovies = Api . RecentlyAdded ( plexSettings . PlexAuthToken , plexSettings . FullUri , movie ? . Key ) ;
if ( recentlyAddedMovies ? . MediaContainer ? . Metadata ! = null )
{
movieMetadata . AddRange ( recentlyAddedMovies ? . MediaContainer ? . Metadata ) ;
}
}
Log . Debug ( "Got RecentlyAdded Movies" ) ;
Log . Debug ( "Started Generating Movie HTML" ) ;
GenerateMovieHtml ( movieMetadata , plexSettings , sb ) ;
Log . Debug ( "Finished Generating Movie HTML" ) ;
Log . Debug ( "Started Generating TV HTML" ) ;
GenerateTvHtml ( tvMetadata , plexSettings , sb ) ;
Log . Debug ( "Finished Generating TV HTML" ) ;
var template = new RecentlyAddedTemplate ( ) ;
html = template . LoadTemplate ( sb . ToString ( ) ) ;
Log . Debug ( "Loaded the template" ) ;
}
else
{
// Old API
var tvChild = new List < RecentlyAddedChild > ( ) ;
var movieChild = new List < RecentlyAddedChild > ( ) ;
foreach ( var tvSection in tvSections )
{
var recentlyAddedTv = Api . RecentlyAddedOld ( plexSettings . PlexAuthToken , plexSettings . FullUri , tvSection ? . Key ) ;
if ( recentlyAddedTv ? . _children ! = null )
{
tvChild . AddRange ( recentlyAddedTv ? . _children ) ;
}
}
Log . Debug ( "Got RecentlyAdded TV Shows" ) ;
foreach ( var movie in movieSection )
{
var recentlyAddedMovies = Api . RecentlyAddedOld ( plexSettings . PlexAuthToken , plexSettings . FullUri , movie ? . Key ) ;
if ( recentlyAddedMovies ? . _children ! = null )
{
tvChild . AddRange ( recentlyAddedMovies ? . _children ) ;
}
}
Log . Debug ( "Got RecentlyAdded Movies" ) ;
Log . Debug ( "Started Generating Movie HTML" ) ;
GenerateMovieHtml ( movieChild , plexSettings , sb ) ;
Log . Debug ( "Finished Generating Movie HTML" ) ;
Log . Debug ( "Started Generating TV HTML" ) ;
GenerateTvHtml ( tvChild , plexSettings , sb ) ;
Log . Debug ( "Finished Generating TV HTML" ) ;
var template = new RecentlyAddedTemplate ( ) ;
html = template . LoadTemplate ( sb . ToString ( ) ) ;
Log . Debug ( "Loaded the template" ) ;
}
string escapedHtml = new string ( html . Where ( c = > ! char . IsControl ( c ) ) . ToArray ( ) ) ;
Log . Debug ( escapedHtml ) ;
SendNewsletter ( newletterSettings , escapedHtml , testEmail ) ;
}
}
private void GenerateMovieHtml ( List < RecentlyAddedChild > movies , PlexSettings plexSettings , StringBuilder sb )
{
var orderedMovies = movies . OrderByDescending ( x = > x ? . addedAt . UnixTimeStampToDateTime ( ) ) . ToList ( ) ? ? new List < RecentlyAddedChild > ( ) ;
sb . Append ( "<h1>New Movies:</h1><br /><br />" ) ;
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 movie in orderedMovies )
{
var plexGUID = string . Empty ;
try
{
var metaData = Api . GetMetadata ( plexSettings . PlexAuthToken , plexSettings . FullUri ,
movie . ratingKey . ToString ( ) ) ;
plexGUID = metaData . Video . Guid ;
var imdbId = PlexHelper . GetProviderIdFromPlexGuid ( plexGUID ) ;
var info = _movieApi . GetMovieInformation ( imdbId ) . Result ;
if ( info = = null )
{
throw new Exception ( $"Movie with Imdb id {imdbId} returned null from the MovieApi" ) ;
}
AddImageInsideTable ( sb , $"https://image.tmdb.org/t/p/w500{info.BackdropPath}" ) ;
sb . Append ( "<tr>" ) ;
sb . Append (
"<td align=\"center\" style=\"font-family: sans-serif; font-size: 14px; vertical-align: top;\" valign=\"top\">" ) ;
Href ( sb , $"https://www.imdb.com/title/{info.ImdbId}/" ) ;
Header ( sb , 3 , $"{info.Title} {info.ReleaseDate?.ToString(" yyyy ") ?? string.Empty}" ) ;
EndTag ( sb , "a" ) ;
if ( info . Genres . Any ( ) )
{
AddParagraph ( sb ,
$"Genre: {string.Join(" , ", info.Genres.Select(x => x.Name.ToString()).ToArray())}" ) ;
}
AddParagraph ( sb , info . Overview ) ;
}
catch ( Exception e )
{
Log . Error ( e ) ;
Log . Error (
"Exception when trying to process a Movie, either in getting the metadata from Plex OR getting the information from TheMovieDB, Plex GUID = {0}" ,
plexGUID ) ;
}
finally
{
EndLoopHtml ( sb ) ;
}
}
sb . Append ( "</table><br /><br />" ) ;
}
private void GenerateMovieHtml ( List < Metadata > movies , PlexSettings plexSettings , StringBuilder sb )
{
var orderedMovies = movies . OrderByDescending ( x = > x ? . addedAt . UnixTimeStampToDateTime ( ) ) . ToList ( ) ? ? new List < Metadata > ( ) ;
sb . Append ( "<h1>New Movies:</h1><br /><br />" ) ;
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 movie in orderedMovies )
{
var plexGUID = string . Empty ;
try
{
var metaData = Api . GetMetadata ( plexSettings . PlexAuthToken , plexSettings . FullUri ,
movie . ratingKey . ToString ( ) ) ;
plexGUID = metaData . Video . Guid ;
var imdbId = PlexHelper . GetProviderIdFromPlexGuid ( plexGUID ) ;
var info = _movieApi . GetMovieInformation ( imdbId ) . Result ;
if ( info = = null )
{
throw new Exception ( $"Movie with Imdb id {imdbId} returned null from the MovieApi" ) ;
}
AddImageInsideTable ( sb , $"https://image.tmdb.org/t/p/w500{info.BackdropPath}" ) ;
sb . Append ( "<tr>" ) ;
sb . Append (
"<td align=\"center\" style=\"font-family: sans-serif; font-size: 14px; vertical-align: top;\" valign=\"top\">" ) ;
Href ( sb , $"https://www.imdb.com/title/{info.ImdbId}/" ) ;
Header ( sb , 3 , $"{info.Title} {info.ReleaseDate?.ToString(" yyyy ") ?? string.Empty}" ) ;
EndTag ( sb , "a" ) ;
if ( info . Genres . Any ( ) )
{
AddParagraph ( sb ,
$"Genre: {string.Join(" , ", info.Genres.Select(x => x.Name.ToString()).ToArray())}" ) ;
}
AddParagraph ( sb , info . Overview ) ;
}
catch ( Exception e )
{
Log . Error ( e ) ;
Log . Error (
"Exception when trying to process a Movie, either in getting the metadata from Plex OR getting the information from TheMovieDB, Plex GUID = {0}" ,
plexGUID ) ;
}
finally
{
EndLoopHtml ( sb ) ;
}
}
sb . Append ( "</table><br /><br />" ) ;
}
private void GenerateTvHtml ( List < RecentlyAddedChild > tv , PlexSettings plexSettings , StringBuilder sb )
{
var orderedTv = tv . OrderByDescending ( x = > x ? . addedAt . UnixTimeStampToDateTime ( ) ) . ToList ( ) ;
// TV
sb . Append ( "<h1>New Episodes:</h1><br /><br />" ) ;
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 )
{
var plexGUID = string . Empty ;
try
{
var parentMetaData = Api . GetMetadata ( plexSettings . PlexAuthToken , plexSettings . FullUri ,
t . parentRatingKey . ToString ( ) ) ;
plexGUID = parentMetaData . Directory . Guid ;
var info = TvApi . ShowLookupByTheTvDbId ( int . Parse ( PlexHelper . GetProviderIdFromPlexGuid ( plexGUID ) ) ) ;
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 title = $"{t.grandparentTitle} - {t.title} {t.originallyAvailableAt?.Substring(0, 4)}" ;
Href ( sb , $"https://www.imdb.com/title/{info.externals.imdb}/" ) ;
Header ( sb , 3 , title ) ;
EndTag ( sb , "a" ) ;
AddParagraph ( sb , $"Season: {t.parentIndex}, Episode: {t.index}" ) ;
if ( info . genres . Any ( ) )
{
AddParagraph ( sb , $"Genre: {string.Join(" , ", info.genres.Select(x => x.ToString()).ToArray())}" ) ;
}
AddParagraph ( sb , string . IsNullOrEmpty ( t . summary ) ? info . summary : t . summary ) ;
}
catch ( Exception e )
{
Log . Error ( e ) ;
Log . Error (
"Exception when trying to process a TV Show, either in getting the metadata from Plex OR getting the information from TVMaze, Plex GUID = {0}" ,
plexGUID ) ;
}
finally
{
EndLoopHtml ( sb ) ;
}
}
sb . Append ( "</table><br /><br />" ) ;
}
private void GenerateTvHtml ( List < Metadata > tv , PlexSettings plexSettings , StringBuilder sb )
{
var orderedTv = tv . OrderByDescending ( x = > x ? . addedAt . UnixTimeStampToDateTime ( ) ) . ToList ( ) ;
// TV
sb . Append ( "<h1>New Episodes:</h1><br /><br />" ) ;
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 )
{
var plexGUID = string . Empty ;
try
if ( plexSettings . Enable )
{
var html = PlexNewsletter . GetNewsletterHtml ( testEmail ) ;
var parentMetaData = Api . GetMetadata ( plexSettings . PlexAuthToken , plexSettings . FullUri ,
t . parentRatingKey . ToString ( ) ) ;
plexGUID = parentMetaData . Directory . Guid ;
var info = TvApi . ShowLookupByTheTvDbId ( int . Parse ( PlexHelper . GetProviderIdFromPlexGuid ( plexGUID ) ) ) ;
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 title = $"{t.grandparentTitle} - {t.title} {t.originallyAvailableAt?.Substring(0, 4)}" ;
Href ( sb , $"https://www.imdb.com/title/{info.externals.imdb}/" ) ;
Header ( sb , 3 , title ) ;
EndTag ( sb , "a" ) ;
AddParagraph ( sb , $"Season: {t.parentIndex}, Episode: {t.index}" ) ;
if ( info . genres . Any ( ) )
{
AddParagraph ( sb , $"Genre: {string.Join(" , ", info.genres.Select(x => x.ToString()).ToArray())}" ) ;
}
AddParagraph ( sb , string . IsNullOrEmpty ( t . summary ) ? info . summary : t . summary ) ;
}
catch ( Exception e )
{
Log . Error ( e ) ;
Log . Error (
"Exception when trying to process a TV Show, either in getting the metadata from Plex OR getting the information from TVMaze, Plex GUID = {0}" ,
plexGUID ) ;
}
finally
{
EndLoopHtml ( sb ) ;
var escapedHtml = new string ( html . Where ( c = > ! char . IsControl ( c ) ) . ToArray ( ) ) ;
Log . Debug ( escapedHtml ) ;
SendNewsletter ( newletterSettings , html , testEmail ) ;
}
}
sb . Append ( "</table><br /><br />" ) ;
}
private void SendMassEmail ( string html , string subject , bool testEmail )
{
var settings = EmailSettings . GetSettings ( ) ;
@ -507,7 +195,7 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter
SendMail ( settings , message ) ;
}
// TODO Emby
private void SendNewsletter ( NewletterSettings newletterSettings , string html , bool testEmail = false , string subject = "New Content on Plex!" )
{
Log . Debug ( "Entering SendNewsletter" ) ;
@ -588,17 +276,5 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter
Log . Error ( e ) ;
}
}
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 ( "</td>" ) ;
sb . Append ( "</tr>" ) ;
}
}
}