1 | #! /usr/bin/env node
|
2 |
|
3 | 'use strict';
|
4 |
|
5 | var program = require('commander'),
|
6 | fs = require('fs'),
|
7 | path = require('path');
|
8 |
|
9 | var ueberDB = require('ueberdb2'),
|
10 | jsonminify = require('jsonminify'),
|
11 | forever = require('async/forever'),
|
12 | eachSeries = require('async/eachSeries'),
|
13 | eachOfSeries = require('async/eachOfSeries');
|
14 |
|
15 | var JOBQ_PREFIX = require('../storage').DBPREFIX.JOBQ;
|
16 |
|
17 |
|
18 | program
|
19 | .version('0.1.0')
|
20 | .option('-s, --settings <file>', '[MANDATORY] the path to your Etherpad\'s settings.json file')
|
21 | .option('-q, --quiet', '[OPTIONAL] low verbosity')
|
22 | .option('-o, --oneshot', '[OPTIONAL] don\'t start a loop, process the jobs and exit')
|
23 | .parse(process.argv);
|
24 |
|
25 |
|
26 | if (!program.settings) {
|
27 | console.log('');
|
28 | console.log('=====================================================================');
|
29 | console.log(' You must provide the path to your Etherpad\'s settings.json file!');
|
30 | console.log('=====================================================================');
|
31 | program.help();
|
32 | }
|
33 |
|
34 |
|
35 | var settingsFilename = path.resolve(program.settings);
|
36 | var settingsStr = fs.readFileSync(settingsFilename).toString();
|
37 | var settings;
|
38 | try {
|
39 | if(settingsStr) {
|
40 | settingsStr = jsonminify(settingsStr).replace(',]',']').replace(',}','}');
|
41 | settings = JSON.parse(settingsStr);
|
42 | }
|
43 | } catch(e) {
|
44 | console.error('There was an error processing your settings.json file: '+e.message);
|
45 | process.exit(1);
|
46 | }
|
47 |
|
48 |
|
49 | var db = new ueberDB.database(settings.dbType, { cache: 0, writeInterval: 0 });
|
50 |
|
51 |
|
52 |
|
53 |
|
54 | function exitIfErr(err) {
|
55 | console.log('=====================');
|
56 | console.error(err);
|
57 | return db.doShutdown(function() { process.exit(1); });
|
58 | }
|
59 |
|
60 |
|
61 | function removeRecord(key, callback) {
|
62 | db.remove(key, function(err) {
|
63 | if (err) { return exitIfErr(err); }
|
64 | callback();
|
65 | });
|
66 | }
|
67 |
|
68 | function deletePads(nextLoop) {
|
69 | if (!program.quiet) { console.log('Entering loop'); }
|
70 |
|
71 | db.findKeys(JOBQ_PREFIX+'deletePad:*', null, function(err, pads) {
|
72 | if (err) { return exitIfErr(err); }
|
73 |
|
74 | if (pads !== null && pads.length > 0) {
|
75 | if (!program.quiet) { console.log('Pads to delete: '+pads); }
|
76 |
|
77 | eachOfSeries(pads, function(padId, index, next) {
|
78 | padId = padId.substring(26);
|
79 |
|
80 | if (!program.quiet) { console.log('Starting deletion of '+padId); }
|
81 |
|
82 |
|
83 |
|
84 | db.get('pad2readonly:'+padId, function(err, readonly2pad) {
|
85 | if (err) { return exitIfErr(err); }
|
86 |
|
87 |
|
88 | db.remove('readonly2pad:'+readonly2pad, function(err) {
|
89 | if (err) { return exitIfErr(err); }
|
90 |
|
91 |
|
92 | db.remove('pad2readonly:'+padId, function(err) {
|
93 | if (err) { return exitIfErr(err); }
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 | db.findKeys('pad:'+padId+':revs:*', null, function(err, keys) {
|
100 | if (err) { return exitIfErr(err); }
|
101 |
|
102 |
|
103 | eachSeries(keys, removeRecord, function(err) {
|
104 | if (err) { return exitIfErr(err); }
|
105 |
|
106 |
|
107 | db.findKeys('pad:'+padId+':chat:*', null, function(err, keys) {
|
108 | if (err) { return exitIfErr(err); }
|
109 |
|
110 |
|
111 | eachSeries(keys, removeRecord, function(err) {
|
112 | if (err) { return exitIfErr(err); }
|
113 |
|
114 |
|
115 | db.remove('mypads:jobqueue:deletePad:'+padId, function(err) {
|
116 | if (err) { return exitIfErr(err); }
|
117 |
|
118 | if (!program.quiet) { console.log('End deletion of '+padId); }
|
119 | return next();
|
120 | });
|
121 | });
|
122 | });
|
123 | });
|
124 | });
|
125 | });
|
126 | });
|
127 | });
|
128 | }, function(err) {
|
129 | if (err) { return exitIfErr(err); }
|
130 |
|
131 | if (program.oneshot) {
|
132 | return db.doShutdown(function() { process.exit(0); });
|
133 | } else {
|
134 | nextLoop();
|
135 | }
|
136 | });
|
137 | } else {
|
138 | if (!program.quiet) { console.log('No pad to process'); }
|
139 |
|
140 | if (program.oneshot) {
|
141 | return db.doShutdown(function() { process.exit(0); });
|
142 | } else {
|
143 | setTimeout(nextLoop, 1000);
|
144 | }
|
145 | }
|
146 | });
|
147 | }
|
148 |
|
149 |
|
150 |
|
151 |
|
152 | db.init(function(err) {
|
153 | if (err) { return exitIfErr(err); }
|
154 | if (program.oneshot) {
|
155 | deletePads();
|
156 | } else {
|
157 | forever(deletePads, exitIfErr);
|
158 | }
|
159 | });
|