From 3db97e9d11760f1efc4b1e535e06525843bd260b Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 20 Nov 2013 21:34:38 -0800 Subject: [PATCH] Moved SeasonFolderFormat to NamingConfig Moved UseSeasonFolder to UI only (add series) --- .../Config/NamingConfigResource.cs | 1 + .../Configuration/ConfigService.cs | 13 ----- .../Configuration/IConfigService.cs | 2 - ...d_season_folder_format_to_naming_config.cs | 56 +++++++++++++++++++ .../030_update_season_folder_format.cs | 54 ------------------ src/NzbDrone.Core/NzbDrone.Core.csproj | 2 +- .../Organizer/FileNameBuilder.cs | 5 +- src/NzbDrone.Core/Organizer/NamingConfig.cs | 4 +- src/NzbDrone.Core/Tv/SeriesService.cs | 2 - .../StartingSeasonSelectionPartial.html | 2 +- src/UI/AddSeries/SearchResultView.js | 20 ++++++- .../AddSeries/SearchResultViewTemplate.html | 8 +++ src/UI/AddSeries/addSeries.less | 14 ++++- src/UI/Config.js | 3 +- src/UI/Content/checkbox-button.less | 28 ++++++++++ src/UI/Content/theme.less | 1 + .../Naming/NamingViewTemplate.html | 11 ++++ .../MediaManagement/Sorting/ViewTemplate.html | 33 +---------- 18 files changed, 147 insertions(+), 112 deletions(-) create mode 100644 src/NzbDrone.Core/Datastore/Migration/030_add_season_folder_format_to_naming_config.cs delete mode 100644 src/NzbDrone.Core/Datastore/Migration/030_update_season_folder_format.cs create mode 100644 src/UI/Content/checkbox-button.less diff --git a/src/NzbDrone.Api/Config/NamingConfigResource.cs b/src/NzbDrone.Api/Config/NamingConfigResource.cs index b57caa4cb..c37fffaa9 100644 --- a/src/NzbDrone.Api/Config/NamingConfigResource.cs +++ b/src/NzbDrone.Api/Config/NamingConfigResource.cs @@ -9,5 +9,6 @@ namespace NzbDrone.Api.Config public Int32 MultiEpisodeStyle { get; set; } public string StandardEpisodeFormat { get; set; } public string DailyEpisodeFormat { get; set; } + public string SeasonFolderFormat { get; set; } } } \ No newline at end of file diff --git a/src/NzbDrone.Core/Configuration/ConfigService.cs b/src/NzbDrone.Core/Configuration/ConfigService.cs index 498731511..89f542670 100644 --- a/src/NzbDrone.Core/Configuration/ConfigService.cs +++ b/src/NzbDrone.Core/Configuration/ConfigService.cs @@ -142,19 +142,6 @@ namespace NzbDrone.Core.Configuration set { SetValue(ConfigKey.DownloadedEpisodesFolder.ToString(), value); } } - public bool UseSeasonFolder - { - get { return GetValueBoolean("UseSeasonFolder", true); } - - set { SetValue("UseSeasonFolder", value); } - } - - public string SeasonFolderFormat - { - get { return GetValue("SeasonFolderFormat", "Season {season}"); } - set { SetValue("SeasonFolderFormat", value); } - } - public bool AutoUnmonitorPreviouslyDownloadedEpisodes { get { return GetValueBoolean("AutoUnmonitorPreviouslyDownloadedEpisodes"); } diff --git a/src/NzbDrone.Core/Configuration/IConfigService.cs b/src/NzbDrone.Core/Configuration/IConfigService.cs index 654f07f73..60f98aada 100644 --- a/src/NzbDrone.Core/Configuration/IConfigService.cs +++ b/src/NzbDrone.Core/Configuration/IConfigService.cs @@ -20,8 +20,6 @@ namespace NzbDrone.Core.Configuration SabPriorityType SabOlderTvPriority { get; set; } Boolean SabUseSsl { get; set; } String DownloadedEpisodesFolder { get; set; } - bool UseSeasonFolder { get; set; } - string SeasonFolderFormat { get; set; } bool AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; } int Retention { get; set; } DownloadClientType DownloadClient { get; set; } diff --git a/src/NzbDrone.Core/Datastore/Migration/030_add_season_folder_format_to_naming_config.cs b/src/NzbDrone.Core/Datastore/Migration/030_add_season_folder_format_to_naming_config.cs new file mode 100644 index 000000000..7e7a2ab87 --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/030_add_season_folder_format_to_naming_config.cs @@ -0,0 +1,56 @@ +using System; +using System.Data; +using FluentMigrator; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(30)] + public class add_season_folder_format_to_naming_config : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Alter.Table("NamingConfig").AddColumn("SeasonFolderFormat").AsString().Nullable(); + Execute.WithConnection(ConvertConfig); + Execute.Sql("DELETE FROM Config WHERE [Key] = 'seasonfolderformat'"); + Execute.Sql("DELETE FROM Config WHERE [Key] = 'useseasonfolder'"); + } + + private void ConvertConfig(IDbConnection conn, IDbTransaction tran) + { + using (IDbCommand namingConfigCmd = conn.CreateCommand()) + { + namingConfigCmd.Transaction = tran; + namingConfigCmd.CommandText = @"SELECT [Value] FROM Config WHERE [Key] = 'seasonfolderformat'"; + var seasonFormat = "Season {season}"; + + using (IDataReader namingConfigReader = namingConfigCmd.ExecuteReader()) + { + while (namingConfigReader.Read()) + { + //only getting one column, so its index is 0 + seasonFormat = namingConfigReader.GetString(0); + + seasonFormat = seasonFormat.Replace("%sn", "{Series Title}") + .Replace("%s.n", "{Series.Title}") + .Replace("%s", "{season}") + .Replace("%0s", "{season:00}") + .Replace("%e", "{episode}") + .Replace("%0e", "{episode:00}"); + } + } + + using (IDbCommand updateCmd = conn.CreateCommand()) + { + var text = String.Format("UPDATE NamingConfig " + + "SET SeasonFolderFormat = '{0}'", + seasonFormat); + + updateCmd.Transaction = tran; + updateCmd.CommandText = text; + updateCmd.ExecuteNonQuery(); + } + } + } + } +} diff --git a/src/NzbDrone.Core/Datastore/Migration/030_update_season_folder_format.cs b/src/NzbDrone.Core/Datastore/Migration/030_update_season_folder_format.cs deleted file mode 100644 index b6ba5e686..000000000 --- a/src/NzbDrone.Core/Datastore/Migration/030_update_season_folder_format.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Data; -using FluentMigrator; -using NzbDrone.Core.Datastore.Migration.Framework; - -namespace NzbDrone.Core.Datastore.Migration -{ - [Migration(30)] - public class update_series_folder_format : NzbDroneMigrationBase - { - protected override void MainDbUpgrade() - { - Execute.WithConnection(ConvertConfig); - } - - private void ConvertConfig(IDbConnection conn, IDbTransaction tran) - { - using (IDbCommand namingConfigCmd = conn.CreateCommand()) - { - namingConfigCmd.Transaction = tran; - namingConfigCmd.CommandText = @"SELECT * FROM Config WHERE [Key] = 'seasonfolderformat'"; - using (IDataReader namingConfigReader = namingConfigCmd.ExecuteReader()) - { - var valueIndex = namingConfigReader.GetOrdinal("[Value]"); - - while (namingConfigReader.Read()) - { - var value = namingConfigReader.GetString(valueIndex); - - value = value.Replace("%sn", "{Series Title}") - .Replace("%s.n", "{Series.Title}") - .Replace("%s", "{season}") - .Replace("%0s", "{season:00}") - .Replace("%e", "{episode}") - .Replace("%0e", "{episode:00}"); - - - using (IDbCommand updateCmd = conn.CreateCommand()) - { - var text = String.Format("UPDATE Config " + - "SET [VALUE] = '{0}'" + - "WHERE [Key] = 'seasonfolderformat'", - value); - - updateCmd.Transaction = tran; - updateCmd.CommandText = text; - updateCmd.ExecuteNonQuery(); - } - } - } - } - } - } -} diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 8e32b557d..315176686 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -186,8 +186,8 @@ - + diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs index eb38719d2..3089fb51e 100644 --- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -163,10 +163,11 @@ namespace NzbDrone.Core.Organizer else { + var nameSpec = _namingConfigService.GetConfig(); var tokenValues = new Dictionary(FilenameBuilderTokenEqualityComparer.Instance); tokenValues.Add("{Series Title}", series.Title); - - seasonFolder = ReplaceSeasonTokens(_configService.SeasonFolderFormat, seasonNumber); + + seasonFolder = ReplaceSeasonTokens(nameSpec.SeasonFolderFormat, seasonNumber); seasonFolder = ReplaceTokens(seasonFolder, tokenValues); } diff --git a/src/NzbDrone.Core/Organizer/NamingConfig.cs b/src/NzbDrone.Core/Organizer/NamingConfig.cs index a7b7c6b8b..7a537e3ce 100644 --- a/src/NzbDrone.Core/Organizer/NamingConfig.cs +++ b/src/NzbDrone.Core/Organizer/NamingConfig.cs @@ -13,7 +13,8 @@ namespace NzbDrone.Core.Organizer RenameEpisodes = false, MultiEpisodeStyle = 0, StandardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title} {Quality Title}", - DailyEpisodeFormat = "{Series Title} - {Air-Date} - {Episode Title} {Quality Title}" + DailyEpisodeFormat = "{Series Title} - {Air-Date} - {Episode Title} {Quality Title}", + SeasonFolderFormat = "Season {season}" }; } } @@ -22,5 +23,6 @@ namespace NzbDrone.Core.Organizer public int MultiEpisodeStyle { get; set; } public string StandardEpisodeFormat { get; set; } public string DailyEpisodeFormat { get; set; } + public string SeasonFolderFormat { get; set; } } } \ No newline at end of file diff --git a/src/NzbDrone.Core/Tv/SeriesService.cs b/src/NzbDrone.Core/Tv/SeriesService.cs index 6f94faa84..9e1da54cd 100644 --- a/src/NzbDrone.Core/Tv/SeriesService.cs +++ b/src/NzbDrone.Core/Tv/SeriesService.cs @@ -71,8 +71,6 @@ namespace NzbDrone.Core.Tv newSeries.Monitored = true; newSeries.CleanTitle = Parser.Parser.CleanSeriesTitle(newSeries.Title); - newSeries.SeasonFolder = _configService.UseSeasonFolder; - _seriesRepository.Insert(newSeries); _eventAggregator.PublishEvent(new SeriesAddedEvent(newSeries)); diff --git a/src/UI/AddSeries/RootFolders/StartingSeasonSelectionPartial.html b/src/UI/AddSeries/RootFolders/StartingSeasonSelectionPartial.html index 0827ba052..82d28119c 100644 --- a/src/UI/AddSeries/RootFolders/StartingSeasonSelectionPartial.html +++ b/src/UI/AddSeries/RootFolders/StartingSeasonSelectionPartial.html @@ -1,4 +1,4 @@ - {{#each this}} {{#if_eq seasonNumber compare="0"}} diff --git a/src/UI/AddSeries/SearchResultView.js b/src/UI/AddSeries/SearchResultView.js index bb81a5f84..e8b24435c 100644 --- a/src/UI/AddSeries/SearchResultView.js +++ b/src/UI/AddSeries/SearchResultView.js @@ -22,6 +22,7 @@ define( ui: { qualityProfile: '.x-quality-profile', rootFolder : '.x-root-folder', + seasonFolder : '.x-season-folder', addButton : '.x-add', overview : '.x-overview', startingSeason: '.x-starting-season' @@ -30,7 +31,8 @@ define( events: { 'click .x-add' : '_addSeries', 'change .x-quality-profile': '_qualityProfileChanged', - 'change .x-root-folder' : '_rootFolderChanged' + 'change .x-root-folder' : '_rootFolderChanged', + 'change .x-season-folder' : '_seasonFolderChanged' }, initialize: function () { @@ -51,6 +53,7 @@ define( var defaultQuality = Config.getValue(Config.Keys.DefaultQualityProfileId); var defaultRoot = Config.getValue(Config.Keys.DefaultRootFolderId); + var useSeasonFolder = Config.getValueBoolean(Config.Keys.UseSeasonFolder, true); if (QualityProfiles.get(defaultQuality)) { this.ui.qualityProfile.val(defaultQuality); @@ -60,6 +63,8 @@ define( this.ui.rootFolder.val(defaultRoot); } + this.ui.seasonFolder.prop('checked', useSeasonFolder); + var minSeasonNotZero = _.min(_.reject(this.model.get('seasons'), { seasonNumber: 0 }), 'seasonNumber'); if (minSeasonNotZero) { @@ -91,15 +96,24 @@ define( if (options.key === Config.Keys.DefaultQualityProfileId) { this.ui.qualityProfile.val(options.value); } + else if (options.key === Config.Keys.DefaultRootFolderId) { this.ui.rootFolder.val(options.value); } + + else if (options.key === Config.Keys.UseSeasonFolder) { + this.ui.seasonFolder.prop('checked', options.value); + } }, _qualityProfileChanged: function () { Config.setValue(Config.Keys.DefaultQualityProfileId, this.ui.qualityProfile.val()); }, + _seasonFolderChanged: function () { + Config.setValue(Config.Keys.UseSeasonFolder, this.ui.seasonFolder.prop('checked')); + }, + _rootFolderChanged: function () { var rootFolderValue = this.ui.rootFolder.val(); if (rootFolderValue === 'addNew') { @@ -125,16 +139,17 @@ define( var quality = this.ui.qualityProfile.val(); var rootFolderPath = this.ui.rootFolder.children(':selected').text(); var startingSeason = this.ui.startingSeason.val(); + var seasonFolder = this.ui.seasonFolder.prop('checked'); this.model.set('qualityProfileId', quality); this.model.set('rootFolderPath', rootFolderPath); this.model.setSeasonPass(startingSeason); + this.model.set('seasonFolder', seasonFolder); var self = this; SeriesCollection.add(this.model); - var promise = this.model.save(); promise.done(function () { @@ -159,7 +174,6 @@ define( } }); - AsValidatedView.apply(view); return view; diff --git a/src/UI/AddSeries/SearchResultViewTemplate.html b/src/UI/AddSeries/SearchResultViewTemplate.html index 5b64b09a9..04747d8cb 100644 --- a/src/UI/AddSeries/SearchResultViewTemplate.html +++ b/src/UI/AddSeries/SearchResultViewTemplate.html @@ -32,6 +32,14 @@ {{> StartingSeasonSelectionPartial seasons}} {{> QualityProfileSelectionPartial qualityProfiles}} + + + Add diff --git a/src/UI/AddSeries/addSeries.less b/src/UI/AddSeries/addSeries.less index 1d36d9906..ee04cb289 100644 --- a/src/UI/AddSeries/addSeries.less +++ b/src/UI/AddSeries/addSeries.less @@ -91,6 +91,18 @@ .add-series { margin-left : 20px; } + + .checkbox { + width : 100px; + margin-left : 0px; + display : inline-block; + padding-top : 0px; + margin-bottom : 0px; + } + + .starting-season { + width: 140px; + } } } @@ -129,4 +141,4 @@ li.add-new:hover { overflow: auto; max-height: 300px; } -} \ No newline at end of file +} diff --git a/src/UI/Config.js b/src/UI/Config.js index 6c44d8857..e826e90cf 100644 --- a/src/UI/Config.js +++ b/src/UI/Config.js @@ -9,7 +9,8 @@ define( }, Keys : { DefaultQualityProfileId: 'DefaultQualityProfileId', - DefaultRootFolderId: 'DefaultRootFolderId' + DefaultRootFolderId: 'DefaultRootFolderId', + UseSeasonFolder: 'UseSeasonFolder' }, getValueBoolean: function (key, defaultValue) { diff --git a/src/UI/Content/checkbox-button.less b/src/UI/Content/checkbox-button.less new file mode 100644 index 000000000..4d12317fb --- /dev/null +++ b/src/UI/Content/checkbox-button.less @@ -0,0 +1,28 @@ +@import "Bootstrap/variables"; +@import "Bootstrap/mixins"; + +.checkbox-button div { + display: none; +} + +@media only screen { + .checkbox-button { + input { + position: absolute; + opacity: 0; + z-index: 5; + } + + div { + display: block; + } + + .btn { + .buttonBackground(@btnDangerBackground, @btnDangerBackgroundHighlight); + } + + input:first-of-type:checked ~ .btn { + .buttonBackground(@btnPrimaryBackground, @btnPrimaryBackgroundHighlight); + } + } +} diff --git a/src/UI/Content/theme.less b/src/UI/Content/theme.less index 3cf7edb0a..7c1decd1f 100644 --- a/src/UI/Content/theme.less +++ b/src/UI/Content/theme.less @@ -7,6 +7,7 @@ @import "Backgrid/backgrid"; @import "prefixer"; @import "icons"; +@import "checkbox-button"; @import "spinner"; @import "legend"; @import "../Shared/Styles/clickable"; diff --git a/src/UI/Settings/MediaManagement/Naming/NamingViewTemplate.html b/src/UI/Settings/MediaManagement/Naming/NamingViewTemplate.html index f4beac4ba..6eb23c4ef 100644 --- a/src/UI/Settings/MediaManagement/Naming/NamingViewTemplate.html +++ b/src/UI/Settings/MediaManagement/Naming/NamingViewTemplate.html @@ -104,6 +104,17 @@ +
+ + +
+ + + + +
+
+
diff --git a/src/UI/Settings/MediaManagement/Sorting/ViewTemplate.html b/src/UI/Settings/MediaManagement/Sorting/ViewTemplate.html index 322a7446c..dde9a2d84 100644 --- a/src/UI/Settings/MediaManagement/Sorting/ViewTemplate.html +++ b/src/UI/Settings/MediaManagement/Sorting/ViewTemplate.html @@ -1,7 +1,7 @@ -
+
Folders -
+
@@ -21,33 +21,4 @@
- - -
- - -
-
- -
- - -
- - - - -
-