UNPKG

11.1 kBJavaScriptView Raw
1var simpleportal = require("./../simpleportal");
2
3var exec = require('child_process').exec;
4
5var path = require('path');
6var fs = require('fs');
7var zlib = require('zlib');
8
9/**
10 * @class PluginUtil
11 * @module util
12 *
13 * @constructor
14 * @param {} options Options for the plugin util
15 *
16 * @return instance Instance of the pluginutil
17 */
18var PluginUtil = function(options) {
19 var instance = this;
20
21 this.configuration = simpleportal.util.clone(PluginUtil.defaults);
22
23 if(options)
24 for(var keys = Object.keys(options), l = keys.length; l; --l) {
25 this.configuration[ keys[l-1] ] = options[ keys[l-1] ];
26 }
27
28 this.builderconfig=simpleportal.util.clone(PluginUtil.builderconfig);
29
30 return instance;
31}
32
33/**
34 * @property defaults
35 * @private
36 */
37PluginUtil.defaults = {};
38
39/**
40 * @property builderconfig
41 * @private
42 */
43PluginUtil.builderconfig = {
44 webapp:{
45 excludes:['js/views/*', 'js/models/*', 'app.js', 'main.js', 'mvc.js', 'models.js', 'views.js', 'app.css']
46 },
47 util:{
48 excludes:['*/downloads/*', '*/models/*', '*/views/*', '*/backboot/source/*', '*/bootstrap/2.3.2/*', '*/bootstrap/2.1.0/*', '*/evimed_*.png']
49 }
50}
51
52/**
53 * To scan directory for plugins
54 *
55 * @method scanDirectory
56 * @param {} plugindir
57 * @param {callback} callback The callback to excecute when complete
58 * @return
59 */
60PluginUtil.prototype.scanDirectory = function(plugindir, callback){
61 var instance = this;
62
63 var plugins = [];
64 if(fs.existsSync(plugindir)){
65 fs.readdirSync(plugindir).forEach(function(filename){
66 var autoplugin = {id:filename};
67
68 simpleportal.pluginloader.readPluginSetting(autoplugin, plugindir);
69
70 plugins.push(autoplugin);
71 });
72 }
73 callback(null, plugins);
74}
75
76/**
77 * To ddownload file from a remote server
78 *
79 * @method getFile
80 *
81 * @param {} url url for the remote server
82 * @param {} path uri path for the file
83 * @param {callback} cb The callback to excecute when complete
84 */
85PluginUtil.prototype.getFile = function(url, path, cb) {
86 var instance = this;
87
88 var http_or_https = require('http');
89 if (/^https:\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/.test(url)) {
90 http_or_https = require('https');
91 }
92
93 http_or_https.get(url, function(response) {
94 var headers = JSON.stringify(response.headers);
95 switch(response.statusCode) {
96 case 200:
97 var file = fs.createWriteStream(path);
98 response.on('data', function(chunk){
99 file.write(chunk);
100 }).on('end', function(){
101 file.end();
102 cb(null);
103 });
104 break;
105 case 301:
106 case 302:
107 case 303:
108 case 307:
109 instance.getFile(response.headers.location, path, cb);
110 break;
111 default:
112 cb(new Error('Server responded with status code ' + response.statusCode));
113 }
114 })
115 .on('error', function(err) {
116 cb(err);
117 });
118};
119
120/**
121 * To check dependencies for a plugin
122 *
123 * @method checkDependencies
124 *
125 * @param {} pluginsettings
126 * @param {callback} callback The callback to excecute when complete
127 */
128PluginUtil.prototype.checkDependencies = function (pluginsettings, callback){
129 var instance = this;
130
131 if(pluginsettings.missingdependencies && pluginsettings.missingdependencies.length > 0)
132 callback('Please Install the dependant plugin before installing the plugin - '+ pluginsettings.id);
133 else
134 callback(null)
135}
136
137/**
138 * To update a plugin
139 *
140 * @method updatePlugin
141 *
142 * @param {} pluginsettings plugin configuration
143 * @param {callback} callback The callback to excecute when complete
144 */
145PluginUtil.prototype.updatePlugin = function (pluginsettings, callback){
146 var instance = this;
147
148 if(pluginsettings.curversion){
149 simpleportal.util.deleteFolderRecursiveSync(pluginsettings.installeddir);
150
151 var downloaddir = simpleportal.util.getServerPath(instance.configuration.downloaddir);
152 var deployedroot = simpleportal.util.getServerPath(instance.configuration.webappdir||'resources/private');
153
154 instance.copyRecursiveSync(downloaddir + '/' + pluginsettings.id, pluginsettings.installeddir);
155
156 simpleportal.util.deleteFolderRecursiveSync(downloaddir + '/' + pluginsettings.id);
157
158 callback(null, 'Successfully updated plugin - ' + pluginsettings.id + ' from ' + pluginsettings.curversion + ' >> ' + pluginsettings.version, null);
159
160 simpleportal.pluginloader.loadPlugin(pluginsettings, function(error, newpluginsettings){
161 callback(error, pluginsettings);
162 });
163 } else if(!pluginsettings.installed){
164 var downloaddir = simpleportal.util.getServerPath(instance.configuration.downloaddir);
165 var deployedroot = simpleportal.util.getServerPath(instance.configuration.webappdir||'resources/private');
166
167 instance.copyRecursiveSync(downloaddir + '/' + pluginsettings.id, deployedroot + '/' + pluginsettings.id)
168 simpleportal.util.deleteFolderRecursiveSync(downloaddir + '/' + pluginsettings.id);
169
170 simpleportal.pluginloader.loadPlugin(pluginsettings, function(error, newpluginsettings){
171 callback(error, pluginsettings);
172 });
173 }else
174 callback('We will update the plugin to the new version !! - ' + pluginsettings.curversion + ' >> ' + pluginsettings.version, null);
175}
176
177/**
178 * To copy files recursively
179 *
180 * @method copyRecursiveSync
181 *
182 * @param {} src Source directory
183 * @param {} dest Destination directory
184 */
185PluginUtil.prototype.copyRecursiveSync = function(src, dest) {
186 var instance = this;
187
188 var exists = fs.existsSync(src);
189 var stats = exists && fs.statSync(src);
190 var isDirectory = exists && stats.isDirectory();
191
192 if (exists && isDirectory) {
193 fs.mkdirSync(dest);
194
195 fs.readdirSync(src).forEach(
196 function(childItemName) {
197 instance.copyRecursiveSync(path.join(src, childItemName), path.join(
198 dest, childItemName));
199 }
200 );
201 } else {
202 fs.linkSync(src, dest);
203 }
204};
205
206/**
207 * To un install a plugin
208 *
209 * @method uninstallPlugin
210 * @param {} pluginsettings plugin configuration
211 * @param {callback} callback The callback to excecute when complete
212 */
213PluginUtil.prototype.uninstallPlugin = function(pluginsettings, callback){
214 var instance = this;
215 simpleportal.pluginloader.readPluginSetting(pluginsettings);
216
217 if(pluginsettings.installed){
218 if(!fs.existsSync(pluginsettings.installeddir + '-' + pluginsettings.version)){
219 fs.renameSync(pluginsettings.installeddir , pluginsettings.installeddir + '-' + pluginsettings.version);
220
221 if(fs.existsSync(pluginsettings.installeddir + '-' + pluginsettings.version + '/plugin.json'))
222 simpleportal.util.deleteFolderRecursiveSync(pluginsettings.installeddir + '-' + pluginsettings.version + '/plugin.json');
223
224 callback(null);
225 }else{
226 fs.renameSync(pluginsettings.installeddir , pluginsettings.installeddir + '-' + pluginsettings.version);
227
228 if(fs.existsSync(pluginsettings.installeddir + '-' + pluginsettings.version + '/plugin.json'))
229 simpleportal.util.deleteFolderRecursiveSync(pluginsettings.installeddir + '-' + pluginsettings.version + '/plugin.json');
230
231 callback(null);
232 }
233 }else{
234 callback('Plugin not found to uninstall!! - '+ pluginsettings.id);
235 }
236}
237
238/**
239 * To install a plugin
240 * @method installPlugin
241 * @param {} pluginsettings plugin configuration
242 * @param {callback} callback The callback to excecute when complete
243 */
244PluginUtil.prototype.installPlugin = function(pluginsettings, callback){
245 var instance = this;
246
247 simpleportal.pluginloader.readPluginSetting(pluginsettings);
248
249 var downloaddir = simpleportal.util.getServerPath(instance.configuration.downloaddir||rootdir + '/downloads');
250 var newpluginsettings = simpleportal.pluginloader.readPluginSetting({id:pluginsettings.id}, downloaddir);
251
252 if(pluginsettings.installed){
253 var curversion = Number(pluginsettings.curversion);
254 var newversion = Number(newpluginsettings.version);
255
256 if(newversion == curversion)
257 callback('Plugin is already installed with the version - ' + pluginsettings.curversion, null);
258 else if(newversion > curversion){
259 instance.checkDependencies(newpluginsettings, function(error){
260 if(error)
261 callback(error, null);
262 else{
263 instance.updatePlugin(pluginsettings, callback);
264 }
265 });
266 } else
267 callback('You are trying to install an older version !! - ' + pluginsettings.curversion + ' >> ' + pluginsettings.version, null);
268 }else{
269 instance.updatePlugin(pluginsettings, callback);
270 }
271}
272
273/**
274 * To upload a plugin
275 *
276 * @method uploadPlugin
277 *
278 * @param {} pluginsettings plugin configuration
279 * @param {callback} callback The callback to excecute when complete
280 */
281PluginUtil.prototype.uploadPlugin = function (pluginsettings, callback){
282 var instance = this;
283
284 var downloaddir = simpleportal.util.getServerPath(instance.configuration.downloaddir||rootdir + '/downloads');
285 simpleportal.util.checkDirSync(downloaddir);
286
287 if(fs.existsSync(pluginsettings.file)){
288 var escaped_downloaddir = downloaddir.replace(/ /g, '\\ ');
289
290 var cmd_bckup = 'cd '+escaped_downloaddir+' && tar -xzvf ' + pluginsettings.file;//' -C '+ path.normalize(pluginsettings.name.replace('.gz', ''));
291
292 exec(cmd_bckup, function (error, stderr, stdout) {
293 if(stderr||error){
294 callback(error, pluginsettings);
295 }else{
296 fs.readdirSync(downloaddir).forEach(function(filename){
297 if(fs.lstatSync(downloaddir + '/' + filename).isDirectory()){
298 if(fs.existsSync(downloaddir + '/' + filename +'/plugin.json')){
299 var downloadpluginsetting = simpleportal.util.readJSONFile(downloaddir + '/' + filename +'/plugin.json');
300
301 instance.installPlugin(downloadpluginsetting, callback);
302 }else{
303 simpleportal.util.deleteFolderRecursiveSync(downloaddir + '/' + filename);
304
305 callback('Not a valid plugin!!');
306 }
307 }
308 });
309 }
310 });
311 }
312}
313
314/**
315 * To download a plugin
316 *
317 * @method downloadPlugin
318 * @param {} pluginsettings plugin configuration
319 * @param {callback} callback The callback to excecute when complete
320 */
321PluginUtil.prototype.downloadPlugin = function (pluginsettings, callback){
322 var instance = this;
323
324 var pluginurl = 'http://localhost:9333/api/plugin';//default url with default port and host
325
326 if(instance.configuration.server.host)
327 pluginurl = pluginurl.replace('localhost', instance.configuration.server.host);
328
329 if(instance.configuration.server.port)
330 pluginurl = pluginurl.replace('9333', instance.configuration.server.port);
331
332 if(instance.configuration.server.secure)
333 pluginurl = pluginurl.replace('http://', 'https://');
334
335 var downloadurl = pluginurl + '/'+ pluginsettings.id +'/download';
336
337 pluginsettings.file = simpleportal.util.getServerPath(instance.configuration.downloaddir + '/' + pluginsettings.id+ '/' + pluginsettings.id + '.gz');
338
339 instance.getFile(downloadurl, pluginsettings.file, function(error, data){
340 callback(error, pluginsettings);
341 });
342}
343
344/*
345 * Exporting the PluginUtil service.
346 */
347module.exports = {
348 getInstance: function(configuration) {
349 return new PluginUtil(configuration);
350 }
351}
352
353/**
354 * @module util
355 */
\No newline at end of file