mirror of
https://github.com/Radarr/Radarr
synced 2024-12-24 17:01:38 +00:00
Search Results grid added.
This commit is contained in:
parent
c83d8879a2
commit
4f005e45c0
12 changed files with 191 additions and 31 deletions
34
NzbDrone.Core/Datastore/Migrations/Migration20120420.cs
Normal file
34
NzbDrone.Core/Datastore/Migrations/Migration20120420.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using System.Data;
|
||||
using Migrator.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migrations
|
||||
{
|
||||
[Migration(20120420)]
|
||||
public class Migration20120420 : NzbDroneMigration
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Database.AddTable("SearchResults", new[]
|
||||
{
|
||||
new Column("Id", DbType.Int32, ColumnProperty.PrimaryKeyWithIdentity),
|
||||
new Column("SeriesId", DbType.Int32, ColumnProperty.NotNull),
|
||||
new Column("SeasonNumber", DbType.Int32, ColumnProperty.Null),
|
||||
new Column("EpisodeId", DbType.Int32, ColumnProperty.Null),
|
||||
new Column("SearchTime", DbType.DateTime, ColumnProperty.NotNull),
|
||||
new Column("SuccessfulDownload", DbType.Boolean, ColumnProperty.NotNull)
|
||||
});
|
||||
|
||||
Database.AddTable("SearchResultItems", new[]
|
||||
{
|
||||
new Column("Id", DbType.Int32, ColumnProperty.PrimaryKeyWithIdentity),
|
||||
new Column("SearchResultId", DbType.Int32, ColumnProperty.NotNull),
|
||||
new Column("ReportTitle", DbType.String, ColumnProperty.NotNull),
|
||||
new Column("Indexer", DbType.String, ColumnProperty.NotNull),
|
||||
new Column("NzbUrl", DbType.String, ColumnProperty.NotNull),
|
||||
new Column("NzbInfoUrl", DbType.String, ColumnProperty.Null),
|
||||
new Column("Success", DbType.Boolean, ColumnProperty.NotNull),
|
||||
new Column("SearchError", DbType.Int32, ColumnProperty.NotNull)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,14 +8,14 @@ public enum ReportRejectionType
|
|||
WrongSeries = 1,
|
||||
QualityNotWanted = 2,
|
||||
WrongSeason = 3,
|
||||
WrongEpisode = 3,
|
||||
Size = 3,
|
||||
Retention = 3,
|
||||
ExistingQualityIsEqualOrBetter = 4,
|
||||
Cutoff = 5,
|
||||
AlreadyInQueue = 6,
|
||||
DownloadClientFailure = 7,
|
||||
Skipped = 8,
|
||||
Failure,
|
||||
WrongEpisode = 4,
|
||||
Size = 5,
|
||||
Retention = 6,
|
||||
ExistingQualityIsEqualOrBetter = 7,
|
||||
Cutoff = 8,
|
||||
AlreadyInQueue = 9,
|
||||
DownloadClientFailure = 10,
|
||||
Skipped = 11,
|
||||
Failure = 12,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -222,6 +222,7 @@
|
|||
<Compile Include="Datastore\MigrationLogger.cs" />
|
||||
<Compile Include="Datastore\MigrationsHelper.cs" />
|
||||
<Compile Include="Datastore\CustomeMapper.cs" />
|
||||
<Compile Include="Datastore\Migrations\Migration20120420.cs" />
|
||||
<Compile Include="Datastore\Migrations\Migration20120228.cs" />
|
||||
<Compile Include="Datastore\Migrations\Migration20120227.cs" />
|
||||
<Compile Include="Datastore\Migrations\Migration20120220.cs" />
|
||||
|
|
|
@ -192,7 +192,6 @@ private List<EpisodeParseResult> Fetch(IEnumerable<string> urls)
|
|||
{
|
||||
parsedEpisode.NzbUrl = NzbDownloadUrl(item);
|
||||
parsedEpisode.Indexer = Name;
|
||||
parsedEpisode.OriginalString = item.Title.Text;
|
||||
result.Add(parsedEpisode);
|
||||
}
|
||||
}
|
||||
|
@ -237,6 +236,7 @@ public EpisodeParseResult ParseFeed(SyndicationItem item)
|
|||
var title = TitlePreParser(item);
|
||||
|
||||
var episodeParseResult = Parser.ParseTitle(title);
|
||||
episodeParseResult.OriginalString = title;
|
||||
if (episodeParseResult != null) episodeParseResult.Age = DateTime.Now.Date.Subtract(item.PublishDate.Date).Days;
|
||||
|
||||
_logger.Trace("Parsed: {0} from: {1}", episodeParseResult, item.Title.Text);
|
||||
|
|
|
@ -172,22 +172,20 @@ public virtual bool EpisodeSearch(ProgressNotification notification, int episode
|
|||
|
||||
if (episode.Series.IsDaily)
|
||||
{
|
||||
searchResult.AirDate = episode.AirDate.Value;
|
||||
searchResult.SearchResultItems = ProcessSearchResults(notification, reports, episode.Series, episode.AirDate.Value);
|
||||
|
||||
_searchResultProvider.Add(searchResult);
|
||||
|
||||
if (searchResult.SearchResultItems.Any(r => r.Success))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!episode.Series.IsDaily)
|
||||
else
|
||||
{
|
||||
searchResult.SeasonNumber = episode.SeasonNumber;
|
||||
searchResult.EpisodeId = episodeId;
|
||||
ProcessSearchResults(notification, reports, episode.Series, episode.SeasonNumber, episode.EpisodeNumber);
|
||||
searchResult.SearchResultItems = ProcessSearchResults(notification, reports, episode.Series, episode.SeasonNumber, episode.EpisodeNumber);
|
||||
_searchResultProvider.Add(searchResult);
|
||||
|
||||
if (searchResult.SearchResultItems.Any(r => r.Success))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -272,7 +270,8 @@ public List<SearchResultItem> ProcessSearchResults(ProgressNotification notifica
|
|||
var item = new SearchResultItem
|
||||
{
|
||||
ReportTitle = episodeParseResult.OriginalString,
|
||||
NzbUrl = episodeParseResult.NzbUrl
|
||||
NzbUrl = episodeParseResult.NzbUrl,
|
||||
Indexer = episodeParseResult.Indexer
|
||||
};
|
||||
|
||||
items.Add(item);
|
||||
|
@ -312,8 +311,8 @@ public List<SearchResultItem> ProcessSearchResults(ProgressNotification notifica
|
|||
continue;
|
||||
}
|
||||
|
||||
var rejectionType = _allowedDownloadSpecification.IsSatisfiedBy(episodeParseResult);
|
||||
if (rejectionType == ReportRejectionType.None)
|
||||
item.SearchError = _allowedDownloadSpecification.IsSatisfiedBy(episodeParseResult);
|
||||
if (item.SearchError == ReportRejectionType.None)
|
||||
{
|
||||
Logger.Debug("Found '{0}'. Adding to download queue.", episodeParseResult);
|
||||
try
|
||||
|
@ -360,7 +359,8 @@ public List<SearchResultItem> ProcessSearchResults(ProgressNotification notifica
|
|||
var item = new SearchResultItem
|
||||
{
|
||||
ReportTitle = episodeParseResult.OriginalString,
|
||||
NzbUrl = episodeParseResult.NzbUrl
|
||||
NzbUrl = episodeParseResult.NzbUrl,
|
||||
Indexer = episodeParseResult.Indexer
|
||||
};
|
||||
|
||||
items.Add(item);
|
||||
|
@ -390,8 +390,8 @@ public List<SearchResultItem> ProcessSearchResults(ProgressNotification notifica
|
|||
continue;
|
||||
}
|
||||
|
||||
var allowedDownload = _allowedDownloadSpecification.IsSatisfiedBy(episodeParseResult);
|
||||
if (allowedDownload == ReportRejectionType.None)
|
||||
item.SearchError = _allowedDownloadSpecification.IsSatisfiedBy(episodeParseResult);
|
||||
if (item.SearchError == ReportRejectionType.None)
|
||||
{
|
||||
Logger.Debug("Found '{0}'. Adding to download queue.", episodeParseResult);
|
||||
try
|
||||
|
@ -416,10 +416,6 @@ public List<SearchResultItem> ProcessSearchResults(ProgressNotification notifica
|
|||
notification.CurrentMessage = String.Format("Unable to add report to download queue. {0}", episodeParseResult);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item.SearchError = allowedDownload;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
using System.Text;
|
||||
using NLog;
|
||||
using Ninject;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Core.Repository.Search;
|
||||
using PetaPoco;
|
||||
|
||||
|
@ -28,9 +29,10 @@ public SearchResultProvider()
|
|||
public virtual void Add(SearchResult searchResult)
|
||||
{
|
||||
logger.Trace("Adding new search result");
|
||||
searchResult.SuccessfulDownload = searchResult.SearchResultItems.Any(s => s.Success);
|
||||
var id = Convert.ToInt32(_database.Insert(searchResult));
|
||||
|
||||
searchResult.SearchResultItems.ForEach(s => s.Id = id);
|
||||
searchResult.SearchResultItems.ForEach(s => s.SearchResultId = id);
|
||||
logger.Trace("Adding search result items");
|
||||
_database.InsertMany(searchResult.SearchResultItems);
|
||||
}
|
||||
|
@ -46,7 +48,27 @@ public virtual void Delete(int id)
|
|||
|
||||
public virtual List<SearchResult> AllSearchResults()
|
||||
{
|
||||
return _database.Fetch<SearchResult>();
|
||||
var sql = @"SELECT SearchResults.Id, SearchResults.SeriesId, SearchResults.SeasonNumber,
|
||||
SearchResults.EpisodeId, SearchResults.SearchTime,
|
||||
Series.Title as SeriesTitle, Series.IsDaily,
|
||||
Episodes.EpisodeNumber, Episodes.SeasonNumber, Episodes.Title as EpisodeTitle,
|
||||
Episodes.AirDate,
|
||||
Count(SearchResultItems.Id) as TotalItems,
|
||||
SUM(CASE WHEN SearchResultItems.Success = 1 THEN 1 ELSE 0 END) as Successes
|
||||
FROM SearchResults
|
||||
INNER JOIN Series
|
||||
ON Series.SeriesId = SearchResults.SeriesId
|
||||
LEFT JOIN Episodes
|
||||
ON Episodes.EpisodeId = SearchResults.EpisodeId
|
||||
INNER JOIN SearchResultItems
|
||||
ON SearchResultItems.SearchResultId = SearchResults.Id
|
||||
GROUP BY SearchResults.Id, SearchResults.SeriesId, SearchResults.SeasonNumber,
|
||||
SearchResults.EpisodeId, SearchResults.SearchTime,
|
||||
Series.Title, Series.IsDaily,
|
||||
Episodes.EpisodeNumber, Episodes.SeasonNumber, Episodes.Title,
|
||||
Episodes.AirDate";
|
||||
|
||||
return _database.Fetch<SearchResult>(sql);
|
||||
}
|
||||
|
||||
public virtual SearchResult GetSearchResult(int id)
|
||||
|
|
|
@ -15,10 +15,31 @@ public class SearchResult
|
|||
public int SeriesId { get; set; }
|
||||
public int? SeasonNumber { get; set; }
|
||||
public int? EpisodeId { get; set; }
|
||||
public DateTime? AirDate { get; set; }
|
||||
public DateTime SearchTime { get; set; }
|
||||
public bool SuccessfulDownload { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
public List<SearchResultItem> SearchResultItems { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
public string SeriesTitle { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
public bool IsDaily { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
public int? EpisodeNumber { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
public string EpisodeTitle { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
public DateTime AirDate { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
public int TotalItems { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
public int Successes { get; set; }
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ public class SearchResultItem
|
|||
public int Id { get; set; }
|
||||
public int SearchResultId { get; set; }
|
||||
public string ReportTitle { get; set; }
|
||||
public string Indexer { get; set; }
|
||||
public string NzbUrl { get; set; }
|
||||
public string NzbInfoUrl { get; set; }
|
||||
public bool Success { get; set; }
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
using DataTables.Mvc.Core.Models;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Instrumentation;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Repository.Search;
|
||||
using NzbDrone.Web.Models;
|
||||
|
||||
namespace NzbDrone.Web.Controllers
|
||||
|
@ -16,12 +18,15 @@ public class LogController : Controller
|
|||
private readonly LogProvider _logProvider;
|
||||
private readonly EnvironmentProvider _environmentProvider;
|
||||
private readonly DiskProvider _diskProvider;
|
||||
private readonly SearchResultProvider _searchResultProvider;
|
||||
|
||||
public LogController(LogProvider logProvider, EnvironmentProvider environmentProvider, DiskProvider diskProvider)
|
||||
public LogController(LogProvider logProvider, EnvironmentProvider environmentProvider,
|
||||
DiskProvider diskProvider, SearchResultProvider searchResultProvider)
|
||||
{
|
||||
_logProvider = logProvider;
|
||||
_environmentProvider = environmentProvider;
|
||||
_diskProvider = diskProvider;
|
||||
_searchResultProvider = searchResultProvider;
|
||||
}
|
||||
|
||||
public ActionResult Index()
|
||||
|
@ -50,6 +55,28 @@ public JsonResult Clear()
|
|||
return JsonNotificationResult.Info("Logs Cleared");
|
||||
}
|
||||
|
||||
public ActionResult SearchResults()
|
||||
{
|
||||
var results = _searchResultProvider.AllSearchResults();
|
||||
|
||||
var model = results.Select(s => new SearchResultsModel
|
||||
{
|
||||
Id = s.Id,
|
||||
SearchTime = s.SearchTime.ToString(),
|
||||
DisplayName = GetDisplayName(s),
|
||||
ReportCount = s.TotalItems,
|
||||
Successful = s.Successes > 0
|
||||
});
|
||||
|
||||
return View(model);
|
||||
}
|
||||
|
||||
public ActionResult SearchDetails(int searchId)
|
||||
{
|
||||
var model = _searchResultProvider.GetSearchResult(searchId);
|
||||
return View(model);
|
||||
}
|
||||
|
||||
public ActionResult AjaxBinding(DataTablesParams dataTablesParams)
|
||||
{
|
||||
var logs = _logProvider.GetAllLogs();
|
||||
|
@ -102,5 +129,24 @@ public ActionResult AjaxBinding(DataTablesParams dataTablesParams)
|
|||
},
|
||||
JsonRequestBehavior.AllowGet);
|
||||
}
|
||||
|
||||
public string GetDisplayName(SearchResult searchResult)
|
||||
{
|
||||
if (!searchResult.EpisodeNumber.HasValue)
|
||||
{
|
||||
return String.Format("{0} - Season {1}", searchResult.SeriesTitle, searchResult.SeasonNumber);
|
||||
}
|
||||
|
||||
string episodeString;
|
||||
|
||||
if (searchResult.IsDaily)
|
||||
episodeString = searchResult.AirDate.ToShortDateString().Replace('/', '-');
|
||||
|
||||
else
|
||||
episodeString = String.Format("S{0:00}E{1:00}", searchResult.SeasonNumber,
|
||||
searchResult.EpisodeNumber);
|
||||
|
||||
return String.Format("{0} - {1} - {2}", searchResult.SeriesTitle, episodeString, searchResult.EpisodeTitle);
|
||||
}
|
||||
}
|
||||
}
|
13
NzbDrone.Web/Models/SearchResultsModel.cs
Normal file
13
NzbDrone.Web/Models/SearchResultsModel.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
|
||||
namespace NzbDrone.Web.Models
|
||||
{
|
||||
public class SearchResultsModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string SearchTime { get; set; }
|
||||
public int ReportCount { get; set; }
|
||||
public bool Successful { get; set; }
|
||||
}
|
||||
}
|
|
@ -237,6 +237,7 @@
|
|||
<Compile Include="Models\JobModel.cs" />
|
||||
<Compile Include="Models\LogModel.cs" />
|
||||
<Compile Include="Models\PostUpgradeModel.cs" />
|
||||
<Compile Include="Models\SearchResultsModel.cs" />
|
||||
<Compile Include="Models\UpcomingEpisodesModel.cs" />
|
||||
<Compile Include="Models\SeasonModel.cs" />
|
||||
<Compile Include="Models\SeriesDetailsModel.cs" />
|
||||
|
@ -519,6 +520,9 @@
|
|||
<Content Include="Views\Shared\NoSeriesBanner.cshtml" />
|
||||
<Content Include="Views\Update\Post.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Log\SearchResults.cshtml" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
|
|
22
NzbDrone.Web/Views/Log/SearchResults.cshtml
Normal file
22
NzbDrone.Web/Views/Log/SearchResults.cshtml
Normal file
|
@ -0,0 +1,22 @@
|
|||
@using DataTables.Mvc.Core
|
||||
@model IEnumerable<NzbDrone.Web.Models.SearchResultsModel>
|
||||
|
||||
@{
|
||||
ViewBag.Title = "Search Results";
|
||||
}
|
||||
|
||||
@Html.GridHtml("searchResultsGrid", "dataTablesGrid")
|
||||
|
||||
@section Scripts
|
||||
{
|
||||
@(
|
||||
Html.GridScriptForModel("#searchResultsGrid")
|
||||
.PageLength(20)
|
||||
.ChangePageLength(false)
|
||||
.AddColumn(new Column().DataProperty("DisplayName").Link("SearchDetails?searchId={Id}", "{DisplayName}").Title("Name"))
|
||||
.AddColumn(new Column().DataProperty("SearchTime").Title("Time").Width("170px"))
|
||||
.AddColumn(new Column().DataProperty("ReportCount").Title("Reports Found").Width("140px"))
|
||||
.AddColumn(new Column().DataProperty("Successful").Title("Successful").Width("110px"))
|
||||
.AddSorting(1)
|
||||
)
|
||||
}
|
Loading…
Reference in a new issue