Fixed QualityProfile mapping to Series, resulted in a large number of changed files referencing ProfileId instead of QualityProfileId

pull/3113/head
markus101 13 years ago
parent 83ee068d45
commit d3b7d199ab

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using FizzWare.NBuilder;
using Gallio.Framework;
@ -10,6 +11,8 @@ using Moq;
using Ninject;
using Ninject.Moq;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality;
using SubSonic.Repository;
using TvdbLib.Data;
using SubSonic.Extensions;
@ -52,5 +55,41 @@ namespace NzbDrone.Core.Test
Assert.Count(episodeCount, kernel.Get<IEpisodeProvider>().GetEpisodeBySeries(seriesId));
Console.WriteLine("Duration: " + sw.Elapsed.ToString());
}
[Test]
public void IsNeededTrue()
{
//Setup
var season = new Mock<ISeasonProvider>();
var series = new Mock<ISeriesProvider>();
var history = new Mock<IHistoryProvider>();
var quality = new Mock<IQualityProvider>();
var repo = new Mock<IRepository>();
var epInDb = new Episode
{
AirDate = DateTime.Today,
EpisodeId = 55555,
EpisodeNumber = 5,
Language = "en",
SeasonId = 4444,
SeasonNumber = 1
};
season.Setup(s => s.IsIgnored(12345, 1)).Returns(false);
series.Setup(s => s.QualityWanted(12345, QualityTypes.TV)).Returns(true);
repo.Setup(s => s.Single<Episode>(c => c.SeriesId == 12345 && c.SeasonNumber == 1 && c.EpisodeNumber == 5)).
Returns(epInDb);
//repo.Setup(s => s.All<EpisodeFile>()).Returns();
//repo.All<EpisodeFile>().Where(c => c.EpisodeId == episode.EpisodeId);
//Act
//Assert
}
}
}

@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test
CleanTitle = "rock",
Monitored = true,
Overview = "Series Overview",
ProfileId = 1,
QualityProfileId = 1,
Title = "30 Rock",
Path = @"C:\Test\TV\30 Rock"
};
@ -81,7 +81,7 @@ namespace NzbDrone.Core.Test
CleanTitle = "rock",
Monitored = true,
Overview = "Series Overview",
ProfileId = 1,
QualityProfileId = 1,
Title = "30 Rock",
Path = @"C:\Test\TV\30 Rock"
};
@ -138,7 +138,7 @@ namespace NzbDrone.Core.Test
CleanTitle = "rock",
Monitored = true,
Overview = "Series Overview",
ProfileId = 1,
QualityProfileId = 1,
Title = "30 Rock",
Path = @"C:\Test\TV\30 Rock"
};
@ -180,4 +180,4 @@ namespace NzbDrone.Core.Test
Assert.AreEqual(result, false);
}
}
}
}

@ -31,10 +31,10 @@ namespace NzbDrone.Core.Test
//Act
var id = (int)repo.Add(testProfile);
var fetch = repo.Single<QualityProfile>(c => c.ProfileId == id);
var fetch = repo.Single<QualityProfile>(c => c.QualityProfileId == id);
//Assert
Assert.AreEqual(id, fetch.ProfileId);
Assert.AreEqual(id, fetch.QualityProfileId);
Assert.AreEqual(testProfile.Name, fetch.Name);
Assert.AreEqual(testProfile.Cutoff, fetch.Cutoff);
Assert.AreEqual(testProfile.Allowed, fetch.Allowed);

@ -90,7 +90,6 @@ namespace NzbDrone.Core.Test
string apikey = "5c770e3197e4fe763423ee7c392c25d1";
string username = "admin";
string password = "pass";
string priority = "0";
var config = new Mock<IConfigProvider>();
config.Setup(c => c.GetValue("SabHost", String.Empty, false)).Returns(sabHost);
@ -124,7 +123,6 @@ namespace NzbDrone.Core.Test
string apikey = "5c770e3197e4fe763423ee7c392c25d1";
string username = "admin";
string password = "pass";
string priority = "0";
var config = new Mock<IConfigProvider>();
config.Setup(c => c.GetValue("SabHost", String.Empty, false)).Returns(sabHost);
@ -158,7 +156,6 @@ namespace NzbDrone.Core.Test
string apikey = "5c770e3197e4fe763423ee7c392c25d1";
string username = "admin";
string password = "pass";
string priority = "0";
var config = new Mock<IConfigProvider>();
config.Setup(c => c.GetValue("SabHost", String.Empty, false)).Returns(sabHost);

@ -303,7 +303,7 @@ namespace NzbDrone.Core
else
{
Logger.Debug(String.Format("Updating default QualityProfile: {0}", sdtv.Name));
sdtv.ProfileId = sdtvDb.ProfileId;
sdtv.QualityProfileId = sdtvDb.QualityProfileId;
repository.Update(sdtv);
}
@ -319,7 +319,7 @@ namespace NzbDrone.Core
else
{
Logger.Debug(String.Format("Updating default QualityProfile: {0}", dvd.Name));
dvd.ProfileId = dvdDb.ProfileId;
dvd.QualityProfileId = dvdDb.QualityProfileId;
repository.Update(dvd);
}
@ -335,7 +335,7 @@ namespace NzbDrone.Core
else
{
Logger.Debug(String.Format("Updating default QualityProfile: {0}", bdrip.Name));
bdrip.ProfileId = bdripDb.ProfileId;
bdrip.QualityProfileId = bdripDb.QualityProfileId;
repository.Update(bdrip);
}
@ -351,7 +351,7 @@ namespace NzbDrone.Core
else
{
Logger.Debug(String.Format("Updating default QualityProfile: {0}", hdtv.Name));
hdtv.ProfileId = hdtvDb.ProfileId;
hdtv.QualityProfileId = hdtvDb.QualityProfileId;
repository.Update(hdtv);
}
@ -367,7 +367,7 @@ namespace NzbDrone.Core
else
{
Logger.Debug(String.Format("Updating default QualityProfile: {0}", webdl.Name));
webdl.ProfileId = webdlDb.ProfileId;
webdl.QualityProfileId = webdlDb.QualityProfileId;
repository.Update(webdl);
}
@ -383,7 +383,7 @@ namespace NzbDrone.Core
else
{
Logger.Debug(String.Format("Updating default QualityProfile: {0}", bluray.Name));
bluray.ProfileId = blurayDb.ProfileId;
bluray.QualityProfileId = blurayDb.QualityProfileId;
repository.Update(bluray);
}
}

@ -95,12 +95,12 @@ namespace NzbDrone.Core.Providers
episode.EpisodeId = dbEpisode.EpisodeId;
var epWithFiles = _sonicRepo.Single<Episode>(c => c.EpisodeId == episode.EpisodeId && c.Files.Count > 0);
var epWithFiles = _sonicRepo.All<EpisodeFile>().Where(c => c.EpisodeId == episode.EpisodeId);
if (epWithFiles != null)
{
//If not null we need to see if this episode has the quality as the download (or if it is better)
foreach (var file in epWithFiles.Files)
foreach (var file in epWithFiles)
{
if (file.Quality == episode.Quality)
{
@ -117,7 +117,7 @@ namespace NzbDrone.Core.Providers
if (file.Quality < episode.Quality)
{
var series = _series.GetSeries(episode.SeriesId);
var quality = _quality.Find(series.ProfileId);
var quality = _quality.Find(series.QualityProfileId);
if (quality.Cutoff <= file.Quality)
{
@ -127,7 +127,6 @@ namespace NzbDrone.Core.Providers
}
}
}
return true;
}
//IsInHistory? (NZBDrone)

@ -27,7 +27,7 @@ namespace NzbDrone.Core.Providers
public void Update(QualityProfile profile)
{
if (!_sonicRepo.Exists<QualityProfile>(q => q.ProfileId == profile.ProfileId))
if (!_sonicRepo.Exists<QualityProfile>(q => q.QualityProfileId == profile.QualityProfileId))
{
Logger.Error("Unable to update non-existing profile");
throw new InvalidOperationException("Unable to update non-existing profile");
@ -50,7 +50,7 @@ namespace NzbDrone.Core.Providers
public QualityProfile Find(int profileId)
{
return _sonicRepo.Single<QualityProfile>(q => q.ProfileId == profileId);
return _sonicRepo.Single<QualityProfile>(q => q.QualityProfileId == profileId);
}
#endregion

@ -132,44 +132,49 @@ namespace NzbDrone.Core.Providers
return;
}
if (episodeParseResults.Count() > 0)
//Todo: How to determine if we want the show if the FeedTitle is drastically different from the TitleOnDisk (CSI is one that comes to mind)
var series = _series.FindSeries(episodeParseResults[0].SeriesTitle);
if (series == null)
{
//Todo: How to determine if we want the show if the FeedTitle is drastically different from the TitleOnDisk (CSI is one that comes to mind)
var series = _series.FindSeries(episodeParseResults[0].SeriesTitle);
Logger.Debug("Show is not being watched: {0}", episodeParseResults[0].SeriesTitle);
return;
}
if (series == null)
{
Logger.Debug("Show is not being watched: {0}", episodeParseResults[0].SeriesTitle);
Logger.Debug("Show is being watched: {0}", series.Title);
nzb.TitleFix = GetTitleFix(episodeParseResults, series.SeriesId); //Get the TitleFix so we can use it later
nzb.Proper = Parser.ParseProper(nzb.Title);
//Loop through the list of the episodeParseResults to ensure that all the episodes are needed)
foreach (var episode in episodeParseResults)
{
//IsEpisodeWanted?
var episodeModel = new EpisodeModel();
episodeModel.Proper = nzb.Proper;
episodeModel.SeriesId = series.SeriesId;
episodeModel.SeriesTitle = series.Title;
episodeModel.Quality = Parser.ParseQuality(nzb.Title);
episodeModel.SeasonNumber = episode.SeasonNumber;
episodeModel.EpisodeNumber = episode.EpisodeNumber;
if (!_episode.IsNeeded(episodeModel))
return;
}
Logger.Debug("Show is being watched: {0}", series.Title);
var titleFix = GetTitleFix(new List<EpisodeParseResult> { episode }, episodeModel.SeriesId);
nzb.TitleFix = GetTitleFix(episodeParseResults, series.SeriesId); //Get the TitleFix so we can use it later
nzb.Proper = Parser.ParseProper(nzb.Title);
if (_sab.IsInQueue(titleFix))
return;
}
//Loop through the list of the episodeParseResults to ensure that all the episodes are needed)
foreach (var episode in episodeParseResults)
{
//IsEpisodeWanted?
var episodeModel = new EpisodeModel();
episodeModel.Proper = nzb.Proper;
episodeModel.SeriesId = series.SeriesId;
episodeModel.SeriesTitle = series.Title;
episodeModel.Quality = Parser.ParseQuality(nzb.Title);
episodeModel.SeasonNumber = episode.SeasonNumber;
episodeModel.EpisodeNumber = episode.EpisodeNumber;
if (!_episode.IsNeeded(episodeModel))
return;
var titleFix = GetTitleFix(new List<EpisodeParseResult> { episode }, episodeModel.SeriesId);
if (_sab.IsInQueue(titleFix))
return;
}
var sabResult = _sab.AddByUrl(nzb.Link.ToString(), nzb.TitleFix);
//If their is more than one episode in this NZB check to see if it has been added as a single NZB
if (episodeParseResults.Count > 1)
{
if (_sab.IsInQueue(nzb.TitleFix))
return;
}
var sabResult = _sab.AddByUrl(nzb.Link.ToString(), nzb.TitleFix);
}
catch (Exception ex)
@ -193,7 +198,7 @@ namespace NzbDrone.Core.Providers
if (episodeInDb == null)
{
Logger.Debug("Episode Not found in Database");
return String.Format("{0} - {1}x{2:00}", series.Title, episode.SeasonNumber, episode.SeriesTitle);
return String.Format("{0} - {1:00}x{2}", series.Title, episode.SeasonNumber, episode.SeriesTitle);
}
seasonNumber = episodeInDb.SeasonNumber;
@ -201,6 +206,8 @@ namespace NzbDrone.Core.Providers
episodeTitles = String.Format("{0} + {1}", episodeTitles, episodeInDb.Title);
}
episodeTitles = episodeTitles.Trim(' ', '+');
return String.Format("{0} - {1}{2} - {3}", series.Title, seasonNumber, episodeNumbers, episodeTitles);
}

@ -58,7 +58,7 @@ namespace NzbDrone.Core.Providers
public bool QualityWanted(int seriesId, QualityTypes quality)
{
var series = _sonioRepo.Single<Series>(seriesId);
var profile = _quality.Find(series.ProfileId);
var profile = _quality.Find(series.QualityProfileId);
return profile.Allowed.Contains(quality);
}
@ -108,7 +108,7 @@ namespace NzbDrone.Core.Providers
repoSeries.Path = path;
repoSeries.CleanTitle = Parser.NormalizeTitle(series.SeriesName);
repoSeries.Monitored = true; //New shows should be monitored
repoSeries.ProfileId = Convert.ToInt32(_config.GetValue("Quality", 1, true));
repoSeries.QualityProfileId = Convert.ToInt32(_config.GetValue("Quality", 1, true));
_sonioRepo.Add(repoSeries);
}

@ -9,7 +9,7 @@ namespace NzbDrone.Core.Repository.Quality
public class QualityProfile
{
[SubSonicPrimaryKey(true)]
public int ProfileId { get; set; }
public int QualityProfileId { get; set; }
[Required(ErrorMessage = "A Name is Required")]
[DisplayName("Name")]

@ -30,10 +30,10 @@ namespace NzbDrone.Core.Repository
public bool Monitored { get; set; }
public virtual int ProfileId { get; set; }
public int QualityProfileId { get; set; }
[SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
public virtual QualityProfile QualityProfile { get; set; }
public virtual QualityProfile QualityProfile { get; private set; }
[SubSonicToManyRelation]
public virtual List<Season> Seasons { get; private set; }

@ -52,6 +52,12 @@ namespace NzbDrone.Web.Controllers
return View(_seriesProvider.GetUnmappedFolders().Select(c => new MappingModel() { Id = 1, Path = c.Value }).ToList());
}
public ActionResult Edit(int seriesId)
{
var series = _seriesProvider.GetSeries(seriesId);
return View(series);
}
public ActionResult LoadEpisodes(int seriesId)
{
_episodeProvider.RefreshEpisodeInfo(seriesId);
@ -159,7 +165,8 @@ namespace NzbDrone.Web.Controllers
public ActionResult Details(int seriesId)
{
return View(_seriesProvider.GetSeries(seriesId));
var series = _seriesProvider.GetSeries(seriesId);
return View(series);
}
}
}

@ -105,15 +105,15 @@ namespace NzbDrone.Web.Controllers
var userProfiles = _qualityProvider.GetAllProfiles().Where(q => q.UserProfile).ToList();
var profiles = _qualityProvider.GetAllProfiles().ToList();
var defaultQualityProfileId = Convert.ToInt32(_configProvider.GetValue("DefaultQualityProfile", profiles[0].ProfileId, true));
var defaultQualityQualityProfileId = Convert.ToInt32(_configProvider.GetValue("DefaultQualityProfile", profiles[0].QualityProfileId, true));
var selectList = new SelectList(profiles, "ProfileId", "Name");
var selectList = new SelectList(profiles, "QualityProfileId", "Name");
var model = new QualityModel
{
Profiles = profiles,
UserProfiles = userProfiles,
DefaultProfileId = defaultQualityProfileId,
DefaultQualityProfileId = defaultQualityQualityProfileId,
SelectList = selectList
};
@ -142,10 +142,10 @@ namespace NzbDrone.Web.Controllers
public QualityModel GetUpdatedProfileList()
{
var profiles = _qualityProvider.GetAllProfiles().ToList();
var defaultQualityProfileId = Convert.ToInt32(_configProvider.GetValue("DefaultQualityProfile", profiles[0].ProfileId, true));
var selectList = new SelectList(profiles, "ProfileId", "Name");
var defaultQualityQualityProfileId = Convert.ToInt32(_configProvider.GetValue("DefaultQualityProfile", profiles[0].QualityProfileId, true));
var selectList = new SelectList(profiles, "QualityProfileId", "Name");
return new QualityModel { DefaultProfileId = defaultQualityProfileId, SelectList = selectList };
return new QualityModel { DefaultQualityProfileId = defaultQualityQualityProfileId, SelectList = selectList };
}
[HttpPost]
@ -209,7 +209,7 @@ namespace NzbDrone.Web.Controllers
{
if (ModelState.IsValid)
{
_configProvider.SetValue("DefaultQualityProfile", data.DefaultProfileId.ToString());
_configProvider.SetValue("DefaultQualityProfile", data.DefaultQualityProfileId.ToString());
//Saves only the Default Quality, skips User Profiles since none exist
if (data.UserProfiles == null)
@ -217,8 +217,8 @@ namespace NzbDrone.Web.Controllers
foreach (var dbProfile in _qualityProvider.GetAllProfiles().Where(q => q.UserProfile))
{
if (!data.UserProfiles.Exists(p => p.ProfileId == dbProfile.ProfileId))
_qualityProvider.Delete(dbProfile.ProfileId);
if (!data.UserProfiles.Exists(p => p.QualityProfileId == dbProfile.QualityProfileId))
_qualityProvider.Delete(dbProfile.QualityProfileId);
}
foreach (var profile in data.UserProfiles)
@ -237,7 +237,7 @@ namespace NzbDrone.Web.Controllers
return Content("Error Saving Settings, please fix any errors");
//profile.Cutoff = profile.Allowed.Last();
if (profile.ProfileId > 0)
if (profile.QualityProfileId > 0)
_qualityProvider.Update(profile);
else

@ -15,7 +15,7 @@ namespace NzbDrone.Web.Models
public List<QualityProfile> UserProfiles { get; set; }
[DisplayName("Default Quality Profile")]
public int DefaultProfileId { get; set; }
public int DefaultQualityProfileId { get; set; }
public SelectList SelectList { get; set; }
}

@ -267,6 +267,7 @@
<Content Include="Views\Home\Test.aspx" />
<Content Include="Views\Log\Index.aspx" />
<Content Include="Views\Series\Details.aspx" />
<Content Include="Views\Series\Edit.aspx" />
<Content Include="Views\Series\EpisodeDetail.ascx" />
<Content Include="Views\Series\index.aspx" />
<Content Include="Views\Series\Unmapped.aspx" />

@ -0,0 +1,118 @@
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<NzbDrone.Core.Repository.Series>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Edit
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Edit</h2>
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.SeriesId) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.SeriesId) %>
<%: Html.ValidationMessageFor(model => model.SeriesId) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Title) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Title) %>
<%: Html.ValidationMessageFor(model => model.Title) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.CleanTitle) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.CleanTitle) %>
<%: Html.ValidationMessageFor(model => model.CleanTitle) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Status) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Status) %>
<%: Html.ValidationMessageFor(model => model.Status) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Overview) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Overview) %>
<%: Html.ValidationMessageFor(model => model.Overview) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.AirTimes) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.AirTimes) %>
<%: Html.ValidationMessageFor(model => model.AirTimes) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Language) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Language) %>
<%: Html.ValidationMessageFor(model => model.Language) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Path) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Path) %>
<%: Html.ValidationMessageFor(model => model.Path) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Monitored) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Monitored) %>
<%: Html.ValidationMessageFor(model => model.Monitored) %>
</div>
<%--<div class="editor-label">
<%: Html.LabelFor(model => model.ProfileId) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.ProfileId) %>
<%: Html.ValidationMessageFor(model => model.ProfileId) %>
</div>--%>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="headerContent" runat="server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="ActionMenu" runat="server">
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="Scripts" runat="server">
</asp:Content>

@ -39,9 +39,9 @@
<div id="defaultQualityDiv" style="float: left; margin: 30px;">
<div class="config-group" style="width: 250px; margin-bottom: 5px; margin-left: 5px;">
<div class="config-title"><%= Html.LabelFor(m => m.DefaultProfileId)%></div>
<div class="config-value"><%: Html.DropDownListFor(m => m.DefaultProfileId, Model.SelectList)%></div>
<div class="config-validation"><%= Html.ValidationMessageFor(m => m.DefaultProfileId)%></div>
<div class="config-title"><%= Html.LabelFor(m => m.DefaultQualityProfileId)%></div>
<div class="config-value"><%: Html.DropDownListFor(m => m.DefaultQualityProfileId, Model.SelectList)%></div>
<div class="config-validation"><%= Html.ValidationMessageFor(m => m.DefaultQualityProfileId)%></div>
</div>
</div>
</div>

@ -109,7 +109,7 @@
<%= Html.ValidationMessageFor(x => x.Cutoff) %>
<div class="hiddenProfileDetails">
<%= Html.TextBoxFor(x => x.ProfileId, new { @style = "display:none" })%>
<%= Html.TextBoxFor(x => x.QualityProfileId, new { @style = "display:none" })%>
<%= Html.CheckBoxFor(x => x.UserProfile, new { @style = "display:none" })%>
<%= Html.TextBoxFor(m => m.AllowedString, new { @style = "display:none" })%>
</div>

Loading…
Cancel
Save