mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-14 11:23:42 +02:00
added release results to episode detail tab
This commit is contained in:
parent
a5be71fd8c
commit
890d1f2398
@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Api.Mapping;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.IndexerSearch;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Parser;
|
||||
using Omu.ValueInjecter;
|
||||
using System.Linq;
|
||||
|
||||
@ -13,13 +11,32 @@ namespace NzbDrone.Api.Indexers
|
||||
public class ReleaseModule : NzbDroneRestModule<ReleaseResource>
|
||||
{
|
||||
private readonly IFetchAndParseRss _rssFetcherAndParser;
|
||||
private readonly ISearchForNzb _nzbSearchService;
|
||||
private readonly IMakeDownloadDecision _downloadDecisionMaker;
|
||||
|
||||
public ReleaseModule(IFetchAndParseRss rssFetcherAndParser, IMakeDownloadDecision downloadDecisionMaker)
|
||||
public ReleaseModule(IFetchAndParseRss rssFetcherAndParser, ISearchForNzb nzbSearchService, IMakeDownloadDecision downloadDecisionMaker)
|
||||
{
|
||||
_rssFetcherAndParser = rssFetcherAndParser;
|
||||
_nzbSearchService = nzbSearchService;
|
||||
_downloadDecisionMaker = downloadDecisionMaker;
|
||||
GetResourceAll = GetRss;
|
||||
GetResourceAll = GetReleases;
|
||||
}
|
||||
|
||||
|
||||
private List<ReleaseResource> GetReleases()
|
||||
{
|
||||
if (Request.Query.episodeId != null)
|
||||
{
|
||||
return GetEpisodeReleases(Request.Query.episodeId);
|
||||
}
|
||||
|
||||
return GetRss();
|
||||
}
|
||||
|
||||
private List<ReleaseResource> GetEpisodeReleases(int episodeId)
|
||||
{
|
||||
var decisions = _nzbSearchService.EpisodeSearch(episodeId);
|
||||
return MapDecisions(decisions);
|
||||
}
|
||||
|
||||
private List<ReleaseResource> GetRss()
|
||||
@ -27,6 +44,11 @@ private List<ReleaseResource> GetRss()
|
||||
var reports = _rssFetcherAndParser.Fetch();
|
||||
var decisions = _downloadDecisionMaker.GetRssDecision(reports);
|
||||
|
||||
return MapDecisions(decisions);
|
||||
}
|
||||
|
||||
private static List<ReleaseResource> MapDecisions(IEnumerable<DownloadDecision> decisions)
|
||||
{
|
||||
var result = new List<ReleaseResource>();
|
||||
|
||||
foreach (var downloadDecision in decisions)
|
||||
@ -44,24 +66,4 @@ private List<ReleaseResource> GetRss()
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class ReleaseResource : RestResource
|
||||
{
|
||||
public Int32 Age { get; set; }
|
||||
public Int64 Size { get; set; }
|
||||
public String Indexer { get; set; }
|
||||
public String NzbInfoUrl { get; set; }
|
||||
public String NzbUrl { get; set; }
|
||||
public String ReleaseGroup { get; set; }
|
||||
public String Title { get; set; }
|
||||
public Boolean FullSeason { get; set; }
|
||||
public Boolean SceneSource { get; set; }
|
||||
public Int32 SeasonNumber { get; set; }
|
||||
public Language Language { get; set; }
|
||||
public DateTime? AirDate { get; set; }
|
||||
public String SeriesTitle { get; set; }
|
||||
public int[] EpisodeNumbers { get; set; }
|
||||
public Boolean Approved { get; set; }
|
||||
public List<string> Rejections { get; set; }
|
||||
}
|
||||
}
|
27
NzbDrone.Api/Indexers/ReleaseResource.cs
Normal file
27
NzbDrone.Api/Indexers/ReleaseResource.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.Parser;
|
||||
|
||||
namespace NzbDrone.Api.Indexers
|
||||
{
|
||||
public class ReleaseResource : RestResource
|
||||
{
|
||||
public Int32 Age { get; set; }
|
||||
public Int64 Size { get; set; }
|
||||
public String Indexer { get; set; }
|
||||
public String NzbInfoUrl { get; set; }
|
||||
public String NzbUrl { get; set; }
|
||||
public String ReleaseGroup { get; set; }
|
||||
public String Title { get; set; }
|
||||
public Boolean FullSeason { get; set; }
|
||||
public Boolean SceneSource { get; set; }
|
||||
public Int32 SeasonNumber { get; set; }
|
||||
public Language Language { get; set; }
|
||||
public DateTime? AirDate { get; set; }
|
||||
public String SeriesTitle { get; set; }
|
||||
public int[] EpisodeNumbers { get; set; }
|
||||
public Boolean Approved { get; set; }
|
||||
public List<string> Rejections { get; set; }
|
||||
}
|
||||
}
|
@ -115,6 +115,7 @@
|
||||
<Compile Include="Indexers\IndexerResource.cs" />
|
||||
<Compile Include="Indexers\ReleaseModule.cs" />
|
||||
<Compile Include="Extensions\LazyExtensions.cs" />
|
||||
<Compile Include="Indexers\ReleaseResource.cs" />
|
||||
<Compile Include="Logs\LogModule.cs" />
|
||||
<Compile Include="Logs\LogResource.cs" />
|
||||
<Compile Include="Mapping\CloneInjection.cs" />
|
||||
|
@ -26,5 +26,11 @@
|
||||
<RegexTestSelector>
|
||||
<RegularExpression>NzbDrone\.Common\.Test\.EventingTests\.ServiceNameFixture\..*</RegularExpression>
|
||||
</RegexTestSelector>
|
||||
<RegexTestSelector>
|
||||
<RegularExpression>NzbDrone\.Common\.Test\.ProcessProviderTests\..*</RegularExpression>
|
||||
</RegexTestSelector>
|
||||
<RegexTestSelector>
|
||||
<RegularExpression>NzbDrone\.Common\.Test\.ServiceFactoryFixture\..*</RegularExpression>
|
||||
</RegexTestSelector>
|
||||
</IgnoredTests>
|
||||
</ProjectConfiguration>
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using NzbDrone.Common.EnsureThat;
|
||||
|
||||
namespace NzbDrone.Core.IndexerSearch.Definitions
|
||||
{
|
||||
@ -21,6 +22,8 @@ public string QueryTitle
|
||||
|
||||
private static string GetQueryTitle(string title)
|
||||
{
|
||||
Ensure.That(() => title).IsNotNullOrWhiteSpace();
|
||||
|
||||
var cleanTitle = BeginningThe.Replace(title, String.Empty);
|
||||
|
||||
cleanTitle = cleanTitle
|
||||
|
@ -14,9 +14,8 @@ namespace NzbDrone.Core.IndexerSearch
|
||||
{
|
||||
public interface ISearchForNzb
|
||||
{
|
||||
List<DownloadDecision> SearchSingle(int seriesId, int seasonNumber, int episodeNumber);
|
||||
List<DownloadDecision> SearchDaily(int seriesId, DateTime airDate);
|
||||
List<DownloadDecision> SearchSeason(int seriesId, int seasonNumber);
|
||||
List<DownloadDecision> EpisodeSearch(int episodeId);
|
||||
List<DownloadDecision> SeasonSearch(int seriesId, int seasonNumber);
|
||||
}
|
||||
|
||||
public class NzbSearchService : ISearchForNzb
|
||||
@ -40,7 +39,23 @@ public NzbSearchService(IIndexerService indexerService, IFetchFeedFromIndexers f
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public List<DownloadDecision> SearchSingle(int seriesId, int seasonNumber, int episodeNumber)
|
||||
|
||||
|
||||
public List<DownloadDecision> EpisodeSearch(int episodeId)
|
||||
{
|
||||
var episode = _episodeService.GetEpisode(episodeId);
|
||||
var series = _seriesService.GetSeries(episode.SeriesId);
|
||||
|
||||
if (series.SeriesType == SeriesTypes.Daily)
|
||||
{
|
||||
return SearchDaily(episode.SeriesId, episode.AirDate.Value.Date);
|
||||
}
|
||||
|
||||
return SearchSingle(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber);
|
||||
}
|
||||
|
||||
|
||||
private List<DownloadDecision> SearchSingle(int seriesId, int seasonNumber, int episodeNumber)
|
||||
{
|
||||
var searchSpec = Get<SingleEpisodeSearchCriteria>(seriesId, seasonNumber);
|
||||
|
||||
@ -59,7 +74,7 @@ public List<DownloadDecision> SearchSingle(int seriesId, int seasonNumber, int e
|
||||
return Dispatch(indexer => _feedFetcher.Fetch(indexer, searchSpec), searchSpec);
|
||||
}
|
||||
|
||||
public List<DownloadDecision> SearchDaily(int seriesId, DateTime airDate)
|
||||
private List<DownloadDecision> SearchDaily(int seriesId, DateTime airDate)
|
||||
{
|
||||
var searchSpec = Get<DailyEpisodeSearchCriteria>(seriesId);
|
||||
searchSpec.Airtime = airDate;
|
||||
@ -67,7 +82,7 @@ public List<DownloadDecision> SearchDaily(int seriesId, DateTime airDate)
|
||||
return Dispatch(indexer => _feedFetcher.Fetch(indexer, searchSpec), searchSpec);
|
||||
}
|
||||
|
||||
public List<DownloadDecision> SearchSeason(int seriesId, int seasonNumber)
|
||||
public List<DownloadDecision> SeasonSearch(int seriesId, int seasonNumber)
|
||||
{
|
||||
var searchSpec = Get<SeasonSearchCriteria>(seriesId, seasonNumber);
|
||||
searchSpec.SeasonNumber = seasonNumber;
|
||||
@ -99,10 +114,15 @@ private List<DownloadDecision> PartialSeasonSearch(SeasonSearchCriteria search)
|
||||
{
|
||||
var spec = new TSpec();
|
||||
|
||||
var tvdbId = _seriesService.GetSeries(seriesId).TvdbId;
|
||||
var series = _seriesService.GetSeries(seriesId);
|
||||
|
||||
spec.SeriesId = seriesId;
|
||||
spec.SceneTitle = _sceneMapping.GetSceneName(tvdbId, seasonNumber);
|
||||
spec.SceneTitle = _sceneMapping.GetSceneName(series.TvdbId, seasonNumber);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(spec.SceneTitle))
|
||||
{
|
||||
spec.SceneTitle = series.Title;
|
||||
}
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ interface ISearchAndDownload
|
||||
void SearchSeason(int seriesId, int seasonNumber);
|
||||
}
|
||||
|
||||
public class SearchAndDownloadService : ISearchAndDownload
|
||||
/* public class SearchAndDownloadService : ISearchAndDownload
|
||||
{
|
||||
private readonly ISearchForNzb _searchService;
|
||||
private readonly IMakeDownloadDecision _downloadDecisionMaker;
|
||||
@ -23,7 +23,7 @@ public SearchAndDownloadService(ISearchForNzb searchService, IMakeDownloadDecisi
|
||||
_downloadDecisionMaker = downloadDecisionMaker;
|
||||
}
|
||||
|
||||
public void SearchSingle(int seriesId, int seasonNumber, int episodeNumber)
|
||||
public void FetchSearchSingle(int seriesId, int seasonNumber, int episodeNumber)
|
||||
{
|
||||
var result = _searchService.SearchSingle(seriesId, seasonNumber, episodeNumber);
|
||||
}
|
||||
@ -37,5 +37,5 @@ public void SearchSeason(int seriesId, int seasonNumber)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
@ -48,7 +48,7 @@ public IList<ReportInfo> Fetch(IIndexer indexer, SeasonSearchCriteria searchCrit
|
||||
{
|
||||
_logger.Debug("Searching for {0}", searchCriteria);
|
||||
|
||||
var searchUrls = indexer.GetSeasonSearchUrls(searchCriteria.SceneTitle, searchCriteria.SeasonNumber);
|
||||
var searchUrls = indexer.GetSeasonSearchUrls(searchCriteria.QueryTitle, searchCriteria.SeasonNumber);
|
||||
var result = Fetch(indexer, searchUrls);
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ public IList<ReportInfo> Fetch(IIndexer indexer, SingleEpisodeSearchCriteria sea
|
||||
{
|
||||
_logger.Debug("Searching for {0}", searchCriteria);
|
||||
|
||||
var searchUrls = indexer.GetEpisodeSearchUrls(searchCriteria.SceneTitle, searchCriteria.SeasonNumber, searchCriteria.EpisodeNumber);
|
||||
var searchUrls = indexer.GetEpisodeSearchUrls(searchCriteria.QueryTitle, searchCriteria.SeasonNumber, searchCriteria.EpisodeNumber);
|
||||
var result = Fetch(indexer, searchUrls);
|
||||
|
||||
|
||||
@ -73,7 +73,7 @@ public IList<ReportInfo> Fetch(IIndexer indexer, PartialSeasonSearchCriteria sea
|
||||
{
|
||||
_logger.Debug("Searching for {0}", searchCriteria);
|
||||
|
||||
var searchUrls = indexer.GetSeasonSearchUrls(searchCriteria.SceneTitle, searchCriteria.SeasonNumber);
|
||||
var searchUrls = indexer.GetSeasonSearchUrls(searchCriteria.QueryTitle, searchCriteria.SeasonNumber);
|
||||
var result = Fetch(indexer, searchUrls);
|
||||
|
||||
|
||||
@ -85,7 +85,7 @@ public IList<ReportInfo> Fetch(IIndexer indexer, DailyEpisodeSearchCriteria sear
|
||||
{
|
||||
_logger.Debug("Searching for {0}", searchCriteria);
|
||||
|
||||
var searchUrls = indexer.GetDailyEpisodeSearchUrls(searchCriteria.SceneTitle, searchCriteria.Airtime);
|
||||
var searchUrls = indexer.GetDailyEpisodeSearchUrls(searchCriteria.QueryTitle, searchCriteria.Airtime);
|
||||
var result = Fetch(indexer, searchUrls);
|
||||
|
||||
_logger.Info("Finished searching {0} on {1}. Found {2}", indexer.Name, searchCriteria, result.Count);
|
||||
|
@ -1,6 +1,6 @@
|
||||
<SolutionConfiguration>
|
||||
<FileVersion>1</FileVersion>
|
||||
<AutoEnableOnStartup>False</AutoEnableOnStartup>
|
||||
<AutoEnableOnStartup>True</AutoEnableOnStartup>
|
||||
<AllowParallelTestExecution>true</AllowParallelTestExecution>
|
||||
<AllowTestsToRunInParallelWithThemselves>true</AllowTestsToRunInParallelWithThemselves>
|
||||
<FrameworkUtilisationTypeForNUnit>UseDynamicAnalysis</FrameworkUtilisationTypeForNUnit>
|
||||
|
@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
define(['app', 'Episode/Summary/View'], function () {
|
||||
define(['app', 'Shared/SpinnerView', 'Episode/Summary/View', 'Episode/Search/Layout', 'Release/Collection'], function () {
|
||||
|
||||
NzbDrone.Episode.Layout = Backbone.Marionette.Layout.extend({
|
||||
template: 'Episode/LayoutTemplate',
|
||||
@ -27,6 +27,7 @@ define(['app', 'Episode/Summary/View'], function () {
|
||||
|
||||
onShow: function () {
|
||||
this.showSummary();
|
||||
this._releaseSearchActivated = false;
|
||||
},
|
||||
|
||||
|
||||
@ -53,9 +54,23 @@ define(['app', 'Episode/Summary/View'], function () {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
if (this._releaseSearchActivated) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
this.ui.search.tab('show');
|
||||
this.search.show(new NzbDrone.Shared.SpinnerView());
|
||||
|
||||
var releases = new NzbDrone.Release.Collection();
|
||||
var promise = releases.fetchEpisodeReleases(this.model.id);
|
||||
|
||||
promise.done(function () {
|
||||
self.search.show(new NzbDrone.Episode.Search.Layout({collection: releases}));
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
@ -2,9 +2,65 @@
|
||||
define(['app'], function () {
|
||||
|
||||
NzbDrone.Episode.Search.Layout = Backbone.Marionette.Layout.extend({
|
||||
template: 'Episode/Search/LayoutTemplate'
|
||||
template: 'Episode/Search/LayoutTemplate',
|
||||
|
||||
regions: {
|
||||
grid: '#episode-release-grid'
|
||||
},
|
||||
|
||||
columns: [
|
||||
{
|
||||
name : 'age',
|
||||
label : 'Age',
|
||||
sortable: true,
|
||||
cell : Backgrid.IntegerCell
|
||||
},
|
||||
{
|
||||
name : 'size',
|
||||
label : 'Size',
|
||||
sortable: true,
|
||||
cell : Backgrid.IntegerCell
|
||||
},
|
||||
{
|
||||
name : 'title',
|
||||
label : 'Title',
|
||||
sortable: true,
|
||||
cell : Backgrid.StringCell
|
||||
},
|
||||
{
|
||||
name : 'seasonNumber',
|
||||
label: 'season',
|
||||
cell : Backgrid.IntegerCell
|
||||
},
|
||||
{
|
||||
name : 'episodeNumber',
|
||||
label: 'episode',
|
||||
cell : Backgrid.StringCell
|
||||
},
|
||||
{
|
||||
name : 'approved',
|
||||
label: 'Approved',
|
||||
cell : Backgrid.BooleanCell
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
|
||||
initialize: function () {
|
||||
|
||||
},
|
||||
|
||||
onShow :function(){
|
||||
if (!this.isClosed) {
|
||||
this.grid.show(new Backgrid.Grid(
|
||||
{
|
||||
row : Backgrid.Row,
|
||||
columns : this.columns,
|
||||
collection: this.collection,
|
||||
className : 'table table-hover'
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
@ -1 +1 @@
|
||||
|
||||
<div id="episode-release-grid"/>
|
||||
|
@ -4,6 +4,10 @@ define(['app', 'Release/Model'], function () {
|
||||
url : NzbDrone.Constants.ApiRoot + '/release',
|
||||
model: NzbDrone.Release.Model,
|
||||
|
||||
mode : 'client'
|
||||
mode: 'client',
|
||||
|
||||
fetchEpisodeReleases: function (episodeId) {
|
||||
return this.fetch({ data: { episodeId: episodeId }});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -10,9 +10,18 @@ define(['app'], function () {
|
||||
$(document).on('click', 'a[href]', this._handleClick);
|
||||
},
|
||||
|
||||
_isInTab: function (element) {
|
||||
return;
|
||||
},
|
||||
|
||||
_handleClick: function (event) {
|
||||
var $target = $(event.target);
|
||||
|
||||
//check if tab nav
|
||||
if ($target.parents('.nav-tabs').length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($target.hasClass('no-router')) {
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user