Chargement des profils distant via HTTP

Этот коммит содержится в:
wpetit 2015-11-05 16:40:42 +01:00
родитель 996ccd90f1
Коммит 736d7600c0
7 изменённых файлов: 113 добавлений и 20 удалений

Просмотреть файл

@ -23,13 +23,13 @@ PITAYA_LOG_LEVEL=debug NODE_ENV=development npm start
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 |
| 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 |
| Variable | Description | Valeurs possibles | Valeur par défaut |
|-------------------|-----------------------------------------------|-------------------------------|-------------------------------|
| PITAYA_MODE | Mode d'exécution de Pitaya | launcher, edit | launcher |
| PITAYA_PROFILE | Chemin ou URL 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
@ -39,6 +39,49 @@ npm run build
Un dossier `pitaya-<target>-<arch>` sera créé dans le répertoire `./build`. Celui ci contient tous les fichiers nécessaires à l'application.
## Profils
Un fichier de profil est utilisé par Pitaya afin de définir l'arborescence d'applications affichée par le lanceur.
Ce fichier est au format JSON et a la structure récursive suivante:
```json
{
"items": [
{
"label": "Label de mon item de type catégorie",
"icon": "Chemin vers l'image d'icône",
"background": "Chemin vers l'image de fond, si besoin",
"items": [
{
"label": "Label de mon sous-item 1 de type application",
"icon": "Chemin vers l'image d'icône",
"exec": "Commande d'exécution de mon application"
},
{
"label": "Label de mon sous-item 2 de type catégorie",
"items": [
{
"label": "etc..."
}
]
}
]
}
]
}
```
### Différence entre catégories et applications
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.
### Import de profils externes
Il est possible d'ajouter une propriété `import` avec comme valeur un chemin de fichier ou une URL sur un item.
Lors du chargement du profil, le lanceur "montera" automatiquement le fichier externe désigné sur l'item portant la propriété.
Voir le fichier `default-profile.json` pour un exemple.
## Comment contribuer

Просмотреть файл

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

До

Ширина:  |  Высота:  |  Размер: 2.7 KiB

После

Ширина:  |  Высота:  |  Размер: 2.7 KiB

Просмотреть файл

@ -34,6 +34,7 @@
"recursive-iterator": "^2.0.0",
"redux": "^2.0.0",
"redux-thunk": "^0.1.0",
"request": "^2.65.0",
"winston": "^1.1.2"
}
}

Просмотреть файл

@ -1,5 +1,17 @@
{
"label": "Partial Level 1",
"icon": "chromium-browser",
"background": "./img/background2.jpg"
"background": "./img/background2.jpg",
"items": [
{
"label": "Firefox",
"icon": "firefox",
"exec": "firefox"
},
{
"label": "Libreoffice Writer",
"icon": "libreoffice-writer",
"exec": "libreoffice --writer"
}
]
}

Просмотреть файл

@ -88,9 +88,19 @@ var LauncherView = React.createClass({
onItemClick: function(evt, itemPath, item) {
if(item.exec) {
console.log(item);
if(item.items) {
this.play(this.refs.appList, 'slide-out-left 250ms ease-in-out')
.then(function() {
this.setState({ currentItemPath: itemPath, currentItem: item });
return this.play(this.refs.appList, 'slide-in-right 250ms ease-in-out');
}.bind(this))
;
} else if(item.exec) {
logger.debug('Launching application "'+item.exec+'"...');
var el = evt.currentTarget;
el.classList.add('pulse');
@ -104,12 +114,7 @@ var LauncherView = React.createClass({
;
} else {
this.play(this.refs.appList, 'slide-out-left 250ms ease-in-out')
.then(function() {
this.setState({ currentItemPath: itemPath, currentItem: item });
return this.play(this.refs.appList, 'slide-in-right 250ms ease-in-out');
}.bind(this))
;
logger.info('No action associated with item "'+item.label+'".');
}
},

Просмотреть файл

@ -3,14 +3,47 @@ var cp = require('child_process');
var glob = require('glob');
var ini = require('ini');
var Cache = require('./cache');
var request = require('request');
var HTTP_REGEX = /^https?:\/\//i;
/**
* Load a JSON file
* Load a JSON file (http or local)
*
* @param filePath The path of the json file
* @return Promise
*/
exports.loadJSON = function(filePath) {
exports.loadJSON = function(jsonUrl) {
if( HTTP_REGEX.test(jsonUrl) ) {
return exports.fetchRemoteJSON(jsonUrl);
} else {
return exports.loadLocalJSON(jsonUrl);
}
};
/**
* Load a remote JSON file via http
*
* @param filePath The path of the json file
* @return Promise
*/
exports.fetchRemoteJSON = function(fileUrl) {
return new Promise(function(resolve, reject) {
request(fileUrl, { followRedirect: true, json: true }, function (err, res, body) {
if(err) return reject(err);
console.log(body);
return resolve(body);
});
});
};
/**
* Load a local JSON file
*
* @param filePath The path of the json file
* @return Promise
*/
exports.loadLocalJSON = function(filePath) {
return new Promise(function(resolve, reject) {
fs.readFile(filePath, 'utf8', function(err, fileContent) {
if(err) return reject(err);

Просмотреть файл

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