diff --git a/README.md b/README.md index a34adf1..4f9d085 100644 --- a/README.md +++ b/README.md @@ -16,18 +16,20 @@ git clone https://forge.cadoles.com/wpetit/pitaya.git cd pitaya git checkout develop npm install -DEBUG=pitaya* NODE_ENV=development npm start +PITAYA_LOG_LEVEL=debug NODE_ENV=development npm start ``` ## Variables d'environnement Vous pouvez configurer le comportement de Pitaya en passant des variables d'environnement: -| Variable | Description | Valeurs possibles | Valeur par défaut | -|-------------------|------------------------------------|-------------------|------------------------| -| PITAYA_MODE | Mode d'exécution de Pitaya | launcher, edit | launcher | -| PITAYA_PROFILE | Chemin du fichier profil à charger | -- | ./default-profile.json | -| PITAYA_AS_DESKTOP | Afficher Pitaya en mode "Bureau" | 1, 0 | 0 | +| Variable | Description | Valeurs possibles | Valeur par défaut | +|-------------------|----------------------------------------|-------------------------------|-------------------------------| +| PITAYA_MODE | Mode d'exécution de Pitaya | launcher, edit | launcher | +| PITAYA_PROFILE | Chemin du fichier profil à charger | -- | ./default-profile.json | +| PITAYA_AS_DESKTOP | Afficher Pitaya en mode "Bureau" | 1, 0 | 0 | +| PITAYA_LOG_FILE | Enregistrer les logs dans un fichier | Chemin absolu vers un fichier | aucune (pas d'enregistrement) | +| PITAYA_LOG_LEVEL | Niveau de log | debug, info, error, fatal | info | ## Comment construire l'application depuis les sources diff --git a/css/style.css b/css/style.css index 6f81888..9282d28 100644 --- a/css/style.css +++ b/css/style.css @@ -190,6 +190,7 @@ html, body { width: 100%; height: 100%; flex-direction: column; + background-color: #f7f7f7; } .edit .title { diff --git a/default-profile.json b/default-profile.json index 4bf6228..e166422 100644 --- a/default-profile.json +++ b/default-profile.json @@ -57,4 +57,4 @@ } ], "_key": "item_1444480285021_0" -} \ No newline at end of file +} diff --git a/main.js b/main.js index ee5310c..8c4221f 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,7 @@ var app = require('app'); // Module to control application life. var BrowserWindow = require('browser-window'); // Module to create native browser window. var Menu = require('menu'); var isDev = process.env.NODE_ENV === 'development'; -var constants = require('./'+(isDev ? 'src': 'dist')+'/util/const'); +var constants = require('./'+(isDev ? 'src': 'dist')+'/util').Const; var mainWindow = null; @@ -14,7 +14,7 @@ app.on('window-all-closed', function() { app.on('ready', function() { // Create the browser window. var electronScreen = require('screen'); - var size = electronScreen.getPrimaryDisplay().size; + var workArea = electronScreen.getPrimaryDisplay().workArea; var asDesktop = process.env.PITAYA_AS_DESKTOP == 1; @@ -22,11 +22,11 @@ app.on('ready', function() { type: asDesktop ? 'desktop' : undefined, 'skip-taskbar': asDesktop, frame: !asDesktop, - width: asDesktop ? size.width : undefined, - height: asDesktop ? size.height : undefined, + width: asDesktop ? workArea.width : undefined, + height: asDesktop ? workArea.height : undefined, 'auto-hide-menu-bar': true, - x: asDesktop ? 0 : undefined, - y: asDesktop ? 0 : undefined, + x: asDesktop ? workArea.x : undefined, + y: asDesktop ? workArea.y : undefined, }); if(isDev) { diff --git a/package.json b/package.json index 50c7061..7c02a5f 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "react-dom": "^0.14.0", "react-redux": "^2.0.0", "redux": "^2.0.0", - "redux-thunk": "^0.1.0" + "redux-thunk": "^0.1.0", + "winston": "^1.1.2" } } diff --git a/src/components/common/app-icon.js b/src/components/common/app-icon.js index 0e8b6d9..4e49a5c 100644 --- a/src/components/common/app-icon.js +++ b/src/components/common/app-icon.js @@ -1,7 +1,7 @@ var React = require('react'); var Util = require('../../util'); var LazyLoad = require('../mixins/lazy-load'); -var debug = Util.Debug('common:app-icon'); +var logger = Util.Logger; var _ = require('lodash'); var LOADING_ICON = 'img/hourglass.svg'; @@ -66,7 +66,7 @@ module.exports = React.createClass({ var self = this; - debug('Search icon %s:%s', iconPath, theme); + logger.debug('Search icon %s:%s', iconPath, theme); Util.DesktopApps.findIcon(iconPath || DEFAULT_ICON, theme) .then(function(iconPath) { @@ -78,7 +78,7 @@ module.exports = React.createClass({ ; }) .then(function(iconPath) { - debug('Found icon %s', iconPath); + logger.debug('Found icon %s', iconPath); self.setState({ iconPath: iconPath }); }) ; diff --git a/src/components/edit/desktop-app-list.js b/src/components/edit/desktop-app-list.js index e080b33..807636f 100644 --- a/src/components/edit/desktop-app-list.js +++ b/src/components/edit/desktop-app-list.js @@ -1,8 +1,6 @@ var React = require('react'); -var Util = require('../../util'); var DesktopAppItem = require('./desktop-app-item.js'); var path = require('path'); -var debug = require('../../util/debug')('pitaya:desktop-app-list'); var DesktopAppList = React.createClass({ diff --git a/src/components/launcher/launcher-view.js b/src/components/launcher/launcher-view.js index 44a2748..975d330 100644 --- a/src/components/launcher/launcher-view.js +++ b/src/components/launcher/launcher-view.js @@ -5,7 +5,7 @@ var Nav = require('./nav.js'); var AnimateMixin = require('../mixins/animate'); var actions = require('../../store/actions'); var connect = require('react-redux').connect; -var debug = require('../../util/debug')('launcher-view'); +var logger = require('../../util/logger'); var CrossfadeImage = require('../common/crossfade-image'); var path = require('path'); @@ -90,7 +90,7 @@ var LauncherView = React.createClass({ if(item.exec) { - debug('Launching application "'+item.exec+'"...'); + logger.debug('Launching application "'+item.exec+'"...'); var el = evt.currentTarget; el.classList.add('pulse'); diff --git a/src/store/actions/common.js b/src/store/actions/common.js index c3002a9..2f02acb 100644 --- a/src/store/actions/common.js +++ b/src/store/actions/common.js @@ -10,8 +10,11 @@ exports.loadProfile = function(profilePath) { dispatch({ type: LOAD_PROFILE, profilePath: profilePath }); + Util.Logger.info('Loading profile "%s"', profilePath); + return Util.System.loadJSON(profilePath) .then(function(profile) { + Util.Logger.info('Profile loaded.'); dispatch({ type: LOAD_PROFILE_SUCCESS, profile: profile }); return profile; }) diff --git a/src/store/actions/edit.js b/src/store/actions/edit.js index 5f41925..82a916a 100644 --- a/src/store/actions/edit.js +++ b/src/store/actions/edit.js @@ -1,4 +1,5 @@ var Util = require('../../util'); +var logger = Util.Logger; var path = require('path'); var _ = require('lodash'); @@ -21,8 +22,11 @@ var UPDATE_PROFILE_ITEM = exports.UPDATE_PROFILE_ITEM = 'UPDATE_PROFILE_ITEM'; // Actions creators exports.loadDesktopApps = function() { + return function(dispatch, getState) { + logger.info('Loading desktop apps...'); + var baseDirs = global.process.env.XDG_DATA_DIRS.split(':').map(function(baseDir){ return path.join(baseDir, 'applications'); }); @@ -31,6 +35,7 @@ exports.loadDesktopApps = function() { return Util.DesktopApps.loadAllDesktopFiles(baseDirs) .then(function(desktopApps) { + logger.info('Desktop apps loaded.'); dispatch({ type: LOAD_DESKTOP_APPS_SUCCESS, desktopApps: desktopApps }); }) .catch(function(err) { @@ -46,6 +51,8 @@ exports.saveProfile = function(destPath, profile) { dispatch({ type: SAVE_PROFILE, profile: profile, path: destPath }); + logger.info('Saving profile to "%s"...', destPath); + var cleanedProfile = _.cloneDeep(profile); Util.Tree.walk(cleanedProfile, function(item) { @@ -56,6 +63,7 @@ exports.saveProfile = function(destPath, profile) { return Util.System.saveJSON(destPath, cleanedProfile) .then(function() { dispatch({ type: SAVE_PROFILE_SUCCESS, profile: profile, path: destPath }); + logger.info('Profile saved.'); }) .catch(function(err) { dispatch({ type: SAVE_PROFILE_FAILED, error: err }); diff --git a/src/store/actions/launcher.js b/src/store/actions/launcher.js index cf9eded..f6e9abb 100644 --- a/src/store/actions/launcher.js +++ b/src/store/actions/launcher.js @@ -1,4 +1,5 @@ var Util = require('../../util'); +var logger = Util.Logger; var RUN_APP = exports.RUN_APP = 'RUN_APP'; var RUN_APP_SUCCESS = exports.RUN_APP_SUCCESS = 'RUN_APP_SUCCESS'; @@ -8,6 +9,8 @@ exports.runApp = function(execPath) { return function(dispatch, getState) { + logger.info('Launching app "%s"', execPath); + dispatch({ type: RUN_APP, execPath: execPath }); return Util.System.runApp(execPath, { clearFreeDesktopFlags: true }) diff --git a/src/store/middlewares/logger.js b/src/store/middlewares/logger.js index 0982a90..fdeaf81 100644 --- a/src/store/middlewares/logger.js +++ b/src/store/middlewares/logger.js @@ -1,14 +1,14 @@ -var debug = require('../../util/debug')('store:logger'); +var logger = require('../../util').Logger; +var app = require('../../util').App; module.exports = function loggerMiddleware(store) { return function(next) { return function(action) { - debug('Action %j', action); - //debug('Store current state %j', store.getState()); + logger.debug('Action', action); next(action); - //debug('Store new state %j', store.getState()); if(action.error) { - console.error(action.error.stack || action.error); + logger.error(action.type, action.error); + return app.quit(1); } }; }; diff --git a/src/util/app.js b/src/util/app.js new file mode 100644 index 0000000..e1efa7b --- /dev/null +++ b/src/util/app.js @@ -0,0 +1,21 @@ +var ipc = require('ipc'); +var isMainProcess = process.type === 'browser'; + +var QUIT_CMD = 'app-util:quit'; + +exports.quit = function(exitCode) { + if(isMainProcess) { + process.exit(exitCode); + } else { + ipc.send(QUIT_CMD, exitCode); + } +}; + +// Main process, setup listeners +if(isMainProcess) { + + ipc.on(QUIT_CMD, function(evt, exitCode) { + exports.quit(exitCode); + }); + +} diff --git a/src/util/debug.js b/src/util/debug.js deleted file mode 100644 index b931e3f..0000000 --- a/src/util/debug.js +++ /dev/null @@ -1,7 +0,0 @@ -var debug = require('debug'); -var util = require('util'); - -module.exports = function createLogger(namespace) { - var logger = debug('pitaya:'+namespace); - return logger; -}; diff --git a/src/util/desktop-apps.js b/src/util/desktop-apps.js index 3645c9c..d6a6b69 100644 --- a/src/util/desktop-apps.js +++ b/src/util/desktop-apps.js @@ -1,6 +1,6 @@ var path = require('path'); var System = require('./system'); -var debug = require('./debug')('desktop-apps'); +var logger = require('./logger'); var Cache = require('./cache'); var promises = require('./promises'); @@ -80,18 +80,18 @@ exports.findIcon = function(iconName, themeName, size, themeIgnore) { var cachedIcon = iconCache.get([iconName, themeName, size]); if(cachedIcon) { - debug('Icon %s:%s:%s found in cache !', iconName, themeName, size); + logger.debug('Icon %s:%s:%s found in cache !', iconName, themeName, size); return Promise.resolve(cachedIcon); } themeIgnore = themeIgnore || []; if(themeIgnore.indexOf(themeIgnore) !== -1) { - debug('Theme %s already processed, ignoring...', themeName); + logger.debug('Theme %s already processed, ignoring...', themeName); return Promise.resolve(null); } themeIgnore.push(themeName); - debug('Finding icon %s:%s:%s...', iconName, themeName, size); + logger.debug('Searching icon %s:%s:%s...', iconName, themeName, size); if( ICON_REALPATH_REGEX.test(iconName) ) { return Promise.resolve(iconName); @@ -116,7 +116,7 @@ exports.findIcon = function(iconName, themeName, size, themeIgnore) { if(foundIcon) return foundIcon; - debug('No icon found. Search in parents...'); + logger.debug('No icon found. Search in parents...'); return exports.findParentsThemeIcon(iconName, themeName, size, themeIgnore) .then(function(iconPath) { @@ -154,7 +154,7 @@ exports.findParentsThemeIcon = function(iconName, themeName, size, themeIgnore) var parents = themeIndex['Icon Theme'].Inherits.split(','); - debug('Found parents %j', parents); + logger.debug('Found parents', {parents: parents}); return promises.seq(parents, function(themeName) { return exports.findIcon(iconName, themeName, size, themeIgnore); @@ -177,16 +177,16 @@ exports.findClosestSizeIcon = function(iconName, themeName, size) { var extPattern = '{svg,png}'; var filePattern = themeName+'/*/*/'+iconName+'.'+extPattern; - debug('File pattern %s', filePattern); + logger.debug('File pattern %s', filePattern); return System.findFiles(filePattern, {cwd: ICON_THEMES_ROOTDIR}) .then(function(iconFiles) { - debug('Found files %j', iconFiles); + logger.debug('Found files', {files: iconFiles}); var scalableIcon = iconFiles.reduce(function(scalableIcon, iconPath) { if(iconPath.indexOf('scalable') !== -1) { - debug('Found scalable icon %s', iconPath); + logger.debug('Found scalable icon %s', iconPath); scalableIcon = iconPath; } return scalableIcon; @@ -211,7 +211,7 @@ exports.findClosestSizeIcon = function(iconName, themeName, size) { }) .then(function(iconPath) { - debug('Closest icon %j', iconPath); + logger.debug('Closest icon', iconPath); return iconPath ? path.join(ICON_THEMES_ROOTDIR, iconPath) : null; }) ; @@ -229,7 +229,7 @@ exports.findClosestSizeIcon = function(iconName, themeName, size) { exports.findPixmapsIcon = function(iconName) { var filePattern = iconName+'.{svg,png}'; - debug('Looking for pixmap icon %s', filePattern); + logger.debug('Looking for pixmap icon %s', filePattern); return System.findFiles(filePattern, {cwd: PIXMAPS_ICONS_ROOTDIR}) .then(function(iconPaths) { iconPaths = iconPaths.map(function(iconPath) { @@ -268,7 +268,7 @@ exports._selectBestIcon = function(iconPaths) { } return iconSelection; }, {scalable: null, bitmap: null}); - debug('Icon selection %j', iconSelection); + logger.debug('Icon selection', iconSelection); return iconSelection.scalable || iconSelection.bitmap; }; diff --git a/src/util/index.js b/src/util/index.js index 9070008..97f1641 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -1,7 +1,8 @@ exports.System = require('./system'); exports.DesktopApps = require('./desktop-apps'); exports.Cache = require('./cache'); -exports.Debug = require('./debug'); +exports.Logger = require('./logger'); exports.Tree = require('./tree'); exports.Const = require('./const'); exports.Promises = require('./promises'); +exports.App = require('./app'); diff --git a/src/util/logger.js b/src/util/logger.js new file mode 100644 index 0000000..0409507 --- /dev/null +++ b/src/util/logger.js @@ -0,0 +1,18 @@ +var winston = require('winston'); +var logger = new winston.Logger({ exitOnError: true }); + +var logLevel = process.env.PITAYA_LOG_LEVEL || 'info'; +var logFile = process.env.PITAYA_LOG_FILE; + +logger.level = logLevel; + +logger.add(winston.transports.Console, { colorize: true }); + +if(logFile) { + logger.add(winston.transports.File, { + filename: logFile, + json: false + }); +} + +module.exports = logger;