From b3e2fe85bc2bf968c3fe3fcf51bc67675c6f7552 Mon Sep 17 00:00:00 2001 From: WEBER Antoine Date: Fri, 9 Oct 2015 21:12:23 +0200 Subject: [PATCH] creation du menu avec tray icon --- bin/www | 114 ----------------------------------- index.html | 13 ++++ app.js => js/build_server.js | 24 ++++---- js/clustering.js | 113 ++++++++++++++++++++++++++++++++++ js/custom-tray-menu.js | 112 ++++++++++++++++++++++++++++++++++ js/startup.js | 53 ++++++++++++++++ package.json | 20 ++++-- public/icon.png | Bin 0 -> 369 bytes views/custom-tray-menu.html | 100 ++++++++++++++++++++++++++++++ 9 files changed, 419 insertions(+), 130 deletions(-) delete mode 100755 bin/www create mode 100644 index.html rename app.js => js/build_server.js (75%) create mode 100644 js/clustering.js create mode 100644 js/custom-tray-menu.js create mode 100644 js/startup.js create mode 100644 public/icon.png create mode 100644 views/custom-tray-menu.html diff --git a/bin/www b/bin/www deleted file mode 100755 index 015a6e5..0000000 --- a/bin/www +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env node - //On commence par la mise en cluster - var cluster = require('cluster'); - - // Code to run if we're in the master process - if (cluster.isMaster) { - // Count the machine's CPUs - var cpuCount = require('os').cpus().length; - - // Create a worker for each CPU - for (var i = 0; i < cpuCount; i += 1) { - console.log('Création du fork ' + i); - cluster.fork(); - } - - // Listen for dying workers - cluster.on('exit', function (worker) { - // Replace the dead worker, we're not sentimental - console.log('Worker ' + worker.id + ' died :('); - cluster.fork(); - console.log('Remplacement du worker '); - }); - - // Code to run if we're in a worker process - } else { - /** - * Module dependencies. - */ - var app = require('../app'); - var debug = require('debug')('plex_webdown:server'); - var http = require('http'); - - /** - * Get port from environment and store in Express. - */ - - var port = normalizePort(process.env.PORT || '3000'); - app.set('port', port); - - /** - * Create HTTP server. - */ - - var server = http.createServer(app); - - /** - * Listen on provided port, on all network interfaces. - */ - - server.listen(port); - server.on('error', onError); - server.on('listening', onListening); -} - - -/** - * Normalize a port into a number, string, or false. - */ - -function normalizePort(val) { - var port = parseInt(val, 10); - - if (isNaN(port)) { - // named pipe - return val; - } - - if (port >= 0) { - // port number - return port; - } - - return false; -} - -/** - * Event listener for HTTP server "error" event. - */ - -function onError(error) { - if (error.syscall !== 'listen') { - throw error; - } - - var bind = typeof port === 'string' - ? 'Pipe ' + port - : 'Port ' + port; - - // handle specific listen errors with friendly messages - switch (error.code) { - case 'EACCES': - console.error(bind + ' requires elevated privileges'); - process.exit(1); - break; - case 'EADDRINUSE': - console.error(bind + ' is already in use'); - process.exit(1); - break; - default: - throw error; - } -} - -/** - * Event listener for HTTP server "listening" event. - */ - -function onListening() { - var addr = server.address(); - var bind = typeof addr === 'string' - ? 'pipe ' + addr - : 'port ' + addr.port; - debug('Listening on ' + bind); -} diff --git a/index.html b/index.html new file mode 100644 index 0000000..f07a4d7 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + PLEX Web Downloader + + + + +
+ +
+ + diff --git a/app.js b/js/build_server.js similarity index 75% rename from app.js rename to js/build_server.js index 9a71faf..d9ffe01 100644 --- a/app.js +++ b/js/build_server.js @@ -4,12 +4,12 @@ var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); -var config = require('./config'); +var config = require('../config'); var app = express(); // view engine setup -app.set('views', path.join(__dirname, 'views')); +app.set('views', path.join(__dirname, '../views')); app.set('view engine', 'jade'); //protection par mot de passe @@ -37,22 +37,22 @@ app.use(function(req, res, next) { next(); }); -app.use(favicon(path.join(__dirname, 'public', 'iconarchive_plex.ico'))); +app.use(favicon(path.join(__dirname, '../public', 'iconarchive_plex.ico'))); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); -app.use(express.static(path.join(__dirname, 'public'))); +app.use(express.static(path.join(__dirname, '../public'))); -app.use('/', require('./routes/index')); -app.use('/users', require('./routes/users')); -app.use('/file', require('./routes/file')); -app.use('/channel', require('./routes/channel')); -app.use('/movie', require('./routes/movie')); -app.use('/show_list', require('./routes/show_list')); -app.use('/show', require('./routes/show')); -app.use('/divers', require('./routes/divers')); +app.use('/', require('../routes/index')); +app.use('/users', require('../routes/users')); +app.use('/file', require('../routes/file')); +app.use('/channel', require('../routes/channel')); +app.use('/movie', require('../routes/movie')); +app.use('/show_list', require('../routes/show_list')); +app.use('/show', require('../routes/show')); +app.use('/divers', require('../routes/divers')); // catch 404 and forward to error handler app.use(function(req, res, next) { diff --git a/js/clustering.js b/js/clustering.js new file mode 100644 index 0000000..75bc78f --- /dev/null +++ b/js/clustering.js @@ -0,0 +1,113 @@ +//On commence par la mise en cluster +var cluster = require('cluster'); + +// Code to run if we're in the master process +if (cluster.isMaster) { + // Count the machine's CPUs + var cpuCount = require('os').cpus().length; + + // Create a worker for each CPU + for (var i = 0; i < cpuCount; i += 1) { + console.log('Création du fork ' + i); + cluster.fork(); + } + + // Listen for dying workers + cluster.on('exit', function (worker) { + // Replace the dead worker, we're not sentimental + console.log('Worker ' + worker.id + ' died :('); + cluster.fork(); + console.log('Remplacement du worker '); + }); + +// Code to run if we're in a worker process +} else { + /** + * Module dependencies. + */ + var app = require('./build_server'); + var debug = require('debug')('plex_webdown:server'); + var http = require('http'); + + /** + * Get port from environment and store in Express. + */ + + var port = normalizePort(process.env.PORT || '3000'); + app.set('port', port); + + /** + * Create HTTP server. + */ + + var server = http.createServer(app); + + /** + * Listen on provided port, on all network interfaces. + */ + + server.listen(port); + server.on('error', onError); + server.on('listening', onListening); +} + + +/** +* Normalize a port into a number, string, or false. +*/ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** +* Event listener for HTTP server "error" event. +*/ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** +* Event listener for HTTP server "listening" event. +*/ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + debug('Listening on ' + bind); +} diff --git a/js/custom-tray-menu.js b/js/custom-tray-menu.js new file mode 100644 index 0000000..a19a910 --- /dev/null +++ b/js/custom-tray-menu.js @@ -0,0 +1,112 @@ +"use strict"; +var gui = global.window.nwDispatcher.requireNwGui(); +var util = require('util'); + +class CustomTrayMenu { + constructor(windowPath, trayIcon, windowOptions) { + this.shown = false; + this.iconWidth = 12; + + //valeur par défaut + this.trayIcon = trayIcon || 'tray2.png'; + this.menuWindowPath = windowPath || 'custom-tray-menu.html'; + this.menuWndowOptions = windowOptions || { + width: 185, + height: 143 + }; + + this._initTray(); + this._initMenuWindow(); + + this.tray.on('click', this.toggleTrayMenuAt.bind(this)); + } + + // remove tray, cose custom menu window + remove() { + this.tray.remove(); + this.tray = null; + this.trayMenu.close(); + process.emit('log', 'Remove tray icon'); + } + + _initTray() { + this.tray = new gui.Tray({ + title: '', + icon: this.trayIcon, + alticon: '', + tooltip: window.document.title, + iconsAreTemplates: false + }); + process.emit('log', 'Add tray icon'); + } + + _initMenuWindow() { + var windowOptions = util._extend({ + width: 200, + height: 100, + frame: false, + transparent: true, + resizable: false, + toolbar: false, + show: false, + 'show_in_taskbar': process.platform == "darwin" + }, this.menuWndowOptions); + + this.trayMenu = gui.Window.open(this.menuWindowPath, windowOptions); + + // add class to new window's body to apply platform specific css + this.trayMenu.on('document-end', function() { + this.trayMenu.window.document.body.className += ' ' + process.platform; + process.emit('log', "Adding class " + process.platform); + }.bind(this)); + + this.trayMenu.on('blur', function () { + this.trayMenu.hide(); + this.shown = false; + process.emit('log', 'Hide custom menu'); + }.bind(this)); + + } + + // called when user click on tray icon + toggleTrayMenuAt(position) { + /*if (this.shown) { + this.trayMenu.hide(); // this will trigger listener added above + this.shown = false; + } else {*/ + this.translate(position); + this.trayMenu.moveTo(position.x, position.y); + //global.main_win.show(); + //global.main_win.focus(); + this.trayMenu.show(); + //this.trayMenu.focus(); + this.shown = true; + process.emit('log', 'Show custom menu'); + //} + } + + // calculdate position for window to appear + translate(pos) { + process.emit('log', "Click position: " + util.inspect(pos)); + if (process.platform == 'darwin') { + pos.x -= Math.floor(this.trayMenu.width / 2 - this.iconWidth); + } else { + pos.x -= Math.floor(this.trayMenu.width / 2); + // for windows can not make exac position, because we have position of click. Just move it 5px up + pos.y -= this._trayAreaIsTop(pos) ? 0 : this.trayMenu.height + this.iconWidth / 2 + 5; + } + } + + _trayAreaIsTop(pos) { + var screen; + if (gui.Screen.Init) gui.Screen.Init(); + function posInBounds(s) { + return pos.y > s.bounds.y && pos.y < (s.bounds.y + s.bounds.height) && + pos.x > s.bounds.x && pos.x < (s.bounds.x + s.bounds.width); + } + screen = gui.Screen.screens.filter(posInBounds)[0]; + return pos.y < (screen.bounds.y + screen.bounds.height) / 2; + } +} + +module.exports = CustomTrayMenu; diff --git a/js/startup.js b/js/startup.js new file mode 100644 index 0000000..0919ca6 --- /dev/null +++ b/js/startup.js @@ -0,0 +1,53 @@ +"use strict"; +var gui = require('nw.gui'); +var CustomTrayMenu = require('./js/custom-tray-menu'); +var win = gui.Window.get(); +global.main_win = win; + +// Extend application menu for Mac OS +if (process.platform == "darwin") { + var menu = new gui.Menu({type: "menubar"}); + menu.createMacBuiltin && menu.createMacBuiltin(window.document.title); + win.menu = menu; +} + +var $ = function (selector) { + return document.querySelector(selector); +} + +var customTray; + +customTray = new CustomTrayMenu('./views/custom-tray-menu.html', 'public/icon.png', { + width: 200, + height: 150 +}); + +// for nw-notify frameless windows +win.on('close', function() { + gui.App.quit(); +}); + +win.on('click',function(t){ + console.log(t); +}); + +// bring window to front when open via terminal +//win.focus(); +win.hide(); + +var writeLog = function (msg, type) { + console.log(msg); +}; + +process.on('log', function (message) { + writeLog(message); +}); + +//on lance l'application en commencant par la creation des cluster +//require('./clustering'); +var child_process = require('child_process'); + +// exec: spawns a shell. +child_process.exec('node js/clustering.js', function(error, stdout, stderr){ + console.log(stdout); +}); diff --git a/package.json b/package.json index 7540096..5bf8e6c 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,22 @@ { "name": "plex_webdown", - "version": "0.0.1", - "private": true, - "scripts": { - "start": "node ./bin/www" + "version": "0.1.0", + "main": "index.html", + "window": { + "show": true, + "frame": true, + "toolbar": false, + "focus": true, + "icon": "public/iconarchive_plex.ico", + "width": 550, + "height": 348 }, + "scripts": { + "start": "nw ." + }, + + "private": true, + "dependencies": { "basic-auth": "^1.0.3", "body-parser": "~1.13.2", diff --git a/public/icon.png b/public/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3d22edf40e16f9b9e7836563ac94cc225e344dd9 GIT binary patch literal 369 zcmV-%0gnEOP)As=6vr>gB||8grJtZfCnpL07~;^WQwNdKK}7l;Bsg@GQXGntICkn-Iu$8Jij$NM z8J$WIvA<_e2s>;#GJJ&=@;e7xmtB|8OJUoc0g5r&~YR6ybrF7NaZ zfhpZ@c&)*%Pw3jJ`GHDm`|554-XVqCf~4zOMl55D)!!>y?1|*c?_B-`j?9Jts%CmE P00000NkvXXu0mjf5}cvy literal 0 HcmV?d00001 diff --git a/views/custom-tray-menu.html b/views/custom-tray-menu.html new file mode 100644 index 0000000..8dfe426 --- /dev/null +++ b/views/custom-tray-menu.html @@ -0,0 +1,100 @@ + + + + +
+

Plex Web Downloader

+

+

+

+
+ +