PageRenderTime 80ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/src/NzbDrone.Core/Notifications/Trakt/TraktService.cs

https://github.com/NzbDrone/NzbDrone
C# | 323 lines | 281 code | 41 blank | 1 comment | 8 complexity | 1434c1aa2ae4795c6c87a2e8396694dc MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using FluentValidation.Results;
  6. using NLog;
  7. using NzbDrone.Common.Extensions;
  8. using NzbDrone.Common.Http;
  9. using NzbDrone.Core.MediaFiles;
  10. using NzbDrone.Core.MediaFiles.MediaInfo;
  11. using NzbDrone.Core.Tv;
  12. using NzbDrone.Core.Notifications.Trakt.Resource;
  13. using NzbDrone.Core.Qualities;
  14. using NzbDrone.Core.MetadataSource.SkyHook.Resource;
  15. using NzbDrone.Core.Indexers.HDBits;
  16. using NzbDrone.Core.IndexerSearch;
  17. namespace NzbDrone.Core.Notifications.Trakt
  18. {
  19. public interface ITraktService
  20. {
  21. HttpRequest GetOAuthRequest(string callbackUrl);
  22. TraktAuthRefreshResource RefreshAuthToken(string refreshToken);
  23. void AddEpisodeToCollection(TraktSettings settings, Series series, EpisodeFile episodeFile);
  24. void RemoveEpisodeFromCollection(TraktSettings settings, Series series, EpisodeFile episodeFile);
  25. void RemoveSeriesFromCollection(TraktSettings settings, Series series);
  26. string GetUserName(string accessToken);
  27. ValidationFailure Test(TraktSettings settings);
  28. }
  29. public class TraktService : ITraktService
  30. {
  31. private readonly ITraktProxy _proxy;
  32. private readonly Logger _logger;
  33. public TraktService(ITraktProxy proxy,
  34. Logger logger)
  35. {
  36. _proxy = proxy;
  37. _logger = logger;
  38. }
  39. public string GetUserName(string accessToken)
  40. {
  41. return _proxy.GetUserName(accessToken);
  42. }
  43. public HttpRequest GetOAuthRequest(string callbackUrl)
  44. {
  45. return _proxy.GetOAuthRequest(callbackUrl);
  46. }
  47. public TraktAuthRefreshResource RefreshAuthToken(string refreshToken)
  48. {
  49. return _proxy.RefreshAuthToken(refreshToken);
  50. }
  51. public ValidationFailure Test(TraktSettings settings)
  52. {
  53. try
  54. {
  55. GetUserName(settings.AccessToken);
  56. return null;
  57. }
  58. catch (HttpException ex)
  59. {
  60. if (ex.Response.StatusCode == HttpStatusCode.Unauthorized)
  61. {
  62. _logger.Error(ex, "Access Token is invalid: " + ex.Message);
  63. return new ValidationFailure("Token", "Access Token is invalid");
  64. }
  65. _logger.Error(ex, "Unable to send test message: " + ex.Message);
  66. return new ValidationFailure("Token", "Unable to send test message");
  67. }
  68. catch (Exception ex)
  69. {
  70. _logger.Error(ex, "Unable to send test message: " + ex.Message);
  71. return new ValidationFailure("", "Unable to send test message");
  72. }
  73. }
  74. public void AddEpisodeToCollection(TraktSettings settings, Series series, EpisodeFile episodeFile)
  75. {
  76. var payload = new TraktCollectShowsResource
  77. {
  78. Shows = new List<TraktCollectShow>()
  79. };
  80. var traktResolution = MapResolution(episodeFile.Quality.Quality.Resolution, episodeFile.MediaInfo?.ScanType);
  81. var mediaType = MapMediaType(episodeFile.Quality.Quality.Source);
  82. var audio = MapAudio(episodeFile);
  83. var audioChannels = MapAudioChannels(episodeFile, audio);
  84. var payloadEpisodes = new List<TraktEpisodeResource>();
  85. foreach (var episode in episodeFile.Episodes.Value)
  86. {
  87. payloadEpisodes.Add(new TraktEpisodeResource
  88. {
  89. Number = episode.EpisodeNumber,
  90. CollectedAt = DateTime.Now,
  91. Resolution = traktResolution,
  92. MediaType = mediaType,
  93. AudioChannels = audioChannels,
  94. Audio = audio,
  95. });
  96. }
  97. var payloadSeasons = new List<TraktSeasonResource>();
  98. payloadSeasons.Add(new TraktSeasonResource
  99. {
  100. Number = episodeFile.SeasonNumber,
  101. Episodes = payloadEpisodes
  102. });
  103. payload.Shows.Add(new TraktCollectShow
  104. {
  105. Title = series.Title,
  106. Year = series.Year,
  107. Ids = new TraktShowIdsResource
  108. {
  109. Tvdb = series.TvdbId,
  110. Imdb = series.ImdbId ?? "",
  111. },
  112. Seasons = payloadSeasons,
  113. });
  114. _proxy.AddToCollection(payload, settings.AccessToken);
  115. }
  116. public void RemoveEpisodeFromCollection(TraktSettings settings, Series series, EpisodeFile episodeFile)
  117. {
  118. var payload = new TraktCollectShowsResource
  119. {
  120. Shows = new List<TraktCollectShow>()
  121. };
  122. var payloadEpisodes = new List<TraktEpisodeResource>();
  123. foreach (var episode in episodeFile.Episodes.Value)
  124. {
  125. payloadEpisodes.Add(new TraktEpisodeResource
  126. {
  127. Number = episode.EpisodeNumber
  128. });
  129. }
  130. var payloadSeasons = new List<TraktSeasonResource>();
  131. payloadSeasons.Add(new TraktSeasonResource
  132. {
  133. Number = episodeFile.SeasonNumber,
  134. Episodes = payloadEpisodes
  135. });
  136. payload.Shows.Add(new TraktCollectShow
  137. {
  138. Title = series.Title,
  139. Year = series.Year,
  140. Ids = new TraktShowIdsResource
  141. {
  142. Tvdb = series.TvdbId,
  143. Imdb = series.ImdbId ?? "",
  144. },
  145. Seasons = payloadSeasons,
  146. });
  147. _proxy.RemoveFromCollection(payload, settings.AccessToken);
  148. }
  149. public void RemoveSeriesFromCollection(TraktSettings settings, Series series)
  150. {
  151. var payload = new TraktCollectShowsResource
  152. {
  153. Shows = new List<TraktCollectShow>()
  154. };
  155. payload.Shows.Add(new TraktCollectShow
  156. {
  157. Title = series.Title,
  158. Year = series.Year,
  159. Ids = new TraktShowIdsResource
  160. {
  161. Tvdb = series.TvdbId,
  162. Imdb = series.ImdbId ?? "",
  163. },
  164. });
  165. _proxy.RemoveFromCollection(payload, settings.AccessToken);
  166. }
  167. private string MapMediaType(QualitySource source)
  168. {
  169. var traktSource = string.Empty;
  170. switch (source)
  171. {
  172. case QualitySource.Web:
  173. case QualitySource.WebRip:
  174. traktSource = "digital";
  175. break;
  176. case QualitySource.BlurayRaw:
  177. case QualitySource.Bluray:
  178. traktSource = "bluray";
  179. break;
  180. case QualitySource.Television:
  181. case QualitySource.TelevisionRaw:
  182. traktSource = "vhs";
  183. break;
  184. case QualitySource.DVD:
  185. traktSource = "dvd";
  186. break;
  187. }
  188. return traktSource;
  189. }
  190. private string MapResolution(int resolution, string scanType)
  191. {
  192. var traktResolution = string.Empty;
  193. //var interlacedTypes = new string[] { "Interlaced", "MBAFF", "PAFF" };
  194. var scanIdentifier = scanType.IsNotNullOrWhiteSpace() && TraktInterlacedTypes.interlacedTypes.Contains(scanType) ? "i" : "p";
  195. switch (resolution)
  196. {
  197. case 2160:
  198. traktResolution = "uhd_4k";
  199. break;
  200. case 1080:
  201. traktResolution = $"hd_1080{scanIdentifier}";
  202. break;
  203. case 720:
  204. traktResolution = "hd_720p";
  205. break;
  206. case 576:
  207. traktResolution = $"sd_576{scanIdentifier}";
  208. break;
  209. case 480:
  210. traktResolution = $"sd_480{scanIdentifier}";
  211. break;
  212. }
  213. return traktResolution;
  214. }
  215. private string MapAudio(EpisodeFile episodeFile)
  216. {
  217. var traktAudioFormat = string.Empty;
  218. var audioCodec = episodeFile.MediaInfo != null ? MediaInfoFormatter.FormatAudioCodec(episodeFile.MediaInfo, episodeFile.SceneName) : string.Empty;
  219. switch (audioCodec)
  220. {
  221. case "AC3":
  222. traktAudioFormat = "dolby_digital";
  223. break;
  224. case "EAC3":
  225. traktAudioFormat = "dolby_digital_plus";
  226. break;
  227. case "TrueHD":
  228. traktAudioFormat = "dolby_truehd";
  229. break;
  230. case "EAC3 Atmos":
  231. traktAudioFormat = "dolby_digital_plus_atmos";
  232. break;
  233. case "TrueHD Atmos":
  234. traktAudioFormat = "dolby_atmos";
  235. break;
  236. case "DTS":
  237. case "DTS-ES":
  238. traktAudioFormat = "dts";
  239. break;
  240. case "DTS-HD MA":
  241. traktAudioFormat = "dts_ma";
  242. break;
  243. case "DTS-HD HRA":
  244. traktAudioFormat = "dts_hr";
  245. break;
  246. case "DTS-X":
  247. traktAudioFormat = "dts_x";
  248. break;
  249. case "MP3":
  250. traktAudioFormat = "mp3";
  251. break;
  252. case "MP2":
  253. traktAudioFormat = "mp2";
  254. break;
  255. case "Vorbis":
  256. traktAudioFormat = "ogg";
  257. break;
  258. case "WMA":
  259. traktAudioFormat = "wma";
  260. break;
  261. case "AAC":
  262. traktAudioFormat = "aac";
  263. break;
  264. case "PCM":
  265. traktAudioFormat = "lpcm";
  266. break;
  267. case "FLAC":
  268. traktAudioFormat = "flac";
  269. break;
  270. case "Opus":
  271. traktAudioFormat = "ogg_opus";
  272. break;
  273. }
  274. return traktAudioFormat;
  275. }
  276. private string MapAudioChannels(EpisodeFile episodeFile, string audioFormat)
  277. {
  278. var audioChannels = episodeFile.MediaInfo != null ? MediaInfoFormatter.FormatAudioChannels(episodeFile.MediaInfo).ToString("0.0") : string.Empty;
  279. return audioChannels;
  280. }
  281. }
  282. }