History VIew Added.

Fixed Relationships between History and Episode/Indexer.
Indexer now uses int as ID, string caused issues.
Get single Indexer by ID.
This commit is contained in:
Mark McDowall 2011-03-22 22:19:23 -07:00
parent 4f2f5a3d71
commit 33b09567ce
14 changed files with 1704 additions and 48 deletions

View File

@ -20,7 +20,7 @@ namespace NzbDrone.Core.Test
public void AllItems() public void AllItems()
{ {
//Setup //Setup
var indexer = new Indexer { Enabled = true, IndexerName = "NzbMatrix", Order = 1, RssUrl = "http://www.nzbmatrix.com" }; var indexer = new Indexer { Enabled = true, IndexerId = 0, IndexerName = "NzbMatrix", Order = 1, RssUrl = "http://www.nzbmatrix.com" };
var series = new Series var series = new Series
{ {
SeriesId = 5656, SeriesId = 5656,
@ -52,7 +52,7 @@ namespace NzbDrone.Core.Test
Date = DateTime.Now, Date = DateTime.Now,
IsProper = false, IsProper = false,
Quality = QualityTypes.TV, Quality = QualityTypes.TV,
IndexerName = indexer.IndexerName, IndexerId = indexer.IndexerId,
EpisodeId = episode.EpisodeId EpisodeId = episode.EpisodeId
}); });
@ -105,7 +105,7 @@ namespace NzbDrone.Core.Test
Date = DateTime.Now, Date = DateTime.Now,
IsProper = false, IsProper = false,
Quality = QualityTypes.TV, Quality = QualityTypes.TV,
IndexerName = indexer.IndexerName, IndexerId = indexer.IndexerId,
EpisodeId = episode.EpisodeId EpisodeId = episode.EpisodeId
}); });
@ -161,7 +161,7 @@ namespace NzbDrone.Core.Test
Date = DateTime.Now, Date = DateTime.Now,
IsProper = false, IsProper = false,
Quality = QualityTypes.TV, Quality = QualityTypes.TV,
IndexerName = indexer.IndexerName, IndexerId = indexer.IndexerId,
EpisodeId = episode.EpisodeId EpisodeId = episode.EpisodeId
}); });

View File

@ -24,6 +24,7 @@ namespace NzbDrone.Core
private static IKernel _kernel; private static IKernel _kernel;
private static readonly Object kernelLock = new object(); private static readonly Object kernelLock = new object();
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static string _startupPath;
public static void BindKernel() public static void BindKernel()
{ {
@ -86,6 +87,9 @@ namespace NzbDrone.Core
SetupIndexers(_kernel.Get<IRepository>()); //Setup the default set of indexers on start-up SetupIndexers(_kernel.Get<IRepository>()); //Setup the default set of indexers on start-up
SetupDefaultQualityProfiles(_kernel.Get<IRepository>()); //Setup the default QualityProfiles on start-up SetupDefaultQualityProfiles(_kernel.Get<IRepository>()); //Setup the default QualityProfiles on start-up
//Store the startup path
_startupPath = AppPath;
//Get the Timers going //Get the Timers going
var config = _kernel.Get<IConfigProvider>(); var config = _kernel.Get<IConfigProvider>();
var timer = _kernel.Get<ITimerProvider>(); var timer = _kernel.Get<ITimerProvider>();
@ -116,6 +120,11 @@ namespace NzbDrone.Core
} }
} }
public static string StartupPath
{
get { return _startupPath; }
}
public static IKernel NinjectKernel public static IKernel NinjectKernel
{ {
get get
@ -134,6 +143,8 @@ namespace NzbDrone.Core
repository.GetPaged<EpisodeFile>(0, 1); repository.GetPaged<EpisodeFile>(0, 1);
repository.GetPaged<Episode>(0, 1); repository.GetPaged<Episode>(0, 1);
repository.GetPaged<Season>(0, 1); repository.GetPaged<Season>(0, 1);
repository.GetPaged<History>(0, 1);
repository.GetPaged<Indexer>(0, 1);
} }
/// <summary> /// <summary>
@ -182,6 +193,7 @@ namespace NzbDrone.Core
var nzbMatrixIndexer = new Indexer var nzbMatrixIndexer = new Indexer
{ {
IndexerId = 1,
IndexerName = "NzbMatrix", IndexerName = "NzbMatrix",
RssUrl = nzbMatrixRss, RssUrl = nzbMatrixRss,
ApiUrl = nzbMatrixApi, ApiUrl = nzbMatrixApi,
@ -190,6 +202,7 @@ namespace NzbDrone.Core
var nzbsOrgIndexer = new Indexer var nzbsOrgIndexer = new Indexer
{ {
IndexerId = 2,
IndexerName = "NzbsOrg", IndexerName = "NzbsOrg",
RssUrl = nzbsOrgRss, RssUrl = nzbsOrgRss,
ApiUrl = nzbsOrgApi, ApiUrl = nzbsOrgApi,
@ -198,6 +211,7 @@ namespace NzbDrone.Core
var nzbsrusIndexer = new Indexer var nzbsrusIndexer = new Indexer
{ {
IndexerId = 3,
IndexerName = "Nzbsrus", IndexerName = "Nzbsrus",
RssUrl = nzbsrusRss, RssUrl = nzbsrusRss,
ApiUrl = nzbsrusApi, ApiUrl = nzbsrusApi,
@ -206,7 +220,7 @@ namespace NzbDrone.Core
//NzbMatrix //NzbMatrix
Logger.Debug("Checking for NzbMatrix Indexer"); Logger.Debug("Checking for NzbMatrix Indexer");
var nzbMatix = repository.Single<Indexer>("NzbMatrix"); var nzbMatix = repository.Single<Indexer>(1);
if (nzbMatix == null) if (nzbMatix == null)
{ {
Logger.Debug("Adding new Indexer: NzbMatrix"); Logger.Debug("Adding new Indexer: NzbMatrix");
@ -223,7 +237,7 @@ namespace NzbDrone.Core
//Nzbs.org //Nzbs.org
Logger.Debug("Checking for Nzbs.org"); Logger.Debug("Checking for Nzbs.org");
var nzbsOrg = repository.Single<Indexer>("NzbsOrg"); var nzbsOrg = repository.Single<Indexer>(2);
if (nzbsOrg == null) if (nzbsOrg == null)
{ {
Logger.Debug("Adding new Indexer: Nzbs.org"); Logger.Debug("Adding new Indexer: Nzbs.org");
@ -240,7 +254,7 @@ namespace NzbDrone.Core
//Nzbsrus //Nzbsrus
Logger.Debug("Checking for Nzbsrus"); Logger.Debug("Checking for Nzbsrus");
var nzbsrus = repository.Single<Indexer>("Nzbsrus"); var nzbsrus = repository.Single<Indexer>(3);
if (nzbsrus == null) if (nzbsrus == null)
{ {
Logger.Debug("Adding new Indexer: Nzbsrus"); Logger.Debug("Adding new Indexer: Nzbsrus");

View File

@ -44,7 +44,7 @@ namespace NzbDrone.Core.Providers
public void Insert(History item) public void Insert(History item)
{ {
_sonicRepo.Add(item); _sonicRepo.Add(item);
Logger.Info("Item added to history: {0} - {1}x{2:00}", item.Episode.Series.Title, item.Episode.SeasonNumber, item.Episode.EpisodeNumber); //Logger.Info("Item added to history: {0} - {1}x{2:00}", item.Episode.Series.Title, item.Episode.SeasonNumber, item.Episode.EpisodeNumber);
} }
public bool Exists(int episodeId, QualityTypes quality, bool proper) public bool Exists(int episodeId, QualityTypes quality, bool proper)

View File

@ -12,5 +12,6 @@ namespace NzbDrone.Core.Providers
List<Indexer> AllIndexers(); List<Indexer> AllIndexers();
List<Indexer> EnabledIndexers(); List<Indexer> EnabledIndexers();
void Update(Indexer indexer); void Update(Indexer indexer);
Indexer Single(int indexerId);
} }
} }

View File

@ -39,6 +39,11 @@ namespace NzbDrone.Core.Providers
_sonicRepo.Update(indexer); _sonicRepo.Update(indexer);
} }
public Indexer Single(int indexerId)
{
return _sonicRepo.Single<Indexer>(indexerId);
}
#endregion #endregion
} }
} }

View File

@ -53,7 +53,7 @@ namespace NzbDrone.Core.Providers
var episodeParseResults = Parser.ParseEpisodeInfo(nzb.Title); var episodeParseResults = Parser.ParseEpisodeInfo(nzb.Title);
if (episodeParseResults.Count() > 1) if (episodeParseResults.Count() > 0)
{ {
ProcessStandardItem(nzb, indexer, episodeParseResults); ProcessStandardItem(nzb, indexer, episodeParseResults);
return false; return false;
@ -70,6 +70,7 @@ namespace NzbDrone.Core.Providers
catch (Exception ex) catch (Exception ex)
{ {
Logger.Error("Unsupported Title: {0}", nzb.Title);
Logger.ErrorException("Error Parsing NZB: " + ex.Message, ex); Logger.ErrorException("Error Parsing NZB: " + ex.Message, ex);
} }
return false; return false;
@ -89,8 +90,10 @@ namespace NzbDrone.Core.Providers
if (episodeInDb == null) if (episodeInDb == null)
{ {
Logger.Debug("Episode Not found in Database"); //Todo: Handle this some other way?
return String.Format("{0} - {1:00}x{2}", series.Title, episode.SeasonNumber, episode.SeriesTitle); Logger.Debug("Episode Not found in Database, Fake it...");
//return String.Format("{0} - {1:00}x{2}", series.Title, episode.SeasonNumber, episode.EpisodeNumber);
episodeInDb = new Episode { EpisodeNumber = episode.EpisodeNumber, Title = "TBA" };
} }
seasonNumber = episodeInDb.SeasonNumber; seasonNumber = episodeInDb.SeasonNumber;
@ -149,7 +152,7 @@ namespace NzbDrone.Core.Providers
var titleFix = GetTitleFix(new List<EpisodeParseResult> { episode }, episodeModel.SeriesId); var titleFix = GetTitleFix(new List<EpisodeParseResult> { episode }, episodeModel.SeriesId);
titleFix = String.Format("{0} [{1}]", titleFix, nzb.Quality); //Add Quality to the titleFix titleFix = String.Format("{0} [{1}]", titleFix, nzb.Quality); //Add Quality to the titleFix
if (Convert.ToBoolean(_configProvider.GetValue("UseBlackhole", true, true))) if (!Convert.ToBoolean(_configProvider.GetValue("UseBlackhole", true, true)))
if (_sabProvider.IsInQueue(titleFix)) if (_sabProvider.IsInQueue(titleFix))
return; return;
} }
@ -165,11 +168,17 @@ namespace NzbDrone.Core.Providers
if (String.IsNullOrEmpty(path)) if (String.IsNullOrEmpty(path))
{ {
//Use the NZBDrone root Directory + /NZBs //Use the NZBDrone root Directory + /NZBs
path = CentralDispatch.AppPath + Path.DirectorySeparatorChar + "NZBs"; //path = CentralDispatch.StartupPath + "NZBs";
path = @"C:\Test\NZBs";
} }
if (_diskProvider.FolderExists(path)) if (_diskProvider.FolderExists(path))
_httpProvider.DownloadFile(nzb.Link.ToString(), path); {
var filename = path + Path.DirectorySeparatorChar + nzb.TitleFix;
if (_httpProvider.DownloadFile(nzb.Link.ToString(), filename))
AddToHistory(episodeParseResults, series, nzb, indexer);
}
else else
Logger.Error("Blackhole Directory doesn't exist, not saving NZB: '{0}'", path); Logger.Error("Blackhole Directory doesn't exist, not saving NZB: '{0}'", path);
@ -185,7 +194,13 @@ namespace NzbDrone.Core.Providers
} }
if (indexer.IndexerName != "Newzbin") if (indexer.IndexerName != "Newzbin")
AddByUrl(episodeParseResults, series, nzb, indexer); {
if (AddByUrl(nzb))
{
AddToHistory(episodeParseResults, series, nzb, indexer);
}
}
else else
{ {
@ -195,35 +210,37 @@ namespace NzbDrone.Core.Providers
} }
private void AddByUrl(List<EpisodeParseResult> episodeParseResults, Series series, NzbInfoModel nzb, Indexer indexer) private bool AddByUrl(NzbInfoModel nzb)
{ {
if (_sabProvider.AddByUrl(nzb.Link.ToString(), nzb.TitleFix)) return _sabProvider.AddByUrl(nzb.Link.ToString(), nzb.TitleFix);
}
private void AddToHistory(List<EpisodeParseResult> episodeParseResults, Series series, NzbInfoModel nzb, Indexer indexer)
{
//We need to loop through the episodeParseResults so each episode in the NZB is properly handled
foreach (var epr in episodeParseResults)
{ {
//We need to loop through the episodeParseResults so each episode in the NZB is properly handled var episode = _episodeProvider.GetEpisode(series.SeriesId, epr.SeasonNumber, epr.EpisodeNumber);
foreach (var epr in episodeParseResults)
if (episode == null)
{ {
var episode = _episodeProvider.GetEpisode(series.SeriesId, epr.SeasonNumber, epr.EpisodeNumber); //Not sure how we got this far, so lets throw an exception
throw new ArgumentOutOfRangeException();
if (episode == null)
{
//Not sure how we got this far, so lets throw an exception
throw new ArgumentOutOfRangeException();
}
//Set episode status to grabbed
episode.Status = EpisodeStatusType.Grabbed;
//Add to History
var history = new History();
history.Date = DateTime.Now;
history.EpisodeId = episode.EpisodeId;
history.IndexerName = indexer.IndexerName;
history.IsProper = nzb.Proper;
history.Quality = nzb.Quality;
history.NzbTitle = nzb.Title;
_historyProvider.Insert(history);
} }
//Set episode status to grabbed
episode.Status = EpisodeStatusType.Grabbed;
//Add to History
var history = new History();
history.Date = DateTime.Now;
history.EpisodeId = episode.EpisodeId;
history.IndexerId = indexer.IndexerId;
history.IsProper = nzb.Proper;
history.Quality = nzb.Quality;
history.NzbTitle = nzb.Title;
_historyProvider.Insert(history);
} }
} }
} }

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Web.Script.Serialization;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using SubSonic.SqlGeneration.Schema; using SubSonic.SqlGeneration.Schema;

View File

@ -1,7 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Repository.Quality;
using SubSonic.SqlGeneration.Schema; using SubSonic.SqlGeneration.Schema;
@ -9,9 +6,10 @@ namespace NzbDrone.Core.Repository
{ {
public class History public class History
{ {
public int HistoryId { get; set; } [SubSonicPrimaryKey(true)]
public virtual int HistoryId { get; set; }
public virtual int EpisodeId { get; set; } public virtual int EpisodeId { get; set; }
public virtual string IndexerName { get; set; } public virtual int IndexerId { get; set; }
public string NzbTitle { get; set; } public string NzbTitle { get; set; }
public QualityTypes Quality { get; set; } public QualityTypes Quality { get; set; }
public DateTime Date { get; set; } public DateTime Date { get; set; }

View File

@ -10,7 +10,9 @@ namespace NzbDrone.Core.Repository
{ {
public class Indexer public class Indexer
{ {
[SubSonicPrimaryKey(true)] [SubSonicPrimaryKey(false)]
public virtual int IndexerId { get; set; }
public string IndexerName { get; set; } public string IndexerName { get; set; }
public string RssUrl { get; set; } public string RssUrl { get; set; }

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Repository.Quality;
using NzbDrone.Web.Models;
using Telerik.Web.Mvc;
namespace NzbDrone.Web.Controllers
{
public class HistoryController : Controller
{
private IHistoryProvider _historyProvider;
public HistoryController(IHistoryProvider historyProvider)
{
_historyProvider = historyProvider;
}
//
// GET: /History/
public ActionResult Index()
{
return View();
}
public ActionResult Trim()
{
_historyProvider.Trim();
return RedirectToAction("Index");
}
public ActionResult Purge()
{
_historyProvider.Purge();
return RedirectToAction("Index");
}
[GridAction]
public ActionResult _AjaxBinding()
{
var history = _historyProvider.AllItems().Select(h => new HistoryModel
{
HistoryId = h.HistoryId,
SeasonNumber = h.Episode.SeasonNumber,
EpisodeNumber = h.Episode.EpisodeNumber,
EpisodeTitle = h.Episode.Title,
EpisodeOverview = h.Episode.Overview,
SeriesTitle = h.Episode.Series.Title,
NzbTitle = h.NzbTitle,
Quality = h.Quality.ToString("G"),
IsProper = h.IsProper,
Date = h.Date
});
return View(new GridModel(history));
}
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality;
namespace NzbDrone.Web.Models
{
public class HistoryModel
{
public int HistoryId { get; set; }
public string SeriesTitle { get; set; }
public int SeasonNumber { get; set; }
public int EpisodeNumber { get; set; }
public string EpisodeTitle { get; set; }
public string EpisodeOverview { get; set; }
public string NzbTitle { get; set; }
public string Quality { get; set; }
public DateTime Date { get; set; }
public bool IsProper { get; set; }
}
}

View File

@ -96,6 +96,7 @@
<Compile Include="Models\AddNewSeriesModel.cs" /> <Compile Include="Models\AddNewSeriesModel.cs" />
<Compile Include="Models\DownloadSettingsModel.cs" /> <Compile Include="Models\DownloadSettingsModel.cs" />
<Compile Include="Models\EpisodeSortingModel.cs" /> <Compile Include="Models\EpisodeSortingModel.cs" />
<Compile Include="Models\HistoryModel.cs" />
<Compile Include="Models\IndexerSettingsModel.cs" /> <Compile Include="Models\IndexerSettingsModel.cs" />
<Compile Include="Models\MappingModel.cs" /> <Compile Include="Models\MappingModel.cs" />
<Compile Include="Models\EpisodeModel.cs" /> <Compile Include="Models\EpisodeModel.cs" />

View File

@ -0,0 +1,62 @@
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<List<NzbDrone.Web.Models.HistoryModel>>" %>
<%@ Import Namespace="Telerik.Web.Mvc.UI" %>
<%@ Import Namespace="NzbDrone.Web.Models" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Scripts" runat="server">
<script type="text/javascript">
function onRowDataBound(e) {
e.row.style.boarder = "";
if (e.dataItem.Level == 3) {
e.row.style.backgroundColor = "#FFD700";
}
else if (e.dataItem.Level == 4) {
e.row.style.backgroundColor = "#FF7500";
}
else if (e.dataItem.Level == 5) {
e.row.style.backgroundColor = "black";
e.row.style.color = "red";
}
//e.row.style.color = 'blue';
}
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="TitleContent" runat="server">
History
</asp:Content>
<asp:Content ID="Menu" ContentPlaceHolderID="ActionMenu" runat="server">
<%
Html.Telerik().Menu().Name("historyMenu").Items(items =>
{
items.Add().Text("Trim History").Action("Trim", "History");
items.Add().Text("Purge History").Action("Purge", "History");
}).Render();
%>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
<%Html.Telerik().Grid<HistoryModel>().Name("history")
.Columns(columns =>
{
columns.Bound(c => c.SeriesTitle).Title("Series Name").Width(120);
columns.Bound(c => c.SeasonNumber).Title("Season #").Width(10);
columns.Bound(c => c.EpisodeNumber).Title("Episode #").Width(10);
columns.Bound(c => c.EpisodeTitle).Title("Episode Title").Width(140);
columns.Bound(c => c.Quality).Title("Quality").Width(30);
columns.Bound(c => c.Date).Title("Date Grabbed").Width(60);
})
.DetailView(detailView => detailView.ClientTemplate(
"<div><b>Overview: </b><#= EpisodeOverview #></div>" +
"<div><b>NZB Title: </b><#= NzbTitle #></div>" +
"<div><b>Proper: </b><#= IsProper #></div>"
))
.DataBinding(data => data.Ajax().Select("_AjaxBinding", "History"))
.Sortable(rows => rows.OrderBy(epSort => epSort.Add(c => c.Date).Descending()).Enabled(true))
.Pageable(c => c.PageSize(20).Position(GridPagerPosition.Both).Style(GridPagerStyles.PageInput | GridPagerStyles.NextPreviousAndNumeric))
//.Filterable()
//.ClientEvents(c => c.OnRowDataBound("onRowDataBound"))
.Render();
%>
</asp:Content>