DAMN! #435 that's a lot of code!

pull/1029/head
tidusjar 8 years ago
parent 868301f552
commit d59d64234f

@ -6,11 +6,11 @@ namespace Ombi.Api.Interfaces
{
public interface IEmbyApi
{
string ApiKey { get; }
EmbyItemContainer<EmbyMovieItem> GetAllMovies(string apiKey, string userId, Uri baseUri);
EmbyItemContainer<EmbySeriesItem> GetAllShows(string apiKey, string userId, Uri baseUri);
EmbyItemContainer<EmbyEpisodeItem> GetAllEpisodes(string apiKey, string userId, Uri baseUri);
List<EmbyUser> GetUsers(Uri baseUri, string apiKey);
EmbyItemContainer<EmbyLibrary> ViewLibrary(string apiKey, string userId, Uri baseUri);
EmbyInformation GetInformation(string mediaId, EmbyMediaType type, string apiKey, string userId, Uri baseUri);
}
}

@ -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; }
}
}

@ -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; }
}
}

@ -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; }
}
}

@ -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; }
}
}

@ -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; }
}
}

@ -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
}
}

@ -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; }
}
}

@ -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; }
}
}

@ -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; }
}
}

@ -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; }
}
}

@ -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; }
}
}

@ -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; }
}
}

@ -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; }
}
}

@ -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
{
}
}

@ -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; }
}
}

@ -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; }
}
}

@ -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; }
}
}

@ -49,15 +49,32 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Emby\EmbyChapter.cs" />
<Compile Include="Emby\EmbyConfiguration.cs" />
<Compile Include="Emby\EmbyEpisodeInformation.cs" />
<Compile Include="Emby\EmbyEpisodeItem.cs" />
<Compile Include="Emby\EmbyExternalurl.cs" />
<Compile Include="Emby\EmbyImagetags.cs" />
<Compile Include="Emby\EmbyInformation.cs" />
<Compile Include="Emby\EmbyItem.cs" />
<Compile Include="Emby\EmbyItemContainer.cs" />
<Compile Include="Emby\EmbyMediasource.cs" />
<Compile Include="Emby\EmbyMediastream.cs" />
<Compile Include="Emby\EmbyMediastream1.cs" />
<Compile Include="Emby\EmbyMediaType.cs" />
<Compile Include="Emby\EmbyMovieItem.cs" />
<Compile Include="Emby\EmbyPerson.cs" />
<Compile Include="Emby\EmbyPolicy.cs" />
<Compile Include="Emby\EmbyProviderids.cs" />
<Compile Include="Emby\EmbyRemotetrailer.cs" />
<Compile Include="Emby\EmbyRequiredhttpheaders.cs" />
<Compile Include="Emby\EmbySeriesInformation.cs" />
<Compile Include="Emby\EmbySeriesItem.cs" />
<Compile Include="Emby\EmbySeriesstudioinfo.cs" />
<Compile Include="Emby\EmbyStudio.cs" />
<Compile Include="Emby\EmbyUser.cs" />
<Compile Include="Emby\EmbyUserdata.cs" />
<Compile Include="Emby\EmbyMovieInformation.cs" />
<Compile Include="Movie\CouchPotatoAdd.cs" />
<Compile Include="Movie\CouchPotatoMovies.cs" />
<Compile Include="Movie\CouchPotatoProfiles.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<EmbyMovieItem>("Movie", apiKey, userId, baseUri);
}
public EmbyItemContainer<EmbyEpisodeItem> GetAllEpisodes(string apiKey, string userId, Uri baseUri)
{
return GetAll<EmbyEpisodeItem>("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<T>({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<EmbyMovieInformation>(request, baseUri))
};
case EmbyMediaType.Series:
return new EmbyInformation
{
SeriesInformation =
policy.Execute(() => Api.ExecuteJson<EmbySeriesInformation>(request, baseUri))
};
case EmbyMediaType.Music:
break;
case EmbyMediaType.Episode:
return new EmbyInformation
{
EpisodeInformation =
policy.Execute(() => Api.ExecuteJson<EmbyEpisodeInformation>(request, baseUri))
};
default:
throw new ArgumentOutOfRangeException(nameof(type), type, null);
}
return new EmbyInformation();
}
public EmbyItemContainer<EmbySeriesItem> GetAllShows(string apiKey, string userId, Uri baseUri)
{
return GetAll<EmbySeriesItem>("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<T>({1}) for Emby, Retrying {0}", timespan, type), new[] {

@ -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);
}
}
}

@ -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; }
}
}

@ -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);
}
}

@ -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> embySettings, IRequestService request, IEmbyApi emby, ICacheProvider cache,
IJobRecord rec, IRepository<EmbyEpisodes> repo,IRepository<EmbyContent> content)
{
Emby = embySettings;
RequestService = request;
EmbyApi = emby;
Cache = cache;
Job = rec;
EpisodeRepo = repo;
EmbyContent = content;
}
private ISettingsService<EmbySettings> Emby { get; }
private IRepository<EmbyEpisodes> 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> EmbyContent { get; }
public void CacheContent()
{
var embySettings = Emby.GetSettings();
if (!ValidateSettings(embySettings))
{
Log.Debug("Validation of emby settings failed.");
return;
}
CachedLibraries(embySettings);
}
public List<EmbyMovieItem> GetMovies()
{
var settings = Emby.GetSettings();
return EmbyApi.GetAllMovies(settings.ApiKey, settings.AdministratorId, settings.FullUri).Items;
}
public List<EmbySeriesItem> 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<EmbyContent>("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<EmbyContent>("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<PlexContent>("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);
}
}
}
}

@ -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> embySettings, IEmbyApi emby, ICacheProvider cache,
IJobRecord rec, IRepository<EmbyEpisodes> repo, ISettingsService<ScheduledJobsSettings> jobs)
{
Emby = embySettings;
EmbyApi = emby;
Cache = cache;
Job = rec;
Repo = repo;
Jobs = jobs;
}
private ISettingsService<EmbySettings> Emby { get; }
private static Logger Log = LogManager.GetCurrentClassLogger();
private IEmbyApi EmbyApi { get; }
private ICacheProvider Cache { get; }
private IJobRecord Job { get; }
private IRepository<EmbyEpisodes> Repo { get; }
private ISettingsService<ScheduledJobsSettings> 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<EmbyEpisodes>();
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);
}
}
}
}

@ -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<EmbyMovieItem> GetMovies();
List<EmbySeriesItem> GetTvShows();
}
}

@ -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();
}
}

@ -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";

@ -93,11 +93,15 @@
<Compile Include="Interfaces\IStoreBackup.cs" />
<Compile Include="Interfaces\IStoreCleanup.cs" />
<Compile Include="Interfaces\IUserRequestLimitResetter.cs" />
<Compile Include="Jobs\IEmbyAvailabilityChecker.cs" />
<Compile Include="Jobs\IFaultQueueHandler.cs" />
<Compile Include="Jobs\IPlexEpisodeCacher.cs" />
<Compile Include="Jobs\IPlexUserChecker.cs" />
<Compile Include="Jobs\Interfaces\IEmbyEpisodeCacher.cs" />
<Compile Include="Jobs\Interfaces\IEmbyContentCacher.cs" />
<Compile Include="Jobs\Interfaces\IEmbyAvailabilityChecker.cs" />
<Compile Include="Jobs\Interfaces\IFaultQueueHandler.cs" />
<Compile Include="Jobs\Interfaces\IPlexEpisodeCacher.cs" />
<Compile Include="Jobs\Interfaces\IPlexUserChecker.cs" />
<Compile Include="Jobs\EmbyAvailabilityChecker.cs" />
<Compile Include="Jobs\EmbyContentCacher.cs" />
<Compile Include="Jobs\EmbyEpisodeCacher.cs" />
<Compile Include="Jobs\RadarrCacher.cs" />
<Compile Include="Jobs\WatcherCacher.cs" />
<Compile Include="Jobs\HtmlTemplateGenerator.cs" />

@ -49,7 +49,7 @@
<button ng-click="updateUser()" class="btn btn-primary-outline">Update</button>
<button ng-click="deleteUser()" class="btn btn-danger-outline">Delete</button>
<button ng-show="selectedUser.type == 1" ng-click="deleteUser()" class="btn btn-danger-outline">Delete</button>
<button ng-click="closeSidebarClick()" style="float: right; margin-right: 10px;" class="btn btn-danger-outline">Close</button>
</div>
</div>

@ -55,9 +55,6 @@ namespace Ombi.UI.Jobs
private IEnumerable<IJobDetail> CreateJobs()
{
var settingsService = Service.Resolve<ISettingsService<ScheduledJobsSettings>>();
var s = settingsService.GetSettings();
var jobs = new List<IJobDetail>();
var jobList = new List<IJobDetail>
@ -76,6 +73,11 @@ namespace Ombi.UI.Jobs
JobBuilder.Create<RecentlyAdded>().WithIdentity("RecentlyAddedModel", "Email").Build(),
JobBuilder.Create<FaultQueueHandler>().WithIdentity("FaultQueueHandler", "Fault").Build(),
JobBuilder.Create<RadarrCacher>().WithIdentity("RadarrCacher", "Cache").Build(),
JobBuilder.Create<EmbyEpisodeCacher>().WithIdentity("EmbyEpisodeCacher", "Emby").Build(),
JobBuilder.Create<EmbyAvailabilityChecker>().WithIdentity("EmbyAvailabilityChecker", "Emby").Build(),
JobBuilder.Create<EmbyContentCacher>().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<ITrigger>();
@ -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;
}

@ -447,11 +447,19 @@ namespace Ombi.UI.Modules.Admin
return Response.AsJson(valid.SendJsonError());
}
var embySettings = await EmbySettings.GetSettingsAsync();
if (plexSettings.Enable)
{
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" });
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());
}
if (emby.Enable)
{
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" });
return
Response.AsJson(new JsonResponseModel
{
Result = false,
Message = "Plex is enabled, we cannot enable Plex and Emby"
});
}
}
// Get the users

@ -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<Response> 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 });

@ -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<PlexRequestSettings> prSettings, IAvailabilityChecker checker,
ISettingsService<PlexRequestSettings> prSettings, IAvailabilityChecker plexChecker,
IRequestService request, ISonarrApi sonarrApi, ISettingsService<SonarrSettings> sonarrSettings,
ISettingsService<SickRageSettings> sickRageService, ISickRageApi srApi,
INotificationService notify, IMusicBrainzApi mbApi, IHeadphonesApi hpApi,
@ -77,7 +79,8 @@ namespace Ombi.UI.Modules
ISettingsService<PlexSettings> plexService, ISettingsService<AuthenticationSettings> auth,
IRepository<UsersToNotify> u, ISettingsService<EmailNotificationSettings> email,
IIssueService issue, IAnalytics a, IRepository<RequestLimit> rl, ITransientFaultQueue tfQueue, IRepository<PlexContent> content,
ISecurityExtensions security, IMovieSender movieSender, IRadarrCacher radarrCacher, ITraktApi traktApi, ISettingsService<CustomizationSettings> cus)
ISecurityExtensions security, IMovieSender movieSender, IRadarrCacher radarrCacher, ITraktApi traktApi, ISettingsService<CustomizationSettings> cus,
IEmbyAvailabilityChecker embyChecker, IRepository<EmbyContent> embyContent, ISettingsService<EmbySettings> 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<PlexContent> PlexContentRepository { get; }
private IRepository<EmbyContent> 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<AuthenticationSettings> Auth { get; }
private ISettingsService<EmbySettings> EmbySettings { get; }
private ISettingsService<PlexSettings> PlexService { get; }
private ISettingsService<PlexRequestSettings> PrService { get; }
private ISettingsService<SonarrSettings> SonarrService { get; }
private ISettingsService<SickRageSettings> SickRageService { get; }
private ISettingsService<HeadphonesSettings> HeadphonesService { get; }
private ISettingsService<EmailNotificationSettings> 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<SearchMovieViewModel>();
var counter = 0;
foreach (var movie in apiMovies)
@ -293,7 +301,6 @@ namespace Ombi.UI.Modules
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,15 +320,36 @@ 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);
var plexSettings = await PlexService.GetSettingsAsync();
var embySettings = await EmbySettings.GetSettingsAsync();
if (plexSettings.Enable)
{
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
{
var dbm = dbMovies[movie.Id];
@ -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<SearchTvShowViewModel>();
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<SearchMusicViewModel>();
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,17 +1071,20 @@ namespace Ombi.UI.Modules
try
{
var plexSettings = await PlexService.GetSettingsAsync();
if (plexSettings.Enable)
{
var content = PlexContentRepository.GetAll();
var shows = Checker.GetPlexTvShows(content);
var shows = PlexChecker.GetPlexTvShows(content);
var providerId = string.Empty;
var plexSettings = await PlexService.GetSettingsAsync();
if (plexSettings.AdvancedSearch)
{
providerId = showId.ToString();
}
if (episodeRequest)
{
var cachedEpisodesTask = await Checker.GetEpisodes();
var cachedEpisodesTask = await PlexChecker.GetEpisodes();
var cachedEpisodes = cachedEpisodesTask.ToList();
foreach (var d in difference) // difference is from an existing request
{
@ -1082,7 +1113,8 @@ namespace Ombi.UI.Modules
{
foreach (var s in showInfo.Season)
{
var result = Checker.IsEpisodeAvailable(showId.ToString(), s.SeasonNumber, s.EpisodeNumber);
var result = PlexChecker.IsEpisodeAvailable(showId.ToString(), s.SeasonNumber,
s.EpisodeNumber);
if (result)
{
return
@ -1094,7 +1126,8 @@ namespace Ombi.UI.Modules
}
}
}
else if (Checker.IsTvShowAvailable(shows.ToArray(), showInfo.name, showInfo.premiered?.Substring(0, 4),
else if (PlexChecker.IsTvShowAvailable(shows.ToArray(), showInfo.name,
showInfo.premiered?.Substring(0, 4),
providerId, model.SeasonList))
{
return
@ -1106,6 +1139,70 @@ namespace Ombi.UI.Modules
}
}
}
var embySettings = await EmbySettings.GetSettingsAsync();
if (embySettings.Enable)
{
var embyContent = EmbyContentRepository.GetAll();
var embyMovies = EmbyChecker.GetEmbyTvShows(embyContent);
var providerId = showId.ToString();
if (episodeRequest)
{
var cachedEpisodesTask = await EmbyChecker.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 (embySettings.EnableEpisodeSearching)
{
foreach (var s in showInfo.Season)
{
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)
{
return
@ -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<SonarrEpisodes>();
if (sonarrEnabled)
@ -1400,16 +1498,21 @@ namespace Ombi.UI.Modules
sonarrEpisodes = sonarrEp?.ToList() ?? new List<SonarrEpisodes>();
}
var plexCacheTask = await Checker.GetEpisodes(providerId);
var plexSettings = await PlexService.GetSettingsAsync();
if (plexSettings.Enable)
{
var plexCacheTask = await PlexChecker.GetEpisodes(providerId);
var plexCache = plexCacheTask.ToList();
foreach (var ep in tvMaxeEpisodes)
foreach (var ep in tvMazeEpisodes)
{
var requested = existingRequest?.Episodes
.Any(episodesModel =>
ep.number == episodesModel.EpisodeNumber && ep.season == episodesModel.SeasonNumber) ?? false;
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 inSonarr =
sonarrEpisodes.Any(x => x.seasonNumber == ep.season && x.episodeNumber == ep.number && x.hasFile);
model.Add(new EpisodeListViewModel
{
@ -1421,6 +1524,34 @@ namespace Ombi.UI.Modules
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)
{
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
}
}
}

@ -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<IPlexUserChecker>().To<PlexUserChecker>();
Bind<IEmbyAvailabilityChecker>().To<EmbyAvailabilityChecker>();
Bind<IEmbyContentCacher>().To<EmbyContentCacher>();
Bind<IEmbyEpisodeCacher>().To<EmbyEpisodeCacher>();
Bind<IAnalytics>().To<Analytics>();

@ -161,7 +161,7 @@
<div class="col-md-7 col-xs-7">
{{#if available}}
<span class="label label-success">@UI.Search_Available_on_plex</span>
<span class="label label-success">@UI.Search_Available</span>
{{else}}
{{#if approved}}
<span class="label label-info">@UI.Search_Processing_Request</span>
@ -207,7 +207,9 @@
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Available</button>
<br />
<br />
{{#if url}}
<a style="text-align: right" class="btn btn-sm btn-primary-outline" href="{{url}}" target="_blank"><i class="fa fa-eye"></i> @UI.Search_ViewInPlex</a>
{{/if}}
{{else}}
{{#if_eq requested true}}
<button style="text-align: right" class="btn btn-primary-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Requested</button>
@ -325,7 +327,7 @@
<span class="label label-info" target="_blank">Release Date: {{releaseDate}}</span>
{{/if}}
{{#if available}}
<span class="label label-success">@UI.Search_Available_on_plex</span>
<span class="label label-success">@UI.Search_Available</span>
{{else}}
{{#if approved}}
<span class="label label-info">@UI.Search_Processing_Request</span>
@ -357,9 +359,11 @@
{{#if_eq type "movie"}}
{{#if_eq available true}}
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Available</button>
{{#if url}}
<br />
<br />
<a style="text-align: right" class="btn btn-sm btn-primary-outline" href="{{url}}" target="_blank"><i class="fa fa-eye"></i> @UI.Search_ViewInPlex</a>
{{/if}}
{{else}}
{{#if_eq requested true}}
<button style="text-align: right" class="btn btn-primary-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Requested</button>
@ -396,9 +400,11 @@
</div>
{{/if_eq}}
{{#if available}}
{{#if url}}
<br />
<a style="text-align: right" class="btn btn-sm btn-primary-outline" href="{{url}}" target="_blank"><i class="fa fa-eye"></i> @UI.Search_ViewInPlex</a>
{{/if}}
{{/if}}
{{/if_eq}}
{{/if_eq}}
@ -458,7 +464,9 @@
<input name="{{type}}Id" type="text" value="{{id}}" hidden="hidden" />
{{#if_eq available true}}
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Available</button><br />
{{#if url}}
<a style="text-align: right" class="btn btn-sm btn-primary-outline" href="{{url}}" target="_blank"><i class="fa fa-eye"></i> @UI.Search_ViewInPlex</a>
{{/if}}
{{else}}
{{#if_eq requested true}}
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Requested</button>

Loading…
Cancel
Save