Merge branch 'develop' of https://github.com/tidusjar/Ombi into develop
60
CHANGELOG.md
|
@ -4,14 +4,68 @@
|
||||||
|
|
||||||
### **New Features**
|
### **New Features**
|
||||||
|
|
||||||
|
- Added the Recently Added Newsletter! You are welcome. [tidusjar]
|
||||||
|
|
||||||
|
- Added a new scrollbar to Ombi. [tidusjar]
|
||||||
|
|
||||||
|
- Added the ability to automatically generate the API Key on startup if it does not exist #2070. [tidusjar]
|
||||||
|
|
||||||
|
- Updated npm dependancies. [Jamie]
|
||||||
|
|
||||||
|
- Update README.md. [Jamie]
|
||||||
|
|
||||||
|
- Update README.md. [Jamie]
|
||||||
|
|
||||||
|
- Update ISSUE_TEMPLATE.md. [Jamie]
|
||||||
|
|
||||||
|
- Update appveyor.yml. [Jamie]
|
||||||
|
|
||||||
|
- Added recently added stuff. [Jamie]
|
||||||
|
|
||||||
|
- Added the recently added engine with some basic methods. [Jamie]
|
||||||
|
|
||||||
- Added the ability to refresh out backend metadata (#2078) [Jamie]
|
- Added the ability to refresh out backend metadata (#2078) [Jamie]
|
||||||
|
|
||||||
### **Fixes**
|
### **Fixes**
|
||||||
|
|
||||||
- Fixed #2074 and #2079. [Jamie]
|
- Specific favicons for different platforms. [louis-lau]
|
||||||
|
|
||||||
|
- MovieDbId was switched to string fron number so accomodated for change. [Anojh]
|
||||||
|
|
||||||
|
- Removing duplicate functions. [Anojh Thayaparan]
|
||||||
|
|
||||||
|
- Conflict resolving and adopting Jamie's new method. [Anojh]
|
||||||
|
|
||||||
|
- Wrote new calls to just get poster and bg. [Anojh]
|
||||||
|
|
||||||
|
- Fix for issue #1907, which is to add content poster and bg to issue details page. [Anojh]
|
||||||
|
|
||||||
|
- Dynamic Background Animation. [Anojh]
|
||||||
|
|
||||||
|
- Improved the message for #2037. [tidusjar]
|
||||||
|
|
||||||
|
- Improved the way we use the notification variables, we have now split out the Username and Alias (Requested User is depricated but not removed) [tidusjar]
|
||||||
|
|
||||||
|
- Removed redundant timers. [Anojh]
|
||||||
|
|
||||||
|
- More optimizations by reducing requests. [Anojh]
|
||||||
|
|
||||||
|
- Improved version. [Anojh]
|
||||||
|
|
||||||
|
- Dynamic Background Animation. [Anojh]
|
||||||
|
|
||||||
|
- Fixed #2055 and #1903. [Jamie]
|
||||||
|
|
||||||
- Small changes to the auto updater, let's see how this works. [Jamie]
|
- Small changes to the auto updater, let's see how this works. [Jamie]
|
||||||
|
|
||||||
|
- Fixed build. [Jamie]
|
||||||
|
|
||||||
|
- Fixed the update check for the master build. [Jamie]
|
||||||
|
|
||||||
|
- Fixed build. [Jamie]
|
||||||
|
|
||||||
|
- Fixed #2074 and #2079. [Jamie]
|
||||||
|
|
||||||
|
|
||||||
## v3.0.3030 (2018-03-14)
|
## v3.0.3030 (2018-03-14)
|
||||||
|
|
||||||
|
@ -19,6 +73,10 @@
|
||||||
|
|
||||||
- Updated the .Net core dependancies #2072. [Jamie]
|
- Updated the .Net core dependancies #2072. [Jamie]
|
||||||
|
|
||||||
|
### **Fixes**
|
||||||
|
|
||||||
|
- Delete Ombi.testdb. [Jamie]
|
||||||
|
|
||||||
|
|
||||||
## v3.0.3020 (2018-03-13)
|
## v3.0.3020 (2018-03-13)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Ombi.Core.Models.Requests;
|
||||||
using Ombi.Core.Models.Search;
|
using Ombi.Core.Models.Search;
|
||||||
using Ombi.Store.Entities.Requests;
|
using Ombi.Store.Entities.Requests;
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ namespace Ombi.Core.Engine.Interfaces
|
||||||
{
|
{
|
||||||
|
|
||||||
Task RemoveTvRequest(int requestId);
|
Task RemoveTvRequest(int requestId);
|
||||||
Task<RequestEngineResult> RequestTvShow(SearchTvShowViewModel tv);
|
Task<RequestEngineResult> RequestTvShow(TvRequestViewModel tv);
|
||||||
Task<RequestEngineResult> DenyChildRequest(int requestId);
|
Task<RequestEngineResult> DenyChildRequest(int requestId);
|
||||||
Task<IEnumerable<TvRequests>> SearchTvRequest(string search);
|
Task<IEnumerable<TvRequests>> SearchTvRequest(string search);
|
||||||
Task<IEnumerable<TreeNode<TvRequests, List<ChildRequests>>>> SearchTvRequestTree(string search);
|
Task<IEnumerable<TreeNode<TvRequests, List<ChildRequests>>>> SearchTvRequestTree(string search);
|
||||||
|
|
|
@ -43,13 +43,13 @@ namespace Ombi.Core.Engine
|
||||||
private IAuditRepository Audit { get; }
|
private IAuditRepository Audit { get; }
|
||||||
private readonly IRepository<RequestLog> _requestLog;
|
private readonly IRepository<RequestLog> _requestLog;
|
||||||
|
|
||||||
public async Task<RequestEngineResult> RequestTvShow(SearchTvShowViewModel tv)
|
public async Task<RequestEngineResult> RequestTvShow(TvRequestViewModel tv)
|
||||||
{
|
{
|
||||||
var user = await GetUser();
|
var user = await GetUser();
|
||||||
|
|
||||||
var tvBuilder = new TvShowRequestBuilder(TvApi);
|
var tvBuilder = new TvShowRequestBuilder(TvApi);
|
||||||
(await tvBuilder
|
(await tvBuilder
|
||||||
.GetShowInfo(tv.Id))
|
.GetShowInfo(tv.TvDbId))
|
||||||
.CreateTvList(tv)
|
.CreateTvList(tv)
|
||||||
.CreateChild(tv, user.Id);
|
.CreateChild(tv, user.Id);
|
||||||
|
|
||||||
|
@ -78,9 +78,9 @@ namespace Ombi.Core.Engine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await Audit.Record(AuditType.Added, AuditArea.TvRequest, $"Added Request {tv.Title}", Username);
|
await Audit.Record(AuditType.Added, AuditArea.TvRequest, $"Added Request {tvBuilder.ChildRequest.Title}", Username);
|
||||||
|
|
||||||
var existingRequest = await TvRepository.Get().FirstOrDefaultAsync(x => x.TvDbId == tv.Id);
|
var existingRequest = await TvRepository.Get().FirstOrDefaultAsync(x => x.TvDbId == tv.TvDbId);
|
||||||
if (existingRequest != null)
|
if (existingRequest != null)
|
||||||
{
|
{
|
||||||
// Remove requests we already have, we just want new ones
|
// Remove requests we already have, we just want new ones
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Ombi.Api.TvMaze;
|
using Ombi.Api.TvMaze;
|
||||||
using Ombi.Api.TvMaze.Models;
|
using Ombi.Api.TvMaze.Models;
|
||||||
|
using Ombi.Core.Models.Requests;
|
||||||
using Ombi.Core.Models.Search;
|
using Ombi.Core.Models.Search;
|
||||||
using Ombi.Helpers;
|
using Ombi.Helpers;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
|
@ -23,7 +24,7 @@ namespace Ombi.Core.Helpers
|
||||||
private ITvMazeApi TvApi { get; }
|
private ITvMazeApi TvApi { get; }
|
||||||
|
|
||||||
public ChildRequests ChildRequest { get; set; }
|
public ChildRequests ChildRequest { get; set; }
|
||||||
public List<SeasonRequests> TvRequests { get; protected set; }
|
public List<SeasonsViewModel> TvRequests { get; protected set; }
|
||||||
public string PosterPath { get; protected set; }
|
public string PosterPath { get; protected set; }
|
||||||
public DateTime FirstAir { get; protected set; }
|
public DateTime FirstAir { get; protected set; }
|
||||||
public TvRequests NewRequest { get; protected set; }
|
public TvRequests NewRequest { get; protected set; }
|
||||||
|
@ -33,7 +34,7 @@ namespace Ombi.Core.Helpers
|
||||||
{
|
{
|
||||||
ShowInfo = await TvApi.ShowLookupByTheTvDbId(id);
|
ShowInfo = await TvApi.ShowLookupByTheTvDbId(id);
|
||||||
|
|
||||||
DateTime.TryParse(ShowInfo.premiered, out DateTime dt);
|
DateTime.TryParse(ShowInfo.premiered, out var dt);
|
||||||
|
|
||||||
FirstAir = dt;
|
FirstAir = dt;
|
||||||
|
|
||||||
|
@ -43,37 +44,29 @@ namespace Ombi.Core.Helpers
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TvShowRequestBuilder CreateChild(SearchTvShowViewModel model, string userId)
|
public TvShowRequestBuilder CreateChild(TvRequestViewModel model, string userId)
|
||||||
{
|
{
|
||||||
ChildRequest = new ChildRequests
|
ChildRequest = new ChildRequests
|
||||||
{
|
{
|
||||||
Id = model.Id,
|
Id = model.TvDbId,
|
||||||
RequestType = RequestType.TvShow,
|
RequestType = RequestType.TvShow,
|
||||||
RequestedDate = DateTime.UtcNow,
|
RequestedDate = DateTime.UtcNow,
|
||||||
Approved = false,
|
Approved = false,
|
||||||
RequestedUserId = userId,
|
RequestedUserId = userId,
|
||||||
SeasonRequests = new List<SeasonRequests>(),
|
SeasonRequests = new List<SeasonRequests>(),
|
||||||
Title = model.Title,
|
Title = ShowInfo.name,
|
||||||
SeriesType = ShowInfo.type.Equals("Animation", StringComparison.CurrentCultureIgnoreCase) ? SeriesType.Anime : SeriesType.Standard
|
SeriesType = ShowInfo.type.Equals("Animation", StringComparison.CurrentCultureIgnoreCase) ? SeriesType.Anime : SeriesType.Standard
|
||||||
};
|
};
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TvShowRequestBuilder CreateTvList(SearchTvShowViewModel tv)
|
public TvShowRequestBuilder CreateTvList(TvRequestViewModel tv)
|
||||||
{
|
{
|
||||||
TvRequests = new List<SeasonRequests>();
|
TvRequests = new List<SeasonsViewModel>();
|
||||||
// Only have the TV requests we actually requested and not everything
|
// Only have the TV requests we actually requested and not everything
|
||||||
foreach (var season in tv.SeasonRequests)
|
foreach (var season in tv.Seasons)
|
||||||
{
|
{
|
||||||
for (int i = season.Episodes.Count - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (!season.Episodes[i].Requested)
|
|
||||||
{
|
|
||||||
season.Episodes.RemoveAt(i); // Remove the episode since it's not requested
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (season.Episodes.Any())
|
if (season.Episodes.Any())
|
||||||
{
|
{
|
||||||
TvRequests.Add(season);
|
TvRequests.Add(season);
|
||||||
|
@ -81,11 +74,10 @@ namespace Ombi.Core.Helpers
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<TvShowRequestBuilder> BuildEpisodes(SearchTvShowViewModel tv)
|
public async Task<TvShowRequestBuilder> BuildEpisodes(TvRequestViewModel tv)
|
||||||
{
|
{
|
||||||
if (tv.RequestAll)
|
if (tv.RequestAll)
|
||||||
{
|
{
|
||||||
|
@ -173,26 +165,68 @@ namespace Ombi.Core.Helpers
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// It's a custom request
|
// It's a custom request
|
||||||
ChildRequest.SeasonRequests = TvRequests;
|
var seasonRequests = new List<SeasonRequests>();
|
||||||
|
var episodes = await TvApi.EpisodeLookup(ShowInfo.id);
|
||||||
|
foreach (var ep in episodes)
|
||||||
|
{
|
||||||
|
var existingSeasonRequest = seasonRequests.FirstOrDefault(x => x.SeasonNumber == ep.season);
|
||||||
|
if (existingSeasonRequest != null)
|
||||||
|
{
|
||||||
|
var requestedSeason = tv.Seasons.FirstOrDefault(x => x.SeasonNumber == ep.season);
|
||||||
|
var requestedEpisode = requestedSeason?.Episodes?.Any(x => x.EpisodeNumber == ep.number) ?? false;
|
||||||
|
if (requestedSeason != null && requestedEpisode)
|
||||||
|
{
|
||||||
|
// We already have this, let's just add the episodes to it
|
||||||
|
existingSeasonRequest.Episodes.Add(new EpisodeRequests
|
||||||
|
{
|
||||||
|
EpisodeNumber = ep.number,
|
||||||
|
AirDate = FormatDate(ep.airdate),
|
||||||
|
Title = ep.name,
|
||||||
|
Url = ep.url,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var newRequest = new SeasonRequests {SeasonNumber = ep.season};
|
||||||
|
var requestedSeason = tv.Seasons.FirstOrDefault(x => x.SeasonNumber == ep.season);
|
||||||
|
var requestedEpisode = requestedSeason?.Episodes?.Any(x => x.EpisodeNumber == ep.number) ?? false;
|
||||||
|
if (requestedSeason != null && requestedEpisode)
|
||||||
|
{
|
||||||
|
newRequest.Episodes.Add(new EpisodeRequests
|
||||||
|
{
|
||||||
|
EpisodeNumber = ep.number,
|
||||||
|
AirDate = FormatDate(ep.airdate),
|
||||||
|
Title = ep.name,
|
||||||
|
Url = ep.url,
|
||||||
|
});
|
||||||
|
seasonRequests.Add(newRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var s in seasonRequests)
|
||||||
|
{
|
||||||
|
ChildRequest.SeasonRequests.Add(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public TvShowRequestBuilder CreateNewRequest(SearchTvShowViewModel tv)
|
public TvShowRequestBuilder CreateNewRequest(TvRequestViewModel tv)
|
||||||
{
|
{
|
||||||
NewRequest = new TvRequests
|
NewRequest = new TvRequests
|
||||||
{
|
{
|
||||||
Id = tv.Id,
|
|
||||||
Overview = ShowInfo.summary.RemoveHtml(),
|
Overview = ShowInfo.summary.RemoveHtml(),
|
||||||
PosterPath = PosterPath,
|
PosterPath = PosterPath,
|
||||||
Title = ShowInfo.name,
|
Title = ShowInfo.name,
|
||||||
ReleaseDate = FirstAir,
|
ReleaseDate = FirstAir,
|
||||||
Status = ShowInfo.status,
|
Status = ShowInfo.status,
|
||||||
ImdbId = ShowInfo.externals?.imdb ?? string.Empty,
|
ImdbId = ShowInfo.externals?.imdb ?? string.Empty,
|
||||||
TvDbId = tv.Id,
|
TvDbId = tv.TvDbId,
|
||||||
ChildRequests = new List<ChildRequests>(),
|
ChildRequests = new List<ChildRequests>(),
|
||||||
TotalSeasons = tv.SeasonRequests.Count()
|
TotalSeasons = tv.Seasons.Count()
|
||||||
};
|
};
|
||||||
NewRequest.ChildRequests.Add(ChildRequest);
|
NewRequest.ChildRequests.Add(ChildRequest);
|
||||||
|
|
||||||
|
|
25
src/Ombi.Core/Models/Requests/TvRequestViewModel.cs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Ombi.Core.Models.Requests
|
||||||
|
{
|
||||||
|
public class TvRequestViewModel
|
||||||
|
{
|
||||||
|
public bool RequestAll { get; set; }
|
||||||
|
public bool LatestSeason { get; set; }
|
||||||
|
public bool FirstSeason { get; set; }
|
||||||
|
public int TvDbId { get; set; }
|
||||||
|
public List<SeasonsViewModel> Seasons { get; set; } = new List<SeasonsViewModel>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SeasonsViewModel
|
||||||
|
{
|
||||||
|
public int SeasonNumber { get; set; }
|
||||||
|
public List<EpisodesViewModel> Episodes { get; set; } = new List<EpisodesViewModel>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EpisodesViewModel
|
||||||
|
{
|
||||||
|
public int EpisodeNumber { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -336,8 +336,16 @@ namespace Ombi.Schedule.Jobs.Ombi
|
||||||
TableData(sb);
|
TableData(sb);
|
||||||
|
|
||||||
Href(sb, $"https://www.imdb.com/title/{info.ImdbId}/");
|
Href(sb, $"https://www.imdb.com/title/{info.ImdbId}/");
|
||||||
var releaseDate = DateTime.Parse(info.ReleaseDate);
|
var releaseDate = string.Empty;
|
||||||
Header(sb, 3, $"{info.Title} ({releaseDate.Year})");
|
try
|
||||||
|
{
|
||||||
|
releaseDate = $"({DateTime.Parse(info.ReleaseDate).Year})";
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// Swallow, couldn't parse the date
|
||||||
|
}
|
||||||
|
Header(sb, 3, $"{info.Title} {releaseDate}");
|
||||||
EndTag(sb, "a");
|
EndTag(sb, "a");
|
||||||
|
|
||||||
if (info.Genres.Any())
|
if (info.Genres.Any())
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace Ombi.Store.Repository.Requests
|
||||||
public class SeasonRequests : Entity
|
public class SeasonRequests : Entity
|
||||||
{
|
{
|
||||||
public int SeasonNumber { get; set; }
|
public int SeasonNumber { get; set; }
|
||||||
public List<EpisodeRequests> Episodes { get; set; }
|
public List<EpisodeRequests> Episodes { get; set; } = new List<EpisodeRequests>();
|
||||||
|
|
||||||
public int ChildRequestId { get; set; }
|
public int ChildRequestId { get; set; }
|
||||||
[ForeignKey(nameof(ChildRequestId))]
|
[ForeignKey(nameof(ChildRequestId))]
|
||||||
|
|
|
@ -30,3 +30,20 @@ export interface ISearchTvResult {
|
||||||
firstSeason: boolean;
|
firstSeason: boolean;
|
||||||
latestSeason: boolean;
|
latestSeason: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ITvRequestViewModel {
|
||||||
|
requestAll: boolean;
|
||||||
|
firstSeason: boolean;
|
||||||
|
latestSeason: boolean;
|
||||||
|
tvDbId: number;
|
||||||
|
seasons: ISeasonsViewModel[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ISeasonsViewModel {
|
||||||
|
seasonNumber: number;
|
||||||
|
episodes: IEpisodesViewModel[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IEpisodesViewModel {
|
||||||
|
episodeNumber: number;
|
||||||
|
}
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
<div *ngIf="issue">
|
<div *ngIf="issue">
|
||||||
|
<div class="myBg backdrop" [style.background-image]="backgroundPath"></div>
|
||||||
|
<div class="tint" style="background-image: linear-gradient(to bottom, rgba(0,0,0,0.6) 0%,rgba(0,0,0,0.6) 100%);"></div>
|
||||||
<h1>{{issue.title}} </h1>
|
<h1>{{issue.title}} </h1>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
<img class="img-responsive poster" src="{{posterPath}}" alt="poster">
|
||||||
<span class="label label-info">{{IssueStatus[issue.status]}}</span>
|
<span class="label label-info">{{IssueStatus[issue.status]}}</span>
|
||||||
<span class="label label-success">{{issue.issueCategory.value}}</span>
|
<span class="label label-success">{{issue.issueCategory.value}}</span>
|
||||||
|
|
||||||
<h3 *ngIf="issue.userReported?.alias">{{'Issues.ReportedBy' | translate}}: {{issue.userReported.alias}}</h3>
|
<h3 *ngIf="issue.userReported?.alias">{{'Issues.ReportedBy' | translate}}: {{issue.userReported.alias}}</h3>
|
||||||
<h3 *ngIf="!issue.userReported?.alias">{{'Issues.ReportedBy' | translate}}: {{issue.userReported.userName}}</h3>
|
<h3 *ngIf="!issue.userReported?.alias">{{'Issues.ReportedBy' | translate}}: {{issue.userReported.userName}}</h3>
|
||||||
<h3 *ngIf="issue.subject">{{'Issues.Subject' | translate}}: {{issue.subject}}</h3>
|
<h3 *ngIf="issue.subject">{{'Issues.Subject' | translate}}: {{issue.subject}}</h3>
|
||||||
<br>
|
<br>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="description" class="control-label" [translate]="'Issues.Description'"></label>
|
<label for="description" class="control-label" [translate]="'Issues.Description'"></label>
|
||||||
<div>
|
<div>
|
||||||
|
@ -26,7 +29,8 @@
|
||||||
<div class="panel-heading top-bar">
|
<div class="panel-heading top-bar">
|
||||||
<div class="col-md-8 col-xs-8">
|
<div class="col-md-8 col-xs-8">
|
||||||
<h3 class="panel-title">
|
<h3 class="panel-title">
|
||||||
<span class="glyphicon glyphicon-comment"></span> {{'Issues.Comments' | translate}}</h3>
|
<span class="glyphicon glyphicon-comment"></span> {{'Issues.Comments' | translate}}
|
||||||
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -51,8 +55,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-footer">
|
<div class="panel-footer">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="btn-input" type="text" class="form-control input-sm chat_input" [(ngModel)]="newComment.comment" [attr.placeholder]="'Issues.WriteMessagePlaceholder' | translate"
|
<input id="btn-input" type="text" class="form-control input-sm chat_input" [(ngModel)]="newComment.comment" [attr.placeholder]="'Issues.WriteMessagePlaceholder' | translate" />
|
||||||
/>
|
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button class="btn btn-primary btn-sm" id="btn-chat" (click)="addComment()" [translate]="'Issues.SendMessageButton'"></button>
|
<button class="btn btn-primary btn-sm" id="btn-chat" (click)="addComment()" [translate]="'Issues.SendMessageButton'"></button>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -64,6 +64,15 @@ body{
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
.myBg {
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
.tint {
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
img-responsive poster {
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
img {
|
img {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -2,8 +2,9 @@ import { Component, OnInit } from "@angular/core";
|
||||||
import { ActivatedRoute } from "@angular/router";
|
import { ActivatedRoute } from "@angular/router";
|
||||||
|
|
||||||
import { AuthService } from "../auth/auth.service";
|
import { AuthService } from "../auth/auth.service";
|
||||||
import { IssuesService, NotificationService, SettingsService } from "../services";
|
import { ImageService, IssuesService, NotificationService, SettingsService } from "../services";
|
||||||
|
|
||||||
|
import { DomSanitizer } from "@angular/platform-browser";
|
||||||
import { IIssues, IIssuesChat, IIssueSettings, INewIssueComments, IssueStatus } from "../interfaces";
|
import { IIssues, IIssuesChat, IIssueSettings, INewIssueComments, IssueStatus } from "../interfaces";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -22,6 +23,8 @@ export class IssueDetailsComponent implements OnInit {
|
||||||
public IssueStatus = IssueStatus;
|
public IssueStatus = IssueStatus;
|
||||||
public isAdmin: boolean;
|
public isAdmin: boolean;
|
||||||
public settings: IIssueSettings;
|
public settings: IIssueSettings;
|
||||||
|
public backgroundPath: any;
|
||||||
|
public posterPath: any;
|
||||||
|
|
||||||
private issueId: number;
|
private issueId: number;
|
||||||
|
|
||||||
|
@ -29,7 +32,9 @@ export class IssueDetailsComponent implements OnInit {
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
private notificationService: NotificationService) {
|
private notificationService: NotificationService,
|
||||||
|
private imageService: ImageService,
|
||||||
|
private sanitizer: DomSanitizer) {
|
||||||
this.route.params
|
this.route.params
|
||||||
.subscribe((params: any) => {
|
.subscribe((params: any) => {
|
||||||
this.issueId = parseInt(params.id);
|
this.issueId = parseInt(params.id);
|
||||||
|
@ -56,8 +61,8 @@ export class IssueDetailsComponent implements OnInit {
|
||||||
providerId: x.providerId,
|
providerId: x.providerId,
|
||||||
userReported: x.userReported,
|
userReported: x.userReported,
|
||||||
};
|
};
|
||||||
|
this.setBackground(x);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.loadComments();
|
this.loadComments();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,4 +90,26 @@ export class IssueDetailsComponent implements OnInit {
|
||||||
private loadComments() {
|
private loadComments() {
|
||||||
this.issueService.getComments(this.issueId).subscribe(x => this.comments = x);
|
this.issueService.getComments(this.issueId).subscribe(x => this.comments = x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setBackground(issue: any) {
|
||||||
|
if (issue.requestType === 1) {
|
||||||
|
this.imageService.getMovieBackground(issue.providerId).subscribe(x => {
|
||||||
|
this.backgroundPath = this.sanitizer.bypassSecurityTrustStyle
|
||||||
|
("url(" + x + ")");
|
||||||
|
});
|
||||||
|
this.imageService.getMoviePoster(issue.providerId).subscribe(x => {
|
||||||
|
this.posterPath = x.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.imageService.getTvBackground(Number(issue.providerId)).subscribe(x => {
|
||||||
|
this.backgroundPath = this.sanitizer.bypassSecurityTrustStyle
|
||||||
|
("url(" + x + ")");
|
||||||
|
});
|
||||||
|
this.imageService.getTvPoster(Number(issue.providerId)).subscribe(x => {
|
||||||
|
this.posterPath = x.toString();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
|
||||||
import { OrderModule } from "ngx-order-pipe";
|
import { OrderModule } from "ngx-order-pipe";
|
||||||
import { PaginatorModule, SharedModule, TabViewModule } from "primeng/primeng";
|
import { PaginatorModule, SharedModule, TabViewModule } from "primeng/primeng";
|
||||||
|
|
||||||
import { IdentityService } from "../services";
|
import { IdentityService, SearchService } from "../services";
|
||||||
|
|
||||||
import { AuthGuard } from "../auth/auth.guard";
|
import { AuthGuard } from "../auth/auth.guard";
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ const routes: Routes = [
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
IdentityService,
|
IdentityService,
|
||||||
|
SearchService,
|
||||||
],
|
],
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -207,7 +207,7 @@
|
||||||
|
|
||||||
|
|
||||||
<issue-report [movie]="true" [visible]="issuesBarVisible" (visibleChange)="issuesBarVisible = $event;" [title]="issueRequest?.title"
|
<issue-report [movie]="true" [visible]="issuesBarVisible" (visibleChange)="issuesBarVisible = $event;" [title]="issueRequest?.title"
|
||||||
[issueCategory]="issueCategorySelected" [id]="issueRequest?.id" [providerId]=""></issue-report>
|
[issueCategory]="issueCategorySelected" [id]="issueRequest?.id" [providerId]="issueProviderId"></issue-report>
|
||||||
|
|
||||||
|
|
||||||
<p-sidebar [(visible)]="filterDisplay" styleClass="ui-sidebar-md side-back side-small">
|
<p-sidebar [(visible)]="filterDisplay" styleClass="ui-sidebar-md side-back side-small">
|
||||||
|
|
|
@ -105,4 +105,4 @@
|
||||||
|
|
||||||
|
|
||||||
<issue-report [movie]="false" [visible]="issuesBarVisible" [title]="issueRequest?.title"
|
<issue-report [movie]="false" [visible]="issuesBarVisible" [title]="issueRequest?.title"
|
||||||
[issueCategory]="issueCategorySelected" [id]="issueRequest?.id" (visibleChange)="issuesBarVisible = $event;"></issue-report>
|
[issueCategory]="issueCategorySelected" [id]="issueRequest?.id" [providerId]="issueProviderId" (visibleChange)="issuesBarVisible = $event;"></issue-report>
|
|
@ -105,6 +105,7 @@ export class TvRequestChildrenComponent {
|
||||||
this.issueRequest = req;
|
this.issueRequest = req;
|
||||||
this.issueCategorySelected = catId;
|
this.issueCategorySelected = catId;
|
||||||
this.issuesBarVisible = true;
|
this.issuesBarVisible = true;
|
||||||
|
this.issueProviderId = req.id.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private removeRequestFromUi(key: IChildRequests) {
|
private removeRequestFromUi(key: IChildRequests) {
|
||||||
|
|
|
@ -90,12 +90,6 @@ export class TvRequestsComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
|
|
||||||
const profile = <ISonarrProfile>{name:"test",id:1 };
|
|
||||||
const folder = <ISonarrRootFolder>{path:"testpath", id:1};
|
|
||||||
|
|
||||||
this.sonarrProfiles.push(profile);
|
|
||||||
this.sonarrRootFolders.push(folder);
|
|
||||||
this.amountToLoad = 1000;
|
this.amountToLoad = 1000;
|
||||||
this.currentlyLoaded = 1000;
|
this.currentlyLoaded = 1000;
|
||||||
this.tvRequests = [];
|
this.tvRequests = [];
|
||||||
|
@ -204,7 +198,7 @@ export class TvRequestsComponent implements OnInit {
|
||||||
this.loadInit();
|
this.loadInit();
|
||||||
}
|
}
|
||||||
private loadBackdrop(val: TreeNode): void {
|
private loadBackdrop(val: TreeNode): void {
|
||||||
this.imageService.getTvBanner(val.data.id).subscribe(x => {
|
this.imageService.getTvBanner(val.data.tvDbId).subscribe(x => {
|
||||||
val.data.background = this.sanitizer.bypassSecurityTrustStyle
|
val.data.background = this.sanitizer.bypassSecurityTrustStyle
|
||||||
("url(" + x + ")");
|
("url(" + x + ")");
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { NotificationService } from "../services";
|
||||||
import { RequestService } from "../services";
|
import { RequestService } from "../services";
|
||||||
import { SearchService } from "../services";
|
import { SearchService } from "../services";
|
||||||
|
|
||||||
import { INewSeasonRequests, IRequestEngineResult } from "../interfaces";
|
import { INewSeasonRequests, IRequestEngineResult, ISeasonsViewModel, ITvRequestViewModel } from "../interfaces";
|
||||||
import { IEpisodesRequests } from "../interfaces";
|
import { IEpisodesRequests } from "../interfaces";
|
||||||
import { ISearchTvResult } from "../interfaces";
|
import { ISearchTvResult } from "../interfaces";
|
||||||
|
|
||||||
|
@ -46,7 +46,22 @@ export class SeriesInformationComponent implements OnInit {
|
||||||
|
|
||||||
this.series.requested = true;
|
this.series.requested = true;
|
||||||
|
|
||||||
this.requestService.requestTv(this.series)
|
const viewModel = <ITvRequestViewModel>{ firstSeason: this.series.firstSeason, latestSeason: this.series.latestSeason, requestAll: this.series.requestAll, tvDbId: this.series.id};
|
||||||
|
viewModel.seasons = [];
|
||||||
|
this.series.seasonRequests.forEach((season) => {
|
||||||
|
const seasonsViewModel = <ISeasonsViewModel>{seasonNumber: season.seasonNumber, episodes: []};
|
||||||
|
season.episodes.forEach(ep => {
|
||||||
|
if(!this.series.latestSeason || !this.series.requestAll || !this.series.firstSeason) {
|
||||||
|
if(ep.requested) {
|
||||||
|
seasonsViewModel.episodes.push({episodeNumber: ep.episodeNumber});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
viewModel.seasons.push(seasonsViewModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.requestService.requestTv(viewModel)
|
||||||
.subscribe(x => {
|
.subscribe(x => {
|
||||||
this.result = x as IRequestEngineResult;
|
this.result = x as IRequestEngineResult;
|
||||||
if (this.result.result) {
|
if (this.result.result) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { ImageService, NotificationService, RequestService, SearchService} from
|
||||||
|
|
||||||
import { TreeNode } from "primeng/primeng";
|
import { TreeNode } from "primeng/primeng";
|
||||||
import { IRequestEngineResult } from "../interfaces";
|
import { IRequestEngineResult } from "../interfaces";
|
||||||
import { IIssueCategory, ISearchTvResult } from "../interfaces";
|
import { IIssueCategory, ISearchTvResult, ISeasonsViewModel, ITvRequestViewModel } from "../interfaces";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "tv-search",
|
selector: "tv-search",
|
||||||
|
@ -154,7 +154,23 @@ export class TvSearchComponent implements OnInit {
|
||||||
if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMovie")) {
|
if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMovie")) {
|
||||||
searchResult.approved = true;
|
searchResult.approved = true;
|
||||||
}
|
}
|
||||||
this.requestService.requestTv(searchResult)
|
|
||||||
|
const viewModel = <ITvRequestViewModel>{ firstSeason: searchResult.firstSeason, latestSeason: searchResult.latestSeason, requestAll: searchResult.requestAll, tvDbId: searchResult.id};
|
||||||
|
viewModel.seasons = [];
|
||||||
|
searchResult.seasonRequests.forEach((season) => {
|
||||||
|
const seasonsViewModel = <ISeasonsViewModel>{seasonNumber: season.seasonNumber, episodes: []};
|
||||||
|
season.episodes.forEach(ep => {
|
||||||
|
if(!searchResult.latestSeason || !searchResult.requestAll || !searchResult.firstSeason) {
|
||||||
|
if(ep.requested) {
|
||||||
|
seasonsViewModel.episodes.push({episodeNumber: ep.episodeNumber});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
viewModel.seasons.push(seasonsViewModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.requestService.requestTv(viewModel)
|
||||||
.subscribe(x => {
|
.subscribe(x => {
|
||||||
this.result = x;
|
this.result = x;
|
||||||
if (this.result.result) {
|
if (this.result.result) {
|
||||||
|
|
|
@ -20,10 +20,21 @@ export class ImageService extends ServiceHelpers {
|
||||||
public getTvBanner(tvdbid: number): Observable<string> {
|
public getTvBanner(tvdbid: number): Observable<string> {
|
||||||
return this.http.get<string>(`${this.url}tv/${tvdbid}`, {headers: this.headers});
|
return this.http.get<string>(`${this.url}tv/${tvdbid}`, {headers: this.headers});
|
||||||
}
|
}
|
||||||
public getMoviePoster(themoviedbid: string): Observable<string> {
|
|
||||||
return this.http.get<string>(`${this.url}poster/movie/${themoviedbid}`, {headers: this.headers});
|
public getMoviePoster(movieDbId: string): Observable<string> {
|
||||||
|
return this.http.get<string>(`${this.url}poster/movie/${movieDbId}`, { headers: this.headers });
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTvPoster(tvdbid: number): Observable<string> {
|
public getTvPoster(tvdbid: number): Observable<string> {
|
||||||
return this.http.get<string>(`${this.url}poster/tv/${tvdbid}`, {headers: this.headers});
|
return this.http.get<string>(`${this.url}poster/tv/${tvdbid}`, { headers: this.headers });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getMovieBackground(movieDbId: string): Observable<string> {
|
||||||
|
return this.http.get<string>(`${this.url}background/movie/${movieDbId}`, { headers: this.headers });
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTvBackground(tvdbid: number): Observable<string> {
|
||||||
|
return this.http.get<string>(`${this.url}background/tv/${tvdbid}`, { headers: this.headers });
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Observable } from "rxjs/Rx";
|
||||||
import { TreeNode } from "primeng/primeng";
|
import { TreeNode } from "primeng/primeng";
|
||||||
import { IRequestEngineResult } from "../interfaces";
|
import { IRequestEngineResult } from "../interfaces";
|
||||||
import { IChildRequests, IFilter, IMovieRequestModel, IMovieRequests, IMovieUpdateModel, ITvRequests, ITvUpdateModel } from "../interfaces";
|
import { IChildRequests, IFilter, IMovieRequestModel, IMovieRequests, IMovieUpdateModel, ITvRequests, ITvUpdateModel } from "../interfaces";
|
||||||
import { ISearchTvResult } from "../interfaces";
|
import { ITvRequestViewModel } from "../interfaces";
|
||||||
import { ServiceHelpers } from "./service.helpers";
|
import { ServiceHelpers } from "./service.helpers";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -20,7 +20,7 @@ export class RequestService extends ServiceHelpers {
|
||||||
return this.http.post<IRequestEngineResult>(`${this.url}Movie/`, JSON.stringify(movie), {headers: this.headers});
|
return this.http.post<IRequestEngineResult>(`${this.url}Movie/`, JSON.stringify(movie), {headers: this.headers});
|
||||||
}
|
}
|
||||||
|
|
||||||
public requestTv(tv: ISearchTvResult): Observable<IRequestEngineResult> {
|
public requestTv(tv: ITvRequestViewModel): Observable<IRequestEngineResult> {
|
||||||
return this.http.post<IRequestEngineResult>(`${this.url}TV/`, JSON.stringify(tv), {headers: this.headers});
|
return this.http.post<IRequestEngineResult>(`${this.url}TV/`, JSON.stringify(tv), {headers: this.headers});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<!-- <div class="form-group">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<input type="checkbox" id="enable" [(ngModel)]="settings.recentlyAddedPage" [checked]="settings.recentlyAddedPage">
|
<input type="checkbox" id="enable" [(ngModel)]="settings.recentlyAddedPage" [checked]="settings.recentlyAddedPage">
|
||||||
<label for="enable">Enable Recently Added Page</label>
|
<label for="enable">Enable Recently Added Page</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="logo" class="control-label">Custom Logo</label>
|
<label for="logo" class="control-label">Custom Logo</label>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<settings-menu></settings-menu>
|
<settings-menu></settings-menu>
|
||||||
|
|
||||||
<wiki [url]="'https://github.com/tidusjar/Ombi/wiki/Newsletter'"></wiki>
|
<wiki [url]="'https://github.com/tidusjar/Ombi/wiki/Newsletter-Settings'"></wiki>
|
||||||
<div *ngIf="settings">
|
<div *ngIf="settings">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Newsletter</legend>
|
<legend>Newsletter</legend>
|
||||||
|
|
|
@ -15,6 +15,8 @@ export class IssuesReportComponent {
|
||||||
@Input() public issueCategory: IIssueCategory;
|
@Input() public issueCategory: IIssueCategory;
|
||||||
@Input() public movie: boolean;
|
@Input() public movie: boolean;
|
||||||
@Input() public providerId: string;
|
@Input() public providerId: string;
|
||||||
|
@Input() public background: string;
|
||||||
|
@Input() public posterPath: string;
|
||||||
|
|
||||||
@Output() public visibleChange = new EventEmitter<boolean>();
|
@Output() public visibleChange = new EventEmitter<boolean>();
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Ombi.Api.FanartTv;
|
using Ombi.Api.FanartTv;
|
||||||
using Ombi.Store.Repository;
|
using Ombi.Store.Repository;
|
||||||
using System;
|
using System;
|
||||||
|
@ -117,6 +117,56 @@ namespace Ombi.Controllers
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("background/movie/{movieDbId}")]
|
||||||
|
public async Task<string> GetMovieBackground(string movieDbId)
|
||||||
|
{
|
||||||
|
var key = await _cache.GetOrAdd(CacheKeys.FanartTv, async () => await Config.Get(Store.Entities.ConfigurationTypes.FanartTv), DateTime.Now.AddDays(1));
|
||||||
|
|
||||||
|
var images = await FanartTvApi.GetMovieImages(movieDbId, key.Value);
|
||||||
|
|
||||||
|
if (images == null)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (images.moviebackground?.Any() ?? false)
|
||||||
|
{
|
||||||
|
var enImage = images.moviebackground.Where(x => x.lang == "en").OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||||
|
if (enImage == null)
|
||||||
|
{
|
||||||
|
return images.moviebackground.OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||||
|
}
|
||||||
|
return enImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("background/tv/{tvdbid}")]
|
||||||
|
public async Task<string> GetTvBackground(int tvdbid)
|
||||||
|
{
|
||||||
|
var key = await _cache.GetOrAdd(CacheKeys.FanartTv, async () => await Config.Get(Store.Entities.ConfigurationTypes.FanartTv), DateTime.Now.AddDays(1));
|
||||||
|
|
||||||
|
var images = await FanartTvApi.GetTvImages(tvdbid, key.Value);
|
||||||
|
|
||||||
|
if (images == null)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (images.showbackground?.Any() ?? false)
|
||||||
|
{
|
||||||
|
var enImage = images.showbackground.Where(x => x.lang == "en").OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||||
|
if (enImage == null)
|
||||||
|
{
|
||||||
|
return images.showbackground.OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||||
|
}
|
||||||
|
return enImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
[HttpGet("background")]
|
[HttpGet("background")]
|
||||||
public async Task<object> GetBackgroundImage()
|
public async Task<object> GetBackgroundImage()
|
||||||
{
|
{
|
||||||
|
@ -141,7 +191,7 @@ namespace Ombi.Controllers
|
||||||
|
|
||||||
movieUrl = result.moviebackground[0].url;
|
movieUrl = result.moviebackground[0].url;
|
||||||
}
|
}
|
||||||
if(tvArray.Any())
|
if (tvArray.Any())
|
||||||
{
|
{
|
||||||
var item = rand.Next(tvArray.Length);
|
var item = rand.Next(tvArray.Length);
|
||||||
var result = await FanartTvApi.GetTvImages(tvArray[item], key.Value);
|
var result = await FanartTvApi.GetTvImages(tvArray[item], key.Value);
|
||||||
|
|
|
@ -174,7 +174,7 @@ namespace Ombi.Controllers
|
||||||
/// <param name="tv">The tv.</param>
|
/// <param name="tv">The tv.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("tv")]
|
[HttpPost("tv")]
|
||||||
public async Task<RequestEngineResult> RequestTv([FromBody] SearchTvShowViewModel tv)
|
public async Task<RequestEngineResult> RequestTv([FromBody] TvRequestViewModel tv)
|
||||||
{
|
{
|
||||||
return await TvRequestEngine.RequestTvShow(tv);
|
return await TvRequestEngine.RequestTvShow(tv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,26 +64,16 @@ O:::::::OOO:::::::Om::::m m::::m m::::mb:::::bbbbbb::::::bi::::::i
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<title>@appName</title>
|
<title>@appName</title>
|
||||||
<base href="/@baseUrl"/>
|
<base href="/@baseUrl"/>
|
||||||
<link rel="SHORTCUT ICON" href="~/images/favicon/favicon.ico"/>
|
|
||||||
<link rel="icon" href="~/images/favicon/favicon.ico" type="image/ico"/>
|
|
||||||
|
|
||||||
<link rel="apple-touch-icon" sizes="57x57" href="~/images/favicon/apple-icon-57x57.png"/>
|
<link rel="apple-touch-icon" sizes="180x180" href="~/images/favicon/apple-touch-icon.png">
|
||||||
<link rel="apple-touch-icon" sizes="60x60" href="~/images/favicon/apple-icon-60x60.png"/>
|
<link rel="icon" type="image/png" sizes="32x32" href="~/images/favicon/favicon-32x32.png">
|
||||||
<link rel="apple-touch-icon" sizes="72x72" href="~/images/favicon/apple-icon-72x72.png"/>
|
<link rel="icon" type="image/png" sizes="16x16" href="~/images/favicon/favicon-16x16.png">
|
||||||
<link rel="apple-touch-icon" sizes="76x76" href="~/images/favicon/apple-icon-76x76.png"/>
|
<link rel="manifest" href="~/images/favicon/site.webmanifest">
|
||||||
<link rel="apple-touch-icon" sizes="114x114" href="~/images/favicon/apple-icon-114x114.png"/>
|
<link rel="mask-icon" href="~/images/favicon/safari-pinned-tab.svg" color="#df691a">
|
||||||
<link rel="apple-touch-icon" sizes="120x120" href="~/images/favicon/apple-icon-120x120.png"/>
|
<link rel="shortcut icon" href="~/images/favicon/favicon.ico">
|
||||||
<link rel="apple-touch-icon" sizes="144x144" href="~/images/favicon/apple-icon-144x144.png"/>
|
<meta name="msapplication-TileColor" content="#df691a">
|
||||||
<link rel="apple-touch-icon" sizes="152x152" href="~/images/favicon/apple-icon-152x152.png"/>
|
<meta name="msapplication-config" content="~/images/favicon/browserconfig.xml">
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="~/images/favicon/apple-icon-180x180.png"/>
|
<meta name="theme-color" content="#df691a">
|
||||||
<link rel="icon" type="image/png" sizes="192x192" href="~/images/favicon/android-icon-192x192.png"/>
|
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="~/images/favicon/favicon-32x32.png"/>
|
|
||||||
<link rel="icon" type="image/png" sizes="96x96" href="~/images/favicon/favicon-96x96.png"/>
|
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="~/images/favicon/favicon-16x16.png"/>
|
|
||||||
<link rel="manifest" href="~/images/favicon/manifest.json">
|
|
||||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
|
||||||
<meta name="msapplication-TileImage" content="~/images/favicon/ms-icon-144x144.png"/>
|
|
||||||
<meta name="theme-color" content="#ffffff"/>
|
|
||||||
|
|
||||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
|
|
||||||
|
|
BIN
src/Ombi/wwwroot/images/favicon/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
src/Ombi/wwwroot/images/favicon/android-chrome-512x512.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 5 KiB |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 5 KiB |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
BIN
src/Ombi/wwwroot/images/favicon/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
|
@ -1,2 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
|
<browserconfig>
|
||||||
|
<msapplication>
|
||||||
|
<tile>
|
||||||
|
<square150x150logo src="/images/favicon/mstile-150x150.png"/>
|
||||||
|
<TileColor>#df691a</TileColor>
|
||||||
|
</tile>
|
||||||
|
</msapplication>
|
||||||
|
</browserconfig>
|
||||||
|
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 505 B |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 738 B |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 15 KiB |
|
@ -1,41 +0,0 @@
|
||||||
{
|
|
||||||
"name": "App",
|
|
||||||
"icons": [
|
|
||||||
{
|
|
||||||
"src": "\/android-icon-36x36.png",
|
|
||||||
"sizes": "36x36",
|
|
||||||
"type": "image\/png",
|
|
||||||
"density": "0.75"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "\/android-icon-48x48.png",
|
|
||||||
"sizes": "48x48",
|
|
||||||
"type": "image\/png",
|
|
||||||
"density": "1.0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "\/android-icon-72x72.png",
|
|
||||||
"sizes": "72x72",
|
|
||||||
"type": "image\/png",
|
|
||||||
"density": "1.5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "\/android-icon-96x96.png",
|
|
||||||
"sizes": "96x96",
|
|
||||||
"type": "image\/png",
|
|
||||||
"density": "2.0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "\/android-icon-144x144.png",
|
|
||||||
"sizes": "144x144",
|
|
||||||
"type": "image\/png",
|
|
||||||
"density": "3.0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "\/android-icon-192x192.png",
|
|
||||||
"sizes": "192x192",
|
|
||||||
"type": "image\/png",
|
|
||||||
"density": "4.0"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 4.9 KiB |
BIN
src/Ombi/wwwroot/images/favicon/mstile-150x150.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
1
src/Ombi/wwwroot/images/favicon/safari-pinned-tab.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg version="1" xmlns="http://www.w3.org/2000/svg" width="1365.333" height="1365.333" viewBox="0 0 1024.000000 1024.000000"><path d="M487.2 71c-140.4 9.8-263.6 80.9-341 196.7-39.5 59-63.1 124.3-71.8 198.8-2.5 21.1-2.5 71.9 0 93 6.5 56 19.9 101.7 43.7 150 21.9 44.5 48.5 81.2 85.3 118 47.8 47.7 105.8 83.8 168.9 105 160.4 53.9 335.7 13.4 454.3-105 36.8-36.8 63.4-73.5 85.3-118 23.8-48.3 37.2-94 43.7-150 2.5-21.1 2.5-71.9 0-93-5.2-44.4-15.1-83.6-30.9-122.2-32.3-78.8-88.7-148.4-159.2-196.6-61.7-42.1-130.7-67.4-205.5-75.2-17.9-1.9-56.3-2.7-72.8-1.5zM391 283c11.3 3.2 21.2 8.6 31.4 17.1 5 4.2 28.7 27.4 52.6 51.5 46.2 46.6 48 48.8 54.4 64.8 4.3 10.7 5.9 19.7 5.8 33.1 0 13.9-1.9 22.6-7.8 35.4l-3.7 8.2 3.8 3.9 3.8 3.9 4.6-2.3c19-9.6 43.2-12.1 63.1-6.6 9.7 2.7 22.1 8.7 29.6 14.4 3.2 2.4 27.1 25.7 52.9 51.8 41.7 42 47.5 48.2 51.4 55.1 8.8 15.7 12.8 32.1 11.7 48.7-.7 10.7-3.4 23-6.7 30.5-6.2 14.2-20 30.1-34.1 39.2-25.2 16.3-57.3 17.7-85.8 3.7l-11.5-5.7-50.1-50.1c-54.7-54.7-56.7-57.1-62.5-73.9-4-11.5-5.2-21.2-4.6-34.7.7-13.3 2.3-20.2 7.7-31.7l3.8-8.1-3.7-3.6-3.7-3.7-7.9 3.6c-27.5 12.6-61.6 10-86.2-6.5-6.6-4.5-98.4-96-103.9-103.7-10.6-14.6-15.7-31.5-15.7-51.3 0-14.6 1.6-22.4 7.3-34.6 12.5-27.1 34.7-44.6 63.5-50.3 8.4-1.7 31.9-.6 40.5 1.9zm179 66c1.9 1.9 2 3.3 2 35.2 0 32.7 0 33.2-2.2 35.5-3.1 3.3-7.7 3.1-11.1-.5l-2.7-2.8V384c0-31.9 0-32.4 2.2-34.7 2.8-3 8.9-3.2 11.8-.3zm74.1 30.9c5.6 5.6 5.3 6.1-20.3 31.8-25.6 25.6-26.9 26.5-31.9 21.7-2.1-2-2.9-3.7-2.9-6.3 0-3.4 1.5-5.1 22.3-25.7 12.2-12.2 23.1-22.7 24.2-23.3 3.3-1.7 5.5-1.3 8.6 1.8zm29.9 73.6c2.1 1.1 3.1 2.5 3.6 5.2.6 3.3.3 4-2.5 6.5L672 468h-64.4l-2.8-2.7c-3.6-3.4-3.7-7.5-.3-10.8l2.4-2.5H639c26.6 0 32.6.3 35 1.5z"/><path d="M358.4 324.5c-28.1 6.1-42.3 34.4-30.7 61 2.4 5.4 7.3 10.6 48.1 51.7 48.4 48.6 50 50 62.7 53.3 7.1 1.8 14.4 1.9 18 .3 2.5-1.1 2.3-1.4-20.8-24.7-21.3-21.5-23.5-24-24.6-28.3-3.3-13.7 6.7-26.8 20.6-26.8 2.9 0 7 .7 9.1 1.6 2.4.9 11.8 9.5 26.3 24l22.6 22.5 1.3-3.1c2.8-6.6-.7-22.3-6.9-31.6-2.3-3.4-22.5-24.3-47.8-49.4-47-46.8-48.3-47.8-61-50.5-8.1-1.7-9-1.7-16.9 0zM567.8 533.7c-1 .2-1.8.7-1.8 1.1 0 .3 13.2 13.9 29.4 30.2 28.2 28.2 29.5 29.7 31 35.1 2 6.8 1.1 12.1-3 18-2.9 4.2-8.8 8.2-13.8 9.3-1.5.4-5.4.2-8.5-.5l-5.6-1.1-30-29.9c-16.6-16.4-30.3-29.9-30.7-29.9-.3 0-1.1 1.9-1.7 4.3-1.9 7.6 1.2 20.8 6.9 29.7 4.2 6.4 90.5 92.1 96 95.2 16.7 9.5 36.8 7 51.4-6.3 13.7-12.5 17.2-33 8.5-50.8-2.8-6-7.6-11.1-48.8-52.2-48.8-48.7-49.3-49.1-61.9-51.8-5.2-1.1-14-1.3-17.4-.4z"/></svg>
|
After Width: | Height: | Size: 2.4 KiB |
19
src/Ombi/wwwroot/images/favicon/site.webmanifest
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"name": "Ombi",
|
||||||
|
"short_name": "Ombi",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/images/favicon/android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/images/favicon/android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"theme_color": "#df691a",
|
||||||
|
"background_color": "#df691a",
|
||||||
|
"display": "standalone"
|
||||||
|
}
|