瀏覽代碼

Merge branch 'feature/logs' into develop

feature/remote-launch
William Petit 3 年之前
父節點
當前提交
d8a0136a99

+ 8
- 6
README.md 查看文件

@@ -16,18 +16,20 @@ git clone https://forge.cadoles.com/wpetit/pitaya.git
16 16
 cd pitaya
17 17
 git checkout develop
18 18
 npm install
19
-DEBUG=pitaya* NODE_ENV=development npm start
19
+PITAYA_LOG_LEVEL=debug NODE_ENV=development npm start
20 20
 ```
21 21
 
22 22
 ## Variables d'environnement
23 23
 
24 24
 Vous pouvez configurer le comportement de Pitaya en passant des variables d'environnement:
25 25
 
26
-| Variable          | Description                        | Valeurs possibles | Valeur par défaut      |
27
-|-------------------|------------------------------------|-------------------|------------------------|
28
-| PITAYA_MODE       | Mode d'exécution de Pitaya         | launcher, edit    | launcher               |
29
-| PITAYA_PROFILE    | Chemin du fichier profil à charger | --                | ./default-profile.json |
30
-| PITAYA_AS_DESKTOP | Afficher Pitaya en mode "Bureau"   | 1, 0              | 0                      |
26
+| Variable          | Description                            | Valeurs possibles             | Valeur par défaut             |
27
+|-------------------|----------------------------------------|-------------------------------|-------------------------------|
28
+| PITAYA_MODE       | Mode d'exécution de Pitaya             | launcher, edit                | launcher                      |
29
+| PITAYA_PROFILE    | Chemin du fichier profil à charger     | --                            | ./default-profile.json        |
30
+| PITAYA_AS_DESKTOP | Afficher Pitaya en mode "Bureau"       | 1, 0                          | 0                             |
31
+| PITAYA_LOG_FILE   | Enregistrer les logs dans un fichier   | Chemin absolu vers un fichier | aucune (pas d'enregistrement) |
32
+| PITAYA_LOG_LEVEL  | Niveau de log                          | debug, info, error, fatal     | info                          |
31 33
 
32 34
 ## Comment construire l'application depuis les sources
33 35
 

+ 2
- 0
css/style.css 查看文件

@@ -104,6 +104,7 @@ html, body {
104 104
   font-size: 50px;
105 105
   color: #fff;
106 106
   text-shadow: 1px 1px #444;
107
+  z-index: 10;
107 108
 }
108 109
 
109 110
 .launcher .category-header > .category-label {
@@ -190,6 +191,7 @@ html, body {
190 191
   width: 100%;
191 192
   height: 100%;
192 193
   flex-direction: column;
194
+  background-color: #f7f7f7;
193 195
 }
194 196
 
195 197
 .edit .title {

+ 2
- 2
debian/changelog 查看文件

@@ -1,5 +1,5 @@
1
-pitaya (0.0.0) unstable; urgency=low
1
+pitaya (0.0.1) unstable; urgency=low
2 2
 
3
-  * Initial release (Closes: #nnnn)  <nnnn is the bug number of your ITP>
3
+  * Dev release
4 4
 
5 5
  -- William Petit <wpetit@cadoles.com>  Fri, 16 Oct 2015 15:57:03 +0200

+ 1
- 1
default-profile.json 查看文件

@@ -57,4 +57,4 @@
57 57
     }
58 58
   ],
59 59
   "_key": "item_1444480285021_0"
60
-}
60
+}

+ 10
- 6
main.js 查看文件

@@ -2,7 +2,7 @@ var app = require('app');  // Module to control application life.
2 2
 var BrowserWindow = require('browser-window');  // Module to create native browser window.
3 3
 var Menu = require('menu');
4 4
 var isDev = process.env.NODE_ENV === 'development';
5
-var constants = require('./'+(isDev ? 'src': 'dist')+'/util/const');
5
+var Util = require('./'+(isDev ? 'src': 'dist')+'/util');
6 6
 
7 7
 var mainWindow = null;
8 8
 
@@ -14,7 +14,7 @@ app.on('window-all-closed', function() {
14 14
 app.on('ready', function() {
15 15
   // Create the browser window.
16 16
   var electronScreen = require('screen');
17
-  var size = electronScreen.getPrimaryDisplay().size;
17
+  var workArea = electronScreen.getPrimaryDisplay().workArea;
18 18
 
19 19
   var asDesktop = process.env.PITAYA_AS_DESKTOP == 1;
20 20
 
@@ -22,11 +22,11 @@ app.on('ready', function() {
22 22
     type:  asDesktop ? 'desktop' : undefined,
23 23
     'skip-taskbar': asDesktop,
24 24
     frame: !asDesktop,
25
-    width: asDesktop ? size.width : undefined,
26
-    height: asDesktop ? size.height : undefined,
25
+    width: asDesktop ? workArea.width : undefined,
26
+    height: asDesktop ? workArea.height : undefined,
27 27
     'auto-hide-menu-bar': true,
28
-    x: asDesktop ? 0 : undefined,
29
-    y: asDesktop ? 0 : undefined,
28
+    x: asDesktop ? workArea.x : undefined,
29
+    y: asDesktop ? workArea.y : undefined,
30 30
   });
31 31
 
32 32
   if(isDev) {
@@ -41,3 +41,7 @@ app.on('ready', function() {
41 41
   });
42 42
 
43 43
 });
44
+
45
+process.on('exit', function(code) {
46
+  Util.Logger.info('Exiting with code "%s"', code || 0);
47
+});

+ 2
- 1
package.json 查看文件

@@ -31,6 +31,7 @@
31 31
     "react-dom": "^0.14.0",
32 32
     "react-redux": "^2.0.0",
33 33
     "redux": "^2.0.0",
34
-    "redux-thunk": "^0.1.0"
34
+    "redux-thunk": "^0.1.0",
35
+    "winston": "^1.1.2"
35 36
   }
36 37
 }

+ 3
- 3
src/components/common/app-icon.js 查看文件

@@ -1,7 +1,7 @@
1 1
 var React = require('react');
2 2
 var Util = require('../../util');
3 3
 var LazyLoad = require('../mixins/lazy-load');
4
-var debug = Util.Debug('common:app-icon');
4
+var logger = Util.Logger;
5 5
 var _ = require('lodash');
6 6
 
7 7
 var LOADING_ICON = 'img/hourglass.svg';
@@ -66,7 +66,7 @@ module.exports = React.createClass({
66 66
 
67 67
     var self = this;
68 68
 
69
-    debug('Search icon %s:%s', iconPath, theme);
69
+    logger.debug('Search icon %s:%s', iconPath, theme);
70 70
 
71 71
     Util.DesktopApps.findIcon(iconPath || DEFAULT_ICON, theme)
72 72
       .then(function(iconPath) {
@@ -78,7 +78,7 @@ module.exports = React.createClass({
78 78
         ;
79 79
       })
80 80
       .then(function(iconPath) {
81
-        debug('Found icon %s', iconPath);
81
+        logger.debug('Found icon %s', iconPath);
82 82
         self.setState({ iconPath: iconPath });
83 83
       })
84 84
     ;

+ 0
- 2
src/components/edit/desktop-app-list.js 查看文件

@@ -1,8 +1,6 @@
1 1
 var React = require('react');
2
-var Util = require('../../util');
3 2
 var DesktopAppItem = require('./desktop-app-item.js');
4 3
 var path = require('path');
5
-var debug = require('../../util/debug')('pitaya:desktop-app-list');
6 4
 
7 5
 var DesktopAppList = React.createClass({
8 6
 

+ 2
- 2
src/components/launcher/launcher-view.js 查看文件

@@ -5,7 +5,7 @@ var Nav = require('./nav.js');
5 5
 var AnimateMixin = require('../mixins/animate');
6 6
 var actions = require('../../store/actions');
7 7
 var connect = require('react-redux').connect;
8
-var debug = require('../../util/debug')('launcher-view');
8
+var logger = require('../../util/logger');
9 9
 var CrossfadeImage = require('../common/crossfade-image');
10 10
 var path = require('path');
11 11
 
@@ -90,7 +90,7 @@ var LauncherView = React.createClass({
90 90
 
91 91
     if(item.exec) {
92 92
 
93
-      debug('Launching application "'+item.exec+'"...');
93
+      logger.debug('Launching application "'+item.exec+'"...');
94 94
       var el = evt.currentTarget;
95 95
       el.classList.add('pulse');
96 96
 

+ 3
- 0
src/store/actions/common.js 查看文件

@@ -10,8 +10,11 @@ exports.loadProfile = function(profilePath) {
10 10
 
11 11
     dispatch({ type: LOAD_PROFILE, profilePath: profilePath });
12 12
 
13
+    Util.Logger.info('Loading profile "%s"', profilePath);
14
+
13 15
     return Util.System.loadJSON(profilePath)
14 16
       .then(function(profile) {
17
+        Util.Logger.info('Profile loaded.');
15 18
         dispatch({ type: LOAD_PROFILE_SUCCESS, profile: profile });
16 19
         return profile;
17 20
       })

+ 8
- 0
src/store/actions/edit.js 查看文件

@@ -1,4 +1,5 @@
1 1
 var Util = require('../../util');
2
+var logger = Util.Logger;
2 3
 var path = require('path');
3 4
 var _ = require('lodash');
4 5
 
@@ -21,8 +22,11 @@ var UPDATE_PROFILE_ITEM = exports.UPDATE_PROFILE_ITEM = 'UPDATE_PROFILE_ITEM';
21 22
 // Actions creators
22 23
 
23 24
 exports.loadDesktopApps = function() {
25
+
24 26
   return function(dispatch, getState) {
25 27
 
28
+    logger.info('Loading desktop apps...');
29
+
26 30
     var baseDirs = global.process.env.XDG_DATA_DIRS.split(':').map(function(baseDir){
27 31
       return path.join(baseDir, 'applications');
28 32
     });
@@ -31,6 +35,7 @@ exports.loadDesktopApps = function() {
31 35
 
32 36
     return Util.DesktopApps.loadAllDesktopFiles(baseDirs)
33 37
       .then(function(desktopApps) {
38
+        logger.info('Desktop apps loaded.');
34 39
         dispatch({ type: LOAD_DESKTOP_APPS_SUCCESS, desktopApps: desktopApps });
35 40
       })
36 41
       .catch(function(err) {
@@ -46,6 +51,8 @@ exports.saveProfile = function(destPath, profile) {
46 51
 
47 52
     dispatch({ type: SAVE_PROFILE, profile: profile, path: destPath });
48 53
 
54
+    logger.info('Saving profile to "%s"...', destPath);
55
+
49 56
     var cleanedProfile = _.cloneDeep(profile);
50 57
 
51 58
     Util.Tree.walk(cleanedProfile, function(item) {
@@ -56,6 +63,7 @@ exports.saveProfile = function(destPath, profile) {
56 63
     return Util.System.saveJSON(destPath, cleanedProfile)
57 64
       .then(function() {
58 65
         dispatch({ type: SAVE_PROFILE_SUCCESS, profile: profile, path: destPath });
66
+        logger.info('Profile saved.');
59 67
       })
60 68
       .catch(function(err) {
61 69
         dispatch({ type: SAVE_PROFILE_FAILED, error: err });

+ 3
- 0
src/store/actions/launcher.js 查看文件

@@ -1,4 +1,5 @@
1 1
 var Util = require('../../util');
2
+var logger = Util.Logger;
2 3
 
3 4
 var RUN_APP = exports.RUN_APP = 'RUN_APP';
4 5
 var RUN_APP_SUCCESS = exports.RUN_APP_SUCCESS = 'RUN_APP_SUCCESS';
@@ -8,6 +9,8 @@ exports.runApp = function(execPath) {
8 9
 
9 10
   return function(dispatch, getState) {
10 11
 
12
+    logger.info('Launching app "%s"', execPath);
13
+
11 14
     dispatch({ type: RUN_APP, execPath: execPath });
12 15
 
13 16
     return Util.System.runApp(execPath, { clearFreeDesktopFlags: true })

+ 4
- 5
src/store/middlewares/logger.js 查看文件

@@ -1,14 +1,13 @@
1
-var debug = require('../../util/debug')('store:logger');
1
+var logger = require('../../util').Logger;
2
+var app = require('../../util').App;
2 3
 
3 4
 module.exports = function loggerMiddleware(store) {
4 5
   return function(next) {
5 6
     return function(action) {
6
-      debug('Action %j', action);
7
-      //debug('Store current state %j', store.getState());
7
+      logger.debug('Action', action);
8 8
       next(action);
9
-      //debug('Store new state %j', store.getState());
10 9
       if(action.error) {
11
-        console.error(action.error.stack || action.error);
10
+        logger.error(action.type, action.error);
12 11
       }
13 12
     };
14 13
   };

+ 21
- 0
src/util/app.js 查看文件

@@ -0,0 +1,21 @@
1
+var ipc = require('ipc');
2
+var isMainProcess = process.type === 'browser';
3
+
4
+var QUIT_CMD = 'app-util:quit';
5
+
6
+exports.quit = function(exitCode) {
7
+  if(isMainProcess) {
8
+    process.exit(exitCode);
9
+  } else {
10
+    ipc.send(QUIT_CMD, exitCode);
11
+  }
12
+};
13
+
14
+// Main process, setup listeners
15
+if(isMainProcess) {
16
+
17
+  ipc.on(QUIT_CMD, function(evt, exitCode) {
18
+    exports.quit(exitCode);
19
+  });
20
+
21
+}

+ 0
- 7
src/util/debug.js 查看文件

@@ -1,7 +0,0 @@
1
-var debug = require('debug');
2
-var util = require('util');
3
-
4
-module.exports = function createLogger(namespace) {
5
-  var logger = debug('pitaya:'+namespace);
6
-  return logger;
7
-};

+ 12
- 12
src/util/desktop-apps.js 查看文件

@@ -1,6 +1,6 @@
1 1
 var path = require('path');
2 2
 var System = require('./system');
3
-var debug = require('./debug')('desktop-apps');
3
+var logger = require('./logger');
4 4
 var Cache = require('./cache');
5 5
 var promises = require('./promises');
6 6
 
@@ -80,18 +80,18 @@ exports.findIcon = function(iconName, themeName, size, themeIgnore) {
80 80
   var cachedIcon = iconCache.get([iconName, themeName, size]);
81 81
 
82 82
   if(cachedIcon) {
83
-    debug('Icon %s:%s:%s found in cache !', iconName, themeName, size);
83
+    logger.debug('Icon %s:%s:%s found in cache !', iconName, themeName, size);
84 84
     return Promise.resolve(cachedIcon);
85 85
   }
86 86
 
87 87
   themeIgnore = themeIgnore || [];
88 88
   if(themeIgnore.indexOf(themeIgnore) !== -1) {
89
-    debug('Theme %s already processed, ignoring...', themeName);
89
+    logger.debug('Theme %s already processed, ignoring...', themeName);
90 90
     return Promise.resolve(null);
91 91
   }
92 92
   themeIgnore.push(themeName);
93 93
 
94
-  debug('Finding icon %s:%s:%s...', iconName, themeName, size);
94
+  logger.debug('Searching icon %s:%s:%s...', iconName, themeName, size);
95 95
 
96 96
   if( ICON_REALPATH_REGEX.test(iconName) ) {
97 97
     return Promise.resolve(iconName);
@@ -116,7 +116,7 @@ exports.findIcon = function(iconName, themeName, size, themeIgnore) {
116 116
 
117 117
       if(foundIcon) return foundIcon;
118 118
 
119
-      debug('No icon found. Search in parents...');
119
+      logger.debug('No icon found. Search in parents...');
120 120
 
121 121
       return exports.findParentsThemeIcon(iconName, themeName, size, themeIgnore)
122 122
         .then(function(iconPath) {
@@ -154,7 +154,7 @@ exports.findParentsThemeIcon = function(iconName, themeName, size, themeIgnore)
154 154
 
155 155
           var parents = themeIndex['Icon Theme'].Inherits.split(',');
156 156
 
157
-          debug('Found parents %j', parents);
157
+          logger.debug('Found parents', {parents: parents});
158 158
 
159 159
           return promises.seq(parents, function(themeName) {
160 160
               return exports.findIcon(iconName, themeName, size, themeIgnore);
@@ -177,16 +177,16 @@ exports.findClosestSizeIcon = function(iconName, themeName, size) {
177 177
   var extPattern = '{svg,png}';
178 178
   var filePattern = themeName+'/*/*/'+iconName+'.'+extPattern;
179 179
 
180
-  debug('File pattern %s', filePattern);
180
+  logger.debug('File pattern %s', filePattern);
181 181
 
182 182
   return System.findFiles(filePattern, {cwd: ICON_THEMES_ROOTDIR})
183 183
     .then(function(iconFiles) {
184 184
 
185
-      debug('Found files %j', iconFiles);
185
+      logger.debug('Found files', {files: iconFiles});
186 186
 
187 187
       var scalableIcon = iconFiles.reduce(function(scalableIcon, iconPath) {
188 188
         if(iconPath.indexOf('scalable') !== -1) {
189
-          debug('Found scalable icon %s', iconPath);
189
+          logger.debug('Found scalable icon %s', iconPath);
190 190
           scalableIcon = iconPath;
191 191
         }
192 192
         return scalableIcon;
@@ -211,7 +211,7 @@ exports.findClosestSizeIcon = function(iconName, themeName, size) {
211 211
 
212 212
     })
213 213
     .then(function(iconPath) {
214
-      debug('Closest icon %j', iconPath);
214
+      logger.debug('Closest icon', iconPath);
215 215
       return iconPath ? path.join(ICON_THEMES_ROOTDIR, iconPath) : null;
216 216
     })
217 217
   ;
@@ -229,7 +229,7 @@ exports.findClosestSizeIcon = function(iconName, themeName, size) {
229 229
 
230 230
 exports.findPixmapsIcon = function(iconName) {
231 231
   var filePattern = iconName+'.{svg,png}';
232
-  debug('Looking for pixmap icon %s', filePattern);
232
+  logger.debug('Looking for pixmap icon %s', filePattern);
233 233
   return System.findFiles(filePattern, {cwd: PIXMAPS_ICONS_ROOTDIR})
234 234
     .then(function(iconPaths) {
235 235
       iconPaths = iconPaths.map(function(iconPath) {
@@ -268,7 +268,7 @@ exports._selectBestIcon = function(iconPaths) {
268 268
     }
269 269
     return iconSelection;
270 270
   }, {scalable: null, bitmap: null});
271
-  debug('Icon selection %j', iconSelection);
271
+  logger.debug('Icon selection', iconSelection);
272 272
   return iconSelection.scalable || iconSelection.bitmap;
273 273
 };
274 274
 

+ 2
- 1
src/util/index.js 查看文件

@@ -1,7 +1,8 @@
1 1
 exports.System = require('./system');
2 2
 exports.DesktopApps = require('./desktop-apps');
3 3
 exports.Cache = require('./cache');
4
-exports.Debug = require('./debug');
4
+exports.Logger = require('./logger');
5 5
 exports.Tree = require('./tree');
6 6
 exports.Const = require('./const');
7 7
 exports.Promises = require('./promises');
8
+exports.App = require('./app');

+ 24
- 0
src/util/logger.js 查看文件

@@ -0,0 +1,24 @@
1
+var winston = require('winston');
2
+var logger = new winston.Logger({ exitOnError: true });
3
+
4
+var logLevel = process.env.PITAYA_LOG_LEVEL || 'info';
5
+var logFile = process.env.PITAYA_LOG_FILE;
6
+
7
+logger.level = logLevel;
8
+
9
+logger.add(winston.transports.Console, {
10
+  colorize: true,
11
+  handleExceptions: true,
12
+  humanReadableUnhandledException: true
13
+});
14
+
15
+if(logFile) {
16
+  logger.add(winston.transports.File, {
17
+    filename: logFile,
18
+    json: false,
19
+    handleExceptions: true,
20
+    humanReadableUnhandledException: true
21
+  });
22
+}
23
+
24
+module.exports = logger;

Loading…
取消
儲存