mirror of https://github.com/Radarr/Radarr
Added option to specify preferred words in quality profile. (#462)
* UI Done * Should theoretically work. * Preferred tags works now correctly :)
This commit is contained in:
parent
00541e6cc1
commit
cbc70a8ff3
|
@ -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<ProfileQualityItemResource> 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
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ namespace NzbDrone.Core.DecisionEngine
|
|||
var comparers = new List<CompareDelegate>
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
|
|
|
@ -183,6 +183,7 @@
|
|||
<Compile Include="Datastore\Migration\002_remove_tvrage_imdb_unique_constraint.cs" />
|
||||
<Compile Include="Datastore\Migration\003_remove_clean_title_from_scene_mapping.cs" />
|
||||
<Compile Include="Datastore\Migration\004_updated_history.cs" />
|
||||
<Compile Include="Datastore\Migration\124_add_preferred_tags_to_profile.cs" />
|
||||
<Compile Include="Datastore\Migration\122_add_movieid_to_blacklist.cs" />
|
||||
<Compile Include="Datastore\Migration\121_update_filedate_config.cs" />
|
||||
<Compile Include="Datastore\Migration\120_add_studio_to_table.cs" />
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace NzbDrone.Core.Profiles
|
|||
public string Name { get; set; }
|
||||
public Quality Cutoff { get; set; }
|
||||
public List<ProfileQualityItem> Items { get; set; }
|
||||
public List<string> PreferredTags { get; set; }
|
||||
public Language Language { get; set; }
|
||||
|
||||
public Quality LastAllowedQuality()
|
||||
|
|
|
@ -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);
|
||||
module.exports = AsModelBoundView.call(view);
|
||||
|
|
|
@ -1,45 +1,59 @@
|
|||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Name</label>
|
||||
<label class="col-sm-3 control-label">Name</label>
|
||||
|
||||
<div class="col-sm-5">
|
||||
<input type="text" name="name" class="form-control">
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<input type="text" name="name" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Language</label>
|
||||
<label class="col-sm-3 control-label">Language</label>
|
||||
|
||||
<div class="col-sm-5">
|
||||
<select class="form-control" name="language">
|
||||
{{#each languages}}
|
||||
{{#unless_eq nameLower compare="unknown"}}
|
||||
<option value="{{nameLower}}">{{name}}</option>
|
||||
{{/unless_eq}}
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<select class="form-control" name="language">
|
||||
{{#each languages}}
|
||||
{{#unless_eq nameLower compare="unknown"}}
|
||||
<option value="{{nameLower}}">{{name}}</option>
|
||||
{{/unless_eq}}
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-1 help-inline">
|
||||
<i class="icon-sonarr-form-info" title="Series assigned this profile will be look for episodes with the selected language"/>
|
||||
</div>
|
||||
<div class="col-sm-1 help-inline">
|
||||
<i class="icon-sonarr-form-info" title="Series assigned this profile will be look for episodes with the selected language"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Preferred Tags</label>
|
||||
|
||||
<div class="col-sm-1 col-sm-push-5 help-inline">
|
||||
<i class="icon-sonarr-form-info" title="When the release contains these tags it will be preferred." />
|
||||
</div>
|
||||
|
||||
<div class="col-sm-5 col-sm-pull-1">
|
||||
<input type="text" name="preferredTags" class="form-control x-preferred"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Cutoff</label>
|
||||
<label class="col-sm-3 control-label">Cutoff</label>
|
||||
|
||||
<div class="col-sm-5">
|
||||
<select class="form-control x-cutoff" name="cutoff.id" validation-name="cutoff">
|
||||
{{#eachReverse items}}
|
||||
{{#if allowed}}
|
||||
<option value="{{quality.id}}">{{quality.name}}</option>
|
||||
{{/if}}
|
||||
{{/eachReverse}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<select class="form-control x-cutoff" name="cutoff.id" validation-name="cutoff">
|
||||
{{#eachReverse items}}
|
||||
{{#if allowed}}
|
||||
<option value="{{quality.id}}">{{quality.name}}</option>
|
||||
{{/if}}
|
||||
{{/eachReverse}}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-1 help-inline">
|
||||
<i class="icon-sonarr-form-info" title="Once this quality is reached Radarr will no longer download episodes"/>
|
||||
</div>
|
||||
<div class="col-sm-1 help-inline">
|
||||
<i class="icon-sonarr-form-info" title="Once this quality is reached Radarr will no longer download episodes"/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -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);
|
||||
module.exports = AsModelBoundView.call(view);
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<div class="profile-item thingy">
|
||||
<div>
|
||||
<h3 name="name"></h3>
|
||||
</div>
|
||||
<div>
|
||||
<h3 name="name"></h3>
|
||||
</div>
|
||||
|
||||
<div class="language">
|
||||
{{languageLabel}}
|
||||
</div>
|
||||
<div class="language">
|
||||
{{languageLabel}}
|
||||
</div>
|
||||
|
||||
<ul class="allowed-qualities">
|
||||
{{allowedLabeler}}
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="allowed-qualities">
|
||||
{{allowedLabeler}}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue