Fixed many bugs #865

This commit is contained in:
Jamie.Rees 2017-06-13 10:39:15 +01:00
parent 22c5d3a19d
commit eb433867af
18 changed files with 135 additions and 62 deletions

View file

@ -41,6 +41,25 @@ namespace Ombi.Core.Engine
// For some reason the poster path is always http // For some reason the poster path is always http
var posterPath = showInfo.image?.medium.Replace("http:", "https:"); var posterPath = showInfo.image?.medium.Replace("http:", "https:");
var tvRequests = new List<SeasonRequestModel>();
// Only have the TV requests we actually requested and not everything
foreach (var season in tv.SeasonRequests)
{
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())
{
tvRequests.Add(season);
}
}
var childRequest = new ChildTvRequest var childRequest = new ChildTvRequest
{ {
Id = tv.Id, Id = tv.Id,
@ -56,7 +75,7 @@ namespace Ombi.Core.Engine
Issues = IssueState.None, Issues = IssueState.None,
ProviderId = tv.Id, ProviderId = tv.Id,
RequestAll = tv.RequestAll, RequestAll = tv.RequestAll,
SeasonRequests = tv.SeasonRequests SeasonRequests = tvRequests
}; };
var model = new TvRequestModel var model = new TvRequestModel

View file

@ -77,13 +77,12 @@ namespace Ombi.Core.Engine
} }
else else
{ {
season.Episodes.Add(new EpisodesRequested // Find the episode
{ var ep = season.Episodes.FirstOrDefault(x => x.EpisodeNumber == e.number);
Url = e.url, ep.Url = e.url;
Title = e.name, ep.Title = e.name;
AirDate = DateTime.Parse(e.airstamp), ep.AirDate = DateTime.Parse(e.airstamp);
EpisodeNumber = e.number, ep.EpisodeNumber = e.number;
});
} }
} }

View file

@ -66,7 +66,7 @@ namespace Ombi.Core
//var rootFolderPath = model.RootFolderSelected <= 0 ? settings.FullRootPath : GetRootPath(model.RootFolderSelected, settings); //var rootFolderPath = model.RootFolderSelected <= 0 ? settings.FullRootPath : GetRootPath(model.RootFolderSelected, settings);
var rootFolderPath = settings.DefaultRootPath; // TODO Allow changing in the UI var rootFolderPath = settings.DefaultRootPath; // TODO Allow changing in the UI
var result = await RadarrApi.AddMovie(model.ProviderId, model.Title, model.ReleaseDate.Year, qualityProfile, rootFolderPath, settings.ApiKey, settings.FullUri, true); var result = await RadarrApi.AddMovie(model.ProviderId, model.Title, model.ReleaseDate.Year, qualityProfile, rootFolderPath, settings.ApiKey, settings.FullUri, !settings.AddOnly);
if (!string.IsNullOrEmpty(result.Error?.message)) if (!string.IsNullOrEmpty(result.Error?.message))
{ {

View file

@ -8,7 +8,7 @@ using Ombi.Notifications;
using Ombi.Notifications.Models; using Ombi.Notifications.Models;
using Ombi.Settings.Settings.Models.Notifications; using Ombi.Settings.Settings.Models.Notifications;
namespace Ombi.Notification.Discord namespace Ombi.Notification.Agents
{ {
public class DiscordNotification : BaseNotification<DiscordNotificationSettings> public class DiscordNotification : BaseNotification<DiscordNotificationSettings>
{ {

View file

@ -9,5 +9,6 @@ namespace Ombi.Settings.Settings.Models.External
public string DefaultQualityProfile { get; set; } public string DefaultQualityProfile { get; set; }
public string DefaultRootPath { get; set; } public string DefaultRootPath { get; set; }
public string FullRootPath { get; set; } public string FullRootPath { get; set; }
public bool AddOnly { get; set; }
} }
} }

View file

@ -1,4 +1,4 @@
<p-growl [value]="notificationService.messages" ></p-growl> <p-growl [value]="notificationService.messages" [life]="3000"></p-growl>
<nav *ngIf="showNav" class="navbar navbar-default navbar-fixed-top"> <nav *ngIf="showNav" class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid"> <div class="container-fluid">

View file

@ -1,37 +1,37 @@
export interface ISettings { export interface ISettings {
id:number id: number
} }
export interface IExternalSettings extends ISettings { export interface IExternalSettings extends ISettings {
ssl: boolean, ssl: boolean,
subDir: string, subDir: string,
ip: string, ip: string,
port:number, port: number,
} }
export interface IOmbiSettings extends ISettings { export interface IOmbiSettings extends ISettings {
port: number, port: number,
//baseUrl:string, //baseUrl:string,
collectAnalyticData: boolean, collectAnalyticData: boolean,
wizard: boolean, wizard: boolean,
apiKey:string apiKey: string
} }
export interface IEmbySettings extends IExternalSettings { export interface IEmbySettings extends IExternalSettings {
apiKey: string, apiKey: string,
enable: boolean, enable: boolean,
administratorId: string, administratorId: string,
enableEpisodeSearching:boolean, enableEpisodeSearching: boolean,
} }
export interface IPlexSettings extends ISettings { export interface IPlexSettings extends ISettings {
enable: boolean, enable: boolean,
servers : IPlexServer[] servers: IPlexServer[]
} }
export interface IPlexServer extends IExternalSettings { export interface IPlexServer extends IExternalSettings {
name:string, name: string,
enableEpisodeSearching: boolean, enableEpisodeSearching: boolean,
plexAuthToken: string, plexAuthToken: string,
machineIdentifier: string, machineIdentifier: string,
@ -41,7 +41,7 @@ export interface IPlexServer extends IExternalSettings {
export interface IPlexLibraries { export interface IPlexLibraries {
key: string, key: string,
title: string, title: string,
enabled:boolean, enabled: boolean,
} }
export interface ISonarrSettings extends IExternalSettings { export interface ISonarrSettings extends IExternalSettings {
@ -50,7 +50,7 @@ export interface ISonarrSettings extends IExternalSettings {
qualityProfile: string, qualityProfile: string,
seasonFolders: boolean, seasonFolders: boolean,
rootPath: string, rootPath: string,
fullRootPath:string, fullRootPath: string,
} }
export interface IRadarrSettings extends IExternalSettings { export interface IRadarrSettings extends IExternalSettings {
@ -58,7 +58,8 @@ export interface IRadarrSettings extends IExternalSettings {
apiKey: string, apiKey: string,
defaultQualityProfile: string, defaultQualityProfile: string,
defaultRootPath: string, defaultRootPath: string,
fullRootPath:string, fullRootPath: string,
addOnly: boolean,
} }
export interface ILandingPageSettings extends ISettings { export interface ILandingPageSettings extends ISettings {
@ -70,10 +71,10 @@ export interface ILandingPageSettings extends ISettings {
noticeBackgroundColor: string, noticeBackgroundColor: string,
timeLimit: boolean, timeLimit: boolean,
startDateTime: Date, startDateTime: Date,
endDateTime:Date, endDateTime: Date,
} }
export interface ICustomizationSettings extends ISettings { export interface ICustomizationSettings extends ISettings {
applicationName: string, applicationName: string,
logo:string, logo: string,
} }

View file

@ -78,7 +78,7 @@
</div> </div>
<!--Child Requests--> <!--Child Requests-->
<button type="button" class="btn btn-sm btn-info-outline" data-toggle="collapse" [attr.data-target]="'#' + request.id +'childRequests'">Children</button> <button type="button" class="btn btn-sm btn-info-outline" data-toggle="collapse" (click)="showChildren(request)" [attr.data-target]="'#' + request.id +'childRequests'">Children</button>
<div id="{{request.id}}childRequests" class="collapse"> <div id="{{request.id}}childRequests" class="collapse">
<div *ngFor="let child of request.childRequests"> <div *ngFor="let child of request.childRequests">
@ -150,8 +150,6 @@
{{/if_eq}} {{/if_eq}}
</form>--> </form>-->
<div *ngIf="!request.denied"> <div *ngIf="!request.denied">
<input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden" /> <input name="requestId" type="text" value="{{request.requestId}}" hidden="hidden" />
<input name="reason" type="text" hidden="hidden" /> <input name="reason" type="text" hidden="hidden" />
@ -173,7 +171,6 @@
<li><a href="#">Separated link</a></li> <li><a href="#">Separated link</a></li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
<form> <form>
@ -184,10 +181,6 @@
<button *ngIf="request.available" (click)="changeAvailability(request, false)" style="text-align: right" value="false" class="btn btn-sm btn-info-outline change"><i class="fa fa-minus"></i> Mark Unavailable</button> <button *ngIf="request.available" (click)="changeAvailability(request, false)" style="text-align: right" value="false" class="btn btn-sm btn-info-outline change"><i class="fa fa-minus"></i> Mark Unavailable</button>
<button *ngIf="!request.available" (click)="changeAvailability(request, true)" style="text-align: right" value="true" class="btn btn-sm btn-success-outline change"><i class="fa fa-plus"></i> Mark Available</button> <button *ngIf="!request.available" (click)="changeAvailability(request, true)" style="text-align: right" value="true" class="btn btn-sm btn-success-outline change"><i class="fa fa-plus"></i> Mark Available</button>
</form> </form>
</div> </div>
@ -209,9 +202,32 @@
</div> </div>
</div> </div>
<hr /> <hr />
</div> </div>
</div> </div>
<div class="modal fade in" *ngIf="showChildDialogue" style="display: block;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" (click)="showChildDialogue=false">&times;</button>
<h4 class="modal-title">{{selectedSeason?.title}}</h4>
</div>
<div class="modal-body">
<div class="col-md-8">
</div>
<div class="col-md-4">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger-outline" (click)="showChildDialogue=false">Close</button>
</div>
</div>
</div>
</div>

View file

@ -50,6 +50,9 @@ export class TvRequestsComponent implements OnInit, OnDestroy {
private currentlyLoaded: number; private currentlyLoaded: number;
private amountToLoad: number; private amountToLoad: number;
public showChildDialogue = false; // This is for the child modal popup
public selectedSeason : ITvRequestModel;
ngOnInit() { ngOnInit() {
this.amountToLoad = 5; this.amountToLoad = 5;
@ -95,6 +98,11 @@ export class TvRequestsComponent implements OnInit, OnDestroy {
this.updateRequest(request); this.updateRequest(request);
} }
public showChildren(request: ITvRequestModel) {
this.selectedSeason = request;
this.showChildDialogue = true;
}
private updateRequest(request: ITvRequestModel) { private updateRequest(request: ITvRequestModel) {
this.requestService.updateTvRequest(request) this.requestService.updateTvRequest(request)
.takeUntil(this.subscriptions) .takeUntil(this.subscriptions)

View file

@ -58,7 +58,7 @@
<td> <td>
<button (click)="addRequest(ep)" [disabled]="ep.available || ep.requested || ep.approved" class="btn btn-sm btn-primary-outline">Request</button> <button (click)="addRequest(ep)" [disabled]="ep.available || ep.requested || ep.approved" class="btn btn-sm btn-primary-outline">Add Request</button>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -71,5 +71,5 @@
<button id="requestFloatingBtn" class="btn btn-sm btn-success" title="Go to top">Request</button> <button id="requestFloatingBtn" class="btn btn-sm btn-success" (click)="submitRequests()" title="Go to top">Submit Request</button>
</div> </div>

View file

@ -29,9 +29,9 @@ export class SeriesInformationComponent implements OnInit, OnDestroy {
private subscriptions = new Subject<void>(); private subscriptions = new Subject<void>();
result : IRequestEngineResult; public result : IRequestEngineResult;
seriesId: number; private seriesId: number;
series: ISearchTvResult; public series: ISearchTvResult;
requestedEpisodes: IEpisodesRequested[] = []; requestedEpisodes: IEpisodesRequested[] = [];
@ -40,13 +40,14 @@ export class SeriesInformationComponent implements OnInit, OnDestroy {
this.searchService.getShowInformation(this.seriesId) this.searchService.getShowInformation(this.seriesId)
.takeUntil(this.subscriptions) .takeUntil(this.subscriptions)
.subscribe(x => { .subscribe(x => {
this.series = x as ISearchTvResult; this.series = x;
}); });
} }
request() { public submitRequests() {
this.series.requested = true; this.series.requested = true;
this.requestService.requestTv(this.series) this.requestService.requestTv(this.series)
.takeUntil(this.subscriptions) .takeUntil(this.subscriptions)
.subscribe(x => { .subscribe(x => {
@ -60,10 +61,8 @@ export class SeriesInformationComponent implements OnInit, OnDestroy {
}); });
} }
addRequest(episode: IEpisodesRequested) { public addRequest(episode: IEpisodesRequested) {
this.requestedEpisodes.push(episode);
episode.requested = true; episode.requested = true;
} }

View file

@ -145,7 +145,7 @@ export class TvSearchComponent implements OnInit, OnDestroy {
} }
selectSeason(searchResult: ISearchTvResult) { selectSeason(searchResult: ISearchTvResult) {
this.route.navigate(['/search/show', searchResult.seriesId]); this.route.navigate(['/search/show', searchResult.id]);
} }
private updateItem(key: ISearchTvResult, updated: ISearchTvResult) { private updateItem(key: ISearchTvResult, updated: ISearchTvResult) {

View file

@ -6,6 +6,7 @@ export class NotificationService {
messages: Message[] = []; messages: Message[] = [];
public addMessage(message: Message) { public addMessage(message: Message) {
this.messages.push(message); this.messages.push(message);
this.messages = JSON.parse(JSON.stringify(this.messages)); // NOTE: THIS IS A HACK AROUND A BUG https://github.com/primefaces/primeng/issues/2943
} }
public success(title: string, body: string) { public success(title: string, body: string) {

View file

@ -3,9 +3,10 @@
<fieldset> <fieldset>
<legend>Plex Configuration</legend> <legend>Plex Configuration</legend>
<div class="checkbox col-md-2 " style="float: right;">
<input type="checkbox" id="advanced" [(ngModel)]="advanced" ng-checked="advanced"> <div style="float: right;">
<label for="advanced">Advanced</label> <span style="vertical-align: top;">Advanced</span>
<p-inputSwitch id="customInputSwitch" [(ngModel)]="advanced"></p-inputSwitch>
</div> </div>
<div class="form-group col-md-3"> <div class="form-group col-md-3">

View file

@ -3,10 +3,14 @@
<div *ngIf="settings"> <div *ngIf="settings">
<fieldset> <fieldset>
<legend>Radarr Settings</legend> <legend>Radarr Settings</legend>
<div style="float: right;">
<span style="vertical-align: top;">Advanced</span>
<p-inputSwitch id="customInputSwitch" [(ngModel)]="advanced"></p-inputSwitch>
</div>
<div class="form-group"> <div class="form-group">
<div class="checkbox"> <div class="checkbox">
<input type="checkbox" [(ngModel)]="settings.enable" ng-checked="settings.enable"> <input type="checkbox" id="enable" [(ngModel)]="settings.enable" ng-checked="settings.enable">
<label for="enable">Enable</label> <label for="enable">Enable</label>
</div> </div>
</div> </div>
@ -78,6 +82,13 @@
</div> </div>
</div> </div>
<div class="form-group" *ngIf="advanced">
<div class="checkbox">
<input type="checkbox" id="addOnly" [(ngModel)]="settings.addOnly" ng-checked="settings.addOnly">
<label for="addOnly">Do not search</label>
</div>
</div>
<div class="form-group"> <div class="form-group">
<div class="checkbox"> <div class="checkbox">

View file

@ -26,6 +26,8 @@ export class RadarrComponent implements OnInit {
profilesRunning: boolean; profilesRunning: boolean;
rootFoldersRunning: boolean; rootFoldersRunning: boolean;
advanced = false;
private subscriptions = new Subject<void>(); private subscriptions = new Subject<void>();
ngOnInit(): void { ngOnInit(): void {

View file

@ -1,2 +1,16 @@
body { $primary-colour: #df691a;
$primary-colour-outline: #ff761b;
$bg-colour: #333333;
$bg-colour-disabled: #252424;
#customInputSwitch > div > .ui-inputswitch-off {
border: 1px solid $bg-colour !important;
background: $bg-colour-disabled !important;
color: white;
}
#customInputSwitch > div > .ui-inputswitch-on {
border: 1px solid $primary-colour-outline !important;
background: $primary-colour !important;
color: white;
} }

View file

@ -6,3 +6,4 @@
@import "../bower_components/font-awesome/scss/font-awesome.scss";*/ @import "../bower_components/font-awesome/scss/font-awesome.scss";*/
@import '../bootstrap.css'; @import '../bootstrap.css';
@import './Styles.scss';