diff --git a/NzbDrone.Core/Providers/MediaFileProvider.cs b/NzbDrone.Core/Providers/MediaFileProvider.cs index 831cb60f3..7cb7d59b9 100644 --- a/NzbDrone.Core/Providers/MediaFileProvider.cs +++ b/NzbDrone.Core/Providers/MediaFileProvider.cs @@ -221,6 +221,16 @@ namespace NzbDrone.Core.Providers return CleanFilename(result.Trim()); } + public virtual void ChangeQuality(int episodeFileId, QualityTypes quality) + { + _database.Execute("UPDATE EpisodeFiles SET Quality = @quality WHERE EpisodeFileId = @episodeFileId", new { episodeFileId, quality }); + } + + public virtual void ChangeQuality(int seriesId, int seasonNumber, QualityTypes quality) + { + _database.Execute("UPDATE EpisodeFiles SET Quality = @quality WHERE SeriesId = @seriesId AND SeasonNumber = @seasonNumber", new { seriesId, seasonNumber, quality }); + } + public static string CleanFilename(string name) { string result = name; diff --git a/NzbDrone.Web/Content/Images/changequality.png b/NzbDrone.Web/Content/Images/changequality.png new file mode 100644 index 000000000..97cdc14cf Binary files /dev/null and b/NzbDrone.Web/Content/Images/changequality.png differ diff --git a/NzbDrone.Web/Controllers/EpisodeController.cs b/NzbDrone.Web/Controllers/EpisodeController.cs index 49b98f6f0..86a7c3771 100644 --- a/NzbDrone.Web/Controllers/EpisodeController.cs +++ b/NzbDrone.Web/Controllers/EpisodeController.cs @@ -1,6 +1,8 @@ using System; using System.Web.Mvc; using NzbDrone.Core.Jobs; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Repository.Quality; using NzbDrone.Web.Models; namespace NzbDrone.Web.Controllers @@ -8,10 +10,12 @@ namespace NzbDrone.Web.Controllers public class EpisodeController : Controller { private readonly JobProvider _jobProvider; + private readonly MediaFileProvider _mediaFileProvider; - public EpisodeController(JobProvider jobProvider) + public EpisodeController(JobProvider jobProvider, MediaFileProvider mediaFileProvider) { _jobProvider = jobProvider; + _mediaFileProvider = mediaFileProvider; } public JsonResult Search(int episodeId) @@ -52,5 +56,19 @@ namespace NzbDrone.Web.Controllers _jobProvider.QueueJob(typeof(RenameSeriesJob)); return JsonNotificationResult.Queued("Series rename"); } + + [HttpPost] + public JsonResult ChangeEpisodeQuality(int episodeFileId, QualityTypes quality) + { + _mediaFileProvider.ChangeQuality(episodeFileId, quality); + return Json("ok"); + } + + [HttpPost] + public JsonResult ChangeSeasonQuality(int seriesId, int seasonNumber, QualityTypes quality) + { + _mediaFileProvider.ChangeQuality(seriesId, seasonNumber, quality); + return Json("ok"); + } } } \ No newline at end of file diff --git a/NzbDrone.Web/Controllers/SeriesController.cs b/NzbDrone.Web/Controllers/SeriesController.cs index a2ecd9437..ac7098962 100644 --- a/NzbDrone.Web/Controllers/SeriesController.cs +++ b/NzbDrone.Web/Controllers/SeriesController.cs @@ -128,6 +128,11 @@ namespace NzbDrone.Web.Controllers CommonStatus = GetCommonStatus(s.Episodes) }).ToList(); model.Seasons = seasons; + + var qualities = (from QualityTypes q in Enum.GetValues(typeof(QualityTypes)) + select new { Id = (int)q, Name = q.ToString() }).ToList(); + + model.QualitySelectList = new SelectList(qualities.Where(q => q.Id > 0), "Id", "Name"); return View(model); } @@ -216,12 +221,14 @@ namespace NzbDrone.Web.Controllers var episodeFileId = 0; var episodePath = String.Empty; var episodeQuality = "N/A"; + var episodeQualityId = 0; if (e.EpisodeFile != null) { episodePath = e.EpisodeFile.Path; episodeFileId = e.EpisodeFile.EpisodeFileId; episodeQuality = e.EpisodeFile.Quality.ToString(); + episodeQualityId = (int)e.EpisodeFile.Quality; } var airDate = String.Empty; @@ -232,6 +239,7 @@ namespace NzbDrone.Web.Controllers episodes.Add(new EpisodeModel { EpisodeId = e.EpisodeId, + EpisodeFileId = episodeFileId, EpisodeNumber = e.EpisodeNumber, SeasonNumber = e.SeasonNumber, Title = e.Title, @@ -240,6 +248,7 @@ namespace NzbDrone.Web.Controllers Path = episodePath, Status = e.Status.ToString(), Quality = episodeQuality, + QualityId = episodeQualityId, Ignored = e.Ignored }); } diff --git a/NzbDrone.Web/Models/EpisodeModel.cs b/NzbDrone.Web/Models/EpisodeModel.cs index b89f6c6ac..3857a9c3c 100644 --- a/NzbDrone.Web/Models/EpisodeModel.cs +++ b/NzbDrone.Web/Models/EpisodeModel.cs @@ -1,5 +1,6 @@ using System; using NzbDrone.Core.Model; +using NzbDrone.Core.Repository.Quality; namespace NzbDrone.Web.Models { @@ -7,6 +8,7 @@ namespace NzbDrone.Web.Models { public string Title { get; set; } public int EpisodeId { get; set; } + public int EpisodeFileId { get; set; } public int EpisodeNumber { get; set; } public int SeasonNumber { get; set; } public string Overview { get; set; } @@ -14,6 +16,7 @@ namespace NzbDrone.Web.Models public String Status { get; set; } public string AirDate { get; set; } public String Quality { get; set; } + public int QualityId { get; set; } public bool Ignored { get; set; } } } \ No newline at end of file diff --git a/NzbDrone.Web/Models/SeriesDetailsModel.cs b/NzbDrone.Web/Models/SeriesDetailsModel.cs index 329e213d5..9c3cb9054 100644 --- a/NzbDrone.Web/Models/SeriesDetailsModel.cs +++ b/NzbDrone.Web/Models/SeriesDetailsModel.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Web; +using System.Web.Mvc; using NzbDrone.Core.Model; using NzbDrone.Core.Repository; @@ -18,5 +19,6 @@ namespace NzbDrone.Web.Models public string Path { get; set; } public bool HasBanner { get; set; } public List Seasons { get; set; } + public SelectList QualitySelectList { get; set; } } } \ No newline at end of file diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj index ca5469081..d5419bb9b 100644 --- a/NzbDrone.Web/NzbDrone.Web.csproj +++ b/NzbDrone.Web/NzbDrone.Web.csproj @@ -164,6 +164,7 @@ + diff --git a/NzbDrone.Web/Scripts/NzbDrone/seriesDetails.js b/NzbDrone.Web/Scripts/NzbDrone/seriesDetails.js index 276494086..495a654aa 100644 --- a/NzbDrone.Web/Scripts/NzbDrone/seriesDetails.js +++ b/NzbDrone.Web/Scripts/NzbDrone/seriesDetails.js @@ -8,6 +8,11 @@ var seriesId = 0; var saveSeasonIgnoreUrl = '../Command/SaveSeasonIgnore'; var saveEpisodeIgnoreUrl = '../Command/SaveEpisodeIgnore'; +var changeQualityType; +var changeQualityData; +var changeEpisodeQualityUrl = '../Episode/ChangeEpisodeQuality'; +var changeSeasonQualityUrl = '../Episode/ChangeSeasonQuality'; + //Episode Ignore Functions $(".ignoreEpisode").live("click", function () { var toggle = $(this); @@ -121,4 +126,82 @@ function saveEpisodeIgnore(episodeId, ignored) { alert("Sorry! We could save the ignore settings for Episode: " + episodeId + " at this time. " + error); } }); -} \ No newline at end of file +} + +//Change quality +$(document).on('click', '.changeQuality', function() { + changeQualityType = $(this).attr('data-changetype'); + + if (changeQualityType === "episode") { + var row = $(this).closest('tr'); + + changeQualityData = $(row).attr('data-episodefileid'); + + if (changeQualityData === "0") + return; + + var qualityId = $(row).find('.episodeQuality').attr('data-qualityid'); + $('#NewQuality').val(qualityId); + } + + else { + changeQualityData = $(this).closest('table').attr('data-season'); + } + + $('#qualityChanger').dialog('open'); +}); + +$("#qualityChanger").dialog({ + autoOpen: false, + height: 'auto', + width: 670, + resizable: false, + modal: true, + buttons: { + "Save": function () { + //Save the quality + var newQualityId = $('#NewQuality').val(); + var newQualityText = $('#NewQuality :selected').text(); + + if (changeQualityType === "episode") { + $.ajax({ + url: changeEpisodeQualityUrl, + data: { episodeFileId: changeQualityData, quality: newQualityId }, + type: 'POST', + success: function(data) { + var row = $('tr[data-episodefileid="' + changeQualityData + '"]'); + var qualityCell = $(row).find('.episodeQuality'); + $(qualityCell).attr('data-qualityid', newQualityId); + $(qualityCell).text(newQualityText); + } + }); + } + + else { + $.ajax({ + url: changeSeasonQualityUrl, + data: { seriesId: seriesId, seasonNumber: changeQualityData, quality: newQualityId }, + type: 'POST', + success: function (data) { + var table = $('table[data-season="' + changeQualityData + '"]'); + var rows = $(table).children('tr'); + + $(rows).each(function() { + if ($(this).attr('data-episodefileid') === 0) + return; + + var qualityCell = $(this).find('.episodeQuality'); + $(qualityCell).attr('data-qualityid', newQualityId); + $(qualityCell).text(newQualityText); + }); + } + }); + } + + $(this).dialog("close"); + }, + Cancel: function () { + $(this).dialog("close"); + } + } +}); \ No newline at end of file diff --git a/NzbDrone.Web/Views/Series/Details.cshtml b/NzbDrone.Web/Views/Series/Details.cshtml index 69c0f7569..60e692cc9 100644 --- a/NzbDrone.Web/Views/Series/Details.cshtml +++ b/NzbDrone.Web/Views/Series/Details.cshtml @@ -111,6 +111,13 @@ +
+
+ + @Html.DropDownList("NewQuality", Model.QualitySelectList) +
+
+ @section Scripts{ @Html.IncludeScript("NzbDrone/seriesDetails.js") @Html.IncludeScript("NzbDrone/series.js") diff --git a/NzbDrone.Web/Views/Series/Episode.cshtml b/NzbDrone.Web/Views/Series/Episode.cshtml index 56c4575ac..bd5d59fa4 100644 --- a/NzbDrone.Web/Views/Series/Episode.cshtml +++ b/NzbDrone.Web/Views/Series/Episode.cshtml @@ -2,11 +2,11 @@ @using NzbDrone.Web.Helpers @model NzbDrone.Web.Models.EpisodeModel - + @Model.EpisodeNumber @Model.Title @Model.AirDate - @Model.Quality + @Model.Quality @{ string cellColourClass = String.Empty; @@ -26,6 +26,7 @@ @Ajax.ImageActionLink("../../Content/Images/Search.png", new { Alt = "Search", Title = "Search for episode", @class = "gridAction" }, "Search", "Episode", new { episodeId = Model.EpisodeId }, null, null) + @Model.Status diff --git a/NzbDrone.Web/Views/Series/Season.cshtml b/NzbDrone.Web/Views/Series/Season.cshtml index 5764cffd8..8a24029c4 100644 --- a/NzbDrone.Web/Views/Series/Season.cshtml +++ b/NzbDrone.Web/Views/Series/Season.cshtml @@ -5,13 +5,13 @@ @(Model.SeasonNumber == 0 ? "Specials" : "Season " + Model.SeasonNumber) - +
- + @@ -24,6 +24,7 @@ diff --git a/NzbDrone/NzbDrone.csproj b/NzbDrone/NzbDrone.csproj index f6741ac32..f2dfdfdb7 100644 --- a/NzbDrone/NzbDrone.csproj +++ b/NzbDrone/NzbDrone.csproj @@ -42,7 +42,7 @@ 4trueBasicCorrectnessRules.ruleset - C:\Users\Markus\AppData\Local\Temp\vs73DE.tmp\x86\Debug\ + C:\Users\Mark\AppData\Local\Temp\vs32F1.tmp\x86\Debug\ x86 @@ -52,7 +52,7 @@ TRACE prompt 4 - C:\Users\Markus\AppData\Local\Temp\vs73DE.tmp\x86\Release\ + C:\Users\Mark\AppData\Local\Temp\vs32F1.tmp\x86\Release\ NzbDrone.ico
@Ajax.ImageActionLink("../../Content/Images/Search.png", new { Alt = "Search", Title = "Search for all episodes in this season", @class = "gridAction" }, "SearchSeason", "Episode", new { SeriesId = Model.SeriesId, SeasonNumber = Model.SeasonNumber }, null, null) + @Ajax.ImageActionLink("../../Content/Images/Rename.png", new { Alt = "Rename", Title = "Rename all episodes in this season", @class = "gridAction" }, "RenameSeason", "Episode", new { SeriesId = Model.SeriesId, SeasonNumber = Model.SeasonNumber }, null, null)