Nativefier/src/options.js

192 lines
5.4 KiB
JavaScript
Raw Normal View History

2016-01-18 15:07:22 +01:00
import os from 'os';
import path from 'path';
2016-01-19 14:32:55 +01:00
import url from 'url';
2016-01-18 15:07:22 +01:00
import request from 'request';
import cheerio from 'cheerio';
2016-01-18 16:56:59 +01:00
import validator from 'validator';
import sanitize from 'sanitize-filename';
import _ from 'lodash';
2016-01-28 14:13:57 +01:00
import async from 'async';
import inferIcon from './inferIcon';
2016-01-18 16:56:59 +01:00
2016-01-18 15:07:22 +01:00
const TEMPLATE_APP_DIR = path.join(__dirname, '../', 'app');
const ELECTRON_VERSION = '0.36.4';
2016-01-28 14:13:57 +01:00
const DEFAULT_APP_NAME = 'APP';
2016-01-18 15:07:22 +01:00
function optionsFactory(name,
targetUrl,
2016-01-18 15:07:22 +01:00
platform = detectPlatform(),
2016-01-18 16:38:52 +01:00
arch = detectArch(),
2016-01-18 15:07:22 +01:00
version = ELECTRON_VERSION,
2016-01-18 16:38:52 +01:00
outDir = process.cwd(),
overwrite = false,
2016-01-18 16:38:52 +01:00
conceal = false,
icon,
counter = false,
2016-01-18 15:07:22 +01:00
width = 1280,
height = 800,
2016-01-22 15:42:56 +01:00
showMenuBar = false,
userAgent,
honest = false,
insecure = false,
callback) {
2016-01-19 14:32:55 +01:00
targetUrl = normalizeUrl(targetUrl);
if (!width) {
width = 1280;
}
if (!height) {
height = 800;
2016-01-18 16:56:59 +01:00
}
if (!userAgent && !honest) {
userAgent = getFakeUserAgent();
}
const options = {
2016-01-18 15:07:22 +01:00
dir: TEMPLATE_APP_DIR,
name: name,
targetUrl: targetUrl,
platform: platform,
2016-01-18 16:38:52 +01:00
arch: arch,
2016-01-18 15:07:22 +01:00
version: version,
out: outDir,
// optionals
overwrite: overwrite,
asar: conceal,
2016-01-18 16:38:52 +01:00
icon: icon,
2016-01-18 15:07:22 +01:00
// app configuration
counter: counter,
2016-01-18 15:07:22 +01:00
width: width,
height: height,
2016-01-22 15:42:56 +01:00
showMenuBar: showMenuBar,
userAgent: userAgent,
insecure: insecure
};
2016-01-28 14:13:57 +01:00
async.waterfall([
callback => {
if (options.icon) {
callback(null, options);
return;
}
inferIcon(options.targetUrl, (error, pngPath) => {
if (error) {
console.warn('Cannot automatically retrieve the app icon:', error);
} else {
options.icon = pngPath;
}
callback(null, options);
});
},
(options, callback) => {
if (name && name.length > 0) {
options.name = name;
callback(null, options);
return;
}
getTitle(options.targetUrl, function(error, pageTitle) {
if (error) {
console.warn(`Unable to automatically determine app name, falling back to '${DEFAULT_APP_NAME}'`);
options.name = DEFAULT_APP_NAME;
} else {
options.name = pageTitle;
}
callback(null, options);
});
}
2016-01-28 14:13:57 +01:00
], (error, options) => {
callback(error, sanitizeOptions(options));
});
2016-01-18 15:07:22 +01:00
}
function sanitizeOptions(options) {
options.name = sanitize(options.name);
if (options.platform === 'linux') {
options.name = _.kebabCase(options.name);
}
return options;
}
2016-01-18 15:07:22 +01:00
function detectPlatform() {
const platform = os.platform();
if (platform === 'darwin' || platform === 'win32' || platform === 'linux') {
return platform;
}
console.warn(`Warning: Untested platform ${platform} detected, assuming linux`);
return 'linux';
}
function detectArch() {
const arch = os.arch();
if (arch !== 'ia32' && arch !== 'x64') {
throw `Incompatible architecture ${arch} detected`;
}
return os.arch();
}
function getTitle(url, callback) {
const options = {
url: url,
headers: {
// fake a user agent because pages like http://messenger.com will throw 404 error
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36'
}
};
request(options, (error, response, body) => {
if (error || response.statusCode !== 200) {
callback(`Request Error: ${error}, Status Code ${response ? response.statusCode : 'No Response'}`);
return;
}
const $ = cheerio.load(body);
2016-01-23 19:02:23 +01:00
const pageTitle = $('title').text().replace(/\//g, '');
callback(null, pageTitle);
});
}
2016-01-19 14:32:55 +01:00
function normalizeUrl(testUrl) {
// add protocol if protocol not found
let normalized = testUrl;
const parsed = url.parse(normalized);
if (!parsed.protocol) {
normalized = 'http://' + normalized;
}
2016-01-20 17:57:51 +01:00
if (!validator.isURL(normalized, {require_protocol: true, require_tld: false})) {
2016-01-19 14:32:55 +01:00
throw `Your Url: "${normalized}" is invalid!`;
}
return normalized;
}
function getFakeUserAgent() {
let userAgent;
switch (os.platform()) {
case 'darwin':
userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36';
break;
case 'win32':
userAgent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36';
break;
case 'linux':
userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36';
break;
2016-01-23 19:02:23 +01:00
default:
break;
}
return userAgent;
}
2016-01-18 15:07:22 +01:00
export default optionsFactory;