mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-19 12:59:39 -07:00
docker support and more, redesign the episodes
This commit is contained in:
parent
b829b10b14
commit
fa5efb6c66
25 changed files with 689 additions and 42 deletions
|
@ -52,27 +52,47 @@ namespace Ombi.Core.Engine
|
||||||
RequestAll = tv.RequestAll
|
RequestAll = tv.RequestAll
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var episodes = await TvApi.EpisodeLookup(showInfo.id);
|
||||||
|
|
||||||
|
foreach (var e in episodes)
|
||||||
|
{
|
||||||
|
var season = model.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == e.season);
|
||||||
|
season?.Episodes.Add(new EpisodesRequested
|
||||||
|
{
|
||||||
|
Url = e.url,
|
||||||
|
Title = e.name,
|
||||||
|
AirDate = DateTime.Parse(e.airstamp),
|
||||||
|
EpisodeNumber = e.number,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (tv.LatestSeason)
|
if (tv.LatestSeason)
|
||||||
{
|
{
|
||||||
var latest = showInfo.Season.OrderBy(x => x).FirstOrDefault();
|
var latest = showInfo.Season.OrderBy(x => x).FirstOrDefault();
|
||||||
model.SeasonRequests = showInfo.Season.Any()
|
foreach (var modelSeasonRequest in model.SeasonRequests)
|
||||||
? new List<SeasonRequestModel> {new SeasonRequestModel
|
{
|
||||||
|
if (modelSeasonRequest.SeasonNumber == latest.SeasonNumber)
|
||||||
{
|
{
|
||||||
SeasonNumber = latest.SeasonNumber,
|
foreach (var episodesRequested in modelSeasonRequest.Episodes)
|
||||||
Episodes = latest.EpisodeNumber
|
{
|
||||||
}}
|
episodesRequested.Requested = true;
|
||||||
: new List<SeasonRequestModel>();
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (tv.FirstSeason)
|
if (tv.FirstSeason)
|
||||||
{
|
{
|
||||||
var first = showInfo.Season.OrderByDescending(x => x).FirstOrDefault();
|
var first = showInfo.Season.OrderByDescending(x => x).FirstOrDefault();
|
||||||
model.SeasonRequests = showInfo.Season.Any()
|
foreach (var modelSeasonRequest in model.SeasonRequests)
|
||||||
? new List<SeasonRequestModel> {new SeasonRequestModel
|
{
|
||||||
|
if (modelSeasonRequest.SeasonNumber == first.SeasonNumber)
|
||||||
{
|
{
|
||||||
SeasonNumber = first.SeasonNumber,
|
foreach (var episodesRequested in modelSeasonRequest.Episodes)
|
||||||
Episodes = first.EpisodeNumber
|
{
|
||||||
}}
|
episodesRequested.Requested = true;
|
||||||
: new List<SeasonRequestModel>();
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -48,10 +49,30 @@ namespace Ombi.Core.Engine
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<SearchTvShowViewModel> GetShowInformation(int tvdbId)
|
public async Task<SearchTvShowViewModel> GetShowInformation(int tvmazeId)
|
||||||
{
|
{
|
||||||
var show = await TvMazeApi.ShowLookupByTheTvDbId(tvdbId);
|
var show = await TvMazeApi.ShowLookup(tvmazeId);
|
||||||
return Mapper.Map<SearchTvShowViewModel>(show);
|
var episodes = await TvMazeApi.EpisodeLookup(show.id);
|
||||||
|
|
||||||
|
var mapped = Mapper.Map<SearchTvShowViewModel>(show);
|
||||||
|
|
||||||
|
foreach (var e in episodes)
|
||||||
|
{
|
||||||
|
var season = mapped.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == e.season);
|
||||||
|
season?.Episodes.Add(new EpisodesRequested
|
||||||
|
{
|
||||||
|
Url = e.url,
|
||||||
|
Title = e.name,
|
||||||
|
AirDate = DateTime.Parse(e.airstamp),
|
||||||
|
EpisodeNumber = e.number,
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingRequests = await GetTvRequests();
|
||||||
|
var plexSettings = await PlexSettings.GetSettingsAsync();
|
||||||
|
var embySettings = await EmbySettings.GetSettingsAsync();
|
||||||
|
return ProcessResult(mapped, existingRequests, plexSettings, embySettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
//public async Task<IEnumerable<SearchTvShowViewModel>> Popular()
|
//public async Task<IEnumerable<SearchTvShowViewModel>> Popular()
|
||||||
|
@ -118,11 +139,28 @@ namespace Ombi.Core.Engine
|
||||||
var tvdbid = item.Id;
|
var tvdbid = item.Id;
|
||||||
if (existingRequests.ContainsKey(tvdbid))
|
if (existingRequests.ContainsKey(tvdbid))
|
||||||
{
|
{
|
||||||
var dbt = existingRequests[tvdbid];
|
var existingRequest = existingRequests[tvdbid];
|
||||||
|
|
||||||
item.Requested = true;
|
item.Requested = true;
|
||||||
item.SeasonRequests = dbt.SeasonRequests.ToList();
|
item.Approved = existingRequest.Approved;
|
||||||
item.Approved = dbt.Approved;
|
|
||||||
|
// Let's modify the seasonsrequested to reflect what we have requested...
|
||||||
|
foreach (var season in item.SeasonRequests)
|
||||||
|
{
|
||||||
|
// Find the existing request season
|
||||||
|
var existingSeason =
|
||||||
|
existingRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == season.SeasonNumber);
|
||||||
|
|
||||||
|
foreach (var ep in existingSeason.Episodes)
|
||||||
|
{
|
||||||
|
// Find the episode from what we are searching
|
||||||
|
var episodeSearching = season.Episodes.FirstOrDefault(x => x.EpisodeNumber == ep.EpisodeNumber);
|
||||||
|
episodeSearching.Requested = ep.Requested;
|
||||||
|
episodeSearching.Available = ep.Available;
|
||||||
|
episodeSearching.Approved = ep.Approved;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//if (sonarrCached.Select(x => x.TvdbId).Contains(tvdbid) || sickRageCache.Contains(tvdbid))
|
//if (sonarrCached.Select(x => x.TvdbId).Contains(tvdbid) || sickRageCache.Contains(tvdbid))
|
||||||
// // compare to the sonarr/sickrage db
|
// // compare to the sonarr/sickrage db
|
||||||
|
|
|
@ -59,7 +59,19 @@ namespace Ombi.Core.Models.Requests
|
||||||
public class SeasonRequestModel
|
public class SeasonRequestModel
|
||||||
{
|
{
|
||||||
public int SeasonNumber { get; set; }
|
public int SeasonNumber { get; set; }
|
||||||
public List<int> Episodes { get; set; }
|
public List<EpisodesRequested> Episodes { get; set; } = new List<EpisodesRequested>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EpisodesRequested
|
||||||
|
{
|
||||||
|
public int EpisodeNumber { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public DateTime AirDate { get; set; }
|
||||||
|
public string Url { get; set; }
|
||||||
|
public bool Requested { get; set; }
|
||||||
|
public string Status { get; set; }
|
||||||
|
public bool Available { get; set; }
|
||||||
|
public bool Approved { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@ namespace Ombi.Core.Models.Search
|
||||||
public class SearchTvShowViewModel : SearchViewModel
|
public class SearchTvShowViewModel : SearchViewModel
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string SeriesName { get; set; }
|
public string Title { get; set; }
|
||||||
public List<string> Aliases { get; set; }
|
public List<string> Aliases { get; set; }
|
||||||
public string Banner { get; set; }
|
public string Banner { get; set; }
|
||||||
public int SeriesId { get; set; }
|
public int SeriesId { get; set; }
|
||||||
|
@ -48,5 +48,6 @@ namespace Ombi.Core.Models.Search
|
||||||
|
|
||||||
public bool FirstSeason { get; set; }
|
public bool FirstSeason { get; set; }
|
||||||
public bool LatestSeason { get; set; }
|
public bool LatestSeason { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,12 +24,10 @@ namespace Ombi.Mapping.Profiles
|
||||||
.ForMember(dest => dest.Rating, opts => opts.MapFrom(src => src.score.ToString(CultureInfo.CurrentUICulture)))
|
.ForMember(dest => dest.Rating, opts => opts.MapFrom(src => src.score.ToString(CultureInfo.CurrentUICulture)))
|
||||||
.ForMember(dest => dest.Runtime, opts => opts.MapFrom(src => src.show.runtime.ToString()))
|
.ForMember(dest => dest.Runtime, opts => opts.MapFrom(src => src.show.runtime.ToString()))
|
||||||
.ForMember(dest => dest.SeriesId, opts => opts.MapFrom(src => src.show.id))
|
.ForMember(dest => dest.SeriesId, opts => opts.MapFrom(src => src.show.id))
|
||||||
.ForMember(dest => dest.SeriesName, opts => opts.MapFrom(src => src.show.name))
|
.ForMember(dest => dest.Title, opts => opts.MapFrom(src => src.show.name))
|
||||||
.ForMember(dest => dest.Banner, opts => opts.MapFrom(src => !string.IsNullOrEmpty(src.show.image.medium) ? src.show.image.medium.Replace("http", "https") : string.Empty))
|
.ForMember(dest => dest.Banner, opts => opts.MapFrom(src => !string.IsNullOrEmpty(src.show.image.medium) ? src.show.image.medium.Replace("http", "https") : string.Empty))
|
||||||
.ForMember(dest => dest.Status, opts => opts.MapFrom(src => src.show.status));
|
.ForMember(dest => dest.Status, opts => opts.MapFrom(src => src.show.status));
|
||||||
|
|
||||||
CreateMap<TvMazeCustomSeason, SeasonRequestModel>()
|
|
||||||
.ConstructUsing(x => new SeasonRequestModel { Episodes = x.EpisodeNumber, SeasonNumber = x.SeasonNumber });
|
|
||||||
CreateMap<TvMazeShow, SearchTvShowViewModel>()
|
CreateMap<TvMazeShow, SearchTvShowViewModel>()
|
||||||
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.externals.thetvdb))
|
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.externals.thetvdb))
|
||||||
.ForMember(dest => dest.FirstAired, opts => opts.MapFrom(src => src.premiered))
|
.ForMember(dest => dest.FirstAired, opts => opts.MapFrom(src => src.premiered))
|
||||||
|
@ -40,7 +38,7 @@ namespace Ombi.Mapping.Profiles
|
||||||
.ForMember(dest => dest.Rating, opts => opts.MapFrom(src => src.rating.ToString()))
|
.ForMember(dest => dest.Rating, opts => opts.MapFrom(src => src.rating.ToString()))
|
||||||
.ForMember(dest => dest.Runtime, opts => opts.MapFrom(src => src.runtime.ToString(CultureInfo.CurrentUICulture)))
|
.ForMember(dest => dest.Runtime, opts => opts.MapFrom(src => src.runtime.ToString(CultureInfo.CurrentUICulture)))
|
||||||
.ForMember(dest => dest.SeriesId, opts => opts.MapFrom(src => src.id))
|
.ForMember(dest => dest.SeriesId, opts => opts.MapFrom(src => src.id))
|
||||||
.ForMember(dest => dest.SeriesName, opts => opts.MapFrom(src => src.name))
|
.ForMember(dest => dest.Title, opts => opts.MapFrom(src => src.name))
|
||||||
.ForMember(dest => dest.Banner, opts => opts.MapFrom(src => !string.IsNullOrEmpty(src.image.medium) ? src.image.medium.Replace("http", "https") : string.Empty))
|
.ForMember(dest => dest.Banner, opts => opts.MapFrom(src => !string.IsNullOrEmpty(src.image.medium) ? src.image.medium.Replace("http", "https") : string.Empty))
|
||||||
.ForMember(dest => dest.Status, opts => opts.MapFrom(src => src.status))
|
.ForMember(dest => dest.Status, opts => opts.MapFrom(src => src.status))
|
||||||
.ForMember(dest => dest.SeasonRequests, opts => opts.MapFrom(src => src.Season));
|
.ForMember(dest => dest.SeasonRequests, opts => opts.MapFrom(src => src.Season));
|
||||||
|
@ -53,7 +51,7 @@ namespace Ombi.Mapping.Profiles
|
||||||
// .ForMember(dest => dest.Overview, opts => opts.MapFrom(src => src.Overview.RemoveHtml()))
|
// .ForMember(dest => dest.Overview, opts => opts.MapFrom(src => src.Overview.RemoveHtml()))
|
||||||
// .ForMember(dest => dest.Rating, opts => opts.MapFrom(src => src.Rating.ToString()))
|
// .ForMember(dest => dest.Rating, opts => opts.MapFrom(src => src.Rating.ToString()))
|
||||||
// .ForMember(dest => dest.Runtime, opts => opts.MapFrom(src => src.Runtime.ToString()))
|
// .ForMember(dest => dest.Runtime, opts => opts.MapFrom(src => src.Runtime.ToString()))
|
||||||
// .ForMember(dest => dest.SeriesName, opts => opts.MapFrom(src => src.Title))
|
// .ForMember(dest => dest.Title, opts => opts.MapFrom(src => src.Title))
|
||||||
// .ForMember(dest => dest.Status, opts => opts.MapFrom(src => src.Status.DisplayName))
|
// .ForMember(dest => dest.Status, opts => opts.MapFrom(src => src.Status.DisplayName))
|
||||||
// .ForMember(dest => dest.Trailer, opts => opts.MapFrom(src => src.Trailer))
|
// .ForMember(dest => dest.Trailer, opts => opts.MapFrom(src => src.Trailer))
|
||||||
// .ForMember(dest => dest.Homepage, opts => opts.MapFrom(src => src.Homepage));
|
// .ForMember(dest => dest.Homepage, opts => opts.MapFrom(src => src.Homepage));
|
||||||
|
@ -66,7 +64,7 @@ namespace Ombi.Mapping.Profiles
|
||||||
// .ForMember(dest => dest.Overview, opts => opts.MapFrom(src => src.Show.Overview.RemoveHtml()))
|
// .ForMember(dest => dest.Overview, opts => opts.MapFrom(src => src.Show.Overview.RemoveHtml()))
|
||||||
// .ForMember(dest => dest.Rating, opts => opts.MapFrom(src => src.Show.Rating.ToString()))
|
// .ForMember(dest => dest.Rating, opts => opts.MapFrom(src => src.Show.Rating.ToString()))
|
||||||
// .ForMember(dest => dest.Runtime, opts => opts.MapFrom(src => src.Show.Runtime.ToString()))
|
// .ForMember(dest => dest.Runtime, opts => opts.MapFrom(src => src.Show.Runtime.ToString()))
|
||||||
// .ForMember(dest => dest.SeriesName, opts => opts.MapFrom(src => src.Show.Title))
|
// .ForMember(dest => dest.Title, opts => opts.MapFrom(src => src.Show.Title))
|
||||||
// .ForMember(dest => dest.Status, opts => opts.MapFrom(src => src.Show.Status.DisplayName))
|
// .ForMember(dest => dest.Status, opts => opts.MapFrom(src => src.Show.Status.DisplayName))
|
||||||
// .ForMember(dest => dest.Trailer, opts => opts.MapFrom(src => src.Show.Trailer))
|
// .ForMember(dest => dest.Trailer, opts => opts.MapFrom(src => src.Show.Trailer))
|
||||||
// .ForMember(dest => dest.Homepage, opts => opts.MapFrom(src => src.Show.Homepage));
|
// .ForMember(dest => dest.Homepage, opts => opts.MapFrom(src => src.Show.Homepage));
|
||||||
|
@ -79,7 +77,7 @@ namespace Ombi.Mapping.Profiles
|
||||||
// .ForMember(dest => dest.Overview, opts => opts.MapFrom(src => src.Show.Overview.RemoveHtml()))
|
// .ForMember(dest => dest.Overview, opts => opts.MapFrom(src => src.Show.Overview.RemoveHtml()))
|
||||||
// .ForMember(dest => dest.Rating, opts => opts.MapFrom(src => src.Show.Rating.ToString()))
|
// .ForMember(dest => dest.Rating, opts => opts.MapFrom(src => src.Show.Rating.ToString()))
|
||||||
// .ForMember(dest => dest.Runtime, opts => opts.MapFrom(src => src.Show.Runtime.ToString()))
|
// .ForMember(dest => dest.Runtime, opts => opts.MapFrom(src => src.Show.Runtime.ToString()))
|
||||||
// .ForMember(dest => dest.SeriesName, opts => opts.MapFrom(src => src.Show.Title))
|
// .ForMember(dest => dest.Title, opts => opts.MapFrom(src => src.Show.Title))
|
||||||
// .ForMember(dest => dest.Status, opts => opts.MapFrom(src => src.Show.Status.DisplayName))
|
// .ForMember(dest => dest.Status, opts => opts.MapFrom(src => src.Show.Status.DisplayName))
|
||||||
// .ForMember(dest => dest.Trailer, opts => opts.MapFrom(src => src.Show.Trailer))
|
// .ForMember(dest => dest.Trailer, opts => opts.MapFrom(src => src.Show.Trailer))
|
||||||
// .ForMember(dest => dest.Homepage, opts => opts.MapFrom(src => src.Show.Homepage));
|
// .ForMember(dest => dest.Homepage, opts => opts.MapFrom(src => src.Show.Homepage));
|
||||||
|
@ -92,7 +90,7 @@ namespace Ombi.Mapping.Profiles
|
||||||
// .ForMember(dest => dest.Overview, opts => opts.MapFrom(src => src.Show.Overview.RemoveHtml()))
|
// .ForMember(dest => dest.Overview, opts => opts.MapFrom(src => src.Show.Overview.RemoveHtml()))
|
||||||
// .ForMember(dest => dest.Rating, opts => opts.MapFrom(src => src.Show.Rating.ToString()))
|
// .ForMember(dest => dest.Rating, opts => opts.MapFrom(src => src.Show.Rating.ToString()))
|
||||||
// .ForMember(dest => dest.Runtime, opts => opts.MapFrom(src => src.Show.Runtime.ToString()))
|
// .ForMember(dest => dest.Runtime, opts => opts.MapFrom(src => src.Show.Runtime.ToString()))
|
||||||
// .ForMember(dest => dest.SeriesName, opts => opts.MapFrom(src => src.Show.Title))
|
// .ForMember(dest => dest.Title, opts => opts.MapFrom(src => src.Show.Title))
|
||||||
// .ForMember(dest => dest.Status, opts => opts.MapFrom(src => src.Show.Status.DisplayName))
|
// .ForMember(dest => dest.Status, opts => opts.MapFrom(src => src.Show.Status.DisplayName))
|
||||||
// .ForMember(dest => dest.Trailer, opts => opts.MapFrom(src => src.Show.Trailer))
|
// .ForMember(dest => dest.Trailer, opts => opts.MapFrom(src => src.Show.Trailer))
|
||||||
// .ForMember(dest => dest.Homepage, opts => opts.MapFrom(src => src.Show.Homepage));
|
// .ForMember(dest => dest.Homepage, opts => opts.MapFrom(src => src.Show.Homepage));
|
||||||
|
|
|
@ -14,8 +14,10 @@ namespace Ombi.Store.Context
|
||||||
_created = true;
|
_created = true;
|
||||||
Database.EnsureCreated();
|
Database.EnsureCreated();
|
||||||
Database.Migrate();
|
Database.Migrate();
|
||||||
|
|
||||||
|
// Run Script
|
||||||
|
|
||||||
|
Database.ExecuteSqlCommand(Sql.SqlTables, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DbSet<RequestBlobs> Requests { get; set; }
|
public DbSet<RequestBlobs> Requests { get; set; }
|
||||||
|
|
|
@ -8,7 +8,6 @@ namespace Ombi.Store.Entities
|
||||||
public int ProviderId { get; set; }
|
public int ProviderId { get; set; }
|
||||||
public byte[] Content { get; set; }
|
public byte[] Content { get; set; }
|
||||||
public RequestType Type { get; set; }
|
public RequestType Type { get; set; }
|
||||||
public string MusicId { get; set; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public enum RequestType
|
public enum RequestType
|
||||||
|
|
|
@ -17,4 +17,17 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
|
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="Sql.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Sql.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Update="Sql.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Sql.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
89
Ombi/Ombi.Store/Sql.Designer.cs
generated
Normal file
89
Ombi/Ombi.Store/Sql.Designer.cs
generated
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace Ombi.Store {
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
/// </summary>
|
||||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
// class via a tool like ResGen or Visual Studio.
|
||||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
// with the /str option, or rebuild your VS project.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Sql {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Sql() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Ombi.Store.Sql", typeof(Sql).GetTypeInfo().Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
|
/// resource lookups using this strongly typed resource class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to CREATE TABLE IF NOT EXISTS GlobalSettings
|
||||||
|
///(
|
||||||
|
/// Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
/// SettingsName varchar(50) NOT NULL,
|
||||||
|
/// Content BLOB NOT NULL
|
||||||
|
///);
|
||||||
|
///
|
||||||
|
///CREATE TABLE IF NOT EXISTS PlexContent
|
||||||
|
///(
|
||||||
|
/// Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
/// Title varchar(50) NOT NULL,
|
||||||
|
/// ProviderId varchar(50) NOT NULL,
|
||||||
|
/// Url varchar(100) NOT NULL,
|
||||||
|
/// Key varchar(50) NOT NULL,
|
||||||
|
/// AddedAt varchar(50) NOT NULL,
|
||||||
|
/// Type INTEGER NOT NULL,
|
||||||
|
/// Relea [rest of string was truncated]";.
|
||||||
|
/// </summary>
|
||||||
|
internal static string SqlTables {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("SqlTables", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
124
Ombi/Ombi.Store/Sql.resx
Normal file
124
Ombi/Ombi.Store/Sql.resx
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
|
<data name="SqlTables" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>SqlTables.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
49
Ombi/Ombi.Store/SqlTables.sql
Normal file
49
Ombi/Ombi.Store/SqlTables.sql
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
CREATE TABLE IF NOT EXISTS GlobalSettings
|
||||||
|
(
|
||||||
|
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
SettingsName varchar(50) NOT NULL,
|
||||||
|
Content BLOB NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS PlexContent
|
||||||
|
(
|
||||||
|
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
Title varchar(50) NOT NULL,
|
||||||
|
ProviderId varchar(50) NOT NULL,
|
||||||
|
Url varchar(100) NOT NULL,
|
||||||
|
Key varchar(50) NOT NULL,
|
||||||
|
AddedAt varchar(50) NOT NULL,
|
||||||
|
Type INTEGER NOT NULL,
|
||||||
|
ReleaseYear varchar(100) NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS SeasonsContent
|
||||||
|
(
|
||||||
|
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
SeasonNumber INTEGER NOT NULL,
|
||||||
|
SeasonKey INTEGER NOT NULL,
|
||||||
|
ParentKey INTEGER NOT NULL
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS RequestBlobs
|
||||||
|
(
|
||||||
|
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
ProviderId INTEGER NOT NULL,
|
||||||
|
Content BLOB NOT NULL,
|
||||||
|
Type INTEGER NOT NULL
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS Users
|
||||||
|
(
|
||||||
|
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
Username VARCHAR(100) NOT NULL,
|
||||||
|
Alias VARCHAR(100) NULL,
|
||||||
|
ClaimsSerialized BLOB NOT NULL,
|
||||||
|
EmailAddress VARCHAR(100) NULL,
|
||||||
|
Password VARCHAR(100) NULL,
|
||||||
|
Salt BLOB NULL,
|
||||||
|
UserType INTEGER NOT NULL
|
||||||
|
|
||||||
|
);
|
39
Ombi/Ombi/.vscode/launch.json
vendored
Normal file
39
Ombi/Ombi/.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name":".NET Core Docker Launch (web)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "composeForDebug",
|
||||||
|
"cwd": "/app",
|
||||||
|
"program": "/app/Ombi.dll",
|
||||||
|
"sourceFileMap": {
|
||||||
|
"/app": "${workspaceRoot}"
|
||||||
|
},
|
||||||
|
|
||||||
|
"launchBrowser": {
|
||||||
|
"enabled": true,
|
||||||
|
"args": "${auto-detect-url}",
|
||||||
|
"windows": {
|
||||||
|
"command": "cmd.exe",
|
||||||
|
"args": "/C start ${auto-detect-url}"
|
||||||
|
},
|
||||||
|
"osx": {
|
||||||
|
"command": "open"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"pipeTransport": {
|
||||||
|
"pipeProgram": "/bin/bash",
|
||||||
|
"pipeCwd": "${workspaceRoot}",
|
||||||
|
"pipeArgs": [ "-c", "./dockerTask.sh startDebugging" ],
|
||||||
|
"windows": {
|
||||||
|
"pipeProgram": "${env.windir}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
|
||||||
|
"pipeCwd": "${workspaceRoot}",
|
||||||
|
"pipeArgs": [ ".\\dockerTask.ps1", "-StartDebugging" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
5
Ombi/Ombi/.vscode/settings.json
vendored
Normal file
5
Ombi/Ombi/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"dockerfile.*": "dockerfile"
|
||||||
|
}
|
||||||
|
}
|
66
Ombi/Ombi/.vscode/tasks.json
vendored
Normal file
66
Ombi/Ombi/.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "0.1.0",
|
||||||
|
"windows": {
|
||||||
|
"command": "powershell",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceRoot}"
|
||||||
|
},
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"taskName": "build",
|
||||||
|
"suppressTaskName": true,
|
||||||
|
"args": ["-ExecutionPolicy", "RemoteSigned", ".\\dockerTask.ps1", "-Build", "-Environment", "debug" ],
|
||||||
|
"isBuildCommand": true,
|
||||||
|
"showOutput": "always",
|
||||||
|
"echoCommand": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"taskName": "compose",
|
||||||
|
"suppressTaskName": true,
|
||||||
|
"args": ["-ExecutionPolicy", "RemoteSigned", ".\\dockerTask.ps1", "-Compose", "-Environment", "debug" ],
|
||||||
|
"isBuildCommand": false,
|
||||||
|
"showOutput": "always",
|
||||||
|
"echoCommand": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"taskName": "composeForDebug",
|
||||||
|
"suppressTaskName": true,
|
||||||
|
"args": ["-ExecutionPolicy", "RemoteSigned", ".\\dockerTask.ps1", "-ComposeForDebug", "-Environment", "debug" ],
|
||||||
|
"isBuildCommand": false,
|
||||||
|
"showOutput": "always",
|
||||||
|
"echoCommand": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"osx": {
|
||||||
|
"command": "/bin/bash",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceRoot}"
|
||||||
|
},
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"taskName": "build",
|
||||||
|
"suppressTaskName": true,
|
||||||
|
"args": [ "-c", "./dockerTask.sh build debug" ],
|
||||||
|
"isBuildCommand": true,
|
||||||
|
"showOutput": "always"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"taskName": "compose",
|
||||||
|
"suppressTaskName": true,
|
||||||
|
"args": [ "-c", "./dockerTask.sh compose debug" ],
|
||||||
|
"isBuildCommand": false,
|
||||||
|
"showOutput": "always"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"taskName": "composeForDebug",
|
||||||
|
"suppressTaskName": true,
|
||||||
|
"args": [ "-c", "./dockerTask.sh composeForDebug debug" ],
|
||||||
|
"isBuildCommand": false,
|
||||||
|
"showOutput": "always"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -66,10 +66,10 @@ namespace Ombi.Controllers
|
||||||
return await TvEngine.Search(searchTerm);
|
return await TvEngine.Search(searchTerm);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("tv/seasons/{tvdbId}")]
|
[HttpGet("tv/info/{tvdbId}")]
|
||||||
public async Task<IEnumerable<int>> GetSeasons(int tvdbId)
|
public async Task<SearchTvShowViewModel> GetShowInfo(int tvdbId)
|
||||||
{
|
{
|
||||||
return await TvEngine.GetSeasons(tvdbId);
|
return await TvEngine.GetShowInformation(tvdbId);
|
||||||
}
|
}
|
||||||
|
|
||||||
//[HttpGet("tv/popular")]
|
//[HttpGet("tv/popular")]
|
||||||
|
|
8
Ombi/Ombi/Dockerfile
Normal file
8
Ombi/Ombi/Dockerfile
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
FROM microsoft/dotnet:1.1-sdk-msbuild
|
||||||
|
ARG source=./bin/Release/netcoreapp1.1/publish
|
||||||
|
WORKDIR /app
|
||||||
|
COPY $source .
|
||||||
|
ENV ASPNETCORE_URLS http://*:5000
|
||||||
|
EXPOSE 5000
|
||||||
|
ENTRYPOINT ["dotnet", "Ombi.dll"]
|
||||||
|
COPY . /app
|
|
@ -89,6 +89,15 @@
|
||||||
<Content Update="wwwroot\app\search\moviesearch - Copy.component.ts">
|
<Content Update="wwwroot\app\search\moviesearch - Copy.component.ts">
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Update="wwwroot\app\search\tvsearch - Copy.component.js">
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="wwwroot\app\search\tvsearch - Copy.component.js.map">
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="wwwroot\app\search\tvsearch - Copy.component.ts">
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
<Content Update="wwwroot\app\usermanagement\request.component.js">
|
<Content Update="wwwroot\app\usermanagement\request.component.js">
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
21
Ombi/Ombi/build.sh
Normal file
21
Ombi/Ombi/build.sh
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
SERVICE="Ombi"
|
||||||
|
# change directory to location of project.json
|
||||||
|
pushd ./
|
||||||
|
# run dotnet publish, specify release build
|
||||||
|
dotnet publish -c Release
|
||||||
|
# equivalent to cd .. (go back to previous directory)
|
||||||
|
#popd
|
||||||
|
# Create a docker image tagged with the name of the project:latest
|
||||||
|
docker build -t "$SERVICE":latest .
|
||||||
|
# Check to see if this container exists.
|
||||||
|
CONTAINER=`docker ps --all | grep "$SERVICE"`
|
||||||
|
# if it doesn't, then just run this.
|
||||||
|
if [ -z "$CONTAINER" ]; then
|
||||||
|
docker run -i -p 8000:5000 --name $SERVICE -t $SERVICE:latest
|
||||||
|
# if it does exist; nuke it and then run the new one
|
||||||
|
else
|
||||||
|
docker rm $SERVICE
|
||||||
|
docker run -i -p 8000:5000 --name $SERVICE -t $SERVICE:latest
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -p "Press enter to continue"
|
|
@ -15,6 +15,7 @@ import { InfiniteScrollModule } from 'ngx-infinite-scroll'
|
||||||
import { SearchComponent } from './search/search.component';
|
import { SearchComponent } from './search/search.component';
|
||||||
import { MovieSearchComponent } from './search/moviesearch.component';
|
import { MovieSearchComponent } from './search/moviesearch.component';
|
||||||
import { TvSearchComponent } from './search/tvsearch.component';
|
import { TvSearchComponent } from './search/tvsearch.component';
|
||||||
|
import { SeriesInformationComponent } from './search/seriesinformation.component';
|
||||||
|
|
||||||
// Request
|
// Request
|
||||||
import { RequestComponent } from './requests/request.component';
|
import { RequestComponent } from './requests/request.component';
|
||||||
|
@ -50,6 +51,7 @@ const routes: Routes = [
|
||||||
{ path: '*', component: PageNotFoundComponent },
|
{ path: '*', component: PageNotFoundComponent },
|
||||||
{ path: '', redirectTo: '/search', pathMatch: 'full' },
|
{ path: '', redirectTo: '/search', pathMatch: 'full' },
|
||||||
{ path: 'search', component: SearchComponent, canActivate: [AuthGuard] },
|
{ path: 'search', component: SearchComponent, canActivate: [AuthGuard] },
|
||||||
|
{ path: 'search/show/:id', component: SeriesInformationComponent, canActivate: [AuthGuard] },
|
||||||
{ path: 'requests', component: RequestComponent, canActivate: [AuthGuard] },
|
{ path: 'requests', component: RequestComponent, canActivate: [AuthGuard] },
|
||||||
{ path: 'login', component: LoginComponent },
|
{ path: 'login', component: LoginComponent },
|
||||||
{ path: 'landingpage', component: LandingPageComponent },
|
{ path: 'landingpage', component: LandingPageComponent },
|
||||||
|
@ -84,7 +86,8 @@ const routes: Routes = [
|
||||||
LandingPageComponent,
|
LandingPageComponent,
|
||||||
UserManagementComponent,
|
UserManagementComponent,
|
||||||
MovieRequestsComponent,
|
MovieRequestsComponent,
|
||||||
TvRequestsComponent
|
TvRequestsComponent,
|
||||||
|
SeriesInformationComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
SearchService,
|
SearchService,
|
||||||
|
|
|
@ -39,7 +39,17 @@ export interface ITvRequestModel extends IMediaBase {
|
||||||
export interface ISeasonRequests
|
export interface ISeasonRequests
|
||||||
{
|
{
|
||||||
seasonNumber: number,
|
seasonNumber: number,
|
||||||
episodes:number[],
|
episodes: IEpisodesRequested[],
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IEpisodesRequested {
|
||||||
|
episodeNumber: number,
|
||||||
|
title: string,
|
||||||
|
airDate: Date,
|
||||||
|
url: string,
|
||||||
|
requested: boolean,
|
||||||
|
status: string,
|
||||||
|
available:boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
<div *ngIf="series">
|
||||||
|
|
||||||
|
<div *ngFor="let season of series.seasonsRequested">
|
||||||
|
<h2>Season: {{season.seasonNumber}}</h2>
|
||||||
|
|
||||||
|
<table class="table table-striped table-hover table-responsive table-condensed">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<a>
|
||||||
|
#
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a>
|
||||||
|
Title
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a>
|
||||||
|
Air Date
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a>
|
||||||
|
Status
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr *ngFor="let ep of season.episodes">
|
||||||
|
<td>
|
||||||
|
{{ep.episodeNumber}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ep.title}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ep.airDate | date: 'dd/MM/yyyy' }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span *ngIf="result.available" class="label label-success">Available</span>
|
||||||
|
<span *ngIf="result.approved && !result.available" class="label label-info">Processing Request</span>
|
||||||
|
<div *ngIf="result.requested && !result.available; then requested else notRequested"></div>
|
||||||
|
<template #requested>
|
||||||
|
<span *ngIf="!result.available" class="label label-warning">Pending Approval</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #notRequested>
|
||||||
|
<span *ngIf="!result.available" class="label label-danger">Not Yet Requested</span>
|
||||||
|
</template>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<a (click)="edit(u)" class="btn btn-sm btn-info-outline">Details/Edit</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
67
Ombi/Ombi/wwwroot/app/search/seriesinformation.component.ts
Normal file
67
Ombi/Ombi/wwwroot/app/search/seriesinformation.component.ts
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
|
||||||
|
import "rxjs/add/operator/takeUntil";
|
||||||
|
|
||||||
|
import { SearchService } from '../services/search.service';
|
||||||
|
import { RequestService } from '../services/request.service';
|
||||||
|
import { NotificationService } from '../services/notification.service';
|
||||||
|
|
||||||
|
import { ISearchTvResult } from '../interfaces/ISearchTvResult';
|
||||||
|
import { IRequestEngineResult } from '../interfaces/IRequestEngineResult';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ombi',
|
||||||
|
moduleId: module.id,
|
||||||
|
templateUrl: './seriesinformation.component.html'
|
||||||
|
})
|
||||||
|
export class SeriesInformationComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
constructor(private searchService: SearchService, private route: ActivatedRoute,
|
||||||
|
private requestService: RequestService, private notificationService: NotificationService) {
|
||||||
|
this.route.params
|
||||||
|
.takeUntil(this.subscriptions)
|
||||||
|
.subscribe(params => {
|
||||||
|
this.seriesId = +params['id']; // (+) converts string 'id' to a number
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private subscriptions = new Subject<void>();
|
||||||
|
|
||||||
|
result : IRequestEngineResult;
|
||||||
|
seriesId: number;
|
||||||
|
series: ISearchTvResult;
|
||||||
|
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.searchService.getShowInformation(this.seriesId)
|
||||||
|
.takeUntil(this.subscriptions)
|
||||||
|
.subscribe(x => {
|
||||||
|
this.series = x;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
request() {
|
||||||
|
this.series.requested = true;
|
||||||
|
this.requestService.requestTv(this.series)
|
||||||
|
.takeUntil(this.subscriptions)
|
||||||
|
.subscribe(x => {
|
||||||
|
this.result = x;
|
||||||
|
if (this.result.requestAdded) {
|
||||||
|
this.notificationService.success("Request Added",
|
||||||
|
`Request for ${this.series.seriesName} has been added successfully`);
|
||||||
|
} else {
|
||||||
|
this.notificationService.warning("Request Added", this.result.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.subscriptions.next();
|
||||||
|
this.subscriptions.complete();
|
||||||
|
}
|
||||||
|
}
|
|
@ -121,8 +121,7 @@
|
||||||
<li><a (click)="allSeasons(result)">All Seasons</a></li>
|
<li><a (click)="allSeasons(result)">All Seasons</a></li>
|
||||||
<li><a (click)="firstSeason(result)">First Season</a></li>
|
<li><a (click)="firstSeason(result)">First Season</a></li>
|
||||||
<li><a (click)="latestSeason(result)">Latest Season</a></li>
|
<li><a (click)="latestSeason(result)">Latest Season</a></li>
|
||||||
<li><a>Select Season...</a></li>
|
<li><a (click)="selectSeason(result)">Select ...</a></li>
|
||||||
<li><a>Select Episode...</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||||
|
import {Router} from '@angular/router';
|
||||||
import { Subject } from 'rxjs/Subject';
|
import { Subject } from 'rxjs/Subject';
|
||||||
import 'rxjs/add/operator/debounceTime';
|
import 'rxjs/add/operator/debounceTime';
|
||||||
import 'rxjs/add/operator/distinctUntilChanged';
|
import 'rxjs/add/operator/distinctUntilChanged';
|
||||||
|
@ -26,7 +27,8 @@ export class TvSearchComponent implements OnInit, OnDestroy {
|
||||||
result: IRequestEngineResult;
|
result: IRequestEngineResult;
|
||||||
searchApplied = false;
|
searchApplied = false;
|
||||||
|
|
||||||
constructor(private searchService: SearchService, private requestService: RequestService, private notificationService: NotificationService) {
|
constructor(private searchService: SearchService, private requestService: RequestService,
|
||||||
|
private notificationService: NotificationService, private route : Router) {
|
||||||
this.searchChanged
|
this.searchChanged
|
||||||
.debounceTime(600) // Wait Xms afterthe last event before emitting last event
|
.debounceTime(600) // Wait Xms afterthe last event before emitting last event
|
||||||
.distinctUntilChanged() // only emit if value is different from previous value
|
.distinctUntilChanged() // only emit if value is different from previous value
|
||||||
|
@ -128,6 +130,10 @@ export class TvSearchComponent implements OnInit, OnDestroy {
|
||||||
this.request(searchResult);
|
this.request(searchResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectSeason(searchResult: ISearchTvResult) {
|
||||||
|
this.route.navigate(['/search/show', searchResult.seriesId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private clearResults() {
|
private clearResults() {
|
||||||
this.tvResults = [];
|
this.tvResults = [];
|
||||||
|
|
|
@ -36,7 +36,12 @@ export class SearchService extends ServiceAuthHelpers {
|
||||||
// TV
|
// TV
|
||||||
searchTv(searchTerm: string): Observable<ISearchTvResult[]> {
|
searchTv(searchTerm: string): Observable<ISearchTvResult[]> {
|
||||||
return this.http.get(`${this.url}/Tv/` + searchTerm).map(this.extractData);
|
return this.http.get(`${this.url}/Tv/` + searchTerm).map(this.extractData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getShowInformation(theTvDbId: number): Observable<ISearchTvResult> {
|
||||||
|
return this.http.get(`${this.url}/Tv/info/${theTvDbId}`).map(this.extractData);
|
||||||
|
}
|
||||||
|
|
||||||
popularTv(): Observable<ISearchTvResult[]> {
|
popularTv(): Observable<ISearchTvResult[]> {
|
||||||
return this.http.get(`${this.url}/Tv/popular`).map(this.extractData);
|
return this.http.get(`${this.url}/Tv/popular`).map(this.extractData);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue