Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
349
gaia/apps/operatorvariant/build/build.js
Executable file
349
gaia/apps/operatorvariant/build/build.js
Executable file
|
|
@ -0,0 +1,349 @@
|
|||
'use strict';
|
||||
|
||||
/* jshint node: true */
|
||||
|
||||
var utils = require('utils');
|
||||
|
||||
// Resources helper constructor
|
||||
var Resources = function(gaia, settings, appDomain) {
|
||||
this.gaia = gaia;
|
||||
this.settings = settings;
|
||||
this.fileList = [];
|
||||
this.json = {};
|
||||
this.appPrefix = 'app://';
|
||||
this.appURL = this.appPrefix + appDomain + '/resources/';
|
||||
};
|
||||
|
||||
// Parse and get resources for a given JSON configuration of one operator.
|
||||
// Also create an output JSON configuration for the processed resources.
|
||||
Resources.prototype.getResources = function(conf) {
|
||||
var operatorJSON = {};
|
||||
|
||||
operatorJSON.default_contacts = this.addFile(conf.default_contacts);
|
||||
operatorJSON.support_contacts = this.addFile(conf.support_contacts);
|
||||
operatorJSON.network_type = this.addFile(conf.network_type);
|
||||
operatorJSON.known_networks = this.addFile(conf.known_networks);
|
||||
operatorJSON.sms = this.addFile(conf.sms);
|
||||
operatorJSON.wallpaper = this.getWallpaperResource(conf.wallpaper);
|
||||
operatorJSON.ringtone = this.getRingtoneResource(conf.ringtone);
|
||||
operatorJSON.power = this.getPowerResource(conf.power);
|
||||
operatorJSON.search = this.getSearchResource(conf.search);
|
||||
operatorJSON.keyboard_settings = this.getKeyboardResource(conf.keyboard);
|
||||
operatorJSON.topsites = this.getResourceWithIcon(conf.topsites, 'topSites',
|
||||
'tilePath', 'tile');
|
||||
operatorJSON.browser = this.getResourceWithIcon(conf.bookmarks, 'bookmarks',
|
||||
'iconPath', 'iconUri');
|
||||
|
||||
if ('nfc' in conf) {
|
||||
operatorJSON.nfc = this.getNfcResource(conf.nfc);
|
||||
}
|
||||
|
||||
if ('data_ftu' in conf) {
|
||||
operatorJSON.data_ftu = conf.data_ftu;
|
||||
}
|
||||
|
||||
if ('data_roaming' in conf) {
|
||||
operatorJSON.data_roaming = conf.data_roaming;
|
||||
}
|
||||
|
||||
conf['mcc-mnc'].forEach(function(mcc) {
|
||||
if (Object.keys(operatorJSON).length !== 0) {
|
||||
this.json[mcc] = operatorJSON;
|
||||
}
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
// Get file object for a given path.
|
||||
Resources.prototype.getFile = function(path) {
|
||||
var distDir = this.gaia.distributionDir;
|
||||
var file = utils.getFile(distDir, path);
|
||||
if (!file.exists()) {
|
||||
throw new Error('Invalid single variant configuration: ' +
|
||||
file.path + ' not found');
|
||||
}
|
||||
|
||||
return file;
|
||||
};
|
||||
|
||||
// Add new resource entry in the output JSON configuration (key / value)
|
||||
// and add the resource path to the resources list.
|
||||
Resources.prototype.addEntry = function(resources, name) {
|
||||
if (resources instanceof Array) {
|
||||
this.fileList.push.apply(this.fileList, resources);
|
||||
} else {
|
||||
this.fileList.push(resources);
|
||||
}
|
||||
|
||||
return '/resources/' + name;
|
||||
};
|
||||
|
||||
// Add file to resources object
|
||||
Resources.prototype.addFile = function(path, key) {
|
||||
if (path) {
|
||||
var file = this.getFile(path);
|
||||
return this.addEntry(file, file.leafName);
|
||||
}
|
||||
};
|
||||
|
||||
// Create a new JSON file and add to resources.
|
||||
Resources.prototype.createJSON = function(name, content) {
|
||||
var obj = { filename: name,
|
||||
content: content };
|
||||
|
||||
return this.addEntry(obj, obj.filename);
|
||||
};
|
||||
|
||||
// Create new wallpaper JSON from a wallpaper file path.
|
||||
Resources.prototype.getWallpaperResource = function(wallpaper) {
|
||||
if (wallpaper) {
|
||||
|
||||
var uri;
|
||||
if (wallpaper.startsWith(this.appPrefix)) {
|
||||
uri = wallpaper;
|
||||
} else {
|
||||
var file = this.getFile(wallpaper);
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
uri = '/resources/' + file.leafName;
|
||||
this.addEntry(file, file.leafName);
|
||||
}
|
||||
|
||||
var content = { uri: uri,
|
||||
default: this.settings['wallpaper.image'] };
|
||||
|
||||
var jsonName = 'wallpaper-' + utils.getHash(wallpaper) + '.json';
|
||||
return this.createJSON(jsonName, content);
|
||||
}
|
||||
};
|
||||
|
||||
// Create ringtone JSON and add file.
|
||||
Resources.prototype.getRingtoneResource = function(ringtone) {
|
||||
if (ringtone) {
|
||||
var jsonName = 'ringtone-' +
|
||||
utils.getHash(JSON.stringify(ringtone)) + '.json';
|
||||
|
||||
var ringtoneName = ringtone.name;
|
||||
if (!ringtoneName) {
|
||||
throw new Error('Missing name for ringtone in single variant conf.');
|
||||
}
|
||||
|
||||
var uri;
|
||||
if (ringtone.path.startsWith(this.appPrefix)) {
|
||||
uri = ringtone.path;
|
||||
} else {
|
||||
var file = this.getFile(ringtone.path);
|
||||
if (!file) {
|
||||
throw new Error('Missing path for ringtone in single variant conf.');
|
||||
}
|
||||
uri = '/resources/' + file.leafName;
|
||||
this.addEntry(file, file.leafName);
|
||||
}
|
||||
|
||||
var content = { uri: uri,
|
||||
name: ringtoneName,
|
||||
default: this.settings['dialer.ringtone.id'] };
|
||||
|
||||
return this.createJSON(jsonName, content);
|
||||
}
|
||||
};
|
||||
|
||||
// Create power JSON and add files.
|
||||
Resources.prototype.getPowerResource = function (power) {
|
||||
if (power) {
|
||||
var jsonName = 'power-' + utils.getHash(JSON.stringify(power)) + '.json';
|
||||
var powerJSON = power;
|
||||
var poweron = power.poweron;
|
||||
var poweronFile;
|
||||
|
||||
if (poweron) {
|
||||
var poweronType = poweron.video ? 'video' : null ||
|
||||
poweron.image ? 'image' : null;
|
||||
if (!poweronType) {
|
||||
throw new Error('Invalid poweron type, only video or image are ' +
|
||||
'valid.');
|
||||
}
|
||||
|
||||
if (poweron[poweronType].startsWith(this.appPrefix)) {
|
||||
powerJSON.poweron[poweronType] = poweron[poweronType];
|
||||
} else {
|
||||
poweronFile = this.getFile(poweron[poweronType]);
|
||||
this.addEntry(poweronFile, poweronFile.leafName);
|
||||
powerJSON.poweron[poweronType] = this.appURL + poweronFile.leafName;
|
||||
}
|
||||
}
|
||||
var poweroff = power.poweroff;
|
||||
var poweroffFile;
|
||||
if (poweroff) {
|
||||
var poweroffType = poweroff.video ? 'video' : null ||
|
||||
poweroff.image ? 'image' : null;
|
||||
if (!poweroffType) {
|
||||
throw new Error('Invalid poweroff type, only video or image are ' +
|
||||
'valid.');
|
||||
}
|
||||
|
||||
if (poweroff[poweroffType].startsWith(this.appPrefix)) {
|
||||
powerJSON.poweroff[poweroffType] = poweroff[poweroffType];
|
||||
} else {
|
||||
poweroffFile = this.getFile(poweroff[poweroffType]);
|
||||
this.addEntry(poweroffFile, poweroffFile.leafName);
|
||||
powerJSON.poweroff[poweroffType] = this.appURL + poweroffFile.leafName;
|
||||
}
|
||||
}
|
||||
|
||||
return this.createJSON(jsonName, powerJSON);
|
||||
}
|
||||
};
|
||||
|
||||
// Create search JSON and add files.
|
||||
Resources.prototype.getSearchResource = function (searchPath) {
|
||||
if (searchPath) {
|
||||
var file = this.getFile(searchPath);
|
||||
var searchContent = utils.getJSON(file);
|
||||
|
||||
searchContent.forEach(function(engine) {
|
||||
if (!engine.iconPath.startsWith(this.appPrefix)) {
|
||||
var searchFile = this.getFile(engine.iconPath);
|
||||
this.addEntry(searchFile, searchFile.leafName);
|
||||
engine.iconUrl = this.appURL + searchFile.leafName;
|
||||
delete engine.iconPath;
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
return this.createJSON(file.leafName, searchContent);
|
||||
}
|
||||
};
|
||||
|
||||
// Create keyboard JSON.
|
||||
Resources.prototype.getKeyboardResource = function (keyboard) {
|
||||
if (keyboard) {
|
||||
var file = utils.getFile(this.gaia.distributionDir, keyboard);
|
||||
if (!file.exists()) {
|
||||
throw new Error('Invalid single variant configuration: ' +
|
||||
file.path + ' not found');
|
||||
}
|
||||
|
||||
var defaults = {
|
||||
'keyboard.vibration': this.settings['keyboard.vibration'],
|
||||
'keyboard.autocorrect': this.settings['keyboard.autocorrect'],
|
||||
'keyboard.clicksound': this.settings['keyboard.clicksound'],
|
||||
'keyboard.wordsuggestion': this.settings['keyboard.wordsuggestion']
|
||||
};
|
||||
|
||||
var content = { values: utils.getJSON(file),
|
||||
defaults: defaults };
|
||||
|
||||
for (var value in content.values) {
|
||||
if (!value.startsWith('keyboard.')) {
|
||||
throw new Error('Invalid keyboard property \'' + value + '\' in file ' +
|
||||
file.path + ', keyboard properties must start ' +
|
||||
'with \'keyboard.\'');
|
||||
}
|
||||
}
|
||||
|
||||
var jsonName = 'keyboard-' + utils.getHash(keyboard) + '.json';
|
||||
return this.createJSON(jsonName, content);
|
||||
}
|
||||
};
|
||||
|
||||
Resources.prototype.getResourceWithIcon = function(aFilePath, aRootKey,
|
||||
aIconPathKey, aIconOutKey) {
|
||||
if (aFilePath) {
|
||||
var file = this.getFile(aFilePath);
|
||||
var json = utils.getJSON(file);
|
||||
|
||||
json[aRootKey].forEach(function(elem) {
|
||||
if (elem[aIconPathKey]) {
|
||||
var iconFile = this.getFile(elem[aIconPathKey]);
|
||||
var icon = utils.getFileAsDataURI(iconFile);
|
||||
elem[aIconOutKey] = icon;
|
||||
delete elem[aIconPathKey];
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
return this.createJSON(file.leafName, json);
|
||||
}
|
||||
};
|
||||
|
||||
// Create nfc JSON.
|
||||
Resources.prototype.getNfcResource = function(nfc) {
|
||||
var content = { isEnabled: nfc,
|
||||
default: this.settings['nfc.enabled'] };
|
||||
|
||||
var jsonName = 'nfc-' + utils.getHash(JSON.stringify(content)) + '.json';
|
||||
return this.createJSON(jsonName, content);
|
||||
};
|
||||
|
||||
// OperatorAppBuilder constructor object.
|
||||
var OperatorAppBuilder = function() {
|
||||
};
|
||||
|
||||
// set destination directory, application directory and get settings in order
|
||||
// to set default values.
|
||||
OperatorAppBuilder.prototype.setOptions = function(options) {
|
||||
this.stageDir = utils.getFile(options.STAGE_APP_DIR);
|
||||
|
||||
this.gaia = utils.gaia.getInstance(options);
|
||||
|
||||
var settingsFile = utils.getFile(options.PROFILE_DIR, 'settings.json');
|
||||
if (!settingsFile.exists()) {
|
||||
throw new Error('file not found: ' + settingsFile.path);
|
||||
}
|
||||
this.settings = utils.getJSON(settingsFile);
|
||||
|
||||
this.appDir = utils.getFile(options.APP_DIR);
|
||||
this.appDomain = this.appDir.leafName + '.' + options.GAIA_DOMAIN;
|
||||
};
|
||||
|
||||
// Get resources and copy files and configuration JSON to build_stage folder.
|
||||
OperatorAppBuilder.prototype.generateCustomizeResources = function() {
|
||||
if (!this.gaia.distributionDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
var variantFile = utils.getFile(this.gaia.distributionDir, 'variant.json');
|
||||
if (variantFile.exists()) {
|
||||
var resources = this.getSingleVariantResources(variantFile);
|
||||
|
||||
var resourceDirFile = utils.getFile(this.stageDir.path, 'resources');
|
||||
utils.ensureFolderExists(resourceDirFile);
|
||||
var customizationFile = utils.getFile(this.stageDir.path,
|
||||
'resources', 'customization.json');
|
||||
utils.writeContent(customizationFile, JSON.stringify(resources.json));
|
||||
|
||||
resources.fileList.forEach(function(file) {
|
||||
if (!file.filename && !file.content) {
|
||||
utils.copyFileTo(file.path, resourceDirFile.path, file.leafName);
|
||||
} else {
|
||||
var resourceFile = utils.getFile(resourceDirFile.path, file.filename);
|
||||
utils.writeContent(resourceFile, JSON.stringify(file.content));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
utils.log('operatorvariant',
|
||||
'Single variant resources will not be added since ' +
|
||||
variantFile.path + ' not found');
|
||||
}
|
||||
};
|
||||
|
||||
// Use Resources object to get the resources for each operator.
|
||||
OperatorAppBuilder.prototype.getSingleVariantResources = function(svConfFile) {
|
||||
var svConf = utils.getJSON(svConfFile);
|
||||
var resources = new Resources(this.gaia, this.settings, this.appDomain);
|
||||
|
||||
svConf.operators.forEach(function(operator) {
|
||||
resources.getResources(operator);
|
||||
});
|
||||
|
||||
return resources;
|
||||
};
|
||||
|
||||
OperatorAppBuilder.prototype.execute = function(options) {
|
||||
utils.copyToStage(options);
|
||||
this.setOptions(options);
|
||||
this.generateCustomizeResources(options);
|
||||
};
|
||||
|
||||
exports.execute = function(options) {
|
||||
(new OperatorAppBuilder()).execute(options);
|
||||
};
|
||||
Loading…
Reference in a new issue