mirror of https://github.com/lidarr/Lidarr
Indexer settings overhaul, reviewed settings tooltips
This commit is contained in:
parent
d60b863e14
commit
5baf2e09c4
|
@ -8,7 +8,7 @@ using NzbDrone.Core.Test.Framework;
|
||||||
namespace NzbDrone.Core.Test.DecisionEngineTests
|
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class NotRestrictedNzbSpecificationFixture : CoreTest<NotRestrictedNzbSpecification>
|
public class NotRestrictedReleaseSpecificationFixture : CoreTest<NotRestrictedReleaseSpecification>
|
||||||
{
|
{
|
||||||
private RemoteEpisode _parseResult;
|
private RemoteEpisode _parseResult;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
[TestCase("2HD\nkyr")]
|
[TestCase("2HD\nkyr")]
|
||||||
public void should_be_false_when_nzb_contains_a_restricted_term(string restrictions)
|
public void should_be_false_when_nzb_contains_a_restricted_term(string restrictions)
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.NzbRestrictions).Returns(restrictions);
|
Mocker.GetMock<IConfigService>().SetupGet(c => c.ReleaseRestrictions).Returns(restrictions);
|
||||||
Subject.IsSatisfiedBy(_parseResult).Should().BeFalse();
|
Subject.IsSatisfiedBy(_parseResult).Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
[TestCase("Hello\nWorld")]
|
[TestCase("Hello\nWorld")]
|
||||||
public void should_be_true_when_nzb_does_not_contain_a_restricted_term(string restrictions)
|
public void should_be_true_when_nzb_does_not_contain_a_restricted_term(string restrictions)
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.NzbRestrictions).Returns(restrictions);
|
Mocker.GetMock<IConfigService>().SetupGet(c => c.ReleaseRestrictions).Returns(restrictions);
|
||||||
Subject.IsSatisfiedBy(_parseResult).Should().BeTrue();
|
Subject.IsSatisfiedBy(_parseResult).Should().BeTrue();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -125,7 +125,7 @@
|
||||||
<Compile Include="Datastore\PagingSpecExtenstionsTests\PagingOffsetFixture.cs" />
|
<Compile Include="Datastore\PagingSpecExtenstionsTests\PagingOffsetFixture.cs" />
|
||||||
<Compile Include="Datastore\ReflectionStrategyFixture\Benchmarks.cs" />
|
<Compile Include="Datastore\ReflectionStrategyFixture\Benchmarks.cs" />
|
||||||
<Compile Include="Datastore\SQLiteMigrationHelperFixture.cs" />
|
<Compile Include="Datastore\SQLiteMigrationHelperFixture.cs" />
|
||||||
<Compile Include="DecisionEngineTests\NotRestrictedNzbSpecificationFixture.cs" />
|
<Compile Include="DecisionEngineTests\NotRestrictedReleaseSpecificationFixture.cs" />
|
||||||
<Compile Include="Download\DownloadApprovedReportsTests\DownloadApprovedFixture.cs" />
|
<Compile Include="Download\DownloadApprovedReportsTests\DownloadApprovedFixture.cs" />
|
||||||
<Compile Include="Download\DownloadApprovedReportsTests\GetQualifiedReportsFixture.cs" />
|
<Compile Include="Download\DownloadApprovedReportsTests\GetQualifiedReportsFixture.cs" />
|
||||||
<Compile Include="Download\DownloadClientTests\BlackholeProviderFixture.cs" />
|
<Compile Include="Download\DownloadClientTests\BlackholeProviderFixture.cs" />
|
||||||
|
|
|
@ -251,10 +251,10 @@ namespace NzbDrone.Core.Configuration
|
||||||
set { SetValue("NzbgetRecentTvPriority", value); }
|
set { SetValue("NzbgetRecentTvPriority", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string NzbRestrictions
|
public string ReleaseRestrictions
|
||||||
{
|
{
|
||||||
get { return GetValue("NzbRestrictions", String.Empty); }
|
get { return GetValue("ReleaseRestrictions", String.Empty); }
|
||||||
set { SetValue("NzbRestrictions", value); }
|
set { SetValue("ReleaseRestrictions", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetValue(string key)
|
private string GetValue(string key)
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace NzbDrone.Core.Configuration
|
||||||
String NzbgetTvCategory { get; set; }
|
String NzbgetTvCategory { get; set; }
|
||||||
Int32 NzbgetPriority { get; set; }
|
Int32 NzbgetPriority { get; set; }
|
||||||
PriorityType NzbgetRecentTvPriority { get; set; }
|
PriorityType NzbgetRecentTvPriority { get; set; }
|
||||||
string NzbRestrictions { get; set; }
|
string ReleaseRestrictions { get; set; }
|
||||||
string GetValue(string key, object defaultValue, bool persist = false);
|
string GetValue(string key, object defaultValue, bool persist = false);
|
||||||
void SetValue(string key, string value);
|
void SetValue(string key, string value);
|
||||||
void SaveValues(Dictionary<string, object> configValues);
|
void SaveValues(Dictionary<string, object> configValues);
|
||||||
|
|
|
@ -8,12 +8,12 @@ using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
{
|
{
|
||||||
public class NotRestrictedNzbSpecification : IDecisionEngineSpecification
|
public class NotRestrictedReleaseSpecification : IDecisionEngineSpecification
|
||||||
{
|
{
|
||||||
private readonly IConfigService _configService;
|
private readonly IConfigService _configService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public NotRestrictedNzbSpecification(IConfigService configService, Logger logger)
|
public NotRestrictedReleaseSpecification(IConfigService configService, Logger logger)
|
||||||
{
|
{
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
@ -29,9 +29,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
|
|
||||||
public virtual bool IsSatisfiedBy(RemoteEpisode subject)
|
public virtual bool IsSatisfiedBy(RemoteEpisode subject)
|
||||||
{
|
{
|
||||||
_logger.Trace("Checking if Nzb contains any restrictions: {0}", subject);
|
_logger.Trace("Checking if release contains any restricted terms: {0}", subject);
|
||||||
|
|
||||||
var restrictionsString = _configService.NzbRestrictions;
|
var restrictionsString = _configService.ReleaseRestrictions;
|
||||||
|
|
||||||
if (String.IsNullOrWhiteSpace(restrictionsString))
|
if (String.IsNullOrWhiteSpace(restrictionsString))
|
||||||
{
|
{
|
|
@ -233,7 +233,7 @@
|
||||||
<Compile Include="DecisionEngine\DownloadDecision.cs" />
|
<Compile Include="DecisionEngine\DownloadDecision.cs" />
|
||||||
<Compile Include="DecisionEngine\IRejectWithReason.cs" />
|
<Compile Include="DecisionEngine\IRejectWithReason.cs" />
|
||||||
<Compile Include="DecisionEngine\IDecisionEngineSpecification.cs" />
|
<Compile Include="DecisionEngine\IDecisionEngineSpecification.cs" />
|
||||||
<Compile Include="DecisionEngine\Specifications\NotRestrictedNzbSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\NotRestrictedReleaseSpecification.cs" />
|
||||||
<Compile Include="DecisionEngine\Specifications\Search\SeasonMatchSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\Search\SeasonMatchSpecification.cs" />
|
||||||
<Compile Include="DecisionEngine\Specifications\Search\DailyEpisodeMatchSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\Search\DailyEpisodeMatchSpecification.cs" />
|
||||||
<Compile Include="DecisionEngine\Specifications\Search\IDecisionEngineSearchSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\Search\IDecisionEngineSearchSpecification.cs" />
|
||||||
|
|
|
@ -31,7 +31,6 @@ namespace NzbDrone.Core.Organizer
|
||||||
_repository = repository;
|
_repository = repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public NamingConfig GetConfig()
|
public NamingConfig GetConfig()
|
||||||
{
|
{
|
||||||
var config = _repository.SingleOrDefault();
|
var config = _repository.SingleOrDefault();
|
||||||
|
|
|
@ -29,6 +29,6 @@
|
||||||
font-size : 12px;
|
font-size : 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea.nzb-restrictions {
|
textarea.release-restrictions {
|
||||||
width : 260px;
|
width : 260px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" name="blackholeFolder" class="x-path"/>
|
<input type="text" name="blackholeFolder" class="x-path"/>
|
||||||
<span class="help-inline">
|
<span class="help-inline">
|
||||||
<i class="icon-question-sign" title="The folder where your download client will pickup .nzb files"/>
|
<i class="icon-form-info" title="The folder where your download client will pickup .nzb files"/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" name="downloadedEpisodesFolder" class="x-path"/>
|
<input type="text" name="downloadedEpisodesFolder" class="x-path"/>
|
||||||
<span class="help-inline">
|
<span class="help-inline">
|
||||||
<i class="icon-question-sign" title="The folder where your download client downloads TV shows to (aka TV Download Dir)"/>
|
<i class="icon-form-info" title="The folder where your download client downloads TV shows to (aka TV Download Dir)"/>
|
||||||
<i class="icon-exclamation-sign danger" title="Do not use the folder that contains some or all of your sorted and named TV shows - doing so could cause data loss"></i>
|
<i class="icon-form-danger" title="Do not use the folder that contains some or all of your sorted and named TV shows - doing so could cause data loss"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
<option value="force">Force</option>
|
<option value="force">Force</option>
|
||||||
</select>
|
</select>
|
||||||
<span class="help-inline">
|
<span class="help-inline">
|
||||||
<i class="icon-question-sign" title="Priority to use when sending episodes that aired within the last 7 days to NZBGet"/>
|
<i class="icon-form-info" title="Priority to use when sending episodes that aired within the last 7 days to NZBGet"/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" name="pneumaticFolder" class="x-path"/>
|
<input type="text" name="pneumaticFolder" class="x-path"/>
|
||||||
<span class="help-inline">
|
<span class="help-inline">
|
||||||
<i class="icon-question-sign" title="Folder to save NZBs for Pneumatic<br/>must be accessible from XBMC"></i>
|
<i class="icon-form-info" title="Folder to save NZBs for Pneumatic<br/>must be accessible from XBMC"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
<option value="force">Force</option>
|
<option value="force">Force</option>
|
||||||
</select>
|
</select>
|
||||||
<span class="help-inline">
|
<span class="help-inline">
|
||||||
<i class="icon-question-sign" title="Priority to use when sending episodes that aired within the last 7 days to SABnzbd"/>
|
<i class="icon-form-info" title="Priority to use when sending episodes that aired within the last 7 days to SABnzbd"/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" placeholder="8989" name="port"/>
|
<input type="text" placeholder="8989" name="port"/>
|
||||||
<span>
|
<span>
|
||||||
<i class="icon-exclamation-sign danger" title="Requires restart to take effect"/>
|
<i class="icon-form-danger" title="Requires restart to take effect"/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
<div class="row">
|
<fieldset>
|
||||||
<div class="span12">
|
<legend>Indexers</legend>
|
||||||
<button class="btn btn-success x-add">Add Newznab</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="span12">
|
<div class="span12">
|
||||||
<ul id="x-indexers" class="indexer-list"></ul>
|
<button class="btn btn-success x-add">Add Newznab</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="span12">
|
||||||
|
<ul id="x-indexers" class="indexer-list"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
|
@ -0,0 +1,28 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
define(
|
||||||
|
[
|
||||||
|
'marionette',
|
||||||
|
'Settings/Indexers/CollectionView',
|
||||||
|
'Settings/Indexers/Options/View'
|
||||||
|
], function (Marionette, CollectionView, OptionsView) {
|
||||||
|
return Marionette.Layout.extend({
|
||||||
|
template: 'Settings/Indexers/LayoutTemplate',
|
||||||
|
|
||||||
|
regions: {
|
||||||
|
indexersRegion : '#indexers-collection',
|
||||||
|
indexerOptions : '#indexer-options'
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function (options) {
|
||||||
|
this.settings = options.settings;
|
||||||
|
this.indexersCollection = options.indexersCollection;
|
||||||
|
},
|
||||||
|
|
||||||
|
onShow: function () {
|
||||||
|
this.indexersRegion.show(new CollectionView({ collection: this.indexersCollection }));
|
||||||
|
this.indexerOptions.show(new OptionsView({ model: this.settings }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<div id="indexers-collection"></div>
|
||||||
|
|
||||||
|
<div class="form-horizontal">
|
||||||
|
<div id="indexer-options"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,13 @@
|
||||||
|
'use strict';
|
||||||
|
define(
|
||||||
|
[
|
||||||
|
'marionette',
|
||||||
|
'Mixins/AsModelBoundView'
|
||||||
|
], function (Marionette, AsModelBoundView) {
|
||||||
|
|
||||||
|
var view = Marionette.ItemView.extend({
|
||||||
|
template: 'Settings/Indexers/Options/ViewTemplate'
|
||||||
|
});
|
||||||
|
|
||||||
|
return AsModelBoundView.call(view);
|
||||||
|
});
|
|
@ -0,0 +1,39 @@
|
||||||
|
<fieldset>
|
||||||
|
<legend>Options</legend>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">Retention</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" name="retention"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">RSS Sync Interval</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<label class="checkbox toggle well">
|
||||||
|
<input type="checkbox" name="rssSyncInterval"/>
|
||||||
|
<p>
|
||||||
|
<span>Yes</span>
|
||||||
|
<span>No</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="btn btn-primary slide-button"/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">Release Restrictions</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<textarea rows="3" name="releaseRestrictions" class="release-restrictions"></textarea>
|
||||||
|
<span class="help-inline">
|
||||||
|
<i class="icon-question-sign" title="Blacklist NZBs based on these words (case-insensitive)"/>
|
||||||
|
</span>
|
||||||
|
<span class="text-area-help">Newline-delimited set of rules</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
|
@ -21,7 +21,7 @@ define(
|
||||||
this.namingSettings = options.namingSettings;
|
this.namingSettings = options.namingSettings;
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender: function () {
|
onShow: function () {
|
||||||
this.episodeNaming.show(new NamingView({ model: this.namingSettings }));
|
this.episodeNaming.show(new NamingView({ model: this.namingSettings }));
|
||||||
this.sorting.show(new SortingView({ model: this.settings }));
|
this.sorting.show(new SortingView({ model: this.settings }));
|
||||||
this.fileManagement.show(new FileManagementView({ model: this.settings }));
|
this.fileManagement.show(new FileManagementView({ model: this.settings }));
|
||||||
|
|
|
@ -1,14 +1,3 @@
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Misc</legend>
|
<legend>Misc</legend>
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label">Nzb Restrictions</label>
|
|
||||||
|
|
||||||
<div class="controls">
|
|
||||||
<textarea rows="3" name="nzbRestrictions" class="nzb-restrictions"></textarea>
|
|
||||||
<span class="help-inline">
|
|
||||||
<i class="icon-question-sign" title="Blacklist NZBs based on these words (case-insensitive)"/>
|
|
||||||
</span>
|
|
||||||
<span class="text-area-help">Newline-delimited set of rules</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
|
@ -23,7 +23,7 @@ define(
|
||||||
this.qualitySizeCollection.fetch();
|
this.qualitySizeCollection.fetch();
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender: function () {
|
onShow: function () {
|
||||||
this.qualityProfile.show(new QualityProfileCollectionView({collection: QualityProfileCollection}));
|
this.qualityProfile.show(new QualityProfileCollectionView({collection: QualityProfileCollection}));
|
||||||
this.qualitySize.show(new QualitySizeCollectionView({collection: this.qualitySizeCollection}));
|
this.qualitySize.show(new QualitySizeCollectionView({collection: this.qualitySizeCollection}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ define(
|
||||||
'Settings/MediaManagement/Naming/Model',
|
'Settings/MediaManagement/Naming/Model',
|
||||||
'Settings/MediaManagement/Layout',
|
'Settings/MediaManagement/Layout',
|
||||||
'Settings/Quality/QualityLayout',
|
'Settings/Quality/QualityLayout',
|
||||||
'Settings/Indexers/CollectionView',
|
'Settings/Indexers/Layout',
|
||||||
'Settings/Indexers/Collection',
|
'Settings/Indexers/Collection',
|
||||||
'Settings/DownloadClient/Layout',
|
'Settings/DownloadClient/Layout',
|
||||||
'Settings/Notifications/CollectionView',
|
'Settings/Notifications/CollectionView',
|
||||||
|
@ -23,7 +23,7 @@ define(
|
||||||
NamingModel,
|
NamingModel,
|
||||||
MediaManagementLayout,
|
MediaManagementLayout,
|
||||||
QualityLayout,
|
QualityLayout,
|
||||||
IndexerCollectionView,
|
IndexerLayout,
|
||||||
IndexerCollection,
|
IndexerCollection,
|
||||||
DownloadClientLayout,
|
DownloadClientLayout,
|
||||||
NotificationCollectionView,
|
NotificationCollectionView,
|
||||||
|
@ -157,14 +157,14 @@ define(
|
||||||
this.indexerSettings.fetch(),
|
this.indexerSettings.fetch(),
|
||||||
this.notificationSettings.fetch()
|
this.notificationSettings.fetch()
|
||||||
).done(function () {
|
).done(function () {
|
||||||
self.loading.$el.hide();
|
self.loading.$el.hide();
|
||||||
self.mediaManagement.show(new MediaManagementLayout({ settings: self.settings, namingSettings: self.namingSettings }));
|
self.mediaManagement.show(new MediaManagementLayout({ settings: self.settings, namingSettings: self.namingSettings }));
|
||||||
self.quality.show(new QualityLayout({settings: self.settings}));
|
self.quality.show(new QualityLayout({settings: self.settings}));
|
||||||
self.indexers.show(new IndexerCollectionView({collection: self.indexerSettings}));
|
self.indexers.show(new IndexerLayout({ settings: self.settings, indexersCollection: self.indexerSettings }));
|
||||||
self.downloadClient.show(new DownloadClientLayout({model: self.settings}));
|
self.downloadClient.show(new DownloadClientLayout({model: self.settings}));
|
||||||
self.notifications.show(new NotificationCollectionView({collection: self.notificationSettings}));
|
self.notifications.show(new NotificationCollectionView({collection: self.notificationSettings}));
|
||||||
self.general.show(new GeneralView({model: self.generalSettings}));
|
self.general.show(new GeneralView({model: self.generalSettings}));
|
||||||
self.misc.show(new MiscView({model: self.settings}));
|
self.misc.show(new MiscView({model: self.settings}));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div class="tab-pane" id="media-management"></div>
|
<div class="tab-pane" id="media-management"></div>
|
||||||
<div class="tab-pane" id="quality"></div>
|
<div class="tab-pane" id="quality"></div>
|
||||||
<div class="tab-pane" id="indexers"></div>
|
<div class="tab-pane" id="indexers">indexers...</div>
|
||||||
<div class="tab-pane" id="download-client"></div>
|
<div class="tab-pane" id="download-client"></div>
|
||||||
<div class="tab-pane" id="notifications"></div>
|
<div class="tab-pane" id="notifications"></div>
|
||||||
<div class="tab-pane" id="general"></div>
|
<div class="tab-pane" id="general"></div>
|
||||||
|
|
Loading…
Reference in New Issue