diff --git a/.babelrc b/.babelrc index a7d6696f..7011d488 100644 --- a/.babelrc +++ b/.babelrc @@ -1,18 +1,15 @@ { - "presets": [ - ["env", - { "modules": false } - ], + "presets": [ + [ "env", { "modules": false } ], "stage-2", "es2015", "es2016" ], - "plugins": [ - "transform-runtime"], + "plugins": ["transform-runtime"], "comments": false, "env": { "test": { - "presets": ["env", "stage-2"], + "presets": [ "env", "stage-2" ], "plugins": [ "istanbul" ] } } diff --git a/SettingsHelper.js b/SettingsHelper.js new file mode 100644 index 00000000..b9147515 --- /dev/null +++ b/SettingsHelper.js @@ -0,0 +1,31 @@ + +var jsonfile = require('jsonfile') + +module.exports = function () { + const fields = [ + 'webroot', + 'serverRoot', + 'accessUrl', + 'autoJoin', + 'autoJoinServer', + 'autoJoinRoom', + 'autoJoinPassword' + ] + // Load and export our settings in preference of ENV -> settings.json -> example_settings.json + let output = {} + let settingsFile + try { + settingsFile = require('./settings.json') + } catch (e) { + console.log('Creating default settings.json') + let defaults = require('./example_settings.json') + jsonfile.writeFileSync('./settings.json', defaults) + settingsFile = defaults + } + let defaults = require('./example_settings.json') + for (let i = 0; i < fields.length; i++) { + let setting = fields[i] + output[setting] = process.env[setting] || settingsFile[setting] || defaults[setting] + } + return output +} diff --git a/build/dev-server.js b/build/dev-server.js index 586ffedd..782dc6fc 100644 --- a/build/dev-server.js +++ b/build/dev-server.js @@ -2,7 +2,7 @@ require('./check-versions')() var config = require('../config') if (!process.env.NODE_ENV) { - process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) + process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) } var opn = require('opn') @@ -24,28 +24,28 @@ var app = express() var compiler = webpack(webpackConfig) var devMiddleware = require('webpack-dev-middleware')(compiler, { - publicPath: webpackConfig.output.publicPath, - quiet: true + publicPath: webpackConfig.output.publicPath, + quiet: true }) var hotMiddleware = require('webpack-hot-middleware')(compiler, { - log: () => {} + log: () => {} }) // force page reload when html-webpack-plugin template changes compiler.plugin('compilation', function (compilation) { - compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { - hotMiddleware.publish({ action: 'reload' }) - cb() - }) + compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { + hotMiddleware.publish({ action: 'reload' }) + cb() + }) }) // proxy api requests Object.keys(proxyTable).forEach(function (context) { - var options = proxyTable[context] - if (typeof options === 'string') { - options = { target: options } - } - app.use(proxyMiddleware(options.filter || context, options)) + var options = proxyTable[context] + if (typeof options === 'string') { + options = { target: options } + } + app.use(proxyMiddleware(options.filter || context, options)) }) // handle fallback for HTML5 history API @@ -66,24 +66,24 @@ var uri = 'http://localhost:' + port var _resolve var readyPromise = new Promise(resolve => { - _resolve = resolve + _resolve = resolve }) console.log('> Starting dev server...') devMiddleware.waitUntilValid(() => { - console.log('> Listening at ' + uri + '\n') - // when env is testing, don't need open it - if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { - opn(uri) - } - _resolve() + console.log('> Listening at ' + uri + '\n') + // when env is testing, don't need open it + if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { + opn(uri) + } + _resolve() }) var server = app.listen(port) module.exports = { - ready: readyPromise, - close: () => { - server.close() - } + ready: readyPromise, + close: () => { + server.close() + } } diff --git a/build/utils.js b/build/utils.js index 445a2022..b1d54b4d 100644 --- a/build/utils.js +++ b/build/utils.js @@ -3,69 +3,69 @@ var config = require('../config') var ExtractTextPlugin = require('extract-text-webpack-plugin') exports.assetsPath = function (_path) { - var assetsSubDirectory = process.env.NODE_ENV === 'production' - ? config.build.assetsSubDirectory - : config.dev.assetsSubDirectory - return path.posix.join(assetsSubDirectory, _path) + var assetsSubDirectory = process.env.NODE_ENV === 'production' + ? config.build.assetsSubDirectory + : config.dev.assetsSubDirectory + return path.posix.join(assetsSubDirectory, _path) } exports.cssLoaders = function (options) { - options = options || {} + options = options || {} - var cssLoader = { - loader: 'css-loader', - options: { - minimize: process.env.NODE_ENV === 'production', - sourceMap: options.sourceMap - } + var cssLoader = { + loader: 'css-loader', + options: { + minimize: process.env.NODE_ENV === 'production', + sourceMap: options.sourceMap + } + } + + // generate loader string to be used with extract text plugin + function generateLoaders (loader, loaderOptions) { + var loaders = [cssLoader] + if (loader) { + loaders.push({ + loader: loader + '-loader', + options: Object.assign({}, loaderOptions, { + sourceMap: options.sourceMap + }) + }) } - // generate loader string to be used with extract text plugin - function generateLoaders (loader, loaderOptions) { - var loaders = [cssLoader] - if (loader) { - loaders.push({ - loader: loader + '-loader', - options: Object.assign({}, loaderOptions, { - sourceMap: options.sourceMap - }) - }) - } - - // Extract CSS when that option is specified - // (which is the case during production build) - if (options.extract) { - return ExtractTextPlugin.extract({ - use: loaders, - fallback: 'vue-style-loader' - }) - } else { - return ['vue-style-loader'].concat(loaders) - } + // Extract CSS when that option is specified + // (which is the case during production build) + if (options.extract) { + return ExtractTextPlugin.extract({ + use: loaders, + fallback: 'vue-style-loader' + }) + } else { + return ['vue-style-loader'].concat(loaders) } + } - // https://vue-loader.vuejs.org/en/configurations/extract-css.html - return { - css: generateLoaders(), - postcss: generateLoaders(), - less: generateLoaders('less'), - sass: generateLoaders('sass', { indentedSyntax: true }), - scss: generateLoaders('sass'), - stylus: generateLoaders('stylus'), - styl: generateLoaders('stylus') - } + // https://vue-loader.vuejs.org/en/configurations/extract-css.html + return { + css: generateLoaders(), + postcss: generateLoaders(), + less: generateLoaders('less'), + sass: generateLoaders('sass', { indentedSyntax: true }), + scss: generateLoaders('sass'), + stylus: generateLoaders('stylus'), + styl: generateLoaders('stylus') + } } // Generate loaders for standalone style files (outside of .vue) exports.styleLoaders = function (options) { - var output = [] - var loaders = exports.cssLoaders(options) - for (var extension in loaders) { - var loader = loaders[extension] - output.push({ - test: new RegExp('\\.' + extension + '$'), - use: loader - }) - } - return output + var output = [] + var loaders = exports.cssLoaders(options) + for (var extension in loaders) { + var loader = loaders[extension] + output.push({ + test: new RegExp('\\.' + extension + '$'), + use: loader + }) + } + return output } diff --git a/config/index.js b/config/index.js index 45f8dff5..cc9f6c53 100644 --- a/config/index.js +++ b/config/index.js @@ -1,38 +1,41 @@ // see http://vuejs-templates.github.io/webpack for documentation. var path = require('path') +let SettingsHelper = require('../SettingsHelper.js') +let settings = new SettingsHelper() + module.exports = { - build: { - env: require('./prod.env'), - index: path.resolve(__dirname, '../dist/index.html'), - assetsRoot: path.resolve(__dirname, '../dist'), - assetsSubDirectory: '', - assetsPublicPath: '/', - productionSourceMap: true, - // Gzip off by default as many popular static hosts such as - // Surge or Netlify already gzip all static assets for you. - // Before setting to `true`, make sure to: - // npm install --save-dev compression-webpack-plugin - productionGzip: false, - productionGzipExtensions: ['js', 'css'], - // Run the build command with an extra argument to - // View the bundle analyzer report after build finishes: - // `npm run build --report` - // Set to `true` or `false` to always turn it on or off - bundleAnalyzerReport: process.env.npm_config_report - }, - dev: { - env: require('./dev.env'), - port: 8080, - autoOpenBrowser: true, - assetsSubDirectory: '', - assetsPublicPath: '/', - proxyTable: {}, - // CSS Sourcemaps off by default because relative paths are "buggy" - // with this option, according to the CSS-Loader README - // (https://github.com/webpack/css-loader#sourcemaps) - // In our experience, they generally work as expected, - // just be aware of this issue when enabling this option. - cssSourceMap: false - } + build: { + env: require('./prod.env'), + index: path.resolve(__dirname, '../dist/index.html'), + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: '', + assetsPublicPath: settings.webroot || '/', + productionSourceMap: true, + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + }, + dev: { + env: require('./dev.env'), + port: 8080, + autoOpenBrowser: true, + assetsSubDirectory: '', + assetsPublicPath: settings.webroot || '/', + proxyTable: {}, + // CSS Sourcemaps off by default because relative paths are "buggy" + // with this option, according to the CSS-Loader README + // (https://github.com/webpack/css-loader#sourcemaps) + // In our experience, they generally work as expected, + // just be aware of this issue when enabling this option. + cssSourceMap: false + } } diff --git a/example_settings.json b/example_settings.json index b84f647b..f4783684 100644 --- a/example_settings.json +++ b/example_settings.json @@ -1,14 +1,9 @@ { "webroot": "", "serverRoot": "", - "webapp_port": 8088, - "server_port": 8089, - "database": { - "datastores": { - "defaults": { - "adapter": "sails-disk", - "filePath": "./" - } - } - } + "accessUrl": "", + "autoJoin": false, + "autoJoinServer": "", + "autoJoinRoom": "", + "autoJoinPassword": "" } \ No newline at end of file diff --git a/server.js b/server.js index 675fefbe..60930ab0 100644 --- a/server.js +++ b/server.js @@ -10,6 +10,9 @@ var express = require('express') var cors = require('cors') +let SettingsHelper = require('./SettingsHelper') +let settings = new SettingsHelper() + var root = express() root.use(cors({ credentials: false })) root.use((req, res, next) => { @@ -18,7 +21,7 @@ root.use((req, res, next) => { }) var ptserver = express() -var PORT = process.env.port || 8089 +var PORT = process.env.server_port || 8089 // Setup our PTServer ptserver.get('/', (req, res) => { @@ -27,7 +30,7 @@ ptserver.get('/', (req, res) => { // Merge everything together -let serverRoot = '/' +let serverRoot = '/' || settings.serverRoot root.use(serverRoot, ptserver) root.get('*', function (req, res) { return res.send('You\'ve connected to the SLServer, you\'re probably looking for the webapp.') diff --git a/src/App.vue b/src/App.vue index 2d928e17..2c7a97f9 100644 --- a/src/App.vue +++ b/src/App.vue @@ -72,6 +72,9 @@ import leftsidebar from './leftsidebar' import upnext from './upnext' import donate from './donate' +let SettingsHelper = require('../SettingsHelper') +let settings = new SettingsHelper() + export default { components: { drawerright, @@ -145,15 +148,6 @@ export default { // Browser is not Chrome window.localStorage.setItem('EXTAVAILABLE', false) } - - if (process.env.autojoin && process.env.autojoin_room && process.env.autojoin_server) { - this.$store.commit('SET_AUTOJOIN', true) - this.$store.commit('SET_AUTOJOINROOM', process.env.autojoin_room) - this.$store.commit('SET_AUTOJOINURL', process.env.autojoin_server) - if (process.env.autojoin_password) { - this.$store.commit('SET_AUTOJOINPASSWORD', process.env.autojoin_password) - } - } if (this.$route.query.autojoin) { this.$store.commit('SET_AUTOJOIN', true) this.$store.commit('SET_AUTOJOINROOM', this.$route.query.room) @@ -197,8 +191,16 @@ export default { await this.$store.dispatch('PLEX_LOGIN_TOKEN', plexstorage.authToken) } catch (e) { console.log('Login failed', e) - this.$router.push('/signin') + return this.$router.push('/signin') } + if (settings.autoJoin) { + await this.$store.dispatch('autoJoin', { + server: settings.autoJoinServer, + password: settings.autoJoinPassword, + room: settings.autoJoinRoom + }) + } + // if (this.$store.getters.getAutoJoin) { // // Attempt to auto join // this.$store.dispatch('socketConnect', { diff --git a/src/router/index.js b/src/router/index.js index 2adbf48d..2da3a386 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -5,12 +5,15 @@ import signin from '../components/signin' import signout from '../components/signout' import join from '../components/join' +let SettingsHelper = require('../../SettingsHelper.js') +let settings = new SettingsHelper() + Vue.use(Router) // ==================== Router registration ==================== export default new Router({ mode: 'hash', - base: '/', + base: settings.webroot || '/', routes: [{ path: '/', meta: { diff --git a/src/store.js b/src/store.js index 3440d1ad..e0048de2 100644 --- a/src/store.js +++ b/src/store.js @@ -102,14 +102,11 @@ const mutations = { // We have a new chosen client, we need to stop return } - console.log('commandInProgress', commandInProgress) if (state.chosenClient.clientIdentifier !== 'PTPLAYER9PLUS10') { if (!commandInProgress) { state.chosenClient.getTimeline().then(() => { - console.log('Fetch timeline done') commandInProgress = false }).catch((e) => { - console.log('Fetch timeline done', e) commandInProgress = false }) commandInProgress = true diff --git a/src/store/modules/plex/actions.js b/src/store/modules/plex/actions.js index d4b52892..1ef0b87d 100644 --- a/src/store/modules/plex/actions.js +++ b/src/store/modules/plex/actions.js @@ -154,7 +154,6 @@ export default { for (let y in server.plexConnections) { let serverConnection = server.plexConnections[y] if (serverConnection.uri === clientConnection.uri) { - console.log('ADDING ACCESS TOKEN FOR MATCHING URL', client, server) client.accessToken = server.accessToken } } diff --git a/src/store/modules/synclounge.js b/src/store/modules/synclounge.js index 92f4f52b..89f3561d 100644 --- a/src/store/modules/synclounge.js +++ b/src/store/modules/synclounge.js @@ -2,6 +2,9 @@ const EventEmitter = require('events') var moment = require('moment') var axios = require('axios') +let SettingsHelper = require('../../../SettingsHelper.js') +let settings = new SettingsHelper() + function sendNotification (message) { return window.EventBus.$emit('notification', message) } @@ -179,8 +182,8 @@ export default { // Generate our short url/invite link console.log('generating our invite link') console.log(state) - - let urlOrigin = window.location.origin + console.log('Loaded settings', settings) + let urlOrigin = window.location.origin + (settings.webroot || '') if (process.env.NODE_ENV === 'development') { urlOrigin = 'http://localhost:8088' } diff --git a/waterline_settings.json b/waterline_settings.json index 126855e2..2a031026 100644 --- a/waterline_settings.json +++ b/waterline_settings.json @@ -1,40 +1,50 @@ { - "models": { - "invite": { + "waterline": { + "models": { + "invite": { + "attributes": { + "server": { + "type": "string", + "required": true + }, + "room": { + "type": "string", + "required": true + }, + "password": { + "type": "string" + }, + "owner": { + "type": "string", + "required": true + }, + "code": { + "type": "string" + }, + "fullUrl": { + "type": "string" + } + } + } + }, + "defaultModelSettings": { + "primaryKey": "id", + "datastore": "defaults", "attributes": { - "server": { - "type": "string", - "required": true - }, - "room": { - "type": "string", - "required": true - }, - "password": { - "type": "string" - }, - "owner": { - "type": "string", - "required": true - }, - "code": { - "type": "string" - }, - "fullUrl": { - "type": "string" + "id": { + "type": "number", + "autoMigrations": { + "autoIncrement": true + } } } - } - }, - "defaultModelSettings": { - "primaryKey": "id", - "datastore": "defaults", - "attributes": { - "id": { - "type": "number", - "autoMigrations": { - "autoIncrement": true - } + } + }, + "database": { + "datastores": { + "defaults": { + "adapter": "sails-disk", + "filePath": "./" } } } diff --git a/webapp.js b/webapp.js index 53b75062..a17a11b4 100644 --- a/webapp.js +++ b/webapp.js @@ -6,49 +6,39 @@ var express = require('express') var path = require('path') var cors = require('cors') -var jsonfile = require('jsonfile') var bodyParser = require('body-parser') var Waterline = require('waterline') var WaterlineMysql = require('waterline-mysql') var SailsDisk = require('sails-disk') -let settings = {} +let SettingsHelper = require('./SettingsHelper') +let settings = new SettingsHelper() +console.log('Settings', settings) var accessIp = '' var PORT = 8088 const bootstrap = () => { return new Promise(async (resolve, reject) => { - try { - settings = require('./settings.json') - } catch (e) { - console.log(e) - console.log('Creating default settings.json') - let defaults = require('./example_settings.json') - jsonfile.writeFileSync('./settings.json', defaults) - await new Promise((resolve, reject) => { - setTimeout(() => resolve(), 500) - }) - settings = require('./settings.json') - } const args = require('args-parser')(process.argv) - if (!args['url'] && !process.env.url) { - console.log('Missing required argument -url. EG. "node webapp.js --url=http://example.com/ptweb". This URL is used for redirecting invite links.') + if (!args['accessUrl'] && !settings.accessUrl) { + console.log('Missing required argument -accessUrl. EG. "node webapp.js --accessUrl=http://sl.example.com". This URL is used for redirecting invite links.') return reject(new Error('Missing URL for invite links')) } - accessIp = args['url'] || process.env.url // EG 'http://95.231.444.12:8088/ptweb' or 'http://example.com/ptweb' - if (args['port'] || process.env.port || settings.webapp_port) { - PORT = args['port'] || process.env.port || settings.webapp_port + accessIp = args['url'] || settings.accessUrl// EG 'http://95.231.444.12:8088/slweb' or 'http://example.com/slweb' + if (args['webapp_port'] || process.env.webapp_port) { + PORT = args['webapp_port'] || process.env.webapp_port } else { console.log('Defaulting webapp to port 8088') } PORT = parseInt(PORT) let baseSettings = require('./waterline_settings.json') - baseSettings.adapters = { + console.log('Basesettings', baseSettings) + baseSettings.waterline.adapters = { 'waterline-mysql': WaterlineMysql, 'sails-disk': SailsDisk } - baseSettings.datastores = settings.database.datastores - baseSettings.models.invite.beforeCreate = async (data, cb) => { + baseSettings.waterline.datastores = baseSettings.database.datastores + baseSettings.waterline.models.invite.beforeCreate = async (data, cb) => { console.log('Creating Invite', data) let fullUrl let params = { @@ -68,7 +58,7 @@ const bootstrap = () => { data.code = (0 | Math.random() * 9e6).toString(36) cb() } - Waterline.start(baseSettings, (err, orm) => { + Waterline.start(baseSettings.waterline, (err, orm) => { if (err) { return reject(err) } @@ -82,7 +72,7 @@ const app = async (orm) => { root.use(cors()) root.use(bodyParser()) // Setup our web app - root.use(settings.webroot + '/', express.static(path.join(__dirname, 'dist'))) + root.use((settings.webroot) + '/', express.static(path.join(__dirname, 'dist'))) root.get(settings.webroot + '/invite/:id', async (req, res) => { console.log('handling an invite', req.params.id) let shortObj = await Waterline.getModel('invite', orm).findOne({ code: req.params.id })