@ -1,7 +1,10 @@
using System ;
using System.Collections.Generic ;
using System.Linq ;
using FluentValidation.Results ;
using NzbDrone.Common.Extensions ;
using NzbDrone.Core.MediaCover ;
using NzbDrone.Core.MediaFiles.MediaInfo ;
using NzbDrone.Core.Notifications.Discord.Payloads ;
using NzbDrone.Core.Tv ;
using NzbDrone.Core.Validation ;
@ -22,34 +25,197 @@ namespace NzbDrone.Core.Notifications.Discord
public override void OnGrab ( GrabMessage message )
{
var embeds = new List < Embed >
var series = message . Series ;
var episodes = message . Episode . Episodes ;
var embed = new Embed
{
new Embed
Author = new DiscordAuthor
{
Name = Settings . Author . IsNullOrWhiteSpace ( ) ? Environment . MachineName : Settings . Author ,
IconUrl = "https://raw.githubusercontent.com/Sonarr/Sonarr/phantom-develop/Logo/256.png"
} ,
Url = $"http://thetvdb.com/?tab=series&id={series.TvdbId}" ,
Description = "Episode Grabbed" ,
Title = GetTitle ( series , episodes ) ,
Color = ( int ) DiscordColors . Standard ,
Fields = new List < DiscordField > ( ) ,
Timestamp = DateTime . UtcNow . ToString ( "yyyy-MM-ddTHH:mm:ss.fffZ" )
} ;
if ( Settings . GrabFields . Contains ( ( int ) DiscordGrabFieldType . Poster ) )
{
Description = message . Message ,
Title = message . Series . Title ,
Text = message . Message ,
Color = ( int ) DiscordColors . Warning
embed . Thumbnail = new DiscordImage
{
Url = series . Images . FirstOrDefault ( x = > x . CoverType = = MediaCoverTypes . Poster ) ? . Url
} ;
}
if ( Settings . GrabFields . Contains ( ( int ) DiscordGrabFieldType . Fanart ) )
{
embed . Image = new DiscordImage
{
Url = series . Images . FirstOrDefault ( x = > x . CoverType = = MediaCoverTypes . Fanart ) ? . Url
} ;
var payload = CreatePayload ( $"Grabbed: {message.Message}" , embeds ) ;
}
foreach ( var field in Settings . GrabFields )
{
var discordField = new DiscordField ( ) ;
switch ( ( DiscordGrabFieldType ) field )
{
case DiscordGrabFieldType . Overview :
var overview = episodes . First ( ) . Overview ;
discordField . Name = "Overview" ;
discordField . Value = overview . Length < = 300 ? overview : overview . Substring ( 0 , 300 ) + "..." ;
break ;
case DiscordGrabFieldType . Rating :
discordField . Name = "Rating" ;
discordField . Value = episodes . First ( ) . Ratings . Value . ToString ( ) ;
break ;
case DiscordGrabFieldType . Genres :
discordField . Name = "Genres" ;
discordField . Value = series . Genres . Take ( 5 ) . Join ( ", " ) ;
break ;
case DiscordGrabFieldType . Quality :
discordField . Name = "Quality" ;
discordField . Inline = true ;
discordField . Value = message . Quality . Quality . Name ;
break ;
case DiscordGrabFieldType . Group :
discordField . Name = "Group" ;
discordField . Value = message . Episode . ParsedEpisodeInfo . ReleaseGroup ;
break ;
case DiscordGrabFieldType . Size :
discordField . Name = "Size" ;
discordField . Value = BytesToString ( message . Episode . Release . Size ) ;
discordField . Inline = true ;
break ;
case DiscordGrabFieldType . Release :
discordField . Name = "Release" ;
discordField . Value = string . Format ( "```{0}```" , message . Episode . Release . Title ) ;
break ;
case DiscordGrabFieldType . Links :
discordField . Name = "Links" ;
discordField . Value = GetLinksString ( series ) ;
break ;
}
if ( discordField . Name . IsNotNullOrWhiteSpace ( ) & & discordField . Value . IsNotNullOrWhiteSpace ( ) )
{
embed . Fields . Add ( discordField ) ;
}
}
var payload = CreatePayload ( null , new List < Embed > { embed } ) ;
_proxy . SendPayload ( payload , Settings ) ;
}
public override void OnDownload ( DownloadMessage message )
{
var embeds = new List < Embed >
var series = message . Series ;
var episodes = message . EpisodeFile . Episodes . Value ;
var isUpgrade = message . OldFiles . Count > 0 ;
var embed = new Embed
{
new Embed
Author = new DiscordAuthor
{
Name = Settings . Author . IsNullOrWhiteSpace ( ) ? Environment . MachineName : Settings . Author ,
IconUrl = "https://raw.githubusercontent.com/Sonarr/Sonarr/phantom-develop/Logo/256.png"
} ,
Url = $"http://thetvdb.com/?tab=series&id={series.TvdbId}" ,
Description = isUpgrade ? "Episode Upgraded" : "Episode Imported" ,
Title = GetTitle ( series , episodes ) ,
Color = isUpgrade ? ( int ) DiscordColors . Upgrade : ( int ) DiscordColors . Standard ,
Fields = new List < DiscordField > ( ) ,
Timestamp = DateTime . UtcNow . ToString ( "yyyy-MM-ddTHH:mm:ss.fffZ" )
} ;
if ( Settings . ImportFields . Contains ( ( int ) DiscordImportFieldType . Poster ) )
{
embed . Thumbnail = new DiscordImage
{
Description = message . Message ,
Title = message . Series . Title ,
Text = message . Message ,
Color = ( int ) DiscordColors . Success
Url = series . Images . FirstOrDefault ( x = > x . CoverType = = MediaCoverTypes . Poster ) . Url
} ;
}
if ( Settings . ImportFields . Contains ( ( int ) DiscordImportFieldType . Fanart ) )
{
embed . Image = new DiscordImage
{
Url = series . Images . FirstOrDefault ( x = > x . CoverType = = MediaCoverTypes . Fanart ) . Url
} ;
var payload = CreatePayload ( $"Imported: {message.Message}" , embeds ) ;
}
foreach ( var field in Settings . ImportFields )
{
var discordField = new DiscordField ( ) ;
switch ( ( DiscordImportFieldType ) field )
{
case DiscordImportFieldType . Overview :
var overview = episodes . First ( ) . Overview ;
discordField . Name = "Overview" ;
discordField . Value = overview . Length < = 300 ? overview : overview . Substring ( 0 , 300 ) + "..." ;
break ;
case DiscordImportFieldType . Rating :
discordField . Name = "Rating" ;
discordField . Value = episodes . First ( ) . Ratings . Value . ToString ( ) ;
break ;
case DiscordImportFieldType . Genres :
discordField . Name = "Genres" ;
discordField . Value = series . Genres . Take ( 5 ) . Join ( ", " ) ;
break ;
case DiscordImportFieldType . Quality :
discordField . Name = "Quality" ;
discordField . Inline = true ;
discordField . Value = message . EpisodeFile . Quality . Quality . Name ;
break ;
case DiscordImportFieldType . Codecs :
discordField . Name = "Codecs" ;
discordField . Inline = true ;
discordField . Value = string . Format ( "{0} / {1} {2}" ,
MediaInfoFormatter . FormatVideoCodec ( message . EpisodeFile . MediaInfo , null ) ,
MediaInfoFormatter . FormatAudioCodec ( message . EpisodeFile . MediaInfo , null ) ,
MediaInfoFormatter . FormatAudioChannels ( message . EpisodeFile . MediaInfo ) ) ;
break ;
case DiscordImportFieldType . Group :
discordField . Name = "Group" ;
discordField . Value = message . EpisodeFile . ReleaseGroup ;
break ;
case DiscordImportFieldType . Size :
discordField . Name = "Size" ;
discordField . Value = BytesToString ( message . EpisodeFile . Size ) ;
discordField . Inline = true ;
break ;
case DiscordImportFieldType . Languages :
discordField . Name = "Languages" ;
discordField . Value = message . EpisodeFile . MediaInfo . AudioLanguages ;
break ;
case DiscordImportFieldType . Subtitles :
discordField . Name = "Subtitles" ;
discordField . Value = message . EpisodeFile . MediaInfo . Subtitles ;
break ;
case DiscordImportFieldType . Release :
discordField . Name = "Release" ;
discordField . Value = message . EpisodeFile . SceneName ;
break ;
case DiscordImportFieldType . Links :
discordField . Name = "Links" ;
discordField . Value = GetLinksString ( series ) ;
break ;
}
if ( discordField . Name . IsNotNullOrWhiteSpace ( ) & & discordField . Value . IsNotNullOrWhiteSpace ( ) )
{
embed . Fields . Add ( discordField ) ;
}
}
var payload = CreatePayload ( null , new List < Embed > { embed } ) ;
_proxy . SendPayload ( payload , Settings ) ;
}
@ -75,13 +241,19 @@ namespace NzbDrone.Core.Notifications.Discord
{
new Embed
{
Author = new DiscordAuthor
{
Name = Settings . Author . IsNullOrWhiteSpace ( ) ? Environment . MachineName : Settings . Author ,
IconUrl = "https://raw.githubusercontent.com/Sonarr/Sonarr/phantom-develop/Logo/256.png"
} ,
Title = healthCheck . Source . Name ,
Text = healthCheck . Message ,
Color = healthCheck . Type = = HealthCheck . HealthCheckResult . Warning ? ( int ) DiscordColors . Warning : ( int ) DiscordColors . Success
Description = healthCheck . Message ,
Timestamp = DateTime . UtcNow . ToString ( "yyyy-MM-ddTHH:mm:ss.fffZ" ) ,
Color = healthCheck . Type = = HealthCheck . HealthCheckResult . Warning ? ( int ) DiscordColors . Warning : ( int ) DiscordColors . Danger
}
} ;
var payload = CreatePayload ( "Health Issue" , attachments ) ;
var payload = CreatePayload ( null , attachments ) ;
_proxy . SendPayload ( payload , Settings ) ;
}
@ -136,5 +308,51 @@ namespace NzbDrone.Core.Notifications.Discord
return payload ;
}
private string BytesToString ( long byteCount )
{
string [ ] suf = { "B" , "KB" , "MB" , "GB" , "TB" , "PB" , "EB" } ; //Longs run out around EB
if ( byteCount = = 0 )
{
return "0 " + suf [ 0 ] ;
}
var bytes = Math . Abs ( byteCount ) ;
var place = Convert . ToInt32 ( Math . Floor ( Math . Log ( bytes , 1024 ) ) ) ;
var num = Math . Round ( bytes / Math . Pow ( 1024 , place ) , 1 ) ;
return string . Format ( "{0} {1}" , ( Math . Sign ( byteCount ) * num ) . ToString ( ) , suf [ place ] ) ;
}
private string GetLinksString ( Series series )
{
var links = new List < string > ( ) ;
links . Add ( $"[The TVDB](https://thetvdb.com/?tab=series&id={series.TvdbId})" ) ;
links . Add ( $"[Trakt](https://trakt.tv/search/tvdb/{series.TvdbId}?id_type=show)" ) ;
if ( series . ImdbId . IsNotNullOrWhiteSpace ( ) )
{
links . Add ( $"[IMDB](https://imdb.com/title/{series.ImdbId}/)" ) ;
}
return string . Join ( " / " , links ) ;
}
private string GetTitle ( Series series , List < Episode > episodes )
{
if ( series . SeriesType = = SeriesTypes . Daily )
{
var episode = episodes . First ( ) ;
return $"{series.Title} - {episode.AirDate} - {episode.Title}" ;
}
var episodeNumbers = string . Concat ( episodes . Select ( e = > e . EpisodeNumber )
. Select ( i = > string . Format ( "x{0:00}" , i ) ) ) ;
var episodeTitles = string . Join ( " + " , episodes . Select ( e = > e . Title ) ) ;
return $"{series.Title} - {episodes.First().SeasonNumber}{episodeNumbers} - {episodeTitles}" ;
}
}
}