Browse Source

Chargement des profils distant via HTTP

William Petit 2 years ago
parent
commit
736d7600c0
7 changed files with 113 additions and 20 deletions
  1. 50 7
      README.md
  2. 1 1
      img/hourglass.svg
  3. 1 0
      package.json
  4. 13 1
      partial-profile.json
  5. 13 8
      src/components/launcher/launcher-view.js
  6. 35 2
      src/util/system.js
  7. 0 1
      test/profile.js

+ 50 - 7
README.md

@@ -23,13 +23,13 @@ PITAYA_LOG_LEVEL=debug NODE_ENV=development npm start
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                             |
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                          |
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 ou URL 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                          |
33 33
 
34 34
 ## Comment construire l'application depuis les sources
35 35
 
@@ -39,6 +39,49 @@ npm run build
39 39
 
40 40
 Un dossier `pitaya-<target>-<arch>` sera créé dans le répertoire `./build`. Celui ci contient tous les fichiers nécessaires à l'application.
41 41
 
42
+## Profils
43
+
44
+Un fichier de profil est utilisé par Pitaya afin de définir l'arborescence d'applications affichée par le lanceur.
45
+Ce fichier est au format JSON et a la structure récursive suivante:
46
+
47
+```json
48
+{
49
+  "items": [
50
+    {
51
+      "label": "Label de mon item de type catégorie",
52
+      "icon": "Chemin vers l'image d'icône",
53
+      "background": "Chemin vers l'image de fond, si besoin",
54
+      "items": [
55
+        {
56
+          "label": "Label de mon sous-item 1 de type application",
57
+          "icon": "Chemin vers l'image d'icône",
58
+          "exec": "Commande d'exécution de mon application"
59
+        },
60
+        {
61
+          "label": "Label de mon sous-item 2 de type catégorie",
62
+          "items": [
63
+            {
64
+              "label": "etc..."
65
+            }
66
+          ]
67
+        }
68
+      ]
69
+    }
70
+  ]
71
+}
72
+```
73
+
74
+### Différence entre catégories et applications
75
+
76
+Un item comprenant un tableau `items` sera automatiquement considéré comme une catégorie et non plus une application, même si la propriété `exec` est également définie.
77
+
78
+### Import de profils externes
79
+
80
+Il est possible d'ajouter une propriété `import` avec comme valeur un chemin de fichier ou une URL sur un item.
81
+
82
+Lors du chargement du profil, le lanceur "montera" automatiquement le fichier externe désigné sur l'item portant la propriété.
83
+
84
+Voir le fichier `default-profile.json` pour un exemple.
42 85
 
43 86
 ## Comment contribuer
44 87
 

+ 1 - 1
img/hourglass.svg

@@ -43,7 +43,7 @@
43 43
      id="namedview30"
44 44
      showgrid="false"
45 45
      inkscape:zoom="13.350176"
46
-     inkscape:cx="-3.9872051"
46
+     inkscape:cx="-17.807248"
47 47
      inkscape:cy="18.89309"
48 48
      inkscape:window-x="0"
49 49
      inkscape:window-y="0"

+ 1 - 0
package.json

@@ -34,6 +34,7 @@
34 34
     "recursive-iterator": "^2.0.0",
35 35
     "redux": "^2.0.0",
36 36
     "redux-thunk": "^0.1.0",
37
+    "request": "^2.65.0",
37 38
     "winston": "^1.1.2"
38 39
   }
39 40
 }

+ 13 - 1
partial-profile.json

@@ -1,5 +1,17 @@
1 1
 {
2 2
   "label": "Partial Level 1",
3 3
   "icon": "chromium-browser",
4
-  "background": "./img/background2.jpg"
4
+  "background": "./img/background2.jpg",
5
+  "items": [
6
+    {
7
+      "label": "Firefox",
8
+      "icon": "firefox",
9
+      "exec": "firefox"
10
+    },
11
+    {
12
+      "label": "Libreoffice Writer",
13
+      "icon": "libreoffice-writer",
14
+      "exec": "libreoffice --writer"
15
+    }
16
+  ]
5 17
 }

+ 13 - 8
src/components/launcher/launcher-view.js

@@ -88,9 +88,19 @@ var LauncherView = React.createClass({
88 88
 
89 89
   onItemClick: function(evt, itemPath, item) {
90 90
 
91
-    if(item.exec) {
91
+    console.log(item);
92
+
93
+    if(item.items) {
94
+
95
+      this.play(this.refs.appList, 'slide-out-left 250ms ease-in-out')
96
+        .then(function() {
97
+          this.setState({ currentItemPath: itemPath, currentItem: item });
98
+          return this.play(this.refs.appList, 'slide-in-right 250ms ease-in-out');
99
+        }.bind(this))
100
+      ;
101
+
102
+    } else if(item.exec) {
92 103
 
93
-      logger.debug('Launching application "'+item.exec+'"...');
94 104
       var el = evt.currentTarget;
95 105
       el.classList.add('pulse');
96 106
 
@@ -104,12 +114,7 @@ var LauncherView = React.createClass({
104 114
       ;
105 115
 
106 116
     } else {
107
-      this.play(this.refs.appList, 'slide-out-left 250ms ease-in-out')
108
-        .then(function() {
109
-          this.setState({ currentItemPath: itemPath, currentItem: item });
110
-          return this.play(this.refs.appList, 'slide-in-right 250ms ease-in-out');
111
-        }.bind(this))
112
-      ;
117
+      logger.info('No action associated with item "'+item.label+'".');
113 118
     }
114 119
 
115 120
   },

+ 35 - 2
src/util/system.js

@@ -3,14 +3,47 @@ var cp = require('child_process');
3 3
 var glob = require('glob');
4 4
 var ini = require('ini');
5 5
 var Cache = require('./cache');
6
+var request = require('request');
6 7
 
8
+var HTTP_REGEX = /^https?:\/\//i;
7 9
 /**
8
- * Load a JSON file
10
+ * Load a JSON file (http or local)
9 11
  *
10 12
  * @param filePath The path of the json file
11 13
  * @return Promise
12 14
  */
13
-exports.loadJSON = function(filePath) {
15
+exports.loadJSON = function(jsonUrl) {
16
+  if( HTTP_REGEX.test(jsonUrl) ) {
17
+    return exports.fetchRemoteJSON(jsonUrl);
18
+  } else {
19
+    return exports.loadLocalJSON(jsonUrl);
20
+  }
21
+};
22
+
23
+/**
24
+ * Load a remote JSON file via http
25
+ *
26
+ * @param filePath The path of the json file
27
+ * @return Promise
28
+ */
29
+exports.fetchRemoteJSON = function(fileUrl) {
30
+  return new Promise(function(resolve, reject) {
31
+    request(fileUrl, { followRedirect: true, json: true }, function (err, res, body) {
32
+      if(err) return reject(err);
33
+      console.log(body);
34
+      return resolve(body);
35
+    });
36
+  });
37
+};
38
+
39
+
40
+/**
41
+ * Load a local JSON file
42
+ *
43
+ * @param filePath The path of the json file
44
+ * @return Promise
45
+ */
46
+exports.loadLocalJSON = function(filePath) {
14 47
   return new Promise(function(resolve, reject) {
15 48
     fs.readFile(filePath, 'utf8', function(err, fileContent) {
16 49
       if(err) return reject(err);

+ 0 - 1
test/profile.js

@@ -6,7 +6,6 @@ ProfileSuite.loadProfileWithImport = function(test) {
6 6
 
7 7
   Profile.load(__dirname+'/../default-profile.json')
8 8
     .then(function(profile) {
9
-      console.log('%j', profile);
10 9
       test.ok(profile.items[0].label === "Partial Level 1", "It should have loaded the partial import !");
11 10
       test.done();
12 11
     })