Search Results grid added.

pull/19/head
Mark McDowall 13 years ago
parent c83d8879a2
commit 4f005e45c0

@ -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 @@ namespace NzbDrone.Core.Model
WrongSeries = 1, WrongSeries = 1,
QualityNotWanted = 2, QualityNotWanted = 2,
WrongSeason = 3, WrongSeason = 3,
WrongEpisode = 3, WrongEpisode = 4,
Size = 3, Size = 5,
Retention = 3, Retention = 6,
ExistingQualityIsEqualOrBetter = 4, ExistingQualityIsEqualOrBetter = 7,
Cutoff = 5, Cutoff = 8,
AlreadyInQueue = 6, AlreadyInQueue = 9,
DownloadClientFailure = 7, DownloadClientFailure = 10,
Skipped = 8, Skipped = 11,
Failure, Failure = 12,
} }
} }

@ -222,6 +222,7 @@
<Compile Include="Datastore\MigrationLogger.cs" /> <Compile Include="Datastore\MigrationLogger.cs" />
<Compile Include="Datastore\MigrationsHelper.cs" /> <Compile Include="Datastore\MigrationsHelper.cs" />
<Compile Include="Datastore\CustomeMapper.cs" /> <Compile Include="Datastore\CustomeMapper.cs" />
<Compile Include="Datastore\Migrations\Migration20120420.cs" />
<Compile Include="Datastore\Migrations\Migration20120228.cs" /> <Compile Include="Datastore\Migrations\Migration20120228.cs" />
<Compile Include="Datastore\Migrations\Migration20120227.cs" /> <Compile Include="Datastore\Migrations\Migration20120227.cs" />
<Compile Include="Datastore\Migrations\Migration20120220.cs" /> <Compile Include="Datastore\Migrations\Migration20120220.cs" />

@ -192,7 +192,6 @@ namespace NzbDrone.Core.Providers.Indexer
{ {
parsedEpisode.NzbUrl = NzbDownloadUrl(item); parsedEpisode.NzbUrl = NzbDownloadUrl(item);
parsedEpisode.Indexer = Name; parsedEpisode.Indexer = Name;
parsedEpisode.OriginalString = item.Title.Text;
result.Add(parsedEpisode); result.Add(parsedEpisode);
} }
} }
@ -237,6 +236,7 @@ namespace NzbDrone.Core.Providers.Indexer
var title = TitlePreParser(item); var title = TitlePreParser(item);
var episodeParseResult = Parser.ParseTitle(title); var episodeParseResult = Parser.ParseTitle(title);
episodeParseResult.OriginalString = title;
if (episodeParseResult != null) episodeParseResult.Age = DateTime.Now.Date.Subtract(item.PublishDate.Date).Days; if (episodeParseResult != null) episodeParseResult.Age = DateTime.Now.Date.Subtract(item.PublishDate.Date).Days;
_logger.Trace("Parsed: {0} from: {1}", episodeParseResult, item.Title.Text); _logger.Trace("Parsed: {0} from: {1}", episodeParseResult, item.Title.Text);

@ -172,22 +172,20 @@ namespace NzbDrone.Core.Providers
if (episode.Series.IsDaily) if (episode.Series.IsDaily)
{ {
searchResult.AirDate = episode.AirDate.Value;
searchResult.SearchResultItems = ProcessSearchResults(notification, reports, episode.Series, episode.AirDate.Value); searchResult.SearchResultItems = ProcessSearchResults(notification, reports, episode.Series, episode.AirDate.Value);
_searchResultProvider.Add(searchResult); _searchResultProvider.Add(searchResult);
if (searchResult.SearchResultItems.Any(r => r.Success)) if (searchResult.SearchResultItems.Any(r => r.Success))
return true; return true;
return false;
} }
if (!episode.Series.IsDaily) else
{ {
searchResult.SeasonNumber = episode.SeasonNumber;
searchResult.EpisodeId = episodeId; 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; return true;
} }
@ -272,7 +270,8 @@ namespace NzbDrone.Core.Providers
var item = new SearchResultItem var item = new SearchResultItem
{ {
ReportTitle = episodeParseResult.OriginalString, ReportTitle = episodeParseResult.OriginalString,
NzbUrl = episodeParseResult.NzbUrl NzbUrl = episodeParseResult.NzbUrl,
Indexer = episodeParseResult.Indexer
}; };
items.Add(item); items.Add(item);
@ -312,8 +311,8 @@ namespace NzbDrone.Core.Providers
continue; continue;
} }
var rejectionType = _allowedDownloadSpecification.IsSatisfiedBy(episodeParseResult); item.SearchError = _allowedDownloadSpecification.IsSatisfiedBy(episodeParseResult);
if (rejectionType == ReportRejectionType.None) if (item.SearchError == ReportRejectionType.None)
{ {
Logger.Debug("Found '{0}'. Adding to download queue.", episodeParseResult); Logger.Debug("Found '{0}'. Adding to download queue.", episodeParseResult);
try try
@ -360,7 +359,8 @@ namespace NzbDrone.Core.Providers
var item = new SearchResultItem var item = new SearchResultItem
{ {
ReportTitle = episodeParseResult.OriginalString, ReportTitle = episodeParseResult.OriginalString,
NzbUrl = episodeParseResult.NzbUrl NzbUrl = episodeParseResult.NzbUrl,
Indexer = episodeParseResult.Indexer
}; };
items.Add(item); items.Add(item);
@ -390,8 +390,8 @@ namespace NzbDrone.Core.Providers
continue; continue;
} }
var allowedDownload = _allowedDownloadSpecification.IsSatisfiedBy(episodeParseResult); item.SearchError = _allowedDownloadSpecification.IsSatisfiedBy(episodeParseResult);
if (allowedDownload == ReportRejectionType.None) if (item.SearchError == ReportRejectionType.None)
{ {
Logger.Debug("Found '{0}'. Adding to download queue.", episodeParseResult); Logger.Debug("Found '{0}'. Adding to download queue.", episodeParseResult);
try try
@ -416,10 +416,6 @@ namespace NzbDrone.Core.Providers
notification.CurrentMessage = String.Format("Unable to add report to download queue. {0}", episodeParseResult); notification.CurrentMessage = String.Format("Unable to add report to download queue. {0}", episodeParseResult);
} }
} }
else
{
item.SearchError = allowedDownload;
}
} }
catch (Exception e) catch (Exception e)
{ {

@ -4,6 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using NLog; using NLog;
using Ninject; using Ninject;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Search; using NzbDrone.Core.Repository.Search;
using PetaPoco; using PetaPoco;
@ -28,9 +29,10 @@ namespace NzbDrone.Core.Providers
public virtual void Add(SearchResult searchResult) public virtual void Add(SearchResult searchResult)
{ {
logger.Trace("Adding new search result"); logger.Trace("Adding new search result");
searchResult.SuccessfulDownload = searchResult.SearchResultItems.Any(s => s.Success);
var id = Convert.ToInt32(_database.Insert(searchResult)); 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"); logger.Trace("Adding search result items");
_database.InsertMany(searchResult.SearchResultItems); _database.InsertMany(searchResult.SearchResultItems);
} }
@ -46,7 +48,27 @@ namespace NzbDrone.Core.Providers
public virtual List<SearchResult> AllSearchResults() 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) public virtual SearchResult GetSearchResult(int id)

@ -15,10 +15,31 @@ namespace NzbDrone.Core.Repository.Search
public int SeriesId { get; set; } public int SeriesId { get; set; }
public int? SeasonNumber { get; set; } public int? SeasonNumber { get; set; }
public int? EpisodeId { get; set; } public int? EpisodeId { get; set; }
public DateTime? AirDate { get; set; }
public DateTime SearchTime { get; set; } public DateTime SearchTime { get; set; }
public bool SuccessfulDownload { get; set; }
[ResultColumn] [ResultColumn]
public List<SearchResultItem> SearchResultItems { get; set; } 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 @@ namespace NzbDrone.Core.Repository.Search
public int Id { get; set; } public int Id { get; set; }
public int SearchResultId { get; set; } public int SearchResultId { get; set; }
public string ReportTitle { get; set; } public string ReportTitle { get; set; }
public string Indexer { get; set; }
public string NzbUrl { get; set; } public string NzbUrl { get; set; }
public string NzbInfoUrl { get; set; } public string NzbInfoUrl { get; set; }
public bool Success { get; set; } public bool Success { get; set; }

@ -7,6 +7,8 @@ using System.Web.Mvc;
using DataTables.Mvc.Core.Models; using DataTables.Mvc.Core.Models;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.Instrumentation; using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Repository.Search;
using NzbDrone.Web.Models; using NzbDrone.Web.Models;
namespace NzbDrone.Web.Controllers namespace NzbDrone.Web.Controllers
@ -16,12 +18,15 @@ namespace NzbDrone.Web.Controllers
private readonly LogProvider _logProvider; private readonly LogProvider _logProvider;
private readonly EnvironmentProvider _environmentProvider; private readonly EnvironmentProvider _environmentProvider;
private readonly DiskProvider _diskProvider; 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; _logProvider = logProvider;
_environmentProvider = environmentProvider; _environmentProvider = environmentProvider;
_diskProvider = diskProvider; _diskProvider = diskProvider;
_searchResultProvider = searchResultProvider;
} }
public ActionResult Index() public ActionResult Index()
@ -50,6 +55,28 @@ namespace NzbDrone.Web.Controllers
return JsonNotificationResult.Info("Logs Cleared"); 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) public ActionResult AjaxBinding(DataTablesParams dataTablesParams)
{ {
var logs = _logProvider.GetAllLogs(); var logs = _logProvider.GetAllLogs();
@ -102,5 +129,24 @@ namespace NzbDrone.Web.Controllers
}, },
JsonRequestBehavior.AllowGet); 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);
}
} }
} }

@ -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\JobModel.cs" />
<Compile Include="Models\LogModel.cs" /> <Compile Include="Models\LogModel.cs" />
<Compile Include="Models\PostUpgradeModel.cs" /> <Compile Include="Models\PostUpgradeModel.cs" />
<Compile Include="Models\SearchResultsModel.cs" />
<Compile Include="Models\UpcomingEpisodesModel.cs" /> <Compile Include="Models\UpcomingEpisodesModel.cs" />
<Compile Include="Models\SeasonModel.cs" /> <Compile Include="Models\SeasonModel.cs" />
<Compile Include="Models\SeriesDetailsModel.cs" /> <Compile Include="Models\SeriesDetailsModel.cs" />
@ -519,6 +520,9 @@
<Content Include="Views\Shared\NoSeriesBanner.cshtml" /> <Content Include="Views\Shared\NoSeriesBanner.cshtml" />
<Content Include="Views\Update\Post.cshtml" /> <Content Include="Views\Update\Post.cshtml" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="Views\Log\SearchResults.cshtml" />
</ItemGroup>
<PropertyGroup> <PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

@ -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…
Cancel
Save