diff --git a/CHANGELOG.md b/CHANGELOG.md
index 263f7ad62d..115d5984e7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@
- Added delete method to EpisodeHandler (apiv2), for deleting a single episode ([#5685](https://github.com/pymedusa/Medusa/pull/5685))
- Allowed Nyaa and Anidex to search for non-anime shows ([#5680](https://github.com/pymedusa/Medusa/pull/5680) & [#5681](https://github.com/pymedusa/Medusa/pull/5681))
- Do not allow to enable the anime options, when using tmdb or tvmaze ([#5701](https://github.com/pymedusa/Medusa/pull/5701))
+- Vueified "config - search" page. Improved responsiveness of the notification page on smaller screens. ([#5553](https://github.com/pymedusa/Medusa/pull/5553))
#### Fixes
- Fixed test not working for Download Station ([#5561](https://github.com/pymedusa/Medusa/pull/5561))
diff --git a/dredd/api-description.yml b/dredd/api-description.yml
index 7c529aebf7..e411a939e0 100644
--- a/dredd/api-description.yml
+++ b/dredd/api-description.yml
@@ -1983,6 +1983,84 @@ definitions:
type: boolean
notifyOnSubtitleDownload:
type: boolean
+ clients:
+ type: object
+ properties:
+ nzb:
+ type: object
+ properties:
+ enabled:
+ type: boolean
+ dir:
+ type: string
+ method:
+ type: string
+ nzbget:
+ type: object
+ properties:
+ category:
+ type: string
+ categoryAnime:
+ type: string
+ categoryAnimeBacklog:
+ type: string
+ categoryBacklog:
+ type: string
+ host:
+ type: string
+ priority:
+ type: integer
+ useHttps:
+ type: boolean
+ username:
+ type: string
+ sabnzbd:
+ type: object
+ properties:
+ category:
+ type: string
+ categoryAnime:
+ type: string
+ categoryAnimeBacklog:
+ type: string
+ categoryBacklog:
+ type: string
+ forced:
+ type: boolean
+ host:
+ type: string
+ username:
+ type: string
+ torrents:
+ type: object
+ properties:
+ username:
+ type: string
+ seedTime:
+ type: integer
+ rpcurl:
+ type: string
+ authType:
+ type: string
+ paused:
+ type: boolean
+ host:
+ type: string
+ path:
+ type: string
+ verifySSL:
+ type: boolean
+ highBandwidth:
+ type: boolean
+ enabled:
+ type: boolean
+ label:
+ type: string
+ labelAnime:
+ type: string
+ method:
+ type: string
+ enum: ["blackhole", "utorrent", "transmission", "deluge", "deluged", "downloadstation", "rtorrent", "qbittorrent", "mlnet"]
Log:
type: object
properties:
diff --git a/medusa/server/api/v2/config.py b/medusa/server/api/v2/config.py
index c681753846..959f726bfa 100644
--- a/medusa/server/api/v2/config.py
+++ b/medusa/server/api/v2/config.py
@@ -72,43 +72,43 @@ class ConfigHandler(BaseRequestHandler):
patches = {
'anonRedirect': StringField(app, 'ANON_REDIRECT'),
'emby.enabled': BooleanField(app, 'USE_EMBY'),
- 'torrents.authType': StringField(app, 'TORRENT_AUTH_TYPE'),
- 'torrents.dir': StringField(app, 'TORRENT_DIR'),
- 'torrents.enabled': BooleanField(app, 'USE_TORRENTS'),
- 'torrents.highBandwidth': StringField(app, 'TORRENT_HIGH_BANDWIDTH'),
- 'torrents.host': StringField(app, 'TORRENT_HOST'),
- 'torrents.label': StringField(app, 'TORRENT_LABEL'),
- 'torrents.labelAnime': StringField(app, 'TORRENT_LABEL_ANIME'),
- 'torrents.method': StringField(app, 'TORRENT_METHOD'),
- 'torrents.password': StringField(app, 'TORRENT_PASSWORD'),
- 'torrents.path': BooleanField(app, 'TORRENT_PATH'),
- 'torrents.paused': BooleanField(app, 'TORRENT_PAUSED'),
- 'torrents.rpcurl': StringField(app, 'TORRENT_RPCURL'),
- 'torrents.seedLocation': StringField(app, 'TORRENT_SEED_LOCATION'),
- 'torrents.seedTime': StringField(app, 'TORRENT_SEED_TIME'),
- 'torrents.username': StringField(app, 'TORRENT_USERNAME'),
- 'torrents.verifySSL': BooleanField(app, 'TORRENT_VERIFY_CERT'),
- 'nzb.enabled': BooleanField(app, 'USE_NZBS'),
- 'nzb.dir': StringField(app, 'NZB_DIR'),
- 'nzb.method': StringField(app, 'NZB_METHOD'),
- 'nzb.nzbget.category': StringField(app, 'NZBGET_CATEGORY'),
- 'nzb.nzbget.categoryAnime': StringField(app, 'NZBGET_CATEGORY_ANIME'),
- 'nzb.nzbget.categoryAnimeBacklog': StringField(app, 'NZBGET_CATEGORY_ANIME_BACKLOG'),
- 'nzb.nzbget.categoryBacklog': StringField(app, 'NZBGET_CATEGORY_BACKLOG'),
- 'nzb.nzbget.host': StringField(app, 'NZBGET_HOST'),
- 'nzb.nzbget.password': StringField(app, 'NZBGET_PASSWORD'),
- 'nzb.nzbget.priority': StringField(app, 'NZBGET_PRIORITY'),
- 'nzb.nzbget.useHttps': BooleanField(app, 'NZBGET_USE_HTTPS'),
- 'nzb.nzbget.username': StringField(app, 'NZBGET_USERNAME'),
- 'nzb.sabnzbd.apiKey': StringField(app, 'SAB_APIKEY'),
- 'nzb.sabnzbd.category': StringField(app, 'SAB_CATEGORY'),
- 'nzb.sabnzbd.categoryAnime': StringField(app, 'SAB_CATEGORY_ANIME'),
- 'nzb.sabnzbd.categoryAnimeBacklog': StringField(app, 'SAB_CATEGORY_ANIME_BACKLOG'),
- 'nzb.sabnzbd.categoryBacklog': StringField(app, 'SAB_CATEGORY_BACKLOG'),
- 'nzb.sabnzbd.forced': BooleanField(app, 'SAB_FORCED'),
- 'nzb.sabnzbd.host': StringField(app, 'SAB_HOST'),
- 'nzb.sabnzbd.password': StringField(app, 'SAB_PASSWORD'),
- 'nzb.sabnzbd.username': StringField(app, 'SAB_USERNAME'),
+ 'clients.torrents.authType': StringField(app, 'TORRENT_AUTH_TYPE'),
+ 'clients.torrents.dir': StringField(app, 'TORRENT_DIR'),
+ 'clients.torrents.enabled': BooleanField(app, 'USE_TORRENTS'),
+ 'clients.torrents.highBandwidth': BooleanField(app, 'TORRENT_HIGH_BANDWIDTH'),
+ 'clients.torrents.host': StringField(app, 'TORRENT_HOST'),
+ 'clients.torrents.label': StringField(app, 'TORRENT_LABEL'),
+ 'clients.torrents.labelAnime': StringField(app, 'TORRENT_LABEL_ANIME'),
+ 'clients.torrents.method': StringField(app, 'TORRENT_METHOD'),
+ 'clients.torrents.password': StringField(app, 'TORRENT_PASSWORD'),
+ 'clients.torrents.path': BooleanField(app, 'TORRENT_PATH'),
+ 'clients.torrents.paused': BooleanField(app, 'TORRENT_PAUSED'),
+ 'clients.torrents.rpcurl': StringField(app, 'TORRENT_RPCURL'),
+ 'clients.torrents.seedLocation': StringField(app, 'TORRENT_SEED_LOCATION'),
+ 'clients.torrents.seedTime': IntegerField(app, 'TORRENT_SEED_TIME'),
+ 'clients.torrents.username': StringField(app, 'TORRENT_USERNAME'),
+ 'clients.torrents.verifySSL': BooleanField(app, 'TORRENT_VERIFY_CERT'),
+ 'clients.nzb.enabled': BooleanField(app, 'USE_NZBS'),
+ 'clients.nzb.dir': StringField(app, 'NZB_DIR'),
+ 'clients.nzb.method': StringField(app, 'NZB_METHOD'),
+ 'clients.nzb.nzbget.category': StringField(app, 'NZBGET_CATEGORY'),
+ 'clients.nzb.nzbget.categoryAnime': StringField(app, 'NZBGET_CATEGORY_ANIME'),
+ 'clients.nzb.nzbget.categoryAnimeBacklog': StringField(app, 'NZBGET_CATEGORY_ANIME_BACKLOG'),
+ 'clients.nzb.nzbget.categoryBacklog': StringField(app, 'NZBGET_CATEGORY_BACKLOG'),
+ 'clients.nzb.nzbget.host': StringField(app, 'NZBGET_HOST'),
+ 'clients.nzb.nzbget.password': StringField(app, 'NZBGET_PASSWORD'),
+ 'clients.nzb.nzbget.priority': IntegerField(app, 'NZBGET_PRIORITY'),
+ 'clients.nzb.nzbget.useHttps': BooleanField(app, 'NZBGET_USE_HTTPS'),
+ 'clients.nzb.nzbget.username': StringField(app, 'NZBGET_USERNAME'),
+ 'clients.nzb.sabnzbd.apiKey': StringField(app, 'SAB_APIKEY'),
+ 'clients.nzb.sabnzbd.category': StringField(app, 'SAB_CATEGORY'),
+ 'clients.nzb.sabnzbd.categoryAnime': StringField(app, 'SAB_CATEGORY_ANIME'),
+ 'clients.nzb.sabnzbd.categoryAnimeBacklog': StringField(app, 'SAB_CATEGORY_ANIME_BACKLOG'),
+ 'clients.nzb.sabnzbd.categoryBacklog': StringField(app, 'SAB_CATEGORY_BACKLOG'),
+ 'clients.nzb.sabnzbd.forced': BooleanField(app, 'SAB_FORCED'),
+ 'clients.nzb.sabnzbd.host': StringField(app, 'SAB_HOST'),
+ 'clients.nzb.sabnzbd.password': StringField(app, 'SAB_PASSWORD'),
+ 'clients.nzb.sabnzbd.username': StringField(app, 'SAB_USERNAME'),
'selectedRootIndex': IntegerField(app, 'SELECTED_ROOT'),
'layout.schedule': EnumField(app, 'COMING_EPS_LAYOUT', ('poster', 'banner', 'list', 'calendar'),
default_value='banner', post_processor=layout_schedule_post_processor),
@@ -534,46 +534,6 @@ def data_main():
section_data['failedDownloads']['enabled'] = bool(app.USE_FAILED_DOWNLOADS)
section_data['failedDownloads']['deleteFailed'] = bool(app.DELETE_FAILED)
- section_data['torrents'] = NonEmptyDict()
- section_data['torrents']['authType'] = app.TORRENT_AUTH_TYPE
- section_data['torrents']['dir'] = app.TORRENT_DIR
- section_data['torrents']['enabled'] = bool(app.USE_TORRENTS)
- section_data['torrents']['highBandwidth'] = app.TORRENT_HIGH_BANDWIDTH
- section_data['torrents']['host'] = app.TORRENT_HOST
- section_data['torrents']['label'] = app.TORRENT_LABEL
- section_data['torrents']['labelAnime'] = app.TORRENT_LABEL_ANIME
- section_data['torrents']['method'] = app.TORRENT_METHOD
- section_data['torrents']['path'] = app.TORRENT_PATH
- section_data['torrents']['paused'] = bool(app.TORRENT_PAUSED)
- section_data['torrents']['rpcurl'] = app.TORRENT_RPCURL
- section_data['torrents']['seedLocation'] = app.TORRENT_SEED_LOCATION
- section_data['torrents']['seedTime'] = app.TORRENT_SEED_TIME
- section_data['torrents']['username'] = app.TORRENT_USERNAME
- section_data['torrents']['verifySSL'] = bool(app.TORRENT_VERIFY_CERT)
-
- section_data['nzb'] = NonEmptyDict()
- section_data['nzb']['enabled'] = bool(app.USE_NZBS)
- section_data['nzb']['dir'] = app.NZB_DIR
- section_data['nzb']['method'] = app.NZB_METHOD
- section_data['nzb']['nzbget'] = NonEmptyDict()
- section_data['nzb']['nzbget']['category'] = app.NZBGET_CATEGORY
- section_data['nzb']['nzbget']['categoryAnime'] = app.NZBGET_CATEGORY_ANIME
- section_data['nzb']['nzbget']['categoryAnimeBacklog'] = app.NZBGET_CATEGORY_ANIME_BACKLOG
- section_data['nzb']['nzbget']['categoryBacklog'] = app.NZBGET_CATEGORY_BACKLOG
- section_data['nzb']['nzbget']['host'] = app.NZBGET_HOST
- section_data['nzb']['nzbget']['priority'] = app.NZBGET_PRIORITY
- section_data['nzb']['nzbget']['useHttps'] = bool(app.NZBGET_USE_HTTPS)
- section_data['nzb']['nzbget']['username'] = app.NZBGET_USERNAME
-
- section_data['nzb']['sabnzbd'] = NonEmptyDict()
- section_data['nzb']['sabnzbd']['category'] = app.SAB_CATEGORY
- section_data['nzb']['sabnzbd']['categoryAnime'] = app.SAB_CATEGORY_ANIME
- section_data['nzb']['sabnzbd']['categoryAnimeBacklog'] = app.SAB_CATEGORY_ANIME_BACKLOG
- section_data['nzb']['sabnzbd']['categoryBacklog'] = app.SAB_CATEGORY_BACKLOG
- section_data['nzb']['sabnzbd']['forced'] = bool(app.SAB_FORCED)
- section_data['nzb']['sabnzbd']['host'] = app.SAB_HOST
- section_data['nzb']['sabnzbd']['username'] = app.SAB_USERNAME
-
section_data['layout'] = NonEmptyDict()
section_data['layout']['schedule'] = app.COMING_EPS_LAYOUT
section_data['layout']['history'] = app.HISTORY_LAYOUT
@@ -951,3 +911,50 @@ def data_notifiers():
section_data['slack']['webhook'] = app.SLACK_WEBHOOK
return section_data
+
+ @staticmethod
+ def data_clients():
+ """Notifications."""
+ section_data = NonEmptyDict()
+
+ section_data['torrents'] = NonEmptyDict()
+ section_data['torrents']['authType'] = app.TORRENT_AUTH_TYPE
+ section_data['torrents']['dir'] = app.TORRENT_DIR
+ section_data['torrents']['enabled'] = bool(app.USE_TORRENTS)
+ section_data['torrents']['highBandwidth'] = bool(app.TORRENT_HIGH_BANDWIDTH)
+ section_data['torrents']['host'] = app.TORRENT_HOST
+ section_data['torrents']['label'] = app.TORRENT_LABEL
+ section_data['torrents']['labelAnime'] = app.TORRENT_LABEL_ANIME
+ section_data['torrents']['method'] = app.TORRENT_METHOD
+ section_data['torrents']['path'] = app.TORRENT_PATH
+ section_data['torrents']['paused'] = bool(app.TORRENT_PAUSED)
+ section_data['torrents']['rpcurl'] = app.TORRENT_RPCURL
+ section_data['torrents']['seedLocation'] = app.TORRENT_SEED_LOCATION
+ section_data['torrents']['seedTime'] = app.TORRENT_SEED_TIME
+ section_data['torrents']['username'] = app.TORRENT_USERNAME
+ section_data['torrents']['verifySSL'] = bool(app.TORRENT_VERIFY_CERT)
+
+ section_data['nzb'] = NonEmptyDict()
+ section_data['nzb']['enabled'] = bool(app.USE_NZBS)
+ section_data['nzb']['dir'] = app.NZB_DIR
+ section_data['nzb']['method'] = app.NZB_METHOD
+ section_data['nzb']['nzbget'] = NonEmptyDict()
+ section_data['nzb']['nzbget']['category'] = app.NZBGET_CATEGORY
+ section_data['nzb']['nzbget']['categoryAnime'] = app.NZBGET_CATEGORY_ANIME
+ section_data['nzb']['nzbget']['categoryAnimeBacklog'] = app.NZBGET_CATEGORY_ANIME_BACKLOG
+ section_data['nzb']['nzbget']['categoryBacklog'] = app.NZBGET_CATEGORY_BACKLOG
+ section_data['nzb']['nzbget']['host'] = app.NZBGET_HOST
+ section_data['nzb']['nzbget']['priority'] = int(app.NZBGET_PRIORITY)
+ section_data['nzb']['nzbget']['useHttps'] = bool(app.NZBGET_USE_HTTPS)
+ section_data['nzb']['nzbget']['username'] = app.NZBGET_USERNAME
+
+ section_data['nzb']['sabnzbd'] = NonEmptyDict()
+ section_data['nzb']['sabnzbd']['category'] = app.SAB_CATEGORY
+ section_data['nzb']['sabnzbd']['categoryAnime'] = app.SAB_CATEGORY_ANIME
+ section_data['nzb']['sabnzbd']['categoryAnimeBacklog'] = app.SAB_CATEGORY_ANIME_BACKLOG
+ section_data['nzb']['sabnzbd']['categoryBacklog'] = app.SAB_CATEGORY_BACKLOG
+ section_data['nzb']['sabnzbd']['forced'] = bool(app.SAB_FORCED)
+ section_data['nzb']['sabnzbd']['host'] = app.SAB_HOST
+ section_data['nzb']['sabnzbd']['username'] = app.SAB_USERNAME
+
+ return section_data
diff --git a/tests/apiv2/test_config.py b/tests/apiv2/test_config.py
index ad1de31b67..58c661809b 100644
--- a/tests/apiv2/test_config.py
+++ b/tests/apiv2/test_config.py
@@ -103,46 +103,6 @@ def config_main(monkeypatch, app_config):
config_data['failedDownloads']['enabled'] = bool(app.USE_FAILED_DOWNLOADS)
config_data['failedDownloads']['deleteFailed'] = bool(app.DELETE_FAILED)
- config_data['torrents'] = NonEmptyDict()
- config_data['torrents']['authType'] = app.TORRENT_AUTH_TYPE
- config_data['torrents']['dir'] = app.TORRENT_DIR
- config_data['torrents']['enabled'] = bool(app.USE_TORRENTS)
- config_data['torrents']['highBandwidth'] = app.TORRENT_HIGH_BANDWIDTH
- config_data['torrents']['host'] = app.TORRENT_HOST
- config_data['torrents']['label'] = app.TORRENT_LABEL
- config_data['torrents']['labelAnime'] = app.TORRENT_LABEL_ANIME
- config_data['torrents']['method'] = app.TORRENT_METHOD
- config_data['torrents']['path'] = app.TORRENT_PATH
- config_data['torrents']['paused'] = bool(app.TORRENT_PAUSED)
- config_data['torrents']['rpcurl'] = app.TORRENT_RPCURL
- config_data['torrents']['seedLocation'] = app.TORRENT_SEED_LOCATION
- config_data['torrents']['seedTime'] = app.TORRENT_SEED_TIME
- config_data['torrents']['username'] = app.TORRENT_USERNAME
- config_data['torrents']['verifySSL'] = bool(app.TORRENT_VERIFY_CERT)
-
- config_data['nzb'] = NonEmptyDict()
- config_data['nzb']['enabled'] = bool(app.USE_NZBS)
- config_data['nzb']['dir'] = app.NZB_DIR
- config_data['nzb']['method'] = app.NZB_METHOD
- config_data['nzb']['nzbget'] = NonEmptyDict()
- config_data['nzb']['nzbget']['category'] = app.NZBGET_CATEGORY
- config_data['nzb']['nzbget']['categoryAnime'] = app.NZBGET_CATEGORY_ANIME
- config_data['nzb']['nzbget']['categoryAnimeBacklog'] = app.NZBGET_CATEGORY_ANIME_BACKLOG
- config_data['nzb']['nzbget']['categoryBacklog'] = app.NZBGET_CATEGORY_BACKLOG
- config_data['nzb']['nzbget']['host'] = app.NZBGET_HOST
- config_data['nzb']['nzbget']['priority'] = app.NZBGET_PRIORITY
- config_data['nzb']['nzbget']['useHttps'] = bool(app.NZBGET_USE_HTTPS)
- config_data['nzb']['nzbget']['username'] = app.NZBGET_USERNAME
-
- config_data['nzb']['sabnzbd'] = NonEmptyDict()
- config_data['nzb']['sabnzbd']['category'] = app.SAB_CATEGORY
- config_data['nzb']['sabnzbd']['categoryAnime'] = app.SAB_CATEGORY_ANIME
- config_data['nzb']['sabnzbd']['categoryAnimeBacklog'] = app.SAB_CATEGORY_ANIME_BACKLOG
- config_data['nzb']['sabnzbd']['categoryBacklog'] = app.SAB_CATEGORY_BACKLOG
- config_data['nzb']['sabnzbd']['forced'] = bool(app.SAB_FORCED)
- config_data['nzb']['sabnzbd']['host'] = app.SAB_HOST
- config_data['nzb']['sabnzbd']['username'] = app.SAB_USERNAME
-
config_data['layout'] = NonEmptyDict()
config_data['layout']['schedule'] = app.COMING_EPS_LAYOUT
config_data['layout']['history'] = app.HISTORY_LAYOUT
diff --git a/themes-default/slim/src/components/helpers/config-textbox-number.vue b/themes-default/slim/src/components/helpers/config-textbox-number.vue
index abe922c974..8948661a7b 100644
--- a/themes-default/slim/src/components/helpers/config-textbox-number.vue
+++ b/themes-default/slim/src/components/helpers/config-textbox-number.vue
@@ -6,7 +6,7 @@
{{ label }}
@@ -46,6 +46,10 @@ export default {
type: Number,
default: 10
},
+ max: {
+ type: Number,
+ default: null
+ },
step: {
type: Number,
default: 1
@@ -53,6 +57,10 @@ export default {
placeholder: {
type: String,
default: ''
+ },
+ disabled: {
+ type: Boolean,
+ default: false
}
},
data() {
diff --git a/themes-default/slim/src/components/helpers/config-textbox.vue b/themes-default/slim/src/components/helpers/config-textbox.vue
index 220896c6b6..3724f8afa2 100644
--- a/themes-default/slim/src/components/helpers/config-textbox.vue
+++ b/themes-default/slim/src/components/helpers/config-textbox.vue
@@ -6,7 +6,7 @@
{{ label }}
@@ -39,6 +39,10 @@ export default {
type: String,
default: 'text'
},
+ disabled: {
+ type: Boolean,
+ default: false
+ },
/**
* Overwrite the default configured class on the element.
*/
diff --git a/themes-default/slim/src/components/helpers/select-list.vue b/themes-default/slim/src/components/helpers/select-list.vue
index 9a9870da54..63b133e27d 100644
--- a/themes-default/slim/src/components/helpers/select-list.vue
+++ b/themes-default/slim/src/components/helpers/select-list.vue
@@ -1,5 +1,5 @@
-
+
@@ -51,6 +51,10 @@ export default {
type: Boolean,
default: false,
required: false
+ },
+ disabled: {
+ type: Boolean,
+ default: false
}
},
data() {
diff --git a/themes-default/slim/src/store/index.js b/themes-default/slim/src/store/index.js
index 42515bd0f3..58800c14a1 100644
--- a/themes-default/slim/src/store/index.js
+++ b/themes-default/slim/src/store/index.js
@@ -3,12 +3,14 @@ import Vuex from 'vuex';
import VueNativeSock from 'vue-native-websocket';
import {
auth,
+ clients,
config,
defaults,
metadata,
notifications,
notifiers,
qualities,
+ search,
shows,
socket,
statuses
@@ -29,12 +31,14 @@ Vue.use(Vuex);
const store = new Store({
modules: {
auth,
+ clients,
config,
defaults,
metadata,
notifications,
notifiers,
qualities,
+ search,
shows,
socket,
statuses
diff --git a/themes-default/slim/src/store/modules/clients.js b/themes-default/slim/src/store/modules/clients.js
new file mode 100644
index 0000000000..dd4696aeec
--- /dev/null
+++ b/themes-default/slim/src/store/modules/clients.js
@@ -0,0 +1,68 @@
+import { ADD_CONFIG } from '../mutation-types';
+
+const state = {
+ torrents: {
+ authType: null,
+ dir: null,
+ enabled: null,
+ highBandwidth: null,
+ host: null,
+ label: null,
+ labelAnime: null,
+ method: null,
+ path: null,
+ paused: null,
+ rpcurl: null,
+ seedLocation: null,
+ seedTime: null,
+ username: null,
+ verifySSL: null,
+ testStatus: 'Click below to test'
+ },
+ nzb: {
+ enabled: null,
+ method: null,
+ nzbget: {
+ category: null,
+ categoryAnime: null,
+ categoryAnimeBacklog: null,
+ categoryBacklog: null,
+ host: null,
+ priority: null,
+ useHttps: null,
+ username: null,
+ testStatus: 'Click below to test'
+ },
+ sabnzbd: {
+ category: null,
+ forced: null,
+ categoryAnime: null,
+ categoryBacklog: null,
+ categoryAnimeBacklog: null,
+ host: null,
+ username: null,
+ password: null,
+ apiKey: null,
+ testStatus: 'Click below to test'
+ }
+ }
+};
+
+const mutations = {
+ [ADD_CONFIG](state, { section, config }) {
+ if (section === 'clients') {
+ state = Object.assign(state, config);
+ }
+ }
+};
+
+const getters = {};
+
+const actions = {};
+
+export default {
+ state,
+ mutations,
+ getters,
+ actions
+};
diff --git a/themes-default/slim/src/store/modules/config.js b/themes-default/slim/src/store/modules/config.js
index 7bcc2f2870..eae38d18ea 100644
--- a/themes-default/slim/src/store/modules/config.js
+++ b/themes-default/slim/src/store/modules/config.js
@@ -67,7 +67,9 @@ const state = {
categoryBacklog: null,
categoryAnimeBacklog: null,
host: null,
- username: null
+ username: null,
+ password: null,
+ apiKey: null
}
},
configFile: null,
diff --git a/themes-default/slim/src/store/modules/index.js b/themes-default/slim/src/store/modules/index.js
index 71d7612f61..bd4d313113 100644
--- a/themes-default/slim/src/store/modules/index.js
+++ b/themes-default/slim/src/store/modules/index.js
@@ -1,4 +1,5 @@
export { default as auth } from './auth';
+export { default as clients } from './clients';
export { default as config } from './config';
export { default as defaults } from './defaults';
export { default as metadata } from './metadata';
@@ -6,5 +7,6 @@ export { default as notifications } from './notifications';
export { default as notifiers } from './notifiers';
export { default as qualities } from './qualities';
export { default as shows } from './shows';
+export { default as search } from './search';
export { default as socket } from './socket';
export { default as statuses } from './statuses';
diff --git a/themes-default/slim/src/store/modules/search.js b/themes-default/slim/src/store/modules/search.js
new file mode 100644
index 0000000000..2347ba3ffa
--- /dev/null
+++ b/themes-default/slim/src/store/modules/search.js
@@ -0,0 +1,94 @@
+import { ADD_CONFIG } from '../mutation-types';
+
+const state = {
+ filters: {
+ ignoreUnknownSubs: false,
+ ignored: [
+ 'german',
+ 'french',
+ 'core2hd',
+ 'dutch',
+ 'swedish',
+ 'reenc',
+ 'MrLss',
+ 'dubbed'
+ ],
+ undesired: [
+ 'internal',
+ 'xvid'
+ ],
+ ignoredSubsList: [
+ 'dk',
+ 'fin',
+ 'heb',
+ 'kor',
+ 'nor',
+ 'nordic',
+ 'pl',
+ 'swe'
+ ],
+ required: [],
+ preferred: []
+ },
+ general: {
+ minDailySearchFrequency: 10,
+ minBacklogFrequency: 720,
+ dailySearchFrequency: 40,
+ checkPropersInterval: '4h',
+ usenetRetention: 500,
+ maxCacheAge: 30,
+ backlogDays: 7,
+ torrentCheckerFrequency: 60,
+ backlogFrequency: 720,
+ cacheTrimming: false,
+ deleteFailed: false,
+ downloadPropers: true,
+ useFailedDownloads: false,
+ minTorrentCheckerFrequency: 30,
+ removeFromClient: false,
+ randomizeProviders: false,
+ propersSearchDays: 2,
+ allowHighPriority: true,
+ trackersList: [
+ 'udp://tracker.coppersurfer.tk:6969/announce',
+ 'udp://tracker.leechers-paradise.org:6969/announce',
+ 'udp://tracker.zer0day.to:1337/announce',
+ 'udp://tracker.opentrackr.org:1337/announce',
+ 'http://tracker.opentrackr.org:1337/announce',
+ 'udp://p4p.arenabg.com:1337/announce',
+ 'http://p4p.arenabg.com:1337/announce',
+ 'udp://explodie.org:6969/announce',
+ 'udp://9.rarbg.com:2710/announce',
+ 'http://explodie.org:6969/announce',
+ 'http://tracker.dler.org:6969/announce',
+ 'udp://public.popcorn-tracker.org:6969/announce',
+ 'udp://tracker.internetwarriors.net:1337/announce',
+ 'udp://ipv4.tracker.harry.lu:80/announce',
+ 'http://ipv4.tracker.harry.lu:80/announce',
+ 'udp://mgtracker.org:2710/announce',
+ 'http://mgtracker.org:6969/announce',
+ 'udp://tracker.mg64.net:6969/announce',
+ 'http://tracker.mg64.net:6881/announce',
+ 'http://torrentsmd.com:8080/announce'
+ ]
+ }
+};
+
+const mutations = {
+ [ADD_CONFIG](state, { section, config }) {
+ if (section === 'search') {
+ state = Object.assign(state, config);
+ }
+ }
+};
+
+const getters = {};
+
+const actions = {};
+
+export default {
+ state,
+ mutations,
+ getters,
+ actions
+};
diff --git a/themes-default/slim/test/specs/config-textbox-number.spec.js b/themes-default/slim/test/specs/config-textbox-number.spec.js
index 2461ed6279..9c61be13fa 100644
--- a/themes-default/slim/test/specs/config-textbox-number.spec.js
+++ b/themes-default/slim/test/specs/config-textbox-number.spec.js
@@ -25,3 +25,24 @@ test('renders', t => {
t.snapshot(wrapper.html());
});
+
+test('renders with min and max', t => {
+ const { localVue } = t.context;
+ const wrapper = mount(ConfigTextboxNumber, {
+ localVue,
+ propsData: {
+ label: 'test-label',
+ explanations: [
+ 'explanation 1',
+ 'explanation 2'
+ ],
+ value: 30,
+ id: 'test-id',
+ min: 20,
+ step: 0.5,
+ max: 100
+ }
+ });
+
+ t.snapshot(wrapper.html());
+});
diff --git a/themes-default/slim/test/specs/snapshots/config-textbox-number.spec.js.md b/themes-default/slim/test/specs/snapshots/config-textbox-number.spec.js.md
index 15ce2dd22f..9ca843795c 100644
--- a/themes-default/slim/test/specs/snapshots/config-textbox-number.spec.js.md
+++ b/themes-default/slim/test/specs/snapshots/config-textbox-number.spec.js.md
@@ -9,3 +9,9 @@ Generated by [AVA](https://ava.li).
> Snapshot 1
''
+
+## renders with min and max
+
+> Snapshot 1
+
+ ''
diff --git a/themes-default/slim/test/specs/snapshots/config-textbox-number.spec.js.snap b/themes-default/slim/test/specs/snapshots/config-textbox-number.spec.js.snap
index 204ef93476..a2951ee2e6 100644
Binary files a/themes-default/slim/test/specs/snapshots/config-textbox-number.spec.js.snap and b/themes-default/slim/test/specs/snapshots/config-textbox-number.spec.js.snap differ
diff --git a/themes-default/slim/views/config_search.mako b/themes-default/slim/views/config_search.mako
index 4f362728ef..080829afba 100644
--- a/themes-default/slim/views/config_search.mako
+++ b/themes-default/slim/views/config_search.mako
@@ -17,7 +17,26 @@ window.app = new Vue({
el: '#vue-wrap',
data() {
return {
- clients: {
+ configLoaded: false,
+ checkPropersIntervalLabels: [
+ { text: '24 hours', value: 'daily' },
+ { text: '4 hours', value: '4h' },
+ { text: '90 mins', value: '90m' },
+ { text: '45 mins', value: '45m' },
+ { text: '24 hours', value: '15m' }
+ ],
+ nzbGetPriorityOptions: [
+ { text: 'Very low', value: -100 },
+ { text: 'Low', value: -50 },
+ { text: 'Normal', value: 0 },
+ { text: 'High', value: 50 },
+ { text: 'Very high', value: 100 },
+ { text: 'Force', value: 900 },
+
+ ],
+
+ // Static clients config
+ clientsConfig: {
torrent: {
blackhole: {
title: 'Black hole'
@@ -103,60 +122,126 @@ window.app = new Vue({
}
},
},
- torrent: {
- enabled: ${js_bool(app.USE_TORRENTS)},
- dir: ${json.dumps(app.TORRENT_DIR)},
- method: ${json.dumps(app.TORRENT_METHOD)},
- host: ${json.dumps(app.TORRENT_HOST)},
- rpcUrl: ${json.dumps(app.TORRENT_RPCURL)},
- username: ${json.dumps(app.TORRENT_USERNAME)},
- password: ${json.dumps(app.TORRENT_PASSWORD)},
- label: ${json.dumps(app.TORRENT_LABEL)},
- labelAnime: ${json.dumps(app.TORRENT_LABEL_ANIME)},
- path: ${json.dumps(app.TORRENT_PATH)},
- seedLocation: ${json.dumps(app.TORRENT_SEED_LOCATION)},
- seedTime: ${json.dumps(app.TORRENT_SEED_TIME)},
- testStatus: 'Click below to test',
- authType: ${json.dumps(app.TORRENT_AUTH_TYPE)},
- verifyCert: ${js_bool(app.TORRENT_VERIFY_CERT)},
- paused: ${js_bool(app.TORRENT_PAUSED)},
- highBandwidth: ${js_bool(app.TORRENT_HIGH_BANDWIDTH)},
- },
- nzb: {
- enabled: ${js_bool(app.USE_NZBS)},
- dir: ${json.dumps(app.NZB_DIR)},
- method: ${json.dumps(app.NZB_METHOD)},
- nzbget: {
- useHttps: ${js_bool(app.NZBGET_USE_HTTPS)},
- host: ${json.dumps(app.NZBGET_HOST)},
- username: ${json.dumps(app.NZBGET_USERNAME)},
- password: ${json.dumps(app.NZBGET_PASSWORD)},
+ // Mapped from state module: clients.js
+ clients: {
+ torrents: {
+ authType: null,
+ dir: null,
+ enabled: null,
+ highBandwidth: null,
+ host: null,
+ label: null,
+ labelAnime: null,
+ method: null,
+ path: null,
+ paused: null,
+ rpcurl: null,
+ seedLocation: null,
+ seedTime: null,
+ username: null,
+ verifySSL: null,
testStatus: 'Click below to test',
- category: ${json.dumps(app.NZBGET_CATEGORY)},
- categoryBacklog: ${json.dumps(app.NZBGET_CATEGORY_BACKLOG)},
- categoryAnime: ${json.dumps(app.NZBGET_CATEGORY_ANIME)},
- categoryAnimeBacklog: ${json.dumps(app.NZBGET_CATEGORY_ANIME_BACKLOG)},
- priority: ${app.NZBGET_PRIORITY},
- priorityOptions: {
- 'Very low': -100,
- 'Low': -50,
- 'Normal': 0,
- 'High': 50,
- 'Very high': 100,
- 'Force': 900
+ },
+ nzb: {
+ enabled: null,
+ method: null,
+ nzbget: {
+ category: null,
+ categoryAnime: null,
+ categoryAnimeBacklog: null,
+ categoryBacklog: null,
+ host: null,
+ priority: null,
+ useHttps: null,
+ username: null,
+ testStatus: 'Click below to test',
+ },
+ sabnzbd: {
+ category: null,
+ forced: null,
+ categoryAnime: null,
+ categoryBacklog: null,
+ categoryAnimeBacklog: null,
+ host: null,
+ username: null,
+ password: null,
+ apiKey: null,
+ testStatus: 'Click below to test',
}
+ }
+ },
+ // Mapped from state module: search.js
+ search: {
+ filters: {
+ ignoreUnknownSubs: false,
+ ignored: [
+ 'german',
+ 'french',
+ 'core2hd',
+ 'dutch',
+ 'swedish',
+ 'reenc',
+ 'MrLss',
+ 'dubbed'
+ ],
+ undesired: [
+ 'internal',
+ 'xvid'
+ ],
+ ignoredSubsList: [
+ 'dk',
+ 'fin',
+ 'heb',
+ 'kor',
+ 'nor',
+ 'nordic',
+ 'pl',
+ 'swe'
+ ],
+ required: [],
+ preferred: []
},
- sabnzbd: {
- host: ${json.dumps(app.SAB_HOST)},
- username: ${json.dumps(app.SAB_USERNAME)},
- password: ${json.dumps(app.SAB_PASSWORD)},
- apiKey: ${json.dumps(app.SAB_APIKEY)},
- testStatus: 'Click below to test',
- category: ${json.dumps(app.SAB_CATEGORY)},
- categoryBacklog: ${json.dumps(app.SAB_CATEGORY_BACKLOG)},
- categoryAnime: ${json.dumps(app.SAB_CATEGORY_ANIME)},
- categoryAnimeBacklog: ${json.dumps(app.SAB_CATEGORY_ANIME_BACKLOG)},
- forced: ${js_bool(app.SAB_FORCED)}
+ general: {
+ minDailySearchFrequency: 10,
+ minBacklogFrequency: 720,
+ dailySearchFrequency: 40,
+ checkPropersInterval: '4h',
+ usenetRetention: 500,
+ maxCacheAge: 30,
+ backlogDays: 7,
+ torrentCheckerFrequency: 60,
+ backlogFrequency: 720,
+ cacheTrimming: false,
+ deleteFailed: false,
+ downloadPropers: true,
+ useFailedDownloads: false,
+ minTorrentCheckerFrequency: 30,
+ removeFromClient: false,
+ randomizeProviders: false,
+ propersSearchDays: 2,
+ allowHighPriority: true,
+ trackersList: [
+ 'udp://tracker.coppersurfer.tk:6969/announce',
+ 'udp://tracker.leechers-paradise.org:6969/announce',
+ 'udp://tracker.zer0day.to:1337/announce',
+ 'udp://tracker.opentrackr.org:1337/announce',
+ 'http://tracker.opentrackr.org:1337/announce',
+ 'udp://p4p.arenabg.com:1337/announce',
+ 'http://p4p.arenabg.com:1337/announce',
+ 'udp://explodie.org:6969/announce',
+ 'udp://9.rarbg.com:2710/announce',
+ 'http://explodie.org:6969/announce',
+ 'http://tracker.dler.org:6969/announce',
+ 'udp://public.popcorn-tracker.org:6969/announce',
+ 'udp://tracker.internetwarriors.net:1337/announce',
+ 'udp://ipv4.tracker.harry.lu:80/announce',
+ 'http://ipv4.tracker.harry.lu:80/announce',
+ 'udp://mgtracker.org:2710/announce',
+ 'http://mgtracker.org:6969/announce',
+ 'udp://tracker.mg64.net:6969/announce',
+ 'http://tracker.mg64.net:6881/announce',
+ 'http://torrentsmd.com:8080/announce'
+ ]
}
},
httpAuthTypes: {
@@ -164,50 +249,56 @@ window.app = new Vue({
basic: 'Basic',
digest: 'Digest'
},
-
- // Episode Search: General Config
- randomizeProviders: ${js_bool(app.RANDOMIZE_PROVIDERS)},
- downloadPropers: ${js_bool(app.DOWNLOAD_PROPERS)},
- checkPropersInterval: ${json.dumps(app.CHECK_PROPERS_INTERVAL)},
- propersIntervalLabels: ${json.dumps(app.PROPERS_INTERVAL_LABELS)},
- propersSearchDays: ${app.PROPERS_SEARCH_DAYS},
- backlogDays: ${app.BACKLOG_DAYS},
- backlogFrequency: ${app.BACKLOG_FREQUENCY},
- minBacklogFrequency: ${app.MIN_BACKLOG_FREQUENCY},
- dailySearchFrequency: ${app.DAILYSEARCH_FREQUENCY},
- minDailySearchFrequency: ${app.MIN_DAILYSEARCH_FREQUENCY},
- removeFromClient: ${js_bool(app.REMOVE_FROM_CLIENT and app.TORRENT_METHOD in ('transmission', 'deluge', 'deluged'))},
- torrentCheckerFrequency: ${app.TORRENT_CHECKER_FREQUENCY},
- minTorrentCheckerFrequency: ${app.MIN_TORRENT_CHECKER_FREQUENCY},
- usenetRetention: ${app.USENET_RETENTION},
- trackersList: ${json.dumps(app.TRACKERS_LIST)}.join(', '),
- allowHighPriority: ${js_bool(app.ALLOW_HIGH_PRIORITY)},
- useFailedDownloads: ${js_bool(app.USE_FAILED_DOWNLOADS)},
- deleteFailed: ${js_bool(app.DELETE_FAILED)},
- cacheTrimming: ${js_bool(app.CACHE_TRIMMING)},
- maxCacheAge: ${app.MAX_CACHE_AGE},
-
- // Episode Search: Search Filters
- ignoreWords: ${json.dumps(app.IGNORE_WORDS)}.join(', '),
- undesiredWords: ${json.dumps(app.UNDESIRED_WORDS)}.join(', '),
- preferredWords: ${json.dumps(app.PREFERRED_WORDS)}.join(', '),
- requireWords: ${json.dumps(app.REQUIRE_WORDS)}.join(', '),
- ignoredSubsList: ${json.dumps(app.IGNORED_SUBS_LIST)}.join(', '),
- ignoreUndSubs: ${js_bool(app.IGNORE_UND_SUBS)},
-
- // Global
- dataDir: ${json.dumps(app.DATA_DIR)},
};
},
+ computed: {
+ stateSearch() {
+ return this.$store.state.search;
+ },
+ stateClients() {
+ return this.$store.state.clients;
+ },
+ torrentUsernameIsDisabled() {
+ const { clients } = this;
+ const { torrents } = clients;
+ const { host, method } = torrents;
+ let torrentHost = host || ''
+ if (!['rtorrent', 'deluge'].includes(method) || method === 'rtorrent' && !torrentHost.startsWith('scgi://')) {
+ return false;
+ }
+ return true;
+ },
+ torrentPasswordIsDisabled() {
+ const { clients } = this;
+ const { torrents } = clients;
+ const { host, method } = torrents;
+ let torrentHost = host || ''
+ if (method !== 'rtorrent' || method === 'rtorrent' && !torrentHost.startsWith('scgi://')) {
+ return false;
+ }
+ return true;
+ },
+ authTypeIsDisabled() {
+ const { clients } = this;
+ const { torrents } = clients;
+ const { host, method } = torrents;
+ let torrentHost = host || ''
+ if (method === 'rtorrent' && !torrentHost.startsWith('scgi://')) {
+ return false;
+ }
+ return true;
+ }
+ },
beforeMount() {
$('#config-components').tabs();
},
methods: {
async testTorrentClient() {
- const { torrent } = this;
- const { method, host, username, password } = torrent;
+ const { clients } = this;
+ const { torrents } = clients;
+ const { method, host, username, password } = torrents;
- this.torrent.testStatus = MEDUSA.config.loading;
+ this.clients.torrents.testStatus = MEDUSA.config.loading;
const params = {
torrent_method: method,
@@ -217,14 +308,15 @@ window.app = new Vue({
};
const resp = await apiRoute.get('home/testTorrent', { params });
- this.torrent.testStatus = resp.data;
+ this.clients.torrents.testStatus = resp.data;
},
async testNzbget() {
- const { nzb } = this;
+ const { clients } = this;
+ const { nzb } = clients;
const { nzbget } = nzb;
const { host, username, password, useHttps } = nzbget;
- this.nzb.nzbget.testStatus = MEDUSA.config.loading;
+ this.clients.nzb.nzbget.testStatus = MEDUSA.config.loading;
const params = {
host,
@@ -234,14 +326,15 @@ window.app = new Vue({
};
const resp = await apiRoute.get('home/testNZBget', { params });
- this.nzb.nzbget.testStatus = resp.data;
+ this.clients.nzb.nzbget.testStatus = resp.data;
},
async testSabnzbd() {
- const { nzb } = this;
+ const { clients } = this;
+ const { nzb } = clients;
const { sabnzbd } = nzb;
const { host, username, password, apiKey } = sabnzbd;
- this.nzb.sabnzbd.testStatus = MEDUSA.config.loading;
+ this.clients.nzb.sabnzbd.testStatus = MEDUSA.config.loading;
const params = {
host,
@@ -251,42 +344,85 @@ window.app = new Vue({
};
const resp = await apiRoute.get('home/testSABnzbd', { params });
- this.nzb.sabnzbd.testStatus = resp.data;
+ this.clients.nzb.sabnzbd.testStatus = resp.data;
+ },
+ save() {
+ const { $store, clients, configLoaded, search } = this;
+ // We want to wait until the page has been fully loaded, before starting to save stuff.
+ if (!configLoaded) {
+ return;
+ }
+ // Disable the save button until we're done.
+ this.saving = true;
+
+ // Clone the config into a new object
+ const config = Object.assign({}, {search}, {clients});
+
+ const section = 'main';
+ $store.dispatch('setConfig', { section, config }).then(() => {
+ this.$snotify.success(
+ 'Saved Search config',
+ 'Saved',
+ { timeout: 5000 }
+ );
+ }).catch(() => {
+ this.$snotify.error(
+ 'Error while trying to save search config',
+ 'Error'
+ );
+ });
}
},
watch: {
- 'torrent.host'(host) {
- const { torrent } = this;
- const { method } = torrent;
+ 'clients.torrents.host'(host) {
+ const { clients } = this;
+ const { torrents } = clients;
+ const { method } = torrents;
if (method === 'rtorrent') {
+ if (!host) {
+ return;
+ }
const isMatch = host.startsWith('scgi://');
if (isMatch) {
- this.torrent.username = '';
- this.torrent.password = '';
- this.torrent.authType = 'none';
+ this.clients.torrents.username = '';
+ this.clients.torrents.password = '';
+ this.clients.torrents.authType = 'none';
}
}
if (method === 'deluge') {
- this.torrent.username = '';
+ this.clients.torrents.username = '';
}
},
- 'torrent.method'(method) {
- if (!this.clients.torrent[method].removeFromClientOption) {
- this.removeFromClient = false;
+ 'clients.torrents.method'(method) {
+ if (!this.clientsConfig.torrent[method].removeFromClientOption) {
+ this.search.general.removeFromClient = false;
}
}
+ },
+ mounted() {
+ // The real vue stuff
+ // This is used to wait for the config to be loaded by the store.
+ this.$once('loaded', () => {
+ const { clients, search, stateClients, stateSearch } = this;
+
+ // Map the state values to local data.
+ this.search = Object.assign({}, search, stateSearch);
+ this.clients = Object.assign({}, clients, stateClients);
+ this.configLoaded = true;
+ });
}
});
%block>
<%block name="content">
+