Merge pull request #202 from WebTools-NG/#195-PMS-Settings

#195 pms settings
This commit is contained in:
Tommy Mikkelsen 2021-01-11 00:30:34 +01:00 committed by GitHub
commit 327c0452a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 501 additions and 23 deletions

View file

@ -90,6 +90,9 @@
"Settings": "Settings",
"Custom": "Custom Levels"
},
"PMS": {
"Settings": "Settings"
},
"About": {
"NavTitle": "About Us"
},
@ -120,6 +123,32 @@
}
},
"Modules": {
"PMS": {
"Name": "Plex Media Server",
"Description": "@:Modules.PMS.Name module allows you to manage your server",
"ErrorNoServerSelectedTitle": "No server selected",
"ErrorNoServerSelectedMsg": "You need to select a server on the top of the screen",
"Settings": {
"Settings": "Settings",
"Description": "Here you can define the settings for the selected server",
"SelectSettingsSelection": "Select Settings Group",
"TTSelectSettingsSelection": "Here you select the group the setting you want to alter is in",
"OnlyHidden": "Show only hidden settings",
"OnlyAdvanced": "Show only advanced settings",
"Undefined": "undefined",
"tblCaption": "Settings",
"tblName": "Name",
"tblLabel": "Label",
"tblSummary": "Summary",
"tblDefault": "Default",
"tblValue": "Value",
"tblType": "Type",
"newSettingTitle": "Enter the new setting for: {0}",
"curSetting": "Current Setting",
"defSetting": "Default Setting",
"newSettingValueTXT": "<Enter new value>"
}
},
"ET": {
"Custom": {
"Title": "Custom levels",

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

View file

@ -9,8 +9,9 @@
<script>
const log = require('electron-log');
console.log = log.log;
import '@fortawesome/fontawesome-free/css/all.css'
import etIcon from '@/assets/ET-256.png';
import '@fortawesome/fontawesome-free/css/all.css';
import etIcon from '@/assets/ET-256.png';
import pmsIcon from '@/assets/plex-pms-icon.png';
export default {
data() {
@ -31,6 +32,23 @@
title: this.$t("Common.Menu.Sidebar.NavSections.Tools"),
hiddenOnCollapse: true
},
{
href: { path: '/pms' },
title: this.$t("Modules.PMS.Name"),
// icon: 'fas fa-file-export',
icon: {
//adjust element
element: 'img',
attributes: { src: pmsIcon },
},
child: [
{
href: '/pms/settings',
title: this.$t("Common.Menu.Sidebar.PMS.Settings"),
icon: 'fa fa-cog'
}
]
},
{
href: { path: '/export' },
title: this.$t("Modules.ET.Name"),

View file

@ -10,6 +10,8 @@
<dl>
<dt>{{ $t("Modules.ET.Name") }}</dt>
<dd>* {{ $t("Modules.ET.Description") }} </dd>
<dt>{{ $t("Modules.PMS.Name") }}</dt>
<dd>* {{ $t("Modules.PMS.Description") }} </dd>
</dl>
</div>
<b-modal ref="showUpdate" hide-footer v-bind:title=this.updateTitle >
@ -40,7 +42,7 @@ export default {
}
},
mounted() {
log.info("About Mounted");
log.info("Home Created");
this.checkLangUpdates();
this.UpdatePresent();
},

View file

@ -78,7 +78,7 @@ export default {
}
},
mounted() {
log.info("About Mounted");
log.info("Language Created");
this.getOnlineLangs();
},
methods: {

View file

@ -0,0 +1,61 @@
<template>
<div class="col-lg-10 col-md-12 col-xs-12">
<h3>{{ $t("Modules.PMS.Name") }} <br>
</h3>
{{ $t("Modules.PMS.Description") }}
<br />
</div>
</template>
<script>
import i18n from '../../../i18n';
import store from '../../../store';
import { wtconfig } from '../General/wtutils';
i18n, store, wtconfig
const log = require("electron-log");
export default {
data() {
return {
selLibraryWait: true,
btnDisable: true,
selMediaType: "movie",
selLibrary: "",
selLibraryOptions: [],
selLevel: "",
};
},
created() {
log.info("PMS Created");
this.serverSelected();
},
methods: {
async serverSelected() {
let serverCheck = this.$store.getters.getSelectedServer;
if (serverCheck == "none") {
log.debug("serverCheck is none");
this.$bvToast.toast(this.$t("Modules.PMS.ErrorNoServerSelectedMsg"), {
title: this.$t("Modules.PMS.ErrorNoServerSelectedTitle"),
autoHideDelay: 4000,
solid: true,
variant: 'primary',
toaster: 'b-toaster-bottom-right'
});
}
}
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
#sync-button {
margin-left: 1em;
}
</style>

View file

@ -0,0 +1,209 @@
<template>
<b-container fluid>
<div class="col-lg-10 col-md-12 col-xs-12">
<h1>{{ $t("Modules.PMS.Settings.Settings") }}</h1>
<p>{{ $t("Modules.PMS.Settings.Description") }}</p>
</div>
<div>
<b-form-group id="b-form-group">
<b-form-checkbox-group
stacked
:options="cbOptions"
v-model="cbSelected"
@change.native="changedOptions">
</b-form-checkbox-group>
</b-form-group>
</div>
<div class="d-flex align-items-center">
<b-form-group id="etLibraryGroup" v-bind:label="$t('Modules.PMS.Settings.SelectSettingsSelection')" label-size="lg" label-class="font-weight-bold pt-0">
<b-tooltip target="etLibraryGroup" triggers="hover">
{{ $t('Modules.PMS.Settings.TTSelectSettingsSelection') }}
</b-tooltip>
<b-form-select
v-model="selSection"
id="selSection"
v-on:change="getGroupSelectedItem"
:options="selSectionOptions"
name="selSection">
</b-form-select>
</b-form-group>
</div>
<div>
<b-modal ref="edtSetting" hide-footer v-bind:title=this.newSettingTitle >
<div class="d-block text-center">
{{ $t('Modules.PMS.Settings.curSetting') }}: {{this.curSetting}}
<br>
{{ $t('Modules.PMS.Settings.defSetting') }}: {{this.defSetting}}
<br>
<b-form-input
v-model="newSettingValue"
v-bind:placeholder=this.newSettingValueTXT >
</b-form-input>
</div>
<b-button class="mt-3" variant="outline-primary" block @click="saveNewSetting">{{ this.newSettingSaveTxt }}</b-button>
</b-modal>
</div>
<div>
<b-table
striped
hover
sticky-header
:items="settingsItems"
:fields="settingsFields"
caption-top
bordered
@row-clicked="tblRowClicked">
<template #table-caption>{{ $t('Modules.PMS.Settings.tblCaption') }}</template>
</b-table>
</div>
</b-container>
</template>
<script>
const log = require("electron-log");
const {JSONPath} = require('jsonpath-plus');
import {wtconfig} from '../../General/wtutils';
import i18n from '../../../../i18n';
import store from '../../../../store';
export default {
data() {
return {
newSettingTitle: "",
newSettingValueTXT: this.$t('Modules.PMS.Settings.newSettingValueTXT'),
newSettingSaveTxt: this.$t('Modules.ET.Custom.NewLevelSaveTxt'),
curSetting: "",
defSetting: "",
newSettingValue: "",
edtSettingKey: "",
selSectionOptions: [],
selSection : "",
cbSelected: [],
cbOptions: [
{ text: i18n.t('Modules.PMS.Settings.OnlyHidden'), value: 'OnlyHidden' },
{ text: i18n.t('Modules.PMS.Settings.OnlyAdvanced'), value: 'OnlyAdvanced' }
],
settingsFields: [
{name: { label: this.$i18n.t('Modules.PMS.Settings.tblName') }},
{label: { label: this.$i18n.t('Modules.PMS.Settings.tblLabel') }},
{summary: { label: this.$i18n.t('Modules.PMS.Settings.tblSummary') }},
{type: { label: this.$i18n.t('Modules.PMS.Settings.tblType') }},
{default: { label: this.$i18n.t('Modules.PMS.Settings.tblDefault') }},
{value: { label: this.$i18n.t('Modules.PMS.Settings.tblValue') }}
],
settingsItems: []
};
},
created() {
log.info("PMS Settings Created");
this.serverSelected();
this.getServerSettings();
this.getcbDefaults();
},
computed: {
selectedServerAddress: function(){
return this.$store.getters.getSelectedServerAddress;
}
},
methods: {
async saveNewSetting() {
log.debug(`Saving setting ${this.newSettingValue} for setting ${this.edtSettingKey}`);
// Contructing url
const url = this.$store.getters.getSelectedServerAddress + '/:/prefs/set?'
console.log('URL: ' + url)
await store.dispatch('setPMSSetting', {
Token: this.$store.getters.getAuthToken,
Address: this.$store.getters.getSelectedServerAddress,
Setting: this.edtSettingKey,
Value: this.newSettingValue});
// http://127.0.0.1:32400/:/prefs/set?LogNumFiles=30&X-Plex-Token=TOKEN
},
tblRowClicked(record) {
console.log('Ged Row clicked')
console.log('Ged2', record)
// Edit Setting
log.debug(`Edit Setting: ${record.name}`);
this.curSetting = record.value;
this.defSetting = record.default;
this.edtSettingKey = record.name;
this.newSettingTitle = i18n.t('Modules.PMS.Settings.newSettingTitle', [this.edtSettingKey]);
this.$refs['edtSetting'].show();
},
getGroupSelectedItem: function(myarg) {
log.debug(`Group changed to: ${myarg}`);
// Update the data table with new settings
const filteredResult = JSONPath({path: `$.${myarg}`, json: this.$store.getters.getPMSSettings})[0];
log.verbose(`filtered settings: ${JSON.stringify(filteredResult)}`);
this.settingsItems = [];
for (var i = 0; i < filteredResult.length; i++) {
var entry = {};
entry['name'] = JSONPath({path: `$.*~`, json: filteredResult[i]})[0];
entry['label'] = JSONPath({path: `$..label`, json: filteredResult[i]})[0];
entry['summary'] = JSONPath({path: `$..summary`, json: filteredResult[i]})[0];
entry['type'] = JSONPath({path: `$..type`, json: filteredResult[i]})[0];
entry['default'] = JSONPath({path: `$..default`, json: filteredResult[i]})[0];
entry['value'] = JSONPath({path: `$..value`, json: filteredResult[i]})[0];
this.settingsItems.push(entry);
}
},
async serverSelected() {
let serverCheck = this.$store.getters.getSelectedServer;
if (serverCheck == "none") {
log.debug("serverCheck is none");
this.$bvToast.toast(this.$t("Modules.PMS.ErrorNoServerSelectedMsg"), {
title: this.$t("Modules.PMS.ErrorNoServerSelectedTitle"),
autoHideDelay: 4000,
solid: true,
variant: 'primary',
toaster: 'b-toaster-bottom-right'
}
);
}
},
async getServerSettings() {
log.debug('Getting Server Settings');
await store.dispatch('fetchPMSSettings', {
Token: this.$store.getters.getAuthToken,
Address: this.$store.getters.getSelectedServerAddress});
log.debug('Options are: ' + JSON.stringify(Object.keys(this.$store.getters.getPMSSettings)))
this.selSectionOptions = Object.keys(this.$store.getters.getPMSSettings).sort();
},
changedOptions() {
log.debug('Updating OnlyHidden Setting');
//this.$nextTick(()=>{console.log(this.cbSelected);})
for( var cbItem of ["OnlyHidden", "OnlyAdvanced"]){
wtconfig.set("PMS." + cbItem, (this.cbSelected.includes(cbItem)))
}
this.getServerSettings();
},
getcbDefaults() {
log.debug('Get OnlyHidden Setting');
const cbItems = ["OnlyHidden", "OnlyAdvanced"];
for(let i = 0; i < cbItems.length; i++){
if (wtconfig.get("PMS." + cbItems[i], true)){
this.cbSelected.push(cbItems[i])
}
}
log.debug('CBOptions: ' + this.cbSelected)
}
}
};
</script>
<style scoped>
.outDirbox{
margin-right:10px;
}
#b-form-group{
margin-top: 20px;
}
</style>

View file

@ -1,14 +1,17 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../components/modules/Main/Login'
import Home from '../components/modules/Main/Home.vue'
import Export from '../components/modules/ExportTools/Export'
import Language from '../components/modules/Main/Language.vue'
import GlobalSettings from '../components/modules/Main/GlobalSettings'
import About from '../components/modules/Main/About'
import Store from '../store/index.js'
import ExportSettings from '../components/modules/ExportTools/Settings/settings'
import ExportCustom from '../components/modules/ExportTools/Custom/custom'
import Vue from 'vue';
import VueRouter from 'vue-router';
import Login from '../components/modules/Main/Login';
import Home from '../components/modules/Main/Home.vue';
import Export from '../components/modules/ExportTools/Export';
import ExportSettings from '../components/modules/ExportTools/Settings/settings';
import ExportCustom from '../components/modules/ExportTools/Custom/custom';
import PMS from '../components/modules/PMS/PMS';
import PMSSettings from '../components/modules/PMS/Settings/settings';
import Language from '../components/modules/Main/Language.vue';
import GlobalSettings from '../components/modules/Main/GlobalSettings';
import About from '../components/modules/Main/About';
import Store from '../store/index.js';
Vue.use(VueRouter)
const router = new VueRouter({
@ -52,6 +55,18 @@ Vue.use(VueRouter)
component: ExportCustom,
meta: {requiresAuth: true}
},
{
path: '/pms',
name: "pms",
component: PMS,
meta: {requiresAuth: true}
},
{
path: '/pms/settings',
name: "pmssettings",
component: PMSSettings,
meta: {requiresAuth: true}
},
{
path: '/language',
name: "language",

View file

@ -1,12 +1,13 @@
import Vue from 'vue'
import Vuex from 'vuex'
import Vue from 'vue';
import Vuex from 'vuex';
import VuexPersistence from 'vuex-persist';
import plextv from './modules/plextv'
import poeditor from './modules/poeditor'
import et from './modules/et'
import language from './modules/language'
import plextv from './modules/plextv';
import poeditor from './modules/poeditor';
import et from './modules/et';
import language from './modules/language';
import pms from './modules/pms';
Vue.use(Vuex)
Vue.use(Vuex);
const vuexLocal = new VuexPersistence({
storage: window.sessionStorage,
@ -24,7 +25,8 @@ export default new Vuex.Store({
plextv,
poeditor,
et,
language
language,
pms
},
plugins: [vuexLocal.plugin]
})

142
src/store/modules/pms.js Normal file
View file

@ -0,0 +1,142 @@
import axios from 'axios';
import {wtconfig, wtutils} from '../../components/modules/General/wtutils';
import i18n from '../../i18n';
const log = require('electron-log');
const {JSONPath} = require('jsonpath-plus');
const state = {
settings: {}
};
const mutations = {
UPDATE_PMS_SETTINGS(state, payload) {
state.settings = payload;
}
};
const getters = {
getPMSSettings: state => state.settings
}
const actions = {
async setPMSSetting({ commit }, payload) {
commit
let header = wtutils.PMSHeader;
header['X-Plex-Token'] = payload.Token;
const url = `${payload.Address}/:/prefs?${payload.Setting}=${payload.Value}`;
// https://192-168-1-9.650391d27095402bbc83cd077b71fbab.plex.direct:32400/:/prefs?iTunesLibraryXmlPath=testefrans
// https://192-168-1-9.650391d27095402bbc83cd077b71fbab.plex.direct:32400/:/prefs/set?iTunesLibraryXmlPath=ged
log.debug(`Setting new setting with url ${url}`);
await axios({
method: 'put',
url: url,
headers: header
})
.then((response) => {
log.debug('Response from setPMSSetting recieved')
response
})
.catch(function (error) {
if (error.response) {
log.error('setPMSSetting: ' + error.response.data)
alert(error.response.data.errors[0].code + " " + error.response.data.errors[0].message)
} else if (error.request) {
log.error('setPMSSetting: ' + error.request)
} else {
log.error('setPMSSetting: ' + error.message)
}
});
},
async fetchPMSSettings({ commit }, payload) {
let header = wtutils.PMSHeader;
header['X-Plex-Token'] = payload.Token;
const url = payload.Address + '/:/prefs';
await axios({
method: 'get',
url: url,
headers: header
})
.then((response) => {
log.debug('Response from fetchPlexServers recieved')
var filteredResult = {}
// filteredResult based on hidden or not
if (wtconfig.get('PMS.OnlyHidden', true) == true){
log.debug('Show only Hidden settings')
filteredResult = JSONPath({path: '$..Setting[?(@.hidden==true)]', json: response.data});
}
else {
log.debug('Show non-hidden settings as well')
filteredResult = JSONPath({path: '$..Setting', json: response.data})[0];
}
if (wtconfig.get('PMS.OnlyAdvanced', true) == true){
log.debug('Show only OnlyAdvanced settings')
filteredResult = JSONPath({path: '$.[?(@.advanced==true)]', json: filteredResult});
}
else {
log.debug('Show all settings');
}
// Reset PMSSettings
var PMSSettings = {};
// Create Array for undefined
PMSSettings[i18n.t('Modules.PMS.Settings.Undefined')] = [];
// Create Arrays for other categories
filteredResult.forEach(group => {
group = JSONPath({path: '$.group', json: group})[0]
if (group !== "") {
PMSSettings[group] = [];
}
})
// Get the single items
filteredResult.forEach(element => {
var id = JSONPath({path: '$.id', json: element});
var itemGroup = JSONPath({path: '$.group', json: element});
if (itemGroup == "")
{
itemGroup = i18n.t('Modules.PMS.Settings.Undefined');
}
var PMSSettingsItem = {}
var jNode = {};
jNode['label'] = JSONPath({path: '$.label', json: element})[0];
jNode['summary'] = JSONPath({path: '$.summary', json: element})[0];
jNode['type'] = JSONPath({path: '$.type', json: element})[0];
jNode['default'] = JSONPath({path: '$.default', json: element})[0];
jNode['value'] = JSONPath({path: '$.value', json: element})[0];
PMSSettingsItem[id] = jNode;
PMSSettings[itemGroup].push(PMSSettingsItem)
});
// Remove undefined category, if empty
if (Object.keys(PMSSettings[i18n.t('Modules.PMS.Settings.Undefined')]).length === 0){
delete PMSSettings[i18n.t('Modules.PMS.Settings.Undefined')];
}
log.verbose(`PMS Settings are: ${JSON.stringify(PMSSettings)}`)
commit('UPDATE_PMS_SETTINGS', PMSSettings);
})
.catch(function (error) {
if (error.response) {
log.error('fetchPMSSettings: ' + error.response.data)
alert(error.response.data.errors[0].code + " " + error.response.data.errors[0].message)
} else if (error.request) {
log.error('fetchPMSSettings: ' + error.request)
} else {
log.error('fetchPMSSettings: ' + error.message)
}
});
}
};
const serverModule = {
state,
mutations,
actions,
getters
};
export default serverModule;