Explain the query is trying to do
[gitter.git] / scripts / utils / auto-lurk-room.js
bloba6ff670f4ec3d691b348a63c2ac34133f2209b83
1 #!/usr/bin/env node
3 'use strict';
5 var userService = require('gitter-web-users');
6 var autoLurkerService = require('gitter-web-rooms/lib/auto-lurker-service');
7 var troupeService = require('gitter-web-rooms/lib/troupe-service');
8 var persistence = require('gitter-web-persistence');
9 var collections = require('gitter-web-utils/lib/collections');
10 var Promise = require('bluebird');
11 var shutdown = require('shutdown');
12 var es = require('event-stream');
14 require('../../server/event-listeners').install();
16 var opts = require('yargs')
17   .option('room', {
18     alias: 'r',
19     description: 'Room URI'
20   })
21   .option('min', {
22     alias: 'm',
23     default: '31',
24     description: 'Minimum time in days since last login'
25   })
26   .option('members', {
27     description: 'Minimum number of members in the room'
28   })
29   .option('dryRun', {
30     type: 'boolean',
31     description: 'Just show the users who will be affected'
32   })
33   .help('help')
34   .alias('help', 'h').argv;
36 var minTimeInDays = parseInt(opts.min, 10);
37 var members = parseInt(opts.members, 10);
39 function run() {
40   if (opts.room) return handleSingleRoom();
41   if (members) return handleMultipleRooms();
42   return Promise.reject(new Error('invalid usage'));
45 function handleRoom(troupe) {
46   return (opts.dryRun
47     ? autoLurkerService.findLurkCandidates(troupe, { minTimeInDays: minTimeInDays })
48     : autoLurkerService.autoLurkInactiveUsers(troupe, { minTimeInDays: minTimeInDays })
49   )
50     .then(function(candidates) {
51       var userIds = candidates.map(function(c) {
52         return c.userId;
53       });
54       return [candidates, userService.findByIds(userIds)];
55     })
56     .spread(function(candidates, users) {
57       console.log('>>>>>>>>>>> ROOM ', troupe.uri, '> ', candidates.length, 'candidates');
58       var usersHash = collections.indexById(users);
60       candidates.forEach(function(c) {
61         var user = usersHash[c.userId];
62         if (!user) return;
64         console.log({
65           username: user.username,
66           notificationSettings: c.notificationSettings,
67           lurk: c.lurk,
68           lastAccessTime: c.lastAccessTime && c.lastAccessTime.toISOString()
69         });
70       });
71     });
74 function handleSingleRoom() {
75   return troupeService.findByUri(opts.room).then(handleRoom);
78 function handleMultipleRooms() {
79   return new Promise(function(resolve, reject) {
80     persistence.Troupe.find({ userCount: { $gt: members } })
81       .sort({ userCount: -1 })
82       .limit(10)
83       .stream()
84       .pipe(
85         es.through(function(room) {
86           this.pause();
88           var self = this;
89           return handleRoom(room)
90             .catch(function(err) {
91               self.emit('error', err);
92             })
93             .finally(function() {
94               self.resume();
95             })
96             .done();
97         })
98       )
99       .on('end', function() {
100         resolve();
101       })
102       .on('error', function(err) {
103         reject(err);
104       });
105   });
108 run()
109   // wait 5 seconds to allow for asynchronous `event-listeners` to finish
110   // https://github.com/troupe/gitter-webapp/issues/580#issuecomment-147445395
111   // https://gitlab.com/gitterHQ/webapp/merge_requests/1605#note_222861592
112   .then(() => {
113     console.log(`Waiting 5 seconds to allow for the asynchronous \`event-listeners\` to finish...`);
114     return new Promise(resolve => setTimeout(resolve, 5000));
115   })
116   .then(function() {
117     shutdown.shutdownGracefully();
118   })
119   .catch(function(err) {
120     console.error('ERROR IS ', err);
121     console.error('ERROR IS ', err.stack);
122     shutdown.shutdownGracefully(1);
123   });