Search Results grid added.

This commit is contained in:
Mark McDowall 2012-04-21 01:16:15 -07:00
parent c83d8879a2
commit 4f005e45c0
12 changed files with 191 additions and 31 deletions

View 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)
});
}
}
}

View File

@ -8,14 +8,14 @@ namespace NzbDrone.Core.Model
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,
}
}

View File

@ -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" />

View File

@ -192,7 +192,6 @@ namespace NzbDrone.Core.Providers.Indexer
{
parsedEpisode.NzbUrl = NzbDownloadUrl(item);
parsedEpisode.Indexer = Name;
parsedEpisode.OriginalString = item.Title.Text;
result.Add(parsedEpisode);
}
}
@ -237,6 +236,7 @@ namespace NzbDrone.Core.Providers.Indexer
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);

View File

@ -172,22 +172,20 @@ namespace NzbDrone.Core.Providers
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 @@ namespace NzbDrone.Core.Providers
var item = new SearchResultItem
{
ReportTitle = episodeParseResult.OriginalString,
NzbUrl = episodeParseResult.NzbUrl
NzbUrl = episodeParseResult.NzbUrl,
Indexer = episodeParseResult.Indexer
};
items.Add(item);
@ -312,8 +311,8 @@ namespace NzbDrone.Core.Providers
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 @@ namespace NzbDrone.Core.Providers
var item = new SearchResultItem
{
ReportTitle = episodeParseResult.OriginalString,
NzbUrl = episodeParseResult.NzbUrl
NzbUrl = episodeParseResult.NzbUrl,
Indexer = episodeParseResult.Indexer
};
items.Add(item);
@ -390,8 +390,8 @@ namespace NzbDrone.Core.Providers
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 @@ namespace NzbDrone.Core.Providers
notification.CurrentMessage = String.Format("Unable to add report to download queue. {0}", episodeParseResult);
}
}
else
{
item.SearchError = allowedDownload;
}
}
catch (Exception e)
{

View File

@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using NLog;
using Ninject;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Search;
using PetaPoco;
@ -28,9 +29,10 @@ namespace NzbDrone.Core.Providers
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 @@ namespace NzbDrone.Core.Providers
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)

View File

@ -15,10 +15,31 @@ namespace NzbDrone.Core.Repository.Search
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; }
}
}

View File

@ -14,6 +14,7 @@ namespace NzbDrone.Core.Repository.Search
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; }

View File

@ -7,6 +7,8 @@ using System.Web.Mvc;
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 @@ namespace NzbDrone.Web.Controllers
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 @@ namespace NzbDrone.Web.Controllers
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 @@ namespace NzbDrone.Web.Controllers
},
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);
}
}
}

View 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; }
}
}

View File

@ -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>

View 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)
)
}