Change episode file quality
New: Ability to change the quality of an episode in the database
This commit is contained in:
parent
d3ccd70470
commit
a7fd486b03
|
@ -221,6 +221,16 @@ namespace NzbDrone.Core.Providers
|
||||||
return CleanFilename(result.Trim());
|
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)
|
public static string CleanFilename(string name)
|
||||||
{
|
{
|
||||||
string result = name;
|
string result = name;
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
|
@ -1,6 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using NzbDrone.Core.Jobs;
|
using NzbDrone.Core.Jobs;
|
||||||
|
using NzbDrone.Core.Providers;
|
||||||
|
using NzbDrone.Core.Repository.Quality;
|
||||||
using NzbDrone.Web.Models;
|
using NzbDrone.Web.Models;
|
||||||
|
|
||||||
namespace NzbDrone.Web.Controllers
|
namespace NzbDrone.Web.Controllers
|
||||||
|
@ -8,10 +10,12 @@ namespace NzbDrone.Web.Controllers
|
||||||
public class EpisodeController : Controller
|
public class EpisodeController : Controller
|
||||||
{
|
{
|
||||||
private readonly JobProvider _jobProvider;
|
private readonly JobProvider _jobProvider;
|
||||||
|
private readonly MediaFileProvider _mediaFileProvider;
|
||||||
|
|
||||||
public EpisodeController(JobProvider jobProvider)
|
public EpisodeController(JobProvider jobProvider, MediaFileProvider mediaFileProvider)
|
||||||
{
|
{
|
||||||
_jobProvider = jobProvider;
|
_jobProvider = jobProvider;
|
||||||
|
_mediaFileProvider = mediaFileProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonResult Search(int episodeId)
|
public JsonResult Search(int episodeId)
|
||||||
|
@ -52,5 +56,19 @@ namespace NzbDrone.Web.Controllers
|
||||||
_jobProvider.QueueJob(typeof(RenameSeriesJob));
|
_jobProvider.QueueJob(typeof(RenameSeriesJob));
|
||||||
return JsonNotificationResult.Queued("Series rename");
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -129,6 +129,11 @@ namespace NzbDrone.Web.Controllers
|
||||||
}).ToList();
|
}).ToList();
|
||||||
model.Seasons = seasons;
|
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);
|
return View(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,12 +221,14 @@ namespace NzbDrone.Web.Controllers
|
||||||
var episodeFileId = 0;
|
var episodeFileId = 0;
|
||||||
var episodePath = String.Empty;
|
var episodePath = String.Empty;
|
||||||
var episodeQuality = "N/A";
|
var episodeQuality = "N/A";
|
||||||
|
var episodeQualityId = 0;
|
||||||
|
|
||||||
if (e.EpisodeFile != null)
|
if (e.EpisodeFile != null)
|
||||||
{
|
{
|
||||||
episodePath = e.EpisodeFile.Path;
|
episodePath = e.EpisodeFile.Path;
|
||||||
episodeFileId = e.EpisodeFile.EpisodeFileId;
|
episodeFileId = e.EpisodeFile.EpisodeFileId;
|
||||||
episodeQuality = e.EpisodeFile.Quality.ToString();
|
episodeQuality = e.EpisodeFile.Quality.ToString();
|
||||||
|
episodeQualityId = (int)e.EpisodeFile.Quality;
|
||||||
}
|
}
|
||||||
|
|
||||||
var airDate = String.Empty;
|
var airDate = String.Empty;
|
||||||
|
@ -232,6 +239,7 @@ namespace NzbDrone.Web.Controllers
|
||||||
episodes.Add(new EpisodeModel
|
episodes.Add(new EpisodeModel
|
||||||
{
|
{
|
||||||
EpisodeId = e.EpisodeId,
|
EpisodeId = e.EpisodeId,
|
||||||
|
EpisodeFileId = episodeFileId,
|
||||||
EpisodeNumber = e.EpisodeNumber,
|
EpisodeNumber = e.EpisodeNumber,
|
||||||
SeasonNumber = e.SeasonNumber,
|
SeasonNumber = e.SeasonNumber,
|
||||||
Title = e.Title,
|
Title = e.Title,
|
||||||
|
@ -240,6 +248,7 @@ namespace NzbDrone.Web.Controllers
|
||||||
Path = episodePath,
|
Path = episodePath,
|
||||||
Status = e.Status.ToString(),
|
Status = e.Status.ToString(),
|
||||||
Quality = episodeQuality,
|
Quality = episodeQuality,
|
||||||
|
QualityId = episodeQualityId,
|
||||||
Ignored = e.Ignored
|
Ignored = e.Ignored
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using NzbDrone.Core.Model;
|
using NzbDrone.Core.Model;
|
||||||
|
using NzbDrone.Core.Repository.Quality;
|
||||||
|
|
||||||
namespace NzbDrone.Web.Models
|
namespace NzbDrone.Web.Models
|
||||||
{
|
{
|
||||||
|
@ -7,6 +8,7 @@ namespace NzbDrone.Web.Models
|
||||||
{
|
{
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public int EpisodeId { get; set; }
|
public int EpisodeId { get; set; }
|
||||||
|
public int EpisodeFileId { get; set; }
|
||||||
public int EpisodeNumber { get; set; }
|
public int EpisodeNumber { get; set; }
|
||||||
public int SeasonNumber { get; set; }
|
public int SeasonNumber { get; set; }
|
||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
|
@ -14,6 +16,7 @@ namespace NzbDrone.Web.Models
|
||||||
public String Status { get; set; }
|
public String Status { get; set; }
|
||||||
public string AirDate { get; set; }
|
public string AirDate { get; set; }
|
||||||
public String Quality { get; set; }
|
public String Quality { get; set; }
|
||||||
|
public int QualityId { get; set; }
|
||||||
public bool Ignored { get; set; }
|
public bool Ignored { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
|
using System.Web.Mvc;
|
||||||
using NzbDrone.Core.Model;
|
using NzbDrone.Core.Model;
|
||||||
using NzbDrone.Core.Repository;
|
using NzbDrone.Core.Repository;
|
||||||
|
|
||||||
|
@ -18,5 +19,6 @@ namespace NzbDrone.Web.Models
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public bool HasBanner { get; set; }
|
public bool HasBanner { get; set; }
|
||||||
public List<SeasonModel> Seasons { get; set; }
|
public List<SeasonModel> Seasons { get; set; }
|
||||||
|
public SelectList QualitySelectList { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -164,6 +164,7 @@
|
||||||
<Content Include="Content\Images\AirsToday.png" />
|
<Content Include="Content\Images\AirsToday.png" />
|
||||||
<Content Include="Content\Images\background.jpg" />
|
<Content Include="Content\Images\background.jpg" />
|
||||||
<Content Include="Content\Images\blue.png" />
|
<Content Include="Content\Images\blue.png" />
|
||||||
|
<Content Include="Content\Images\changequality.png" />
|
||||||
<Content Include="Content\Images\False.png" />
|
<Content Include="Content\Images\False.png" />
|
||||||
<Content Include="Content\Images\Gear.png" />
|
<Content Include="Content\Images\Gear.png" />
|
||||||
<Content Include="Content\Images\green.png" />
|
<Content Include="Content\Images\green.png" />
|
||||||
|
|
|
@ -8,6 +8,11 @@ var seriesId = 0;
|
||||||
var saveSeasonIgnoreUrl = '../Command/SaveSeasonIgnore';
|
var saveSeasonIgnoreUrl = '../Command/SaveSeasonIgnore';
|
||||||
var saveEpisodeIgnoreUrl = '../Command/SaveEpisodeIgnore';
|
var saveEpisodeIgnoreUrl = '../Command/SaveEpisodeIgnore';
|
||||||
|
|
||||||
|
var changeQualityType;
|
||||||
|
var changeQualityData;
|
||||||
|
var changeEpisodeQualityUrl = '../Episode/ChangeEpisodeQuality';
|
||||||
|
var changeSeasonQualityUrl = '../Episode/ChangeSeasonQuality';
|
||||||
|
|
||||||
//Episode Ignore Functions
|
//Episode Ignore Functions
|
||||||
$(".ignoreEpisode").live("click", function () {
|
$(".ignoreEpisode").live("click", function () {
|
||||||
var toggle = $(this);
|
var toggle = $(this);
|
||||||
|
@ -122,3 +127,81 @@ function saveEpisodeIgnore(episodeId, ignored) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -111,6 +111,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style="visibility: hidden">
|
||||||
|
<div id="qualityChanger" title="Change Quality">
|
||||||
|
<label for="NewQuality">New Quality</label>
|
||||||
|
@Html.DropDownList("NewQuality", Model.QualitySelectList)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
@section Scripts{
|
@section Scripts{
|
||||||
@Html.IncludeScript("NzbDrone/seriesDetails.js")
|
@Html.IncludeScript("NzbDrone/seriesDetails.js")
|
||||||
@Html.IncludeScript("NzbDrone/series.js")
|
@Html.IncludeScript("NzbDrone/series.js")
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
@using NzbDrone.Web.Helpers
|
@using NzbDrone.Web.Helpers
|
||||||
@model NzbDrone.Web.Models.EpisodeModel
|
@model NzbDrone.Web.Models.EpisodeModel
|
||||||
|
|
||||||
<tr class="episodeId_@(Model.EpisodeId) data-row@(ViewData["AltRow"] == null || !(bool)ViewData["AltRow"] ? "" : " alt-row")">
|
<tr class="episodeId_@(Model.EpisodeId) data-row@(ViewData["AltRow"] == null || !(bool)ViewData["AltRow"] ? "" : " alt-row")" data-episodefileid="@Model.EpisodeFileId">
|
||||||
<td>@Model.EpisodeNumber</td>
|
<td>@Model.EpisodeNumber</td>
|
||||||
<td>@Model.Title</td>
|
<td>@Model.Title</td>
|
||||||
<td>@Model.AirDate</td>
|
<td>@Model.AirDate</td>
|
||||||
<td class="episodeQuality">@Model.Quality</td>
|
<td class="episodeQuality" data-qualityid="@Model.QualityId">@Model.Quality</td>
|
||||||
|
|
||||||
@{
|
@{
|
||||||
string cellColourClass = String.Empty;
|
string cellColourClass = String.Empty;
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
<td class="@cellColourClass">
|
<td class="@cellColourClass">
|
||||||
<img src='../../Content/Images/@(Model.Ignored ? "ignored" : "notIgnored").png' class='ignoreEpisode ignoreEpisode_@(Model.SeasonNumber)@(Model.Ignored ? " ignored" : " ") gridAction' id='@Model.EpisodeId' title='Click to toggle episode ignore status' />
|
<img src='../../Content/Images/@(Model.Ignored ? "ignored" : "notIgnored").png' class='ignoreEpisode ignoreEpisode_@(Model.SeasonNumber)@(Model.Ignored ? " ignored" : " ") gridAction' id='@Model.EpisodeId' title='Click to toggle episode ignore status' />
|
||||||
@Ajax.ImageActionLink("../../Content/Images/Search.png", new { Alt = "Search", Title = "Search for episode", @class = "gridAction" }, "Search", "Episode", new { episodeId = Model.EpisodeId }, null, null)
|
@Ajax.ImageActionLink("../../Content/Images/Search.png", new { Alt = "Search", Title = "Search for episode", @class = "gridAction" }, "Search", "Episode", new { episodeId = Model.EpisodeId }, null, null)
|
||||||
|
<img src='../../Content/Images/changequality.png' class='changeQuality gridAction' title='Click to change the quality of the episode file' data-changetype="episode"/>
|
||||||
<img src='../../Content/Images/@(Model.Status).png' alt='@Model.Status' title='@Model.Status' class='gridImage status-@Model.Status statusImage' />
|
<img src='../../Content/Images/@(Model.Status).png' alt='@Model.Status' title='@Model.Status' class='gridImage status-@Model.Status statusImage' />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
@(Model.SeasonNumber == 0 ? "Specials" : "Season " + Model.SeasonNumber)
|
@(Model.SeasonNumber == 0 ? "Specials" : "Season " + Model.SeasonNumber)
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<table class="seriesTable">
|
<table class="seriesTable" data-season="@Model.SeasonNumber">
|
||||||
<colgroup>
|
<colgroup>
|
||||||
<col style="width:40px"/>
|
<col style="width:40px"/>
|
||||||
<col style="width:auto"/>
|
<col style="width:auto"/>
|
||||||
<col style="width:100px" />
|
<col style="width:100px" />
|
||||||
<col style="width:100px" />
|
<col style="width:100px" />
|
||||||
<col style="width:90px" />
|
<col style="width:110px" />
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -24,6 +24,7 @@
|
||||||
<th>
|
<th>
|
||||||
<img src='../../Content/Images/@(Model.Ignored ? "ignored" : "notIgnored").png' class='ignoredEpisodesMaster ignoreEpisode ignoreSeason_@(Model.SeasonNumber)@(Model.Ignored ? " ignored" : " ") gridAction' title='Click to toggle season ignore status' />
|
<img src='../../Content/Images/@(Model.Ignored ? "ignored" : "notIgnored").png' class='ignoredEpisodesMaster ignoreEpisode ignoreSeason_@(Model.SeasonNumber)@(Model.Ignored ? " ignored" : " ") gridAction' title='Click to toggle season ignore status' />
|
||||||
@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/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)
|
||||||
|
<img src='../../Content/Images/changequality.png' class='changeQuality gridAction' title='Click to change the quality of all episode files in this season' data-changetype="season"/>
|
||||||
@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)
|
@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)
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<UseVSHostingProcess>true</UseVSHostingProcess>
|
<UseVSHostingProcess>true</UseVSHostingProcess>
|
||||||
<CodeAnalysisRuleSet>BasicCorrectnessRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>BasicCorrectnessRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<IntermediateOutputPath>C:\Users\Markus\AppData\Local\Temp\vs73DE.tmp\x86\Debug\</IntermediateOutputPath>
|
<IntermediateOutputPath>C:\Users\Mark\AppData\Local\Temp\vs32F1.tmp\x86\Debug\</IntermediateOutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<IntermediateOutputPath>C:\Users\Markus\AppData\Local\Temp\vs73DE.tmp\x86\Release\</IntermediateOutputPath>
|
<IntermediateOutputPath>C:\Users\Mark\AppData\Local\Temp\vs32F1.tmp\x86\Release\</IntermediateOutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ApplicationIcon>NzbDrone.ico</ApplicationIcon>
|
<ApplicationIcon>NzbDrone.ico</ApplicationIcon>
|
||||||
|
|
Loading…
Reference in New Issue