A lot more lidarr work, i'm done for the day wow... !wip #2313

pull/2478/head
Jamie 6 years ago
parent 207c60b7f8
commit 3750243f11

@ -7,6 +7,6 @@
public int trackCount { get; set; }
public int totalTrackCount { get; set; }
public int sizeOnDisk { get; set; }
public decimal percentOfTracks { get; set; }
public decimal percentOfEpisodes { get; set; }
}
}

@ -73,7 +73,7 @@ namespace Ombi.Core.Engine
var vm = new List<SearchArtistViewModel>();
foreach (var r in result)
{
vm.Add(MapIntoArtistVm(r));
vm.Add(await MapIntoArtistVm(r));
}
return vm;
@ -107,7 +107,7 @@ namespace Ombi.Core.Engine
return await _lidarrApi.GetArtist(artistId, settings.ApiKey, settings.FullUri);
}
private SearchArtistViewModel MapIntoArtistVm(ArtistLookup a)
private async Task<SearchArtistViewModel> MapIntoArtistVm(ArtistLookup a)
{
var vm = new SearchArtistViewModel
{
@ -121,13 +121,16 @@ namespace Ombi.Core.Engine
Links = a.links,
Overview = a.overview,
};
var poster = a.images?.FirstOrDefault(x => x.coverType.Equals("poaster"));
if (poster == null)
{
vm.Poster = a.remotePoster;
}
await Rules.StartSpecificRules(vm, SpecificRules.LidarrArtist);
return vm;
}
@ -162,6 +165,10 @@ namespace Ombi.Core.Engine
vm.Cover = a.remoteCover;
}
await Rules.StartSpecificRules(vm, SpecificRules.LidarrAlbum);
await RunSearchRules(vm);
return vm;
}
private LidarrSettings _settings;

@ -1,8 +1,9 @@
using System;
using Ombi.Store.Entities;
namespace Ombi.Core.Models.Search
{
public class SearchAlbumViewModel
public class SearchAlbumViewModel : SearchViewModel
{
public string Title { get; set; }
public string ForeignAlbumId { get; set; }
@ -14,6 +15,9 @@ namespace Ombi.Core.Models.Search
public string ForeignArtistId { get; set; }
public string Cover { get; set; }
public string Disk { get; set; }
public decimal PercentOfTracks { get; set; }
public override RequestType Type => RequestType.Album;
public bool PartiallyAvailable => PercentOfTracks != 100 && PercentOfTracks > 0;
public bool FullyAvailable => PercentOfTracks == 100;
}
}

@ -12,8 +12,6 @@ namespace Ombi.Core.Models.Search
public string Poster { get; set; }
public string Logo { get; set; }
public bool Monitored { get; set; }
public bool Available { get; set; }
public bool Requested { get; set; }
public string ArtistType { get; set; }
public string CleanName { get; set; }
public Link[] Links { get; set; } // Couldn't be bothered to map it

@ -3,5 +3,7 @@
public enum SpecificRules
{
CanSendNotification,
LidarrArtist,
LidarrAlbum,
}
}

@ -11,13 +11,15 @@ namespace Ombi.Core.Rule.Rules.Search
{
public class ExistingRule : BaseSearchRule, IRules<SearchViewModel>
{
public ExistingRule(IMovieRequestRepository movie, ITvRequestRepository tv)
public ExistingRule(IMovieRequestRepository movie, ITvRequestRepository tv, IMusicRequestRepository music)
{
Movie = movie;
Tv = tv;
Music = music;
}
private IMovieRequestRepository Movie { get; }
private IMusicRequestRepository Music { get; }
private ITvRequestRepository Tv { get; }
public async Task<RuleResult> Execute(SearchViewModel obj)
@ -37,7 +39,7 @@ namespace Ombi.Core.Rule.Rules.Search
}
return Success();
}
else if (obj.Type == RequestType.Album)
if (obj.Type == RequestType.TvShow)
{
//var tvRequests = Tv.GetRequest(obj.Id);
//if (tvRequests != null) // Do we already have a request for this?
@ -50,7 +52,7 @@ namespace Ombi.Core.Rule.Rules.Search
// return Task.FromResult(Success());
//}
var request = (SearchTvShowViewModel) obj;
var request = (SearchTvShowViewModel)obj;
var tvRequests = Tv.GetRequest(obj.Id);
if (tvRequests != null) // Do we already have a request for this?
{
@ -96,6 +98,21 @@ namespace Ombi.Core.Rule.Rules.Search
return Success();
}
if (obj.Type == RequestType.Album)
{
var album = (SearchAlbumViewModel) obj;
var albumRequest = await Music.GetRequestAsync(album.ForeignAlbumId);
if (albumRequest != null) // Do we already have a request for this?
{
obj.Requested = true;
obj.RequestId = albumRequest.Id;
obj.Approved = albumRequest.Approved;
obj.Available = albumRequest.Available;
return Success();
}
return Success();
}
return Success();
}
}

@ -0,0 +1,36 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Ombi.Core.Models.Search;
using Ombi.Core.Rule.Interfaces;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
namespace Ombi.Core.Rule.Rules.Search
{
public class LidarrAlbumCacheRule : SpecificRule, ISpecificRule<object>
{
public LidarrAlbumCacheRule(IRepository<LidarrAlbumCache> db)
{
_db = db;
}
private readonly IRepository<LidarrAlbumCache> _db;
public Task<RuleResult> Execute(object objec)
{
var obj = (SearchAlbumViewModel) objec;
// Check if it's in Lidarr
var result = _db.GetAll().FirstOrDefault(x => x.ForeignAlbumId.Equals(obj.ForeignAlbumId, StringComparison.InvariantCultureIgnoreCase));
if (result != null)
{
obj.PercentOfTracks = result.PercentOfTracks;
obj.Monitored = true; // It's in Lidarr so it's monitored
}
return Task.FromResult(Success());
}
public override SpecificRules Rule => SpecificRules.LidarrAlbum;
}
}

@ -0,0 +1,35 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Ombi.Core.Models.Search;
using Ombi.Core.Rule.Interfaces;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
namespace Ombi.Core.Rule.Rules.Search
{
public class LidarrArtistCacheRule : SpecificRule, ISpecificRule<object>
{
public LidarrArtistCacheRule(IRepository<LidarrArtistCache> db)
{
_db = db;
}
private readonly IRepository<LidarrArtistCache> _db;
public Task<RuleResult> Execute(object objec)
{
var obj = (SearchArtistViewModel) objec;
// Check if it's in Lidarr
var result = _db.GetAll().FirstOrDefault(x => x.ForeignArtistId.Equals(obj.ForignArtistId, StringComparison.InvariantCultureIgnoreCase));
if (result != null)
{
obj.Monitored = true; // It's in Lidarr so it's monitored
}
return Task.FromResult(Success());
}
public override SpecificRules Rule => SpecificRules.LidarrArtist;
}
}

@ -48,23 +48,24 @@ namespace Ombi.Schedule.Jobs.Lidarr
// Let's remove the old cached data
await _ctx.Database.ExecuteSqlCommandAsync("DELETE FROM LidarrAlbumCache");
var artistCache = new List<LidarrAlbumCache>();
var albumCache = new List<LidarrAlbumCache>();
foreach (var a in albums)
{
if (a.id > 0)
{
artistCache.Add(new LidarrAlbumCache
albumCache.Add(new LidarrAlbumCache
{
ArtistId = a.artistId,
ForeignAlbumId = a.foreignAlbumId,
ReleaseDate = a.releaseDate,
TrackCount = a.currentRelease.trackCount,
Monitored = a.monitored,
Title = a.title
Title = a.title,
PercentOfTracks = a.statistics?.percentOfEpisodes ?? 0m
});
}
}
await _ctx.LidarrAlbumCache.AddRangeAsync(artistCache);
await _ctx.LidarrAlbumCache.AddRangeAsync(albumCache);
await _ctx.SaveChangesAsync();
}

@ -12,8 +12,6 @@ namespace Ombi.Store.Entities
public DateTime ReleaseDate { get; set; }
public bool Monitored { get; set; }
public string Title { get; set; }
[ForeignKey(nameof(ArtistId))]
public LidarrArtistCache Artist { get; set; }
public decimal PercentOfTracks { get; set; }
}
}

@ -6,12 +6,9 @@ namespace Ombi.Store.Entities
[Table("LidarrArtistCache")]
public class LidarrArtistCache : Entity
{
[ForeignKey(nameof(ArtistId))]
public int ArtistId { get; set; }
public string ArtistName { get; set; }
public string ForeignArtistId { get; set; }
public bool Monitored { get; set; }
public List<LidarrAlbumCache> Albums { get; set; }
}
}

@ -9,7 +9,7 @@ using Ombi.Store.Context;
namespace Ombi.Store.Migrations
{
[DbContext(typeof(OmbiContext))]
[Migration("20180824202308_LidarrSyncJobs")]
[Migration("20180824211553_LidarrSyncJobs")]
partial class LidarrSyncJobs
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -257,6 +257,8 @@ namespace Ombi.Store.Migrations
b.Property<bool>("Monitored");
b.Property<decimal>("PercentOfTracks");
b.Property<DateTime>("ReleaseDate");
b.Property<string>("Title");
@ -265,8 +267,6 @@ namespace Ombi.Store.Migrations
b.HasKey("Id");
b.HasIndex("ArtistId");
b.ToTable("LidarrAlbumCache");
});
@ -965,14 +965,6 @@ namespace Ombi.Store.Migrations
.HasPrincipalKey("EmbyId");
});
modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b =>
{
b.HasOne("Ombi.Store.Entities.LidarrArtistCache", "Artist")
.WithMany("Albums")
.HasForeignKey("ArtistId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b =>
{
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")

@ -8,49 +8,39 @@ namespace Ombi.Store.Migrations
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "LidarrArtistCache",
name: "LidarrAlbumCache",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
ArtistId = table.Column<int>(nullable: false),
ArtistName = table.Column<string>(nullable: true),
ForeignArtistId = table.Column<string>(nullable: true),
Monitored = table.Column<bool>(nullable: false)
ForeignAlbumId = table.Column<string>(nullable: true),
TrackCount = table.Column<int>(nullable: false),
ReleaseDate = table.Column<DateTime>(nullable: false),
Monitored = table.Column<bool>(nullable: false),
Title = table.Column<string>(nullable: true),
PercentOfTracks = table.Column<decimal>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_LidarrArtistCache", x => x.Id);
table.PrimaryKey("PK_LidarrAlbumCache", x => x.Id);
});
migrationBuilder.CreateTable(
name: "LidarrAlbumCache",
name: "LidarrArtistCache",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
ArtistId = table.Column<int>(nullable: false),
ForeignAlbumId = table.Column<string>(nullable: true),
TrackCount = table.Column<int>(nullable: false),
ReleaseDate = table.Column<DateTime>(nullable: false),
Monitored = table.Column<bool>(nullable: false),
Title = table.Column<string>(nullable: true)
ArtistName = table.Column<string>(nullable: true),
ForeignArtistId = table.Column<string>(nullable: true),
Monitored = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_LidarrAlbumCache", x => x.Id);
table.ForeignKey(
name: "FK_LidarrAlbumCache_LidarrArtistCache_ArtistId",
column: x => x.ArtistId,
principalTable: "LidarrArtistCache",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.PrimaryKey("PK_LidarrArtistCache", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_LidarrAlbumCache_ArtistId",
table: "LidarrAlbumCache",
column: "ArtistId");
}
protected override void Down(MigrationBuilder migrationBuilder)

@ -255,6 +255,8 @@ namespace Ombi.Store.Migrations
b.Property<bool>("Monitored");
b.Property<decimal>("PercentOfTracks");
b.Property<DateTime>("ReleaseDate");
b.Property<string>("Title");
@ -263,8 +265,6 @@ namespace Ombi.Store.Migrations
b.HasKey("Id");
b.HasIndex("ArtistId");
b.ToTable("LidarrAlbumCache");
});
@ -963,14 +963,6 @@ namespace Ombi.Store.Migrations
.HasPrincipalKey("EmbyId");
});
modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b =>
{
b.HasOne("Ombi.Store.Entities.LidarrArtistCache", "Artist")
.WithMany("Albums")
.HasForeignKey("ArtistId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b =>
{
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")

@ -29,6 +29,8 @@ export interface ILink {
}
export interface ISearchAlbumResult {
id: number;
requestId: number;
albumType: string;
artistName: string;
cover: string;
@ -39,10 +41,11 @@ export interface ISearchAlbumResult {
rating: number;
releaseDate: Date;
title: string;
approved: boolean;
fullyAvailable: boolean;
partiallyAvailable: boolean;
requested: boolean;
requestId: number;
available: boolean;
approved: boolean;
subscribed: boolean;
// for the UI
showSubscribe: boolean;

@ -33,27 +33,32 @@
<a *ngIf="result.homepage" href="{{result.homepage}}" id="homePageLabel" target="_blank"><span class="label label-info" [translate]="'Search.Movies.HomePage'"></span></a>
<a *ngIf="result.trailer" href="{{result.trailer}}" id="trailerLabel" target="_blank"><span class="label label-info" [translate]="'Search.Movies.Trailer'"></span></a> -->
<ng-template [ngIf]="result.releaseDate">
<span class="label label-info" id="availableLabel">Release Date: {{result.releaseDate | date:'yyyy-MM-dd'}}</span>
<ng-template [ngIf]="!result.requested && !result.fullyAvailable && !result.approved">
<span class="label label-danger" id="notRequestedLabel" [translate]="'Common.NotRequested'"></span>
</ng-template>
<ng-template [ngIf]="result.fullyAvailable">
<span class="label label-success" id="availableLabel" [translate]="'Common.Available'"></span>
</ng-template>
<ng-template [ngIf]="result.partiallyAvailable">
<span class="label label-info" id="availableLabel" [translate]="'Common.PartiallyAvailable'"></span>
</ng-template>
<ng-template [ngIf]="result.monitored && !result.fullyAvailable">
<span class="label label-info" id="processingRequestLabel" [translate]="'Common.Monitored'"></span>
</ng-template>
<ng-template [ngIf]="result.rating">
<span class="label label-info" id="availableLabel">{{result.rating}}/10</span>
<ng-template [ngIf]="result.requested && !result.approved && !result.available">
<span class="label label-warning" id="pendingApprovalLabel" [translate]="'Common.PendingApproval'"></span>
</ng-template>
<ng-template [ngIf]="result.approved && !result.available"><span class="label label-info" id="processingRequestLabel" [translate]="'Common.ProcessingRequest'"></span></ng-template>
<ng-template [ngIf]="result.available">
<span class="label label-success" id="availableLabel" [translate]="'Common.Available'"></span>
</ng-template>
<ng-template [ngIf]="result.approved && !result.available">
<span class="label label-info" id="processingRequestLabel" [translate]="'Common.ProcessingRequest'"></span>
</ng-template>
<ng-template [ngIf]="result.requested && !result.approved && !result.available">
<span class="label label-warning" id="pendingApprovalLabel" [translate]="'Common.PendingApproval'"></span>
</ng-template>
<ng-template [ngIf]="!result.requested && !result.available && !result.approved">
<span class="label label-danger" id="notRequestedLabel" [translate]="'Common.NotRequested'"></span>
</ng-template>
<ng-template [ngIf]="result.releaseDate">
<span class="label label-info" id="availableLabel">Release Date: {{result.releaseDate | date:'yyyy-MM-dd'}}</span>
</ng-template>
<ng-template [ngIf]="result.rating">
<span class="label label-info" id="availableLabel">{{result.rating}}/10</span>
</ng-template>
</span>

@ -34,6 +34,7 @@ export class JobsComponent implements OnInit {
refreshMetadata: [x.refreshMetadata, Validators.required],
newsletter: [x.newsletter, Validators.required],
plexRecentlyAddedSync: [x.plexRecentlyAddedSync, Validators.required],
lidarrArtistSync: [x.lidarrArtistSync, Validators.required],
});
});
}

@ -3,14 +3,14 @@
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:3579/",
"applicationUrl": "http://localhost:3577/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"commandLineArgs": "--host http://*:3579",
"commandLineArgs": "--host http://*:3577",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"

@ -12,6 +12,8 @@
"Common": {
"ContinueButton": "Continue",
"Available": "Available",
"PartiallyAvailable": "Partially Available",
"Monitored": "Monitored",
"NotAvailable": "Not Available",
"ProcessingRequest": "Processing Request",
"PendingApproval": "Pending Approval",

Loading…
Cancel
Save