forked from tilemill-project/tilemill
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcore.bones
232 lines (205 loc) · 8.17 KB
/
core.bones
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
var fs = require('fs');
var fsutil = require('../lib/fsutil');
var create_files = require('../lib/create_files');
var path = require('path');
var Step = require('step');
var defaults = models.Config.defaults;
var mapnik = require('mapnik');
var carto = require('carto');
if (mapnik.register_default_fonts) mapnik.register_default_fonts();
if (mapnik.register_system_fonts) mapnik.register_system_fonts();
if (mapnik.register_default_input_plugins) mapnik.register_default_input_plugins();
var semver = require('semver');
var os = require('os');
var crypto = require('crypto');
// node v6 -> v8 compatibility
var existsSync = require('fs').existsSync || require('path').existsSync;
command = Bones.Command.extend();
command.description = 'start ui server';
command.options['port'] = {
'title': 'port=[port]',
'description': 'Server port.',
'default': defaults.port
};
command.options['tilePort'] = {
'title': 'tilePort=[port]',
'description': 'Tile server port.',
'default': defaults.tilePort
};
command.options['coreSocket'] = {
'title': 'coreSocket=[/path/to/socket]',
'description': 'Server port socket, overrides `port` option.',
};
command.options['tileSocket'] = {
'title': 'tileSocket=[/path/to/socket]',
'description': 'Tile server socket, overrides `tilePort` option.',
};
command.options['coreUrl'] = {
'title': 'coreUrl=[host:port]'
};
command.options['tileUrl'] = {
'title': 'tileUrl=[host:port]'
};
command.options['examples'] = {
'title': 'examples=1|0',
'description': 'Copy example projects on first start.',
'default': defaults.examples
};
command.options['sampledata'] = {
'title': 'sampledata=1|0',
'description': 'Precache sample data for low bandwidth connections.',
'default': defaults.sampledata
};
command.options['listenHost'] = {
'title': 'listenHost=n.n.n.n',
'description': 'Bind the server to the given host.',
'default': defaults.listenHost
};
command.options['updates'] = {
'title': 'updates=1|0',
'description': 'Automatically check for TileMill updates.',
'default': true
};
command.options['profile'] = {
'title': 'profile=1|0',
'description': 'Report system profile anonymously.',
'default': true
};
command.options['concurrency'] = {
'title': 'concurrency=[num]',
'description': 'Number of exports that can be run concurrently.',
'default': 4
};
command.options['updatesTime'] = { 'default': 0 };
command.options['updatesVersion'] = { 'default': '0.0.1' };
command.prototype.bootstrap = function(plugin, callback) {
process.title = 'tilemill-ui';
var settings = Bones.plugin.config;
settings.host = false;
settings.files = path.resolve(settings.files.replace(/^~/, process.env.HOME));
settings.coreUrl = settings.coreUrl || '127.0.0.1:' + settings.port;
settings.tileUrl = settings.tileUrl || '127.0.0.1:' + settings.tilePort;
carto.tree.Reference.setVersion(mapnik.versions.mapnik);
Bones.plugin.abilities = {
version: (function() {
try {
return _(fs.readFileSync(path.resolve(__dirname + '/../VERSION'),'utf8').split('\n')).compact();
} catch(e) {
return ['unknown', 'unknown'];
}
})(),
platform: process.platform,
totalmem: os.totalmem(),
cpus: os.cpus(),
coreUrl: settings.coreUrl,
tileUrl: settings.tileUrl,
tilePort: settings.tilePort,
tilemill: JSON.parse(fs.readFileSync(path.resolve(__dirname + '/../package.json'),'utf8')),
carto: carto.tree.Reference.data,
fonts: mapnik.fonts(),
datasources: mapnik.datasources(),
exports: {
mbtiles: true,
png: mapnik.supports.png,
jpeg: mapnik.supports.jpeg,
webp: mapnik.supports.webp,
tiff: mapnik.supports.tiff,
grid: mapnik.supports.grid,
proj4: mapnik.supports.proj4,
pdf: mapnik.supports.cairo_pdf || mapnik.supports.cairo,
svg: mapnik.supports.cairo_svg || mapnik.supports.cairo
}
};
var configDir = path.join(process.env.HOME, '.tilemill');
if (!existsSync(configDir)) {
console.warn('Creating configuration dir %s', configDir);
fsutil.mkdirpSync(configDir, 0755);
}
// try/catch here to allow TileMill to start even if the app cannot write to
// its (potentially invalid) docs location so that user can still edit the settings
// to get out of problem without hand editing the config.json
// https://github.com/mapbox/tilemill/issues/2024
try {
create_files.init_dirs(['export', 'project', 'cache'],settings);
// Apply server-side mixins/overrides.
var db = require('backbone-dirty')(settings.files + '/app.db');
db.dirty.on('error', console.log);
Backbone.sync = db.sync;
} catch (err) {
console.error(err);
}
// Process any waiting exports.
(new models.Exports).fetch();
// Load plugins.
// @TODO we may need to move this to a global bootstrap to allow
// other servers/processes to be accessible to plugin code.
Bones.plugin.abilities.plugins = _([
path.resolve(__dirname + '/../plugins'),
path.join(process.env.HOME, '.tilemill/node_modules')
]).chain()
.map(function(p, index) {
try {
return fs.readdirSync(p).filter(function(d) {
return d[0] !== '.';
}).map(function(dir) {
var data;
try {
var pkg = path.join(p, dir, 'package.json');
data = JSON.parse(fs.readFileSync(pkg, 'utf8'));
data.core = index === 0;
data.id = data.name;
// Engines key missing.
if (!data.engines || !data.engines.tilemill) {
console.warn('Plugin [%s] "engines" missing.',
Bones.utils.colorize(data.name, 'red'));
return false;
}
// Check that TileMill version satisfies plugin requirements.
// Pass data through such that the plugin can be shown in the
// UI as failing to satisfy requirements.
if (!semver.satisfies(Bones.plugin.abilities.tilemill.version, data.engines.tilemill)) {
console.warn('Plugin [%s] requires TileMill %s.',
Bones.utils.colorize(data.name, 'red'),
data.engines.tilemill);
return data;
}
// Load plugin
// NOTE: even broken plugins (ones that throw upon require) will likely get partially loaded here
require('bones').load(path.join(p, dir));
console.warn('Plugin [%s] loaded.', Bones.utils.colorize(data.name, 'green'));
return data;
} catch (err) {
if (data && data.name) {
// consider, as broken, plugins which partially loaded but threw so that
// the user can know to uninstall them, because unloading is not possible
data.broken = true;
console.error('Plugin [' + data.name + '] unable to be loaded: ' + err.stack || err.toString());
return data;
} else {
console.error('Plugin loading error: ' + err.stack || err.message);
return false;
}
}
});
} catch(err) {
return [];
}
})
.flatten()
.compact()
.reduce(function(memo, plugin) {
memo[plugin.name] = plugin;
return memo;
}, {})
.value();
callback();
};
command.prototype.initialize = function(plugin, callback) {
this.servers = {};
this.servers['Core'] = new plugin.servers['Core'](plugin);
this.servers['Core'].start(function() {
console.warn('Started %s.', Bones.utils.colorize(this, 'green'));
this.emit('start');
callback && callback();
});
};