From cbc70a8ff3fa6673504a4798556d604b3f108209 Mon Sep 17 00:00:00 2001 From: Leonardo Galli Date: Fri, 27 Jan 2017 20:01:28 +0100 Subject: [PATCH] Added option to specify preferred words in quality profile. (#462) * UI Done * Should theoretically work. * Preferred tags works now correctly :) --- src/NzbDrone.Api/Profiles/ProfileResource.cs | 3 + .../124_add_preferred_tags_to_profile.cs | 20 +++++ .../DownloadDecisionComparer.cs | 21 ++++++ src/NzbDrone.Core/NzbDrone.Core.csproj | 1 + src/NzbDrone.Core/Profiles/Profile.cs | 1 + .../Settings/Profile/Edit/EditProfileView.js | 36 ++++++--- .../Profile/Edit/EditProfileViewTemplate.hbs | 74 +++++++++++-------- src/UI/Settings/Profile/ProfileView.js | 42 ++++++----- .../Settings/Profile/ProfileViewTemplate.hbs | 20 ++--- 9 files changed, 146 insertions(+), 72 deletions(-) create mode 100644 src/NzbDrone.Core/Datastore/Migration/124_add_preferred_tags_to_profile.cs diff --git a/src/NzbDrone.Api/Profiles/ProfileResource.cs b/src/NzbDrone.Api/Profiles/ProfileResource.cs index ee02bcb32..65e560b59 100644 --- a/src/NzbDrone.Api/Profiles/ProfileResource.cs +++ b/src/NzbDrone.Api/Profiles/ProfileResource.cs @@ -11,6 +11,7 @@ namespace NzbDrone.Api.Profiles { public string Name { get; set; } public Quality Cutoff { get; set; } + public string PreferredTags { get; set; } public List Items { get; set; } public Language Language { get; set; } } @@ -33,6 +34,7 @@ namespace NzbDrone.Api.Profiles Name = model.Name, Cutoff = model.Cutoff, + PreferredTags = model.PreferredTags != null ? string.Join(",", model.PreferredTags) : "", Items = model.Items.ConvertAll(ToResource), Language = model.Language }; @@ -59,6 +61,7 @@ namespace NzbDrone.Api.Profiles Name = resource.Name, Cutoff = (Quality)resource.Cutoff.Id, + PreferredTags = resource.PreferredTags.Split(',').ToList(), Items = resource.Items.ConvertAll(ToModel), Language = resource.Language }; diff --git a/src/NzbDrone.Core/Datastore/Migration/124_add_preferred_tags_to_profile.cs b/src/NzbDrone.Core/Datastore/Migration/124_add_preferred_tags_to_profile.cs new file mode 100644 index 000000000..531af0eb6 --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/124_add_preferred_tags_to_profile.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using FluentMigrator; +using NzbDrone.Core.Datastore.Migration.Framework; +using System.Data; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(124)] + public class add_preferred_tags_to_profile : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Alter.Table("Profiles").AddColumn("PreferredTags").AsString().Nullable(); + } + + } +} diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs index aba427cbf..fdb45f6d4 100644 --- a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs +++ b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs @@ -23,6 +23,7 @@ namespace NzbDrone.Core.DecisionEngine var comparers = new List { CompareQuality, + ComparePreferredWords, CompareProtocol, ComparePeersIfTorrent, CompareAgeIfUsenet, @@ -65,6 +66,26 @@ namespace NzbDrone.Core.DecisionEngine CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version)); } + private int ComparePreferredWords(DownloadDecision x, DownloadDecision y) + { + return CompareBy(x.RemoteMovie, y.RemoteMovie, remoteMovie => + { + var title = remoteMovie.Release.Title; + remoteMovie.Movie.Profile.LazyLoad(); + var preferredWords = remoteMovie.Movie.Profile.Value.PreferredTags; + + if (preferredWords == null) + { + return 0; + } + + var num = preferredWords.AsEnumerable().Count(w => title.ToLower().Contains(w.ToLower())); + + return num; + + }); +; } + private int CompareProtocol(DownloadDecision x, DownloadDecision y) { diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 6f7eee5c0..d84d0401b 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -183,6 +183,7 @@ + diff --git a/src/NzbDrone.Core/Profiles/Profile.cs b/src/NzbDrone.Core/Profiles/Profile.cs index 6215e9474..d25104fb6 100644 --- a/src/NzbDrone.Core/Profiles/Profile.cs +++ b/src/NzbDrone.Core/Profiles/Profile.cs @@ -11,6 +11,7 @@ namespace NzbDrone.Core.Profiles public string Name { get; set; } public Quality Cutoff { get; set; } public List Items { get; set; } + public List PreferredTags { get; set; } public Language Language { get; set; } public Quality LastAllowedQuality() diff --git a/src/UI/Settings/Profile/Edit/EditProfileView.js b/src/UI/Settings/Profile/Edit/EditProfileView.js index 23535d9e6..52459c6c1 100644 --- a/src/UI/Settings/Profile/Edit/EditProfileView.js +++ b/src/UI/Settings/Profile/Edit/EditProfileView.js @@ -4,25 +4,37 @@ var LanguageCollection = require('../Language/LanguageCollection'); var Config = require('../../../Config'); var AsModelBoundView = require('../../../Mixins/AsModelBoundView'); var AsValidatedView = require('../../../Mixins/AsValidatedView'); +require('../../../Mixins/TagInput'); +require('bootstrap'); +require('bootstrap.tagsinput'); var view = Marionette.ItemView.extend({ - template : 'Settings/Profile/Edit/EditProfileViewTemplate', + template : 'Settings/Profile/Edit/EditProfileViewTemplate', - ui : { cutoff : '.x-cutoff' }, + ui : { cutoff : '.x-cutoff', + preferred : '.x-preferred', + }, - templateHelpers : function() { - return { - languages : LanguageCollection.toJSON() - }; - }, + onRender : function() { + this.ui.preferred.tagsinput({ + trimValue : true, + tagClass : 'label label-success' + }); + }, - getCutoff : function() { - var self = this; + templateHelpers : function() { + return { + languages : LanguageCollection.toJSON() + }; + }, - return _.findWhere(_.pluck(this.model.get('items'), 'quality'), { id : parseInt(self.ui.cutoff.val(), 10) }); - } + getCutoff : function() { + var self = this; + + return _.findWhere(_.pluck(this.model.get('items'), 'quality'), { id : parseInt(self.ui.cutoff.val(), 10) }); + } }); AsValidatedView.call(view); -module.exports = AsModelBoundView.call(view); \ No newline at end of file +module.exports = AsModelBoundView.call(view); diff --git a/src/UI/Settings/Profile/Edit/EditProfileViewTemplate.hbs b/src/UI/Settings/Profile/Edit/EditProfileViewTemplate.hbs index c19d10e5c..072a70ed0 100644 --- a/src/UI/Settings/Profile/Edit/EditProfileViewTemplate.hbs +++ b/src/UI/Settings/Profile/Edit/EditProfileViewTemplate.hbs @@ -1,45 +1,59 @@
- + -
- -
+
+ +

- + -
- -
+
+ +
-
- -
+
+ +
+ +
+ + +
+ +
+ +
+ +
+
+ +
- + -
- -
+
+ +
-
- -
+
+ +
diff --git a/src/UI/Settings/Profile/ProfileView.js b/src/UI/Settings/Profile/ProfileView.js index 4241c3f12..10a4a9be3 100644 --- a/src/UI/Settings/Profile/ProfileView.js +++ b/src/UI/Settings/Profile/ProfileView.js @@ -6,30 +6,32 @@ require('./AllowedLabeler'); require('./LanguageLabel'); require('bootstrap'); + var view = Marionette.ItemView.extend({ - template : 'Settings/Profile/ProfileViewTemplate', - tagName : 'li', + template : 'Settings/Profile/ProfileViewTemplate', + tagName : 'li', - ui : { - "progressbar" : '.progress .bar', - "deleteButton" : '.x-delete' - }, + ui : { + "progressbar" : '.progress .bar', + "deleteButton" : '.x-delete', - events : { - 'click' : '_editProfile' - }, + }, - initialize : function() { - this.listenTo(this.model, 'sync', this.render); - }, + events : { + 'click' : '_editProfile' + }, - _editProfile : function() { - var view = new EditProfileView({ - model : this.model, - profileCollection : this.model.collection - }); - AppLayout.modalRegion.show(view); - } + initialize : function() { + this.listenTo(this.model, 'sync', this.render); + }, + + _editProfile : function() { + var view = new EditProfileView({ + model : this.model, + profileCollection : this.model.collection + }); + AppLayout.modalRegion.show(view); + } }); -module.exports = AsModelBoundView.call(view); \ No newline at end of file +module.exports = AsModelBoundView.call(view); diff --git a/src/UI/Settings/Profile/ProfileViewTemplate.hbs b/src/UI/Settings/Profile/ProfileViewTemplate.hbs index 4f5b3eef0..2f827a351 100644 --- a/src/UI/Settings/Profile/ProfileViewTemplate.hbs +++ b/src/UI/Settings/Profile/ProfileViewTemplate.hbs @@ -1,13 +1,13 @@
-
-

-
+
+

+
-
- {{languageLabel}} -
+
+ {{languageLabel}} +
-
    - {{allowedLabeler}} -
-
\ No newline at end of file +
    + {{allowedLabeler}} +
+