1 | #! /usr/bin/env node
|
2 |
|
3 | 'use strict';
|
4 |
|
5 |
|
6 | var program = require('commander'),
|
7 | fs = require('fs'),
|
8 | path = require('path');
|
9 |
|
10 | var _cliProgress = require('cli-progress');
|
11 |
|
12 | var ueberDB = require('ueberdb2'),
|
13 | jsonminify = require('jsonminify'),
|
14 | eachSeries = require('async/eachSeries'),
|
15 | eachOfSeries = require('async/eachOfSeries');
|
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('-n, --dryrun', '(optional) just count the number of pads that would have been normally deleted')
|
22 | .parse(process.argv);
|
23 |
|
24 |
|
25 | if (!program.settings) {
|
26 | console.log('');
|
27 | console.log('=====================================================================');
|
28 | console.log(' You must provide the path to your Etherpad\'s settings.json file!');
|
29 | console.log('=====================================================================');
|
30 | program.help();
|
31 | }
|
32 |
|
33 |
|
34 | var settingsFilename = path.resolve(program.settings);
|
35 | var settingsStr = fs.readFileSync(settingsFilename).toString();
|
36 | var settings;
|
37 | try {
|
38 | if(settingsStr) {
|
39 | settingsStr = jsonminify(settingsStr).replace(',]',']').replace(',}','}');
|
40 | settings = JSON.parse(settingsStr);
|
41 | }
|
42 | } catch(e) {
|
43 | console.error('There was an error processing your settings.json file: '+e.message);
|
44 | process.exit(1);
|
45 | }
|
46 |
|
47 |
|
48 | var db = new ueberDB.database(settings.dbType, settings.dbSettings, {cache: 0, writeInterval: 0});
|
49 |
|
50 |
|
51 |
|
52 |
|
53 | function exitIfErr(err) {
|
54 | console.log('=====================');
|
55 | console.error(err);
|
56 | return db.doShutdown(function() { process.exit(1); });
|
57 | }
|
58 |
|
59 |
|
60 | function removeRecord(key, callback) {
|
61 | db.remove(key, function(err) {
|
62 | if (err) { return exitIfErr(err); }
|
63 | callback();
|
64 | });
|
65 | }
|
66 |
|
67 |
|
68 |
|
69 |
|
70 | db.init(function(err) {
|
71 | if (err) { return exitIfErr(err); }
|
72 |
|
73 | db.get('mypads:conf:allowEtherPads', function(err, val) {
|
74 | if (err) { return exitIfErr(err); }
|
75 |
|
76 |
|
77 | if (val !== false) {
|
78 | console.log(' _______________');
|
79 | console.log('|===============|');
|
80 | console.log('|: .---------. :|');
|
81 | console.log('|: | HAL-9000| :|');
|
82 | console.log('|: \'---------\' :|');
|
83 | console.log('|: :| ________________________________________');
|
84 | console.log('|: :| / I\'m sorry, Dave, I\'m afraid I can\'t do \\');
|
85 | console.log('|: :| \\ that. /');
|
86 | console.log('|: :| ----------------------------------------');
|
87 | console.log('|: _ :| /');
|
88 | console.log('|: ,` `. :| __/');
|
89 | console.log('|: : (o) : :|');
|
90 | console.log('|: `. _ ,` :|');
|
91 | console.log('|: :|');
|
92 | console.log('|:_____________:|');
|
93 | console.log('|:=============:|');
|
94 | console.log('|:*%*%*%*%*%*%*:|');
|
95 | console.log('|:%*%*%*%*%*%*%:|');
|
96 | console.log('|:*%*%*%*%*%*%*:|');
|
97 | console.log('|:%*%*%*%*%*%*%:|');
|
98 | console.log('\'===============\'');
|
99 | console.log('');
|
100 | console.log('================================================');
|
101 | console.log('It seems that you allow anonymous pads.');
|
102 | console.log('This script would delete all the anonymous pads.');
|
103 | console.log('Exiting');
|
104 | console.log('================================================');
|
105 | return db.doShutdown(function() { process.exit(1); });
|
106 | }
|
107 |
|
108 |
|
109 | db.findKeys('readonly2pad:*', null, function(err, keys) {
|
110 | if (err) { return exitIfErr(err); }
|
111 |
|
112 | var candidatesForDeletion = 0;
|
113 |
|
114 | if (keys.length === 0) {
|
115 | console.log('No pads to check.');
|
116 | return db.doShutdown(function() { process.exit(0); });
|
117 | }
|
118 |
|
119 | console.log(keys.length+' pad(s) to check.');
|
120 |
|
121 |
|
122 | var bar = new _cliProgress.Bar({
|
123 | format: '[{bar}] {percentage}% | ETA: {eta}s | {val}/{tot}',
|
124 | stopOnComplete: true,
|
125 | hideCursor: true,
|
126 | barsize: 60,
|
127 | fps: 60
|
128 | }, _cliProgress.Presets.shades_grey);
|
129 | bar.start(2 * keys.length, 0, { val: 0, tot: keys.length });
|
130 |
|
131 |
|
132 | eachOfSeries(keys, function(readonly2pad, index, next) {
|
133 | bar.increment(1, { val: index + 1 });
|
134 |
|
135 |
|
136 | db.get(readonly2pad, function(err, padId) {
|
137 | if (err) { return exitIfErr(err); }
|
138 |
|
139 |
|
140 | db.get('mypads:pad:'+padId, function(err, val) {
|
141 | if (err) { return exitIfErr(err); }
|
142 |
|
143 |
|
144 | if (val === null) {
|
145 | if (program.dryrun) {
|
146 | bar.increment();
|
147 | candidatesForDeletion++;
|
148 | return next();
|
149 | }
|
150 |
|
151 |
|
152 | db.remove(readonly2pad, function(err) {
|
153 | if (err) { return exitIfErr(err); }
|
154 |
|
155 |
|
156 | db.remove('pad2readonly:'+padId, function(err) {
|
157 | if (err) { return exitIfErr(err); }
|
158 |
|
159 |
|
160 | db.remove('pad:'+padId, function(err) {
|
161 | if (err) { return exitIfErr(err); }
|
162 |
|
163 |
|
164 | db.findKeys('pad:'+padId+':revs:*', null, function(err, keys) {
|
165 | if (err) { return exitIfErr(err); }
|
166 |
|
167 |
|
168 | eachSeries(keys, removeRecord, function(err) {
|
169 | if (err) { return exitIfErr(err); }
|
170 |
|
171 | db.findKeys('pad:'+padId+':chat:*', null, function(err, keys) {
|
172 | if (err) { return exitIfErr(err); }
|
173 |
|
174 |
|
175 | eachSeries(keys, removeRecord, function(err){
|
176 | if (err) { return exitIfErr(err); }
|
177 | bar.increment();
|
178 | return next();
|
179 | });
|
180 | });
|
181 | });
|
182 | });
|
183 | });
|
184 | });
|
185 | });
|
186 | } else {
|
187 |
|
188 | bar.increment();
|
189 | return next();
|
190 | }
|
191 | });
|
192 | });
|
193 | }, function(err) {
|
194 | if (err) { return exitIfErr(err); }
|
195 |
|
196 |
|
197 | setTimeout(function() {
|
198 | console.log(keys.length+' pad(s) checked.');
|
199 |
|
200 | if (program.dryrun) {
|
201 | console.log(candidatesForDeletion+' pad(s) would have been deleted.');
|
202 | }
|
203 |
|
204 | return db.doShutdown(function() { process.exit(0); });
|
205 | }, 100);
|
206 | });
|
207 | });
|
208 | });
|
209 | });
|