From d59d64234fbd959cbb878847f25fa92b978b4656 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sun, 29 Jan 2017 00:13:07 +0000 Subject: [PATCH] DAMN! #435 that's a lot of code! --- Ombi.Api.Interfaces/IEmbyApi.cs | 4 +- Ombi.Api.Models/Emby/EmbyChapter.cs | 37 +++ .../Emby/EmbyEpisodeInformation.cs | 97 ++++++ Ombi.Api.Models/Emby/EmbyEpisodeItem.cs | 69 +++++ Ombi.Api.Models/Emby/EmbyExternalurl.cs | 42 +++ Ombi.Api.Models/Emby/EmbyInformation.cs | 35 +++ Ombi.Api.Models/Emby/EmbyMediaType.cs | 36 +++ Ombi.Api.Models/Emby/EmbyMediasource.cs | 59 ++++ Ombi.Api.Models/Emby/EmbyMediastream.cs | 64 ++++ Ombi.Api.Models/Emby/EmbyMediastream1.cs | 64 ++++ Ombi.Api.Models/Emby/EmbyMovieInformation.cs | 87 ++++++ Ombi.Api.Models/Emby/EmbyPerson.cs | 39 +++ Ombi.Api.Models/Emby/EmbyProviderids.cs | 41 +++ Ombi.Api.Models/Emby/EmbyRemotetrailer.cs | 36 +++ .../Emby/EmbyRequiredhttpheaders.cs | 36 +++ Ombi.Api.Models/Emby/EmbySeriesInformation.cs | 83 +++++ Ombi.Api.Models/Emby/EmbySeriesstudioinfo.cs | 37 +++ Ombi.Api.Models/Emby/EmbyStudio.cs | 37 +++ Ombi.Api.Models/Ombi.Api.Models.csproj | 17 ++ Ombi.Api/EmbyApi.cs | 60 +++- Ombi.Core.Migration/Migrations/Version2200.cs | 4 + .../SettingModels/ScheduledJobsSettings.cs | 4 + Ombi.Services/Jobs/EmbyAvailabilityChecker.cs | 2 +- Ombi.Services/Jobs/EmbyContentCacher.cs | 250 +++++++++++++++ Ombi.Services/Jobs/EmbyEpisodeCacher.cs | 167 ++++++++++ .../IEmbyAvailabilityChecker.cs | 0 .../Jobs/Interfaces/IEmbyContentCacher.cs | 14 + .../Jobs/Interfaces/IEmbyEpisodeCacher.cs | 12 + .../{ => Interfaces}/IFaultQueueHandler.cs | 0 .../{ => Interfaces}/IPlexEpisodeCacher.cs | 0 .../Jobs/{ => Interfaces}/IPlexUserChecker.cs | 0 Ombi.Services/Jobs/JobNames.cs | 2 + Ombi.Services/Ombi.Services.csproj | 12 +- .../userManagement/Directives/sidebar.html | 2 +- Ombi.UI/Jobs/Scheduler.cs | 47 ++- Ombi.UI/Modules/Admin/AdminModule.cs | 30 +- .../Admin/ScheduledJobsRunnerModule.cs | 22 +- Ombi.UI/Modules/SearchModule.cs | 286 +++++++++++++----- Ombi.UI/NinjectModules/ServicesModule.cs | 3 + Ombi.UI/Views/Search/Index.cshtml | 14 +- 40 files changed, 1747 insertions(+), 104 deletions(-) create mode 100644 Ombi.Api.Models/Emby/EmbyChapter.cs create mode 100644 Ombi.Api.Models/Emby/EmbyEpisodeInformation.cs create mode 100644 Ombi.Api.Models/Emby/EmbyEpisodeItem.cs create mode 100644 Ombi.Api.Models/Emby/EmbyExternalurl.cs create mode 100644 Ombi.Api.Models/Emby/EmbyInformation.cs create mode 100644 Ombi.Api.Models/Emby/EmbyMediaType.cs create mode 100644 Ombi.Api.Models/Emby/EmbyMediasource.cs create mode 100644 Ombi.Api.Models/Emby/EmbyMediastream.cs create mode 100644 Ombi.Api.Models/Emby/EmbyMediastream1.cs create mode 100644 Ombi.Api.Models/Emby/EmbyMovieInformation.cs create mode 100644 Ombi.Api.Models/Emby/EmbyPerson.cs create mode 100644 Ombi.Api.Models/Emby/EmbyProviderids.cs create mode 100644 Ombi.Api.Models/Emby/EmbyRemotetrailer.cs create mode 100644 Ombi.Api.Models/Emby/EmbyRequiredhttpheaders.cs create mode 100644 Ombi.Api.Models/Emby/EmbySeriesInformation.cs create mode 100644 Ombi.Api.Models/Emby/EmbySeriesstudioinfo.cs create mode 100644 Ombi.Api.Models/Emby/EmbyStudio.cs create mode 100644 Ombi.Services/Jobs/EmbyContentCacher.cs create mode 100644 Ombi.Services/Jobs/EmbyEpisodeCacher.cs rename Ombi.Services/Jobs/{ => Interfaces}/IEmbyAvailabilityChecker.cs (100%) create mode 100644 Ombi.Services/Jobs/Interfaces/IEmbyContentCacher.cs create mode 100644 Ombi.Services/Jobs/Interfaces/IEmbyEpisodeCacher.cs rename Ombi.Services/Jobs/{ => Interfaces}/IFaultQueueHandler.cs (100%) rename Ombi.Services/Jobs/{ => Interfaces}/IPlexEpisodeCacher.cs (100%) rename Ombi.Services/Jobs/{ => Interfaces}/IPlexUserChecker.cs (100%) diff --git a/Ombi.Api.Interfaces/IEmbyApi.cs b/Ombi.Api.Interfaces/IEmbyApi.cs index 58ea0087b..c02bcb2e0 100644 --- a/Ombi.Api.Interfaces/IEmbyApi.cs +++ b/Ombi.Api.Interfaces/IEmbyApi.cs @@ -6,11 +6,11 @@ namespace Ombi.Api.Interfaces { public interface IEmbyApi { - string ApiKey { get; } - EmbyItemContainer GetAllMovies(string apiKey, string userId, Uri baseUri); EmbyItemContainer GetAllShows(string apiKey, string userId, Uri baseUri); + EmbyItemContainer GetAllEpisodes(string apiKey, string userId, Uri baseUri); List GetUsers(Uri baseUri, string apiKey); EmbyItemContainer ViewLibrary(string apiKey, string userId, Uri baseUri); + EmbyInformation GetInformation(string mediaId, EmbyMediaType type, string apiKey, string userId, Uri baseUri); } } \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyChapter.cs b/Ombi.Api.Models/Emby/EmbyChapter.cs new file mode 100644 index 000000000..9677eae76 --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyChapter.cs @@ -0,0 +1,37 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: MovieInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + + +namespace Ombi.Api.Models.Emby +{ + public class EmbyChapter + { + public long StartPositionTicks { get; set; } + public string Name { get; set; } + } + +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyEpisodeInformation.cs b/Ombi.Api.Models/Emby/EmbyEpisodeInformation.cs new file mode 100644 index 000000000..49e3e0f56 --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyEpisodeInformation.cs @@ -0,0 +1,97 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: EmbyEpisodeInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System; + +namespace Ombi.Api.Models.Emby +{ + public class EmbyEpisodeInformation + { + public string Name { get; set; } + public string ServerId { get; set; } + public string Id { get; set; } + public string Etag { get; set; } + public DateTime DateCreated { get; set; } + public bool CanDelete { get; set; } + public bool CanDownload { get; set; } + public bool SupportsSync { get; set; } + public string Container { get; set; } + public string SortName { get; set; } + public DateTime PremiereDate { get; set; } + public EmbyExternalurl[] ExternalUrls { get; set; } + public EmbyMediasource[] MediaSources { get; set; } + public string Path { get; set; } + public string Overview { get; set; } + public object[] Taglines { get; set; } + public object[] Genres { get; set; } + public string[] SeriesGenres { get; set; } + public int CommunityRating { get; set; } + public int VoteCount { get; set; } + public long RunTimeTicks { get; set; } + public string PlayAccess { get; set; } + public int ProductionYear { get; set; } + public bool IsPlaceHolder { get; set; } + public int IndexNumber { get; set; } + public int ParentIndexNumber { get; set; } + public object[] RemoteTrailers { get; set; } + public EmbyProviderids ProviderIds { get; set; } + public bool IsHD { get; set; } + public bool IsFolder { get; set; } + public string ParentId { get; set; } + public string Type { get; set; } + public object[] People { get; set; } + public object[] Studios { get; set; } + public string ParentLogoItemId { get; set; } + public string ParentBackdropItemId { get; set; } + public string[] ParentBackdropImageTags { get; set; } + public int LocalTrailerCount { get; set; } + public EmbyUserdata UserData { get; set; } + public string SeriesName { get; set; } + public string SeriesId { get; set; } + public string SeasonId { get; set; } + public string DisplayPreferencesId { get; set; } + public object[] Tags { get; set; } + public object[] Keywords { get; set; } + public string SeriesPrimaryImageTag { get; set; } + public string SeasonName { get; set; } + public EmbyMediastream1[] MediaStreams { get; set; } + public string VideoType { get; set; } + public EmbyImagetags ImageTags { get; set; } + public object[] BackdropImageTags { get; set; } + public object[] ScreenshotImageTags { get; set; } + public string ParentLogoImageTag { get; set; } + public string SeriesStudio { get; set; } + public EmbySeriesstudioinfo SeriesStudioInfo { get; set; } + public string ParentThumbItemId { get; set; } + public string ParentThumbImageTag { get; set; } + public EmbyChapter[] Chapters { get; set; } + public string LocationType { get; set; } + public string MediaType { get; set; } + public object[] LockedFields { get; set; } + public bool LockData { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyEpisodeItem.cs b/Ombi.Api.Models/Emby/EmbyEpisodeItem.cs new file mode 100644 index 000000000..a86552727 --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyEpisodeItem.cs @@ -0,0 +1,69 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: EmbyEpisodeItem.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System; + +namespace Ombi.Api.Models.Emby +{ + public class EmbyEpisodeItem + { + public string Name { get; set; } + public string ServerId { get; set; } + public string Id { get; set; } + public string Container { get; set; } + public DateTime PremiereDate { get; set; } + public float CommunityRating { get; set; } + public long RunTimeTicks { get; set; } + public string PlayAccess { get; set; } + public int ProductionYear { get; set; } + public bool IsPlaceHolder { get; set; } + public int IndexNumber { get; set; } + public int ParentIndexNumber { get; set; } + public bool IsHD { get; set; } + public bool IsFolder { get; set; } + public string Type { get; set; } + public string ParentLogoItemId { get; set; } + public string ParentBackdropItemId { get; set; } + public string[] ParentBackdropImageTags { get; set; } + public int LocalTrailerCount { get; set; } + public EmbyUserdata UserData { get; set; } + public string SeriesName { get; set; } + public string SeriesId { get; set; } + public string SeasonId { get; set; } + public string SeriesPrimaryImageTag { get; set; } + public string SeasonName { get; set; } + public string VideoType { get; set; } + public EmbyImagetags ImageTags { get; set; } + public object[] BackdropImageTags { get; set; } + public string ParentLogoImageTag { get; set; } + public string ParentThumbItemId { get; set; } + public string ParentThumbImageTag { get; set; } + public string LocationType { get; set; } + public string MediaType { get; set; } + public bool HasSubtitles { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyExternalurl.cs b/Ombi.Api.Models/Emby/EmbyExternalurl.cs new file mode 100644 index 000000000..2d7de2a3c --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyExternalurl.cs @@ -0,0 +1,42 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: MovieInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + + +namespace Ombi.Api.Models.Emby +{ + public class EmbyExternalurl + { + public string Name { get; set; } + public string Url { get; set; } + } + + + + + + +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyInformation.cs b/Ombi.Api.Models/Emby/EmbyInformation.cs new file mode 100644 index 000000000..8edb432ba --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyInformation.cs @@ -0,0 +1,35 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: EmbyInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion +namespace Ombi.Api.Models.Emby +{ + public class EmbyInformation + { + public EmbySeriesInformation SeriesInformation { get; set; } + public EmbyMovieInformation MovieInformation { get; set; } + public EmbyEpisodeInformation EpisodeInformation { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyMediaType.cs b/Ombi.Api.Models/Emby/EmbyMediaType.cs new file mode 100644 index 000000000..0ec18ad4e --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyMediaType.cs @@ -0,0 +1,36 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: EmbyMediaType.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion +namespace Ombi.Api.Models.Emby +{ + public enum EmbyMediaType + { + Movie = 0, + Series = 1, + Music = 2, + Episode = 3 + } +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyMediasource.cs b/Ombi.Api.Models/Emby/EmbyMediasource.cs new file mode 100644 index 000000000..bc3f4122c --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyMediasource.cs @@ -0,0 +1,59 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: MovieInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + + +namespace Ombi.Api.Models.Emby +{ + public class EmbyMediasource + { + public string Protocol { get; set; } + public string Id { get; set; } + public string Path { get; set; } + public string Type { get; set; } + public string Container { get; set; } + public string Name { get; set; } + public bool IsRemote { get; set; } + public string ETag { get; set; } + public long RunTimeTicks { get; set; } + public bool ReadAtNativeFramerate { get; set; } + public bool SupportsTranscoding { get; set; } + public bool SupportsDirectStream { get; set; } + public bool SupportsDirectPlay { get; set; } + public bool IsInfiniteStream { get; set; } + public bool RequiresOpening { get; set; } + public bool RequiresClosing { get; set; } + public bool SupportsProbing { get; set; } + public string VideoType { get; set; } + public EmbyMediastream[] MediaStreams { get; set; } + public object[] PlayableStreamFileNames { get; set; } + public object[] Formats { get; set; } + public int Bitrate { get; set; } + public EmbyRequiredhttpheaders RequiredHttpHeaders { get; set; } + public int DefaultAudioStreamIndex { get; set; } + + } +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyMediastream.cs b/Ombi.Api.Models/Emby/EmbyMediastream.cs new file mode 100644 index 000000000..75aff476b --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyMediastream.cs @@ -0,0 +1,64 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: MovieInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + + +namespace Ombi.Api.Models.Emby +{ + public class EmbyMediastream + { + public string Codec { get; set; } + public string Language { get; set; } + public string TimeBase { get; set; } + public string CodecTimeBase { get; set; } + public string NalLengthSize { get; set; } + public bool IsInterlaced { get; set; } + public bool IsAVC { get; set; } + public int BitRate { get; set; } + public int BitDepth { get; set; } + public int RefFrames { get; set; } + public bool IsDefault { get; set; } + public bool IsForced { get; set; } + public int Height { get; set; } + public int Width { get; set; } + public float AverageFrameRate { get; set; } + public float RealFrameRate { get; set; } + public string Profile { get; set; } + public string Type { get; set; } + public string AspectRatio { get; set; } + public int Index { get; set; } + public bool IsExternal { get; set; } + public bool IsTextSubtitleStream { get; set; } + public bool SupportsExternalStream { get; set; } + public string PixelFormat { get; set; } + public int Level { get; set; } + public bool IsAnamorphic { get; set; } + public string DisplayTitle { get; set; } + public string ChannelLayout { get; set; } + public int Channels { get; set; } + public int SampleRate { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyMediastream1.cs b/Ombi.Api.Models/Emby/EmbyMediastream1.cs new file mode 100644 index 000000000..61153b900 --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyMediastream1.cs @@ -0,0 +1,64 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: MovieInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + + +namespace Ombi.Api.Models.Emby +{ + public class EmbyMediastream1 + { + public string Codec { get; set; } + public string Language { get; set; } + public string TimeBase { get; set; } + public string CodecTimeBase { get; set; } + public string NalLengthSize { get; set; } + public bool IsInterlaced { get; set; } + public bool IsAVC { get; set; } + public int BitRate { get; set; } + public int BitDepth { get; set; } + public int RefFrames { get; set; } + public bool IsDefault { get; set; } + public bool IsForced { get; set; } + public int Height { get; set; } + public int Width { get; set; } + public float AverageFrameRate { get; set; } + public float RealFrameRate { get; set; } + public string Profile { get; set; } + public string Type { get; set; } + public string AspectRatio { get; set; } + public int Index { get; set; } + public bool IsExternal { get; set; } + public bool IsTextSubtitleStream { get; set; } + public bool SupportsExternalStream { get; set; } + public string PixelFormat { get; set; } + public int Level { get; set; } + public bool IsAnamorphic { get; set; } + public string DisplayTitle { get; set; } + public string ChannelLayout { get; set; } + public int Channels { get; set; } + public int SampleRate { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyMovieInformation.cs b/Ombi.Api.Models/Emby/EmbyMovieInformation.cs new file mode 100644 index 000000000..72f8ebc02 --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyMovieInformation.cs @@ -0,0 +1,87 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: MovieInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System; + +namespace Ombi.Api.Models.Emby +{ + public class EmbyMovieInformation + { + public string Name { get; set; } + public string OriginalTitle { get; set; } + public string ServerId { get; set; } + public string Id { get; set; } + public string Etag { get; set; } + public DateTime DateCreated { get; set; } + public bool CanDelete { get; set; } + public bool CanDownload { get; set; } + public bool SupportsSync { get; set; } + public string Container { get; set; } + public string SortName { get; set; } + public DateTime PremiereDate { get; set; } + public EmbyExternalurl[] ExternalUrls { get; set; } + public EmbyMediasource[] MediaSources { get; set; } + public string[] ProductionLocations { get; set; } + public string Path { get; set; } + public string OfficialRating { get; set; } + public string Overview { get; set; } + public string[] Taglines { get; set; } + public string[] Genres { get; set; } + public float CommunityRating { get; set; } + public int VoteCount { get; set; } + public long RunTimeTicks { get; set; } + public string PlayAccess { get; set; } + public int ProductionYear { get; set; } + public bool IsPlaceHolder { get; set; } + public EmbyRemotetrailer[] RemoteTrailers { get; set; } + public EmbyProviderids ProviderIds { get; set; } + public bool IsHD { get; set; } + public bool IsFolder { get; set; } + public string ParentId { get; set; } + public string Type { get; set; } + public EmbyPerson[] People { get; set; } + public EmbyStudio[] Studios { get; set; } + public int LocalTrailerCount { get; set; } + public EmbyUserdata UserData { get; set; } + public string DisplayPreferencesId { get; set; } + public object[] Tags { get; set; } + public string[] Keywords { get; set; } + public EmbyMediastream1[] MediaStreams { get; set; } + public string VideoType { get; set; } + public EmbyImagetags ImageTags { get; set; } + public string[] BackdropImageTags { get; set; } + public object[] ScreenshotImageTags { get; set; } + public EmbyChapter[] Chapters { get; set; } + public string LocationType { get; set; } + public string MediaType { get; set; } + public string HomePageUrl { get; set; } + public int Budget { get; set; } + public int Revenue { get; set; } + public object[] LockedFields { get; set; } + public bool LockData { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyPerson.cs b/Ombi.Api.Models/Emby/EmbyPerson.cs new file mode 100644 index 000000000..7ae04d1c4 --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyPerson.cs @@ -0,0 +1,39 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: MovieInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + + +namespace Ombi.Api.Models.Emby +{ + public class EmbyPerson + { + public string Name { get; set; } + public string Id { get; set; } + public string Role { get; set; } + public string Type { get; set; } + public string PrimaryImageTag { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyProviderids.cs b/Ombi.Api.Models/Emby/EmbyProviderids.cs new file mode 100644 index 000000000..d2858850f --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyProviderids.cs @@ -0,0 +1,41 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: MovieInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + + +namespace Ombi.Api.Models.Emby +{ + public class EmbyProviderids + { + public string Tmdb { get; set; } + public string Imdb { get; set; } + public string TmdbCollection { get; set; } + + public string Tvdb { get; set; } + public string Zap2It { get; set; } + public string TvRage { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyRemotetrailer.cs b/Ombi.Api.Models/Emby/EmbyRemotetrailer.cs new file mode 100644 index 000000000..5f2d60923 --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyRemotetrailer.cs @@ -0,0 +1,36 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: MovieInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + + +namespace Ombi.Api.Models.Emby +{ + public class EmbyRemotetrailer + { + public string Url { get; set; } + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyRequiredhttpheaders.cs b/Ombi.Api.Models/Emby/EmbyRequiredhttpheaders.cs new file mode 100644 index 000000000..bd2cbef45 --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyRequiredhttpheaders.cs @@ -0,0 +1,36 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: MovieInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + + +namespace Ombi.Api.Models.Emby +{ + public class EmbyRequiredhttpheaders + { + } + + +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbySeriesInformation.cs b/Ombi.Api.Models/Emby/EmbySeriesInformation.cs new file mode 100644 index 000000000..7cc8ba9ce --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbySeriesInformation.cs @@ -0,0 +1,83 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: EmbySeriesInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System; + +namespace Ombi.Api.Models.Emby +{ + public class EmbySeriesInformation + { + public string Name { get; set; } + public string ServerId { get; set; } + public string Id { get; set; } + public string Etag { get; set; } + public DateTime DateCreated { get; set; } + public DateTime DateLastMediaAdded { get; set; } + public bool CanDelete { get; set; } + public bool CanDownload { get; set; } + public bool SupportsSync { get; set; } + public string SortName { get; set; } + public DateTime PremiereDate { get; set; } + public EmbyExternalurl[] ExternalUrls { get; set; } + public string Path { get; set; } + public string OfficialRating { get; set; } + public string Overview { get; set; } + public string ShortOverview { get; set; } + public object[] Taglines { get; set; } + public string[] Genres { get; set; } + public float CommunityRating { get; set; } + public int VoteCount { get; set; } + public long CumulativeRunTimeTicks { get; set; } + public long RunTimeTicks { get; set; } + public string PlayAccess { get; set; } + public int ProductionYear { get; set; } + public EmbyRemotetrailer[] RemoteTrailers { get; set; } + public EmbyProviderids ProviderIds { get; set; } + public bool IsFolder { get; set; } + public string ParentId { get; set; } + public string Type { get; set; } + public EmbyPerson[] People { get; set; } + public EmbyStudio[] Studios { get; set; } + public int LocalTrailerCount { get; set; } + public EmbyUserdata UserData { get; set; } + public int RecursiveItemCount { get; set; } + public int ChildCount { get; set; } + public string DisplayPreferencesId { get; set; } + public string Status { get; set; } + public string AirTime { get; set; } + public string[] AirDays { get; set; } + public object[] Tags { get; set; } + public object[] Keywords { get; set; } + public EmbyImagetags ImageTags { get; set; } + public string[] BackdropImageTags { get; set; } + public object[] ScreenshotImageTags { get; set; } + public string LocationType { get; set; } + public string HomePageUrl { get; set; } + public object[] LockedFields { get; set; } + public bool LockData { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbySeriesstudioinfo.cs b/Ombi.Api.Models/Emby/EmbySeriesstudioinfo.cs new file mode 100644 index 000000000..8b2ab437d --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbySeriesstudioinfo.cs @@ -0,0 +1,37 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: EmbyEpisodeInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + + +namespace Ombi.Api.Models.Emby +{ + public class EmbySeriesstudioinfo + { + public string Name { get; set; } + public string Id { get; set; } + } + +} \ No newline at end of file diff --git a/Ombi.Api.Models/Emby/EmbyStudio.cs b/Ombi.Api.Models/Emby/EmbyStudio.cs new file mode 100644 index 000000000..9fa11afe3 --- /dev/null +++ b/Ombi.Api.Models/Emby/EmbyStudio.cs @@ -0,0 +1,37 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: MovieInformation.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + + +namespace Ombi.Api.Models.Emby +{ + public class EmbyStudio + { + public string Name { get; set; } + public string Id { get; set; } + } + +} \ No newline at end of file diff --git a/Ombi.Api.Models/Ombi.Api.Models.csproj b/Ombi.Api.Models/Ombi.Api.Models.csproj index 1e71a7008..c0926455f 100644 --- a/Ombi.Api.Models/Ombi.Api.Models.csproj +++ b/Ombi.Api.Models/Ombi.Api.Models.csproj @@ -49,15 +49,32 @@ + + + + + + + + + + + + + + + + + diff --git a/Ombi.Api/EmbyApi.cs b/Ombi.Api/EmbyApi.cs index 151ae020a..9ca6e5845 100644 --- a/Ombi.Api/EmbyApi.cs +++ b/Ombi.Api/EmbyApi.cs @@ -36,8 +36,6 @@ namespace Ombi.Api { public class EmbyApi : IEmbyApi { - public string ApiKey => "4aa083121ab646bfa38aa5f7196056cf"; - public EmbyApi() { Api = new ApiRequest(); @@ -59,7 +57,7 @@ namespace Ombi.Api Method = Method.GET }; - AddHeaders(request, ApiKey); + AddHeaders(request, apiKey); var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => Log.Error(exception, "Exception when calling GetUsers for Emby, Retrying {0}", timespan), new[] { TimeSpan.FromSeconds (1), @@ -80,7 +78,7 @@ namespace Ombi.Api }; request.AddUrlSegment("userId", userId); - AddHeaders(request, ApiKey); + AddHeaders(request, apiKey); var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => Log.Error(exception, "Exception when calling ViewLibrary for Emby, Retrying {0}", timespan), new[] { TimeSpan.FromSeconds (1), @@ -97,6 +95,58 @@ namespace Ombi.Api return GetAll("Movie", apiKey, userId, baseUri); } + public EmbyItemContainer GetAllEpisodes(string apiKey, string userId, Uri baseUri) + { + return GetAll("Episode", apiKey, userId, baseUri); + } + + public EmbyInformation GetInformation(string mediaId, EmbyMediaType type, string apiKey, string userId, Uri baseUri) + { + var request = new RestRequest + { + Resource = "emby/users/{userId}/items/{mediaId}", + Method = Method.GET + }; + + request.AddUrlSegment("userId", userId); + request.AddUrlSegment("mediaId", mediaId); + + AddHeaders(request, apiKey); + + + var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => Log.Error(exception, "Exception when calling GetAll({1}) for Emby, Retrying {0}", timespan, type), new[] { + TimeSpan.FromSeconds (1), + TimeSpan.FromSeconds(5) + }); + + switch (type) + { + case EmbyMediaType.Movie: + return new EmbyInformation + { + MovieInformation = policy.Execute(() => Api.ExecuteJson(request, baseUri)) + }; + case EmbyMediaType.Series: + return new EmbyInformation + { + SeriesInformation = + policy.Execute(() => Api.ExecuteJson(request, baseUri)) + }; + case EmbyMediaType.Music: + break; + case EmbyMediaType.Episode: + return new EmbyInformation + { + EpisodeInformation = + policy.Execute(() => Api.ExecuteJson(request, baseUri)) + }; + default: + throw new ArgumentOutOfRangeException(nameof(type), type, null); + } + return new EmbyInformation(); + } + + public EmbyItemContainer GetAllShows(string apiKey, string userId, Uri baseUri) { return GetAll("Series", apiKey, userId, baseUri); @@ -114,7 +164,7 @@ namespace Ombi.Api request.AddQueryParameter("Recursive", true.ToString()); request.AddQueryParameter("IncludeItemTypes", type); - AddHeaders(request, ApiKey); + AddHeaders(request, apiKey); var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => Log.Error(exception, "Exception when calling GetAll({1}) for Emby, Retrying {0}", timespan, type), new[] { diff --git a/Ombi.Core.Migration/Migrations/Version2200.cs b/Ombi.Core.Migration/Migrations/Version2200.cs index d4ffc4042..ac9b5d1a7 100644 --- a/Ombi.Core.Migration/Migrations/Version2200.cs +++ b/Ombi.Core.Migration/Migrations/Version2200.cs @@ -58,16 +58,20 @@ namespace Ombi.Core.Migration.Migrations private void UpdatePlexSettings() { +#if !DEBUG var s = PlexSettings.GetSettings(); s.Enable = true; PlexSettings.SaveSettings(s); +#endif } private void UpdateCustomSettings() { + var settings = Customization.GetSettings(); settings.NewSearch = true; // Use the new search Customization.SaveSettings(settings); + } } } diff --git a/Ombi.Core/SettingModels/ScheduledJobsSettings.cs b/Ombi.Core/SettingModels/ScheduledJobsSettings.cs index a2609206b..f018cdb73 100644 --- a/Ombi.Core/SettingModels/ScheduledJobsSettings.cs +++ b/Ombi.Core/SettingModels/ScheduledJobsSettings.cs @@ -47,5 +47,9 @@ namespace Ombi.Core.SettingModels public int PlexContentCacher { get; set; } public int PlexUserChecker { get; set; } public int RadarrCacher { get; set; } + + public int EmbyEpisodeCacher { get; set; } + public int EmbyContentCacher { get; set; } + public int EmbyAvailabilityChecker { get; set; } } } \ No newline at end of file diff --git a/Ombi.Services/Jobs/EmbyAvailabilityChecker.cs b/Ombi.Services/Jobs/EmbyAvailabilityChecker.cs index 2a77718f0..467e5227e 100644 --- a/Ombi.Services/Jobs/EmbyAvailabilityChecker.cs +++ b/Ombi.Services/Jobs/EmbyAvailabilityChecker.cs @@ -148,7 +148,7 @@ namespace Ombi.Services.Jobs if (modifiedModel.Any()) { - NotificationEngine.NotifyUsers(modifiedModel, embySettings.ApiKey, NotificationType.RequestAvailable); // TODO Emby + //NotificationEngine.NotifyUsers(modifiedModel, embySettings.ApiKey, NotificationType.RequestAvailable); // TODO Emby RequestService.BatchUpdate(modifiedModel); } } diff --git a/Ombi.Services/Jobs/EmbyContentCacher.cs b/Ombi.Services/Jobs/EmbyContentCacher.cs new file mode 100644 index 000000000..ac1ba7bd2 --- /dev/null +++ b/Ombi.Services/Jobs/EmbyContentCacher.cs @@ -0,0 +1,250 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: PlexAvailabilityChecker.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System; +using System.Collections.Generic; +using Dapper; +using NLog; +using Ombi.Api.Interfaces; +using Ombi.Api.Models.Emby; +using Ombi.Core; +using Ombi.Core.SettingModels; +using Ombi.Helpers; +using Ombi.Services.Interfaces; +using Ombi.Services.Jobs.Interfaces; +using Ombi.Store.Models.Emby; +using Ombi.Store.Repository; +using Quartz; +using EmbyMediaType = Ombi.Api.Models.Emby.EmbyMediaType; + +namespace Ombi.Services.Jobs +{ + public class EmbyContentCacher : IJob, IEmbyContentCacher + { + public EmbyContentCacher(ISettingsService embySettings, IRequestService request, IEmbyApi emby, ICacheProvider cache, + IJobRecord rec, IRepository repo,IRepository content) + { + Emby = embySettings; + RequestService = request; + EmbyApi = emby; + Cache = cache; + Job = rec; + EpisodeRepo = repo; + EmbyContent = content; + } + + private ISettingsService Emby { get; } + private IRepository EpisodeRepo { get; } + private IRequestService RequestService { get; } + private static Logger Log = LogManager.GetCurrentClassLogger(); + private IEmbyApi EmbyApi { get; } + private ICacheProvider Cache { get; } + private IJobRecord Job { get; } + private IRepository EmbyContent { get; } + + public void CacheContent() + { + var embySettings = Emby.GetSettings(); + + if (!ValidateSettings(embySettings)) + { + Log.Debug("Validation of emby settings failed."); + return; + } + CachedLibraries(embySettings); + } + + + public List GetMovies() + { + var settings = Emby.GetSettings(); + return EmbyApi.GetAllMovies(settings.ApiKey, settings.AdministratorId, settings.FullUri).Items; + } + + public List GetTvShows() + { + var settings = Emby.GetSettings(); + return EmbyApi.GetAllShows(settings.ApiKey, settings.AdministratorId, settings.FullUri).Items; + } + + private void CachedLibraries(EmbySettings embySettings) + { + + if (!ValidateSettings(embySettings)) + { + Log.Warn("The settings are not configured"); + } + + try + { + var movies = GetMovies(); + + foreach (var m in movies) + { + var movieInfo = EmbyApi.GetInformation(m.Id, EmbyMediaType.Movie, embySettings.ApiKey, + embySettings.AdministratorId, embySettings.FullUri).MovieInformation; + + if (string.IsNullOrEmpty(movieInfo.ProviderIds.Imdb)) + { + Log.Error("Provider Id on movie {0} is null", movieInfo.Name); + continue; + } + + // Check if it exists + var item = EmbyContent.Custom(connection => + { + connection.Open(); + var media = connection.QueryFirstOrDefault("select * from EmbyContent where ProviderId = @ProviderId and type = @type", new { ProviderId = movieInfo.ProviderIds.Imdb, type = 0 }); + connection.Dispose(); + return media; + }); + + if (item == null) + { + // Doesn't exist, insert it + EmbyContent.Insert(new EmbyContent + { + ProviderId = movieInfo.ProviderIds.Imdb, + PremierDate = movieInfo.PremiereDate, + Title = movieInfo.Name, + Type = Store.Models.Plex.EmbyMediaType.Movie, + EmbyId = m.Id + }); + } + } + + var tv = GetTvShows(); + + foreach (var t in tv) + { + var tvInfo = EmbyApi.GetInformation(t.Id, EmbyMediaType.Series, embySettings.ApiKey, + embySettings.AdministratorId, embySettings.FullUri).SeriesInformation; + if (string.IsNullOrEmpty(tvInfo.ProviderIds?.Tvdb)) + { + Log.Error("Provider Id on tv {0} is null", t.Name); + continue; + } + + + // Check if it exists + var item = EmbyContent.Custom(connection => + { + connection.Open(); + var media = connection.QueryFirstOrDefault("select * from EmbyContent where ProviderId = @ProviderId and type = @type", new { ProviderId = tvInfo.ProviderIds.Tvdb, type = 1 }); + connection.Dispose(); + return media; + }); + + if (item == null) + { + EmbyContent.Insert(new EmbyContent + { + ProviderId = tvInfo.ProviderIds.Tvdb, + PremierDate = tvInfo.PremiereDate, + Title = tvInfo.Name, + Type = Store.Models.Plex.EmbyMediaType.Series, + EmbyId = t.Id + }); + } + } + + //TODO Emby + //var albums = GetPlexAlbums(results); + //foreach (var a in albums) + //{ + // if (string.IsNullOrEmpty(a.ProviderId)) + // { + // Log.Error("Provider Id on album {0} is null", a.Title); + // continue; + // } + + + // // Check if it exists + // var item = EmbyContent.Custom(connection => + // { + // connection.Open(); + // var media = connection.QueryFirstOrDefault("select * from EmbyContent where ProviderId = @ProviderId and type = @type", new { a.ProviderId, type = 2 }); + // connection.Dispose(); + // return media; + // }); + + // if (item == null) + // { + + // EmbyContent.Insert(new PlexContent + // { + // ProviderId = a.ProviderId, + // ReleaseYear = a.ReleaseYear ?? string.Empty, + // Title = a.Title, + // Type = Store.Models.Plex.PlexMediaType.Artist, + // Url = a.Url + // }); + // } + //} + + } + catch (Exception ex) + { + Log.Error(ex, "Failed to obtain Emby libraries"); + } + } + + + + private bool ValidateSettings(EmbySettings emby) + { + if (emby.Enable) + { + if (emby?.Ip == null || string.IsNullOrEmpty(emby?.ApiKey)) + { + Log.Warn("A setting is null, Ensure Emby is configured correctly, and we have a Emby Auth token."); + return false; + } + } + return emby.Enable; + } + + public void Execute(IJobExecutionContext context) + { + + Job.SetRunning(true, JobNames.EmbyCacher); + try + { + CacheContent(); + } + catch (Exception e) + { + Log.Error(e); + } + finally + { + Job.Record(JobNames.EmbyCacher); + Job.SetRunning(false, JobNames.EmbyCacher); + } + } + } +} \ No newline at end of file diff --git a/Ombi.Services/Jobs/EmbyEpisodeCacher.cs b/Ombi.Services/Jobs/EmbyEpisodeCacher.cs new file mode 100644 index 000000000..945908149 --- /dev/null +++ b/Ombi.Services/Jobs/EmbyEpisodeCacher.cs @@ -0,0 +1,167 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: PlexEpisodeCacher.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using NLog; +using Ombi.Api.Interfaces; +using Ombi.Api.Models.Emby; +using Ombi.Core; +using Ombi.Core.SettingModels; +using Ombi.Helpers; +using Ombi.Services.Interfaces; +using Ombi.Services.Jobs.Interfaces; +using Ombi.Store.Models.Emby; +using Ombi.Store.Repository; +using Quartz; + +namespace Ombi.Services.Jobs +{ + public class EmbyEpisodeCacher : IJob, IEmbyEpisodeCacher + { + public EmbyEpisodeCacher(ISettingsService embySettings, IEmbyApi emby, ICacheProvider cache, + IJobRecord rec, IRepository repo, ISettingsService jobs) + { + Emby = embySettings; + EmbyApi = emby; + Cache = cache; + Job = rec; + Repo = repo; + Jobs = jobs; + } + + private ISettingsService Emby { get; } + private static Logger Log = LogManager.GetCurrentClassLogger(); + private IEmbyApi EmbyApi { get; } + private ICacheProvider Cache { get; } + private IJobRecord Job { get; } + private IRepository Repo { get; } + private ISettingsService Jobs { get; } + + private const string TableName = "EmbyEpisodes"; + + + public void CacheEpisodes(EmbySettings settings) + { + var allEpisodes = EmbyApi.GetAllEpisodes(settings.ApiKey, settings.AdministratorId, settings.FullUri); + var model = new List(); + foreach (var ep in allEpisodes.Items) + { + var epInfo = EmbyApi.GetInformation(ep.Id, EmbyMediaType.Episode, settings.ApiKey, + settings.AdministratorId, settings.FullUri); + model.Add(new EmbyEpisodes + { + EmbyId = ep.Id, + EpisodeNumber = ep.IndexNumber, + SeasonNumber = ep.ParentIndexNumber, + EpisodeTitle = ep.Name, + ParentId = ep.SeriesId, + ShowTitle = ep.SeriesName, + ProviderId = epInfo.EpisodeInformation.ProviderIds.Tmdb + }); + } + + // Delete all of the current items + Repo.DeleteAll(TableName); + + // Insert the new items + var result = Repo.BatchInsert(model, TableName, typeof(EmbyEpisodes).GetPropertyNames()); + + if (!result) + { + Log.Error("Saving the emby episodes to the DB Failed"); + } + } + + public void Start() + { + try + { + var s = Emby.GetSettings(); + if (!s.EnableEpisodeSearching) + { + return; + } + + var jobs = Job.GetJobs(); + var job = jobs.FirstOrDefault(x => x.Name.Equals(JobNames.EmbyEpisodeCacher, StringComparison.CurrentCultureIgnoreCase)); + if (job != null) + { + if (job.LastRun > DateTime.Now.AddHours(-11)) // If it's been run in the last 11 hours + { + return; + } + } + Job.SetRunning(true, JobNames.EmbyEpisodeCacher); + CacheEpisodes(s); + } + catch (Exception e) + { + Log.Error(e); + } + finally + { + Job.Record(JobNames.EmbyEpisodeCacher); + Job.SetRunning(false, JobNames.EmbyEpisodeCacher); + } + } + public void Execute(IJobExecutionContext context) + { + + try + { + var s = Emby.GetSettings(); + if (!s.EnableEpisodeSearching) + { + return; + } + + var jobs = Job.GetJobs(); + var job = jobs.FirstOrDefault(x => x.Name.Equals(JobNames.EmbyEpisodeCacher, StringComparison.CurrentCultureIgnoreCase)); + if (job != null) + { + if (job.LastRun > DateTime.Now.AddHours(-11)) // If it's been run in the last 11 hours + { + return; + } + } + Job.SetRunning(true, JobNames.EmbyEpisodeCacher); + CacheEpisodes(s); + } + catch (Exception e) + { + Log.Error(e); + } + finally + { + Job.Record(JobNames.EmbyEpisodeCacher); + Job.SetRunning(false, JobNames.EmbyEpisodeCacher); + } + } + } +} \ No newline at end of file diff --git a/Ombi.Services/Jobs/IEmbyAvailabilityChecker.cs b/Ombi.Services/Jobs/Interfaces/IEmbyAvailabilityChecker.cs similarity index 100% rename from Ombi.Services/Jobs/IEmbyAvailabilityChecker.cs rename to Ombi.Services/Jobs/Interfaces/IEmbyAvailabilityChecker.cs diff --git a/Ombi.Services/Jobs/Interfaces/IEmbyContentCacher.cs b/Ombi.Services/Jobs/Interfaces/IEmbyContentCacher.cs new file mode 100644 index 000000000..8edf27a82 --- /dev/null +++ b/Ombi.Services/Jobs/Interfaces/IEmbyContentCacher.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Ombi.Api.Models.Emby; +using Quartz; + +namespace Ombi.Services.Jobs.Interfaces +{ + public interface IEmbyContentCacher + { + void CacheContent(); + void Execute(IJobExecutionContext context); + List GetMovies(); + List GetTvShows(); + } +} \ No newline at end of file diff --git a/Ombi.Services/Jobs/Interfaces/IEmbyEpisodeCacher.cs b/Ombi.Services/Jobs/Interfaces/IEmbyEpisodeCacher.cs new file mode 100644 index 000000000..b066331ca --- /dev/null +++ b/Ombi.Services/Jobs/Interfaces/IEmbyEpisodeCacher.cs @@ -0,0 +1,12 @@ +using Ombi.Core.SettingModels; +using Quartz; + +namespace Ombi.Services.Jobs.Interfaces +{ + public interface IEmbyEpisodeCacher + { + void CacheEpisodes(EmbySettings settings); + void Execute(IJobExecutionContext context); + void Start(); + } +} \ No newline at end of file diff --git a/Ombi.Services/Jobs/IFaultQueueHandler.cs b/Ombi.Services/Jobs/Interfaces/IFaultQueueHandler.cs similarity index 100% rename from Ombi.Services/Jobs/IFaultQueueHandler.cs rename to Ombi.Services/Jobs/Interfaces/IFaultQueueHandler.cs diff --git a/Ombi.Services/Jobs/IPlexEpisodeCacher.cs b/Ombi.Services/Jobs/Interfaces/IPlexEpisodeCacher.cs similarity index 100% rename from Ombi.Services/Jobs/IPlexEpisodeCacher.cs rename to Ombi.Services/Jobs/Interfaces/IPlexEpisodeCacher.cs diff --git a/Ombi.Services/Jobs/IPlexUserChecker.cs b/Ombi.Services/Jobs/Interfaces/IPlexUserChecker.cs similarity index 100% rename from Ombi.Services/Jobs/IPlexUserChecker.cs rename to Ombi.Services/Jobs/Interfaces/IPlexUserChecker.cs diff --git a/Ombi.Services/Jobs/JobNames.cs b/Ombi.Services/Jobs/JobNames.cs index 61b546cc1..006af8761 100644 --- a/Ombi.Services/Jobs/JobNames.cs +++ b/Ombi.Services/Jobs/JobNames.cs @@ -37,9 +37,11 @@ namespace Ombi.Services.Jobs public const string PlexChecker = "Plex Availability Cacher"; public const string EmbyChecker = "Emby Availability Cacher"; public const string PlexCacher = "Plex Cacher"; + public const string EmbyCacher = "Emby Cacher"; public const string StoreCleanup = "Database Cleanup"; public const string RequestLimitReset = "Request Limit Reset"; public const string EpisodeCacher = "Plex Episode Cacher"; + public const string EmbyEpisodeCacher = "Emby Episode Cacher"; public const string RecentlyAddedEmail = "Recently Added Email Notification"; public const string FaultQueueHandler = "Request Fault Queue Handler"; public const string PlexUserChecker = "Plex User Checker"; diff --git a/Ombi.Services/Ombi.Services.csproj b/Ombi.Services/Ombi.Services.csproj index dfe630a25..46cc73965 100644 --- a/Ombi.Services/Ombi.Services.csproj +++ b/Ombi.Services/Ombi.Services.csproj @@ -93,11 +93,15 @@ - - - - + + + + + + + + diff --git a/Ombi.UI/Content/app/userManagement/Directives/sidebar.html b/Ombi.UI/Content/app/userManagement/Directives/sidebar.html index 799c133fe..ed7546840 100644 --- a/Ombi.UI/Content/app/userManagement/Directives/sidebar.html +++ b/Ombi.UI/Content/app/userManagement/Directives/sidebar.html @@ -49,7 +49,7 @@ - + diff --git a/Ombi.UI/Jobs/Scheduler.cs b/Ombi.UI/Jobs/Scheduler.cs index b2c32188a..2573e756d 100644 --- a/Ombi.UI/Jobs/Scheduler.cs +++ b/Ombi.UI/Jobs/Scheduler.cs @@ -55,9 +55,6 @@ namespace Ombi.UI.Jobs private IEnumerable CreateJobs() { - var settingsService = Service.Resolve>(); - var s = settingsService.GetSettings(); - var jobs = new List(); var jobList = new List @@ -76,6 +73,11 @@ namespace Ombi.UI.Jobs JobBuilder.Create().WithIdentity("RecentlyAddedModel", "Email").Build(), JobBuilder.Create().WithIdentity("FaultQueueHandler", "Fault").Build(), JobBuilder.Create().WithIdentity("RadarrCacher", "Cache").Build(), + + + JobBuilder.Create().WithIdentity("EmbyEpisodeCacher", "Emby").Build(), + JobBuilder.Create().WithIdentity("EmbyAvailabilityChecker", "Emby").Build(), + JobBuilder.Create().WithIdentity("EmbyContentCacher", "Emby").Build(), }; jobs.AddRange(jobList); @@ -175,6 +177,18 @@ namespace Ombi.UI.Jobs { s.RadarrCacher = 60; } + if (s.EmbyContentCacher == 0) + { + s.EmbyContentCacher = 60; + } + if (s.EmbyAvailabilityChecker == 0) + { + s.EmbyAvailabilityChecker = 60; + } + if (s.EmbyEpisodeCacher == 0) + { + s.EmbyEpisodeCacher = 11; + } var triggers = new List(); @@ -280,6 +294,30 @@ namespace Ombi.UI.Jobs .WithSimpleSchedule(x => x.WithIntervalInHours(s.FaultQueueHandler).RepeatForever()) .Build(); + + //Emby + var embyEpisode = + TriggerBuilder.Create() + .WithIdentity("EmbyEpisodeCacher", "Emby") + //.StartAt(DateBuilder.FutureDate(10, IntervalUnit.Minute)) + .StartAt(DateBuilder.FutureDate(10, IntervalUnit.Minute)) + .WithSimpleSchedule(x => x.WithIntervalInHours(s.EmbyEpisodeCacher).RepeatForever()) + .Build(); + + var embyContentCacher = + TriggerBuilder.Create() + .WithIdentity("EmbyContentCacher", "Emby") + .StartNow() + .WithSimpleSchedule(x => x.WithIntervalInHours(s.EmbyContentCacher).RepeatForever()) + .Build(); + + var embyAvailabilityChecker = + TriggerBuilder.Create() + .WithIdentity("EmbyAvailabilityChecker", "Emby") + .StartAt(DateBuilder.FutureDate(5, IntervalUnit.Minute)) + .WithSimpleSchedule(x => x.WithIntervalInHours(s.EmbyAvailabilityChecker).RepeatForever()) + .Build(); + triggers.Add(rencentlyAdded); triggers.Add(plexAvailabilityChecker); triggers.Add(srCacher); @@ -294,6 +332,9 @@ namespace Ombi.UI.Jobs triggers.Add(plexCacher); triggers.Add(plexUserChecker); triggers.Add(radarrCacher); + triggers.Add(embyEpisode); + triggers.Add(embyAvailabilityChecker); + triggers.Add(embyContentCacher); return triggers; } diff --git a/Ombi.UI/Modules/Admin/AdminModule.cs b/Ombi.UI/Modules/Admin/AdminModule.cs index effea7815..94184521e 100644 --- a/Ombi.UI/Modules/Admin/AdminModule.cs +++ b/Ombi.UI/Modules/Admin/AdminModule.cs @@ -447,11 +447,19 @@ namespace Ombi.UI.Modules.Admin return Response.AsJson(valid.SendJsonError()); } - var embySettings = await EmbySettings.GetSettingsAsync(); - - if (embySettings.Enable) + + if (plexSettings.Enable) { - return Response.AsJson(new JsonResponseModel { Result = false, Message = "Emby is enabled, we cannot enable Plex and Emby" }); + var embySettings = await EmbySettings.GetSettingsAsync(); + if (embySettings.Enable) + { + return + Response.AsJson(new JsonResponseModel + { + Result = false, + Message = "Emby is enabled, we cannot enable Plex and Emby" + }); + } } if (string.IsNullOrEmpty(plexSettings.MachineIdentifier)) @@ -485,10 +493,18 @@ namespace Ombi.UI.Modules.Admin return Response.AsJson(valid.SendJsonError()); } - var plexSettings = await PlexService.GetSettingsAsync(); - if (plexSettings.Enable) + if (emby.Enable) { - return Response.AsJson(new JsonResponseModel { Result = false, Message = "Plex is enabled, we cannot enable Plex and Emby" }); + var plexSettings = await PlexService.GetSettingsAsync(); + if (plexSettings.Enable) + { + return + Response.AsJson(new JsonResponseModel + { + Result = false, + Message = "Plex is enabled, we cannot enable Plex and Emby" + }); + } } // Get the users diff --git a/Ombi.UI/Modules/Admin/ScheduledJobsRunnerModule.cs b/Ombi.UI/Modules/Admin/ScheduledJobsRunnerModule.cs index a21ebd16a..52a16b01d 100644 --- a/Ombi.UI/Modules/Admin/ScheduledJobsRunnerModule.cs +++ b/Ombi.UI/Modules/Admin/ScheduledJobsRunnerModule.cs @@ -33,6 +33,7 @@ using Ombi.Core.SettingModels; using Ombi.Helpers.Permissions; using Ombi.Services.Interfaces; using Ombi.Services.Jobs; +using Ombi.Services.Jobs.Interfaces; using Ombi.UI.Models; using ISecurityExtensions = Ombi.Core.ISecurityExtensions; @@ -44,7 +45,8 @@ namespace Ombi.UI.Modules.Admin ISecurityExtensions security, IPlexContentCacher contentCacher, ISonarrCacher sonarrCacher, IWatcherCacher watcherCacher, IRadarrCacher radarrCacher, ICouchPotatoCacher cpCacher, IStoreBackup store, ISickRageCacher srCacher, IAvailabilityChecker plexChceker, IStoreCleanup cleanup, IUserRequestLimitResetter requestLimit, IPlexEpisodeCacher episodeCacher, IRecentlyAdded recentlyAdded, - IFaultQueueHandler faultQueueHandler, IPlexUserChecker plexUserChecker) : base("admin", settingsService, security) + IFaultQueueHandler faultQueueHandler, IPlexUserChecker plexUserChecker, IEmbyAvailabilityChecker embyAvailabilityChecker, IEmbyEpisodeCacher embyEpisode, + IEmbyContentCacher embyContentCacher) : base("admin", settingsService, security) { Before += (ctx) => Security.AdminLoginRedirect(Permissions.Administrator, ctx); @@ -62,6 +64,9 @@ namespace Ombi.UI.Modules.Admin RecentlyAdded = recentlyAdded; FaultQueueHandler = faultQueueHandler; PlexUserChecker = plexUserChecker; + EmbyAvailabilityChecker = embyAvailabilityChecker; + EmbyContentCacher = embyContentCacher; + EmbyEpisodeCacher = embyEpisode; Post["/schedulerun", true] = async (x, ct) => await ScheduleRun((string)Request.Form.key); } @@ -80,6 +85,9 @@ namespace Ombi.UI.Modules.Admin private IRecentlyAdded RecentlyAdded { get; } private IFaultQueueHandler FaultQueueHandler { get; } private IPlexUserChecker PlexUserChecker { get; } + private IEmbyAvailabilityChecker EmbyAvailabilityChecker { get; } + private IEmbyContentCacher EmbyContentCacher { get; } + private IEmbyEpisodeCacher EmbyEpisodeCacher { get; } private async Task ScheduleRun(string key) @@ -142,6 +150,18 @@ namespace Ombi.UI.Modules.Admin { RequestLimit.Start(); } + if (key.Equals(JobNames.EmbyEpisodeCacher, StringComparison.CurrentCultureIgnoreCase)) + { + EmbyEpisodeCacher.Start(); + } + if (key.Equals(JobNames.EmbyCacher, StringComparison.CurrentCultureIgnoreCase)) + { + EmbyContentCacher.CacheContent(); + } + if (key.Equals(JobNames.EmbyChecker, StringComparison.CurrentCultureIgnoreCase)) + { + EmbyAvailabilityChecker.CheckAndUpdateAll(); + } return Response.AsJson(new JsonResponseModel { Result = true }); diff --git a/Ombi.UI/Modules/SearchModule.cs b/Ombi.UI/Modules/SearchModule.cs index 4aa29c316..20b43097d 100644 --- a/Ombi.UI/Modules/SearchModule.cs +++ b/Ombi.UI/Modules/SearchModule.cs @@ -50,9 +50,11 @@ using Ombi.Helpers; using Ombi.Helpers.Analytics; using Ombi.Helpers.Permissions; using Ombi.Services.Interfaces; +using Ombi.Services.Jobs; using Ombi.Services.Notification; using Ombi.Store; using Ombi.Store.Models; +using Ombi.Store.Models.Emby; using Ombi.Store.Models.Plex; using Ombi.Store.Repository; using Ombi.UI.Helpers; @@ -68,7 +70,7 @@ namespace Ombi.UI.Modules public class SearchModule : BaseAuthModule { public SearchModule(ICacheProvider cache, - ISettingsService prSettings, IAvailabilityChecker checker, + ISettingsService prSettings, IAvailabilityChecker plexChecker, IRequestService request, ISonarrApi sonarrApi, ISettingsService sonarrSettings, ISettingsService sickRageService, ISickRageApi srApi, INotificationService notify, IMusicBrainzApi mbApi, IHeadphonesApi hpApi, @@ -77,7 +79,8 @@ namespace Ombi.UI.Modules ISettingsService plexService, ISettingsService auth, IRepository u, ISettingsService email, IIssueService issue, IAnalytics a, IRepository rl, ITransientFaultQueue tfQueue, IRepository content, - ISecurityExtensions security, IMovieSender movieSender, IRadarrCacher radarrCacher, ITraktApi traktApi, ISettingsService cus) + ISecurityExtensions security, IMovieSender movieSender, IRadarrCacher radarrCacher, ITraktApi traktApi, ISettingsService cus, + IEmbyAvailabilityChecker embyChecker, IRepository embyContent, ISettingsService embySettings) : base("search", prSettings, security) { Auth = auth; @@ -86,7 +89,7 @@ namespace Ombi.UI.Modules PrService = prSettings; MovieApi = new TheMovieDbApi(); Cache = cache; - Checker = checker; + PlexChecker = plexChecker; CpCacher = cpCacher; SonarrCacher = sonarrCacher; SickRageCacher = sickRageCacher; @@ -112,6 +115,9 @@ namespace Ombi.UI.Modules RadarrCacher = radarrCacher; TraktApi = traktApi; CustomizationSettings = cus; + EmbyChecker = embyChecker; + EmbyContentRepository = embyContent; + EmbySettings = embySettings; Get["SearchIndex", "/", true] = async (x, ct) => await RequestLoad(); @@ -143,6 +149,7 @@ namespace Ombi.UI.Modules private IWatcherCacher WatcherCacher { get; } private IMovieSender MovieSender { get; } private IRepository PlexContentRepository { get; } + private IRepository EmbyContentRepository { get; } private TvMazeApi TvApi { get; } private IPlexApi PlexApi { get; } private TheMovieDbApi MovieApi { get; } @@ -152,13 +159,15 @@ namespace Ombi.UI.Modules private IRequestService RequestService { get; } private ICacheProvider Cache { get; } private ISettingsService Auth { get; } + private ISettingsService EmbySettings { get; } private ISettingsService PlexService { get; } private ISettingsService PrService { get; } private ISettingsService SonarrService { get; } private ISettingsService SickRageService { get; } private ISettingsService HeadphonesService { get; } private ISettingsService EmailNotificationSettings { get; } - private IAvailabilityChecker Checker { get; } + private IAvailabilityChecker PlexChecker { get; } + private IEmbyAvailabilityChecker EmbyChecker { get; } private ICouchPotatoCacher CpCacher { get; } private ISonarrCacher SonarrCacher { get; } private ISickRageCacher SickRageCacher { get; } @@ -269,8 +278,7 @@ namespace Ombi.UI.Modules var cpCached = CpCacher.QueuedIds(); var watcherCached = WatcherCacher.QueuedIds(); var radarrCached = RadarrCacher.QueuedIds(); - var content = PlexContentRepository.GetAll(); - var plexMovies = Checker.GetPlexMovies(content); + var viewMovies = new List(); var counter = 0; foreach (var movie in apiMovies) @@ -292,8 +300,7 @@ namespace Ombi.UI.Modules VoteAverage = movie.VoteAverage, VoteCount = movie.VoteCount }; - - var imdbId = string.Empty; + if (counter <= 5) // Let's only do it for the first 5 items { var movieInfo = MovieApi.GetMovieInformationWithVideos(movie.Id); @@ -313,14 +320,35 @@ namespace Ombi.UI.Modules counter++; } - var canSee = CanUserSeeThisRequest(viewMovie.Id, Security.HasPermissions(User, Permissions.UsersCanViewOnlyOwnRequests), dbMovies); - var plexMovie = Checker.GetMovie(plexMovies.ToArray(), movie.Title, movie.ReleaseDate?.Year.ToString(), - imdbId); - if (plexMovie != null) + + var plexSettings = await PlexService.GetSettingsAsync(); + var embySettings = await EmbySettings.GetSettingsAsync(); + if (plexSettings.Enable) { - viewMovie.Available = true; - viewMovie.PlexUrl = plexMovie.Url; + var content = PlexContentRepository.GetAll(); + var plexMovies = PlexChecker.GetPlexMovies(content); + + var plexMovie = PlexChecker.GetMovie(plexMovies.ToArray(), movie.Title, + movie.ReleaseDate?.Year.ToString(), + viewMovie.ImdbId); + if (plexMovie != null) + { + viewMovie.Available = true; + viewMovie.PlexUrl = plexMovie.Url; + } + } + if (embySettings.Enable) + { + var embyContent = EmbyContentRepository.GetAll(); + var embyMovies = EmbyChecker.GetEmbyMovies(embyContent); + + var embyMovie = EmbyChecker.GetMovie(embyMovies.ToArray(), movie.Title, + movie.ReleaseDate?.Year.ToString(), viewMovie.ImdbId); + if (embyMovie != null) + { + viewMovie.Available = true; + } } else if (dbMovies.ContainsKey(movie.Id) && canSee) // compare to the requests db { @@ -335,7 +363,7 @@ namespace Ombi.UI.Modules viewMovie.Approved = true; viewMovie.Requested = true; } - else if(watcherCached.Contains(imdbId) && canSee) // compare to the watcher db + else if (watcherCached.Contains(viewMovie.ImdbId) && canSee) // compare to the watcher db { viewMovie.Approved = true; viewMovie.Requested = true; @@ -507,7 +535,7 @@ namespace Ombi.UI.Modules var sonarrCached = SonarrCacher.QueuedIds().ToList(); var sickRageCache = SickRageCacher.QueuedIds(); // consider just merging sonarr/sickrage arrays var content = PlexContentRepository.GetAll(); - var plexTvShows = Checker.GetPlexTvShows(content).ToList(); + var plexTvShows = PlexChecker.GetPlexTvShows(content).ToList(); foreach (var show in shows) { @@ -516,7 +544,7 @@ namespace Ombi.UI.Modules providerId = show.Id.ToString(); } - var plexShow = Checker.GetTvShow(plexTvShows.ToArray(), show.SeriesName, show.FirstAired?.Substring(0, 4), + var plexShow = PlexChecker.GetTvShow(plexTvShows.ToArray(), show.SeriesName, show.FirstAired?.Substring(0, 4), providerId); if (plexShow != null) { @@ -571,7 +599,7 @@ namespace Ombi.UI.Modules var sonarrCached = SonarrCacher.QueuedIds(); var sickRageCache = SickRageCacher.QueuedIds(); // consider just merging sonarr/sickrage arrays var content = PlexContentRepository.GetAll(); - var plexTvShows = Checker.GetPlexTvShows(content); + var plexTvShows = PlexChecker.GetPlexTvShows(content); var viewTv = new List(); foreach (var t in apiTv) @@ -611,7 +639,7 @@ namespace Ombi.UI.Modules providerId = viewT.Id.ToString(); } - var plexShow = Checker.GetTvShow(plexTvShows.ToArray(), t.show.name, t.show.premiered?.Substring(0, 4), + var plexShow = PlexChecker.GetTvShow(plexTvShows.ToArray(), t.show.name, t.show.premiered?.Substring(0, 4), providerId); if (plexShow != null) { @@ -658,7 +686,7 @@ namespace Ombi.UI.Modules var dbAlbum = allResults.ToDictionary(x => x.MusicBrainzId); var content = PlexContentRepository.GetAll(); - var plexAlbums = Checker.GetPlexAlbums(content); + var plexAlbums = PlexChecker.GetPlexAlbums(content); var viewAlbum = new List(); foreach (var a in apiAlbums) @@ -678,7 +706,7 @@ namespace Ombi.UI.Modules DateTime release; DateTimeHelper.CustomParse(a.ReleaseEvents?.FirstOrDefault()?.date, out release); var artist = a.ArtistCredit?.FirstOrDefault()?.artist; - var plexAlbum = Checker.GetAlbum(plexAlbums.ToArray(), a.title, release.ToString("yyyy"), artist?.name); + var plexAlbum = PlexChecker.GetAlbum(plexAlbums.ToArray(), a.title, release.ToString("yyyy"), artist?.name); if (plexAlbum != null) { viewA.Available = true; @@ -760,8 +788,8 @@ namespace Ombi.UI.Modules { var content = PlexContentRepository.GetAll(); - var movies = Checker.GetPlexMovies(content); - if (Checker.IsMovieAvailable(movies.ToArray(), movieInfo.Title, movieInfo.ReleaseDate?.Year.ToString())) + var movies = PlexChecker.GetPlexMovies(content); + if (PlexChecker.IsMovieAvailable(movies.ToArray(), movieInfo.Title, movieInfo.ReleaseDate?.Year.ToString())) { return Response.AsJson(new JsonResponseModel @@ -1043,67 +1071,136 @@ namespace Ombi.UI.Modules try { - var content = PlexContentRepository.GetAll(); - var shows = Checker.GetPlexTvShows(content); - var providerId = string.Empty; var plexSettings = await PlexService.GetSettingsAsync(); - if (plexSettings.AdvancedSearch) - { - providerId = showId.ToString(); - } - if (episodeRequest) + if (plexSettings.Enable) { - var cachedEpisodesTask = await Checker.GetEpisodes(); - var cachedEpisodes = cachedEpisodesTask.ToList(); - foreach (var d in difference) // difference is from an existing request + var content = PlexContentRepository.GetAll(); + var shows = PlexChecker.GetPlexTvShows(content); + + var providerId = string.Empty; + if (plexSettings.AdvancedSearch) { - if ( - cachedEpisodes.Any( - x => - x.SeasonNumber == d.SeasonNumber && x.EpisodeNumber == d.EpisodeNumber && - x.ProviderId == providerId)) + providerId = showId.ToString(); + } + if (episodeRequest) + { + var cachedEpisodesTask = await PlexChecker.GetEpisodes(); + var cachedEpisodes = cachedEpisodesTask.ToList(); + foreach (var d in difference) // difference is from an existing request + { + if ( + cachedEpisodes.Any( + x => + x.SeasonNumber == d.SeasonNumber && x.EpisodeNumber == d.EpisodeNumber && + x.ProviderId == providerId)) + { + return + Response.AsJson(new JsonResponseModel + { + Result = false, + Message = + $"{fullShowName} {d.SeasonNumber} - {d.EpisodeNumber} {Resources.UI.Search_AlreadyInPlex}" + }); + } + } + + var diff = await GetEpisodeRequestDifference(showId, model); + model.Episodes = diff.ToList(); + } + else + { + if (plexSettings.EnableTvEpisodeSearching) + { + foreach (var s in showInfo.Season) + { + var result = PlexChecker.IsEpisodeAvailable(showId.ToString(), s.SeasonNumber, + s.EpisodeNumber); + if (result) + { + return + Response.AsJson(new JsonResponseModel + { + Result = false, + Message = $"{fullShowName} {Resources.UI.Search_AlreadyInPlex}" + }); + } + } + } + else if (PlexChecker.IsTvShowAvailable(shows.ToArray(), showInfo.name, + showInfo.premiered?.Substring(0, 4), + providerId, model.SeasonList)) { return Response.AsJson(new JsonResponseModel { Result = false, - Message = - $"{fullShowName} {d.SeasonNumber} - {d.EpisodeNumber} {Resources.UI.Search_AlreadyInPlex}" + Message = $"{fullShowName} {Resources.UI.Search_AlreadyInPlex}" }); } } - - var diff = await GetEpisodeRequestDifference(showId, model); - model.Episodes = diff.ToList(); } - else + var embySettings = await EmbySettings.GetSettingsAsync(); + if (embySettings.Enable) { - if (plexSettings.EnableTvEpisodeSearching) + var embyContent = EmbyContentRepository.GetAll(); + var embyMovies = EmbyChecker.GetEmbyTvShows(embyContent); + var providerId = showId.ToString(); + if (episodeRequest) { - foreach (var s in showInfo.Season) + var cachedEpisodesTask = await EmbyChecker.GetEpisodes(); + var cachedEpisodes = cachedEpisodesTask.ToList(); + foreach (var d in difference) // difference is from an existing request { - var result = Checker.IsEpisodeAvailable(showId.ToString(), s.SeasonNumber, s.EpisodeNumber); - if (result) + if ( + cachedEpisodes.Any( + x => + x.SeasonNumber == d.SeasonNumber && x.EpisodeNumber == d.EpisodeNumber && + x.ProviderId == providerId)) { return Response.AsJson(new JsonResponseModel { Result = false, - Message = $"{fullShowName} {Resources.UI.Search_AlreadyInPlex}" + Message = + $"{fullShowName} {d.SeasonNumber} - {d.EpisodeNumber} {Resources.UI.Search_AlreadyInPlex}" }); } } + + var diff = await GetEpisodeRequestDifference(showId, model); + model.Episodes = diff.ToList(); } - else if (Checker.IsTvShowAvailable(shows.ToArray(), showInfo.name, showInfo.premiered?.Substring(0, 4), - providerId, model.SeasonList)) + else { - return - Response.AsJson(new JsonResponseModel + if (embySettings.EnableEpisodeSearching) + { + foreach (var s in showInfo.Season) { - Result = false, - Message = $"{fullShowName} {Resources.UI.Search_AlreadyInPlex}" - }); - } + var result = EmbyChecker.IsEpisodeAvailable(showId.ToString(), s.SeasonNumber, + s.EpisodeNumber); + if (result) + { + return + Response.AsJson(new JsonResponseModel + { + Result = false, + Message = $"{fullShowName} is already in Emby!" + }); + } + } + } + else if (EmbyChecker.IsTvShowAvailable(embyMovies.ToArray(), showInfo.name, + showInfo.premiered?.Substring(0, 4), + providerId, model.SeasonList)) + { + return + Response.AsJson(new JsonResponseModel + { + Result = false, + Message = $"{fullShowName} is already in Emby!" + }); + } + } } } catch (Exception) @@ -1261,8 +1358,8 @@ namespace Ombi.UI.Modules var content = PlexContentRepository.GetAll(); - var albums = Checker.GetPlexAlbums(content); - var alreadyInPlex = Checker.IsAlbumAvailable(albums.ToArray(), albumInfo.title, release.ToString("yyyy"), + var albums = PlexChecker.GetPlexAlbums(content); + var alreadyInPlex = PlexChecker.IsAlbumAvailable(albums.ToArray(), albumInfo.title, release.ToString("yyyy"), artist.name); if (alreadyInPlex) @@ -1390,7 +1487,8 @@ namespace Ombi.UI.Modules var existingRequest = requests.FirstOrDefault(x => x.Type == RequestType.TvShow && x.TvDbId == providerId.ToString()); var show = await Task.Run(() => TvApi.ShowLookupByTheTvDbId(providerId)); - var tvMaxeEpisodes = await Task.Run(() => TvApi.EpisodeLookup(show.id)); + var tvMazeEpisodesTask = await Task.Run(() => TvApi.EpisodeLookup(show.id)); + var tvMazeEpisodes = tvMazeEpisodesTask.ToList(); var sonarrEpisodes = new List(); if (sonarrEnabled) @@ -1400,26 +1498,59 @@ namespace Ombi.UI.Modules sonarrEpisodes = sonarrEp?.ToList() ?? new List(); } - var plexCacheTask = await Checker.GetEpisodes(providerId); - var plexCache = plexCacheTask.ToList(); - foreach (var ep in tvMaxeEpisodes) + var plexSettings = await PlexService.GetSettingsAsync(); + if (plexSettings.Enable) { - var requested = existingRequest?.Episodes - .Any(episodesModel => - ep.number == episodesModel.EpisodeNumber && ep.season == episodesModel.SeasonNumber) ?? false; + var plexCacheTask = await PlexChecker.GetEpisodes(providerId); + var plexCache = plexCacheTask.ToList(); + foreach (var ep in tvMazeEpisodes) + { + var requested = existingRequest?.Episodes + .Any(episodesModel => + ep.number == episodesModel.EpisodeNumber && + ep.season == episodesModel.SeasonNumber) ?? false; - var alreadyInPlex = plexCache.Any(x => x.EpisodeNumber == ep.number && x.SeasonNumber == ep.season); - var inSonarr = sonarrEpisodes.Any(x => x.seasonNumber == ep.season && x.episodeNumber == ep.number && x.hasFile); + var alreadyInPlex = plexCache.Any(x => x.EpisodeNumber == ep.number && x.SeasonNumber == ep.season); + var inSonarr = + sonarrEpisodes.Any(x => x.seasonNumber == ep.season && x.episodeNumber == ep.number && x.hasFile); - model.Add(new EpisodeListViewModel + model.Add(new EpisodeListViewModel + { + Id = show.id, + SeasonNumber = ep.season, + EpisodeNumber = ep.number, + Requested = requested || alreadyInPlex || inSonarr, + Name = ep.name, + EpisodeId = ep.id + }); + } + } + var embySettings = await EmbySettings.GetSettingsAsync(); + if (embySettings.Enable) + { + var embyCacheTask = await EmbyChecker.GetEpisodes(providerId); + var cache = embyCacheTask.ToList(); + foreach (var ep in tvMazeEpisodes) { - Id = show.id, - SeasonNumber = ep.season, - EpisodeNumber = ep.number, - Requested = requested || alreadyInPlex || inSonarr, - Name = ep.name, - EpisodeId = ep.id - }); + var requested = existingRequest?.Episodes + .Any(episodesModel => + ep.number == episodesModel.EpisodeNumber && + ep.season == episodesModel.SeasonNumber) ?? false; + + var alreadyInEmby = cache.Any(x => x.EpisodeNumber == ep.number && x.SeasonNumber == ep.season); + var inSonarr = + sonarrEpisodes.Any(x => x.seasonNumber == ep.season && x.episodeNumber == ep.number && x.hasFile); + + model.Add(new EpisodeListViewModel + { + Id = show.id, + SeasonNumber = ep.season, + EpisodeNumber = ep.number, + Requested = requested || alreadyInEmby || inSonarr, + Name = ep.name, + EpisodeId = ep.id + }); + } } return model; @@ -1651,3 +1782,4 @@ namespace Ombi.UI.Modules } } } + diff --git a/Ombi.UI/NinjectModules/ServicesModule.cs b/Ombi.UI/NinjectModules/ServicesModule.cs index 31ad2c1d2..a573e1ddf 100644 --- a/Ombi.UI/NinjectModules/ServicesModule.cs +++ b/Ombi.UI/NinjectModules/ServicesModule.cs @@ -31,6 +31,7 @@ using Ombi.Core.Queue; using Ombi.Helpers.Analytics; using Ombi.Services.Interfaces; using Ombi.Services.Jobs; +using Ombi.Services.Jobs.Interfaces; using Ombi.UI.Jobs; using Quartz; using Quartz.Impl; @@ -60,6 +61,8 @@ namespace Ombi.UI.NinjectModules Bind().To(); Bind().To(); + Bind().To(); + Bind().To(); Bind().To(); diff --git a/Ombi.UI/Views/Search/Index.cshtml b/Ombi.UI/Views/Search/Index.cshtml index db5b25dd9..cef2e73e8 100644 --- a/Ombi.UI/Views/Search/Index.cshtml +++ b/Ombi.UI/Views/Search/Index.cshtml @@ -161,7 +161,7 @@
{{#if available}} - @UI.Search_Available_on_plex + @UI.Search_Available {{else}} {{#if approved}} @UI.Search_Processing_Request @@ -207,7 +207,9 @@

+ {{#if url}} @UI.Search_ViewInPlex + {{/if}} {{else}} {{#if_eq requested true}} @@ -325,7 +327,7 @@ Release Date: {{releaseDate}} {{/if}} {{#if available}} - @UI.Search_Available_on_plex + @UI.Search_Available {{else}} {{#if approved}} @UI.Search_Processing_Request @@ -357,9 +359,11 @@ {{#if_eq type "movie"}} {{#if_eq available true}} + {{#if url}}

@UI.Search_ViewInPlex + {{/if}} {{else}} {{#if_eq requested true}} @@ -396,9 +400,11 @@
{{/if_eq}} {{#if available}} + {{#if url}}
@UI.Search_ViewInPlex {{/if}} + {{/if}} {{/if_eq}} {{/if_eq}} @@ -432,7 +438,7 @@ -