From c02e3647592a2f8117c995f07d3eeae0904f82f6 Mon Sep 17 00:00:00 2001 From: Niko Storni Date: Tue, 27 Nov 2018 17:03:18 -0500 Subject: [PATCH] rewrite claimbot add missing packages rename example config update example config --- bot/modules/claimbot.js | 217 ++++++++++++++---------------------- config/default.example.json | 82 ++++++++++++++ config/default.json.example | 101 ----------------- package-lock.json | 151 ++++++++++++++++--------- package.json | 3 +- 5 files changed, 268 insertions(+), 286 deletions(-) create mode 100644 config/default.example.json delete mode 100644 config/default.json.example diff --git a/bot/modules/claimbot.js b/bot/modules/claimbot.js index 40049bd..bbc97d5 100644 --- a/bot/modules/claimbot.js +++ b/bot/modules/claimbot.js @@ -1,26 +1,24 @@ 'use strict'; -let lbry; let mongo; let discordBot; let moment = require('moment'); -let request = require('request'); -let sleep = require('sleep'); let config = require('config'); let channels = config.get('claimbot').channels; const Discord = require('discord.js'); -const rp = require('request-promise'); -const jsonfile = require('jsonfile'); const path = require('path'); const fs = require('fs'); const appRoot = require('app-root-path'); const fileExists = require('file-exists'); +const request = require('request'); +let lastProcessedBlock = 0; + module.exports = { init: init }; function init(discordBot_) { - if (lbry) { + if (discordBot) { throw new Error('init was already called once'); } @@ -35,7 +33,7 @@ function init(discordBot_) { } mongo = db; - console.log('Activating claimbot '); + console.log('Activating claimbot'); discordBot.channels.get(channels[0]).send('activating claimbot'); // Check that our syncState file exist. @@ -48,110 +46,101 @@ function init(discordBot_) { } }); setInterval(function() { - //announceClaims(); pause the claim until https://github.com/lbryio/chainquery/issues/58 has been fixed. + announceClaimsV2(); }, 60 * 1000); //announceClaims(); } - ); + ).catch(console.error); } -async function announceClaims() { - // get last block form the explorer API. - let lastBlockHeight = JSON.parse(await rp('https://explorer.lbry.io/api/v1/status')).status.height; - // get the latest claims from chainquery since last sync - let syncState = await getJSON(path.join(appRoot.path, 'syncState.json')); // get our persisted state - if (!syncState.LastSyncTime) { - syncState.LastSyncTime = new Date() - .toISOString() - .slice(0, 19) - .replace('T', ' '); - } - let claimsSince = JSON.parse(await getClaimsSince(syncState.LastSyncTime)).data; - // filter out the claims that we should add to discord - let claims = []; - for (let claim of claimsSince) { - claim.value = JSON.parse(claim.value); - if (claim.value.Claim && claim.value.Claim.stream) { - claim.metadata = claim.value.Claim.stream.metadata; - } else { - claim.metadata = null; - } - if (claim.bid_state !== 'Spent' || claim.bid_state !== 'Expired') { - claims.push(claim); - } - } - for (let claim of claims) { - console.log(claim); - } - // send each claim to discord. - for (let claim of claims) { - console.log(claim); - if (claim.metadata) { - // If its a claim, make a claimEmbed - let claimEmbed = new Discord.RichEmbed() - .setAuthor( - claim.channel ? `New claim from ${claim.channel}` : 'New claim from Anonymous', - 'http://barkpost-assets.s3.amazonaws.com/wp-content/uploads/2013/11/3dDoge.gif', - `http://open.lbry.io/${claim.channel ? `${claim.channel}#${claim.channelId}/${claim['name']}` : `${claim['name']}#${claim['claimId']}`}` - ) - .setTitle('lbry://' + (claim.channel ? `${claim.channel}/` : '') + claim['name']) - .setURL(`http://open.lbry.io/${claim.channel ? `${claim.channel}#${claim.channelId}/${claim['name']}` : `${claim['name']}#${claim['claimId']}`}`) +function announceClaimsV2() { + getClaimsForLastBlock() + .then(claims => { + let currentBlock = lastProcessedBlock; + claims.forEach(c => { + if (c.height <= lastProcessedBlock) return; + currentBlock = c.height; + console.log(JSON.stringify(c, null, 4)); + + //filter claims that we don't want to announce + if (c.bid_state === 'Expired' || c.bid_state === 'Spent') return; + + discordPost(embedFromClaim(c)); + }); + lastProcessedBlock = currentBlock; + }) + .catch(console.error); +} + +/** + * + * @param {Object} claim + * @returns {RichEmbed} discordEmbeded + */ +function embedFromClaim(claim) { + let e = new Discord.RichEmbed(); + const typeClaim = 1, + typeChannel = 2; + switch (claim.claim_type) { + case typeClaim: + let channelName = claim.channel_name ? claim.channel_name : 'Anonymous'; + let channelPermalink = claim.channel_name ? `${claim.channel_name}#${claim.publisher_id}` : ''; + let claimPermalink = claim.channel_name ? `${channelPermalink}/${claim.name}` : `${claim.name}#${claim.claim_id}`; + let metadata = JSON.parse(claim.value_as_json).claim.stream.metadata; + e.setAuthor(`New claim from ${channelName}`, 'http://barkpost-assets.s3.amazonaws.com/wp-content/uploads/2013/11/3dDoge.gif', `http://open.lbry.io/${claimPermalink}`) + .setTitle(`lbry://${claimPermalink}`) + .setURL(`http://open.lbry.io/${claimPermalink}`) .setColor(1399626) - .setFooter(`Block ${claim.height} • Claim ID ${claim.claimId} • Data from Chainquery`); - if (claim.metadata['title']) claimEmbed.addField('Title', claim.metadata['title']); - if (claim.channel) claimEmbed.addField('Channel', claim.channel); - if (claim.metadata['description']) { - claimEmbed.addField('Description', claim.metadata['description'].substring(0, 1020)); + .setFooter(`Block ${claim.height} • Claim ID ${claim.claim_id} • Data from Chainquery`); + if (metadata.title) e.addField('Title', claim.metadata['title']); + if (claim.channel_name) e.addField('Channel', claim.channel_name); + if (metadata.description) { + e.addField('Description', claim.metadata.description.substring(0, 1020)); } - if (claim.metadata['fee']) claimEmbed.addField('Fee', claim.metadata['fee'].amount + ' ' + claim.metadata['fee'].currency); - if (claim.metadata['license'] && claim.metadata['license'].length > 2) claimEmbed.addField('License', claim.metadata['license']); - if (!claim.metadata['nsfw'] && claim.metadata['thumbnail']) claimEmbed.setImage(claim.metadata['thumbnail']); + if (metadata.fee) e.addField('Fee', `${metadata.fee.amount} ${metadata.fee.currency}`); + if (metadata.license && metadata.license.length > 2) e.addField('License', metadata.license); + if (!metadata.nsfw && metadata.thumbnail) e.setImage(claim.metadata.thumbnail); if (claim.bid_state !== 'Controlling' && claim.height < claim.valid_at_height) { // Claim have not taken over the old claim, send approx time to event. - let takeoverTime = Date.now() + (claim.valid_at_height - lastBlockHeight) * 161 * 1000; // in theory this should be 150, but in practice its closer to 161 - claimEmbed.addField('Takes effect on approx', moment(takeoverTime, 'x').format('MMMM Do [at] HH:mm [UTC]') + ` • at block height ${claim.valid_at_height}`); + let blockTime = 150 * 1000; + let takeoverTime = Date.now() + (claim.valid_at_height - lastBlockHeight) * blockTime; + e.addField('Takes effect on approx', `${moment(takeoverTime, 'x').format('MMMM Do [at] HH:mm [UTC]')} • at block height ${claim.valid_at_height}`); } - claimEmbed.addField('Claimed for', `${Number.parseFloat(claim.outputValue)} LBC`); - discordPost(claimEmbed); - } else if (claim.name.charAt(0) === '@') { - // This is a channel claim - let channelEmbed = new Discord.RichEmbed() - .setAuthor('New channel claim', 'http://barkpost-assets.s3.amazonaws.com/wp-content/uploads/2013/11/3dDoge.gif', `http://open.lbry.io/${claim['name']}#${claim['claimId']}`) - .setTitle('lbry://' + (claim.channel ? claim.channel + '/' : '') + claim['name']) - .setURL(`http://open.lbry.io/${claim['name']}#${claim['claimId']}`) + e.addField('Claimed for', `${Number.parseFloat(claim.bid_amount)} LBC`); + break; + case typeChannel: + e.setAuthor('New channel claim', 'http://barkpost-assets.s3.amazonaws.com/wp-content/uploads/2013/11/3dDoge.gif', `https://open.lbry.io/${claim.name}#${claim.claim_id}`) + .setTitle(`lbry://${claim.name}`) + .setURL(`https://open.lbry.io/${claim.name}#${claim.claim_id}`) .setColor(1399626) - .setFooter(`Block ${claim.height} • Claim ID ${claim.claimId} • Data from Chainquery`) - .addField('Channel Name', claim['name']); - discordPost(channelEmbed); - } + .setFooter(`Block ${claim.height} • Claim ID ${claim.claim_id} • Data from Chainquery`) + .addField('Channel Name', claim.name); + break; } - // set the last sync time to the db. - syncState.LastSyncTime = new Date() - .toISOString() - .slice(0, 19) - .replace('T', ' '); - await saveJSON(path.join(appRoot.path, 'syncState.json'), syncState); + return e; } -function getJSON(path) { +/** + * + * @returns {Promise} claims in last block + */ +function getClaimsForLastBlock() { return new Promise((resolve, reject) => { - jsonfile.readFile(path, function(err, jsoncontent) { - if (err) { - reject(err); - } else { - resolve(jsoncontent); - } - }); - }); -} -function saveJSON(path, obj) { - return new Promise((resolve, reject) => { - jsonfile.writeFile(path, obj, function(err, jsoncontent) { - if (err) { - reject(err); - } else { - resolve(); - } + let query = + 'SELECT t1.*, t3.name AS channel_name, t4.value AS bid_amount FROM claim t1 INNER JOIN (SELECT MAX(height) AS height FROM block) t2 ON t1.height = t2.height LEFT JOIN claim t3 ON t1.publisher_id = t3.claim_id LEFT JOIN output t4 ON (t1.transaction_hash_id = t4.transaction_hash AND t1.vout = t4.vout)'; + let options = { + method: 'GET', + url: 'https://chainquery.lbry.io/api/sql', + qs: { query: query }, + headers: { 'Cache-Control': 'no-cache' } + }; + + request(options, function(error, response, body) { + if (error) return reject(error); + if (response.statusCode !== 200 || !body) return reject(response); + if (!body.success || body.error) return reject(response); + let claimsInBlock = body.data; + return resolve(claimsInBlock); }); }); } @@ -164,39 +153,3 @@ function discordPost(embed) { .catch(console.error); }); } - -function getClaimsSince(time) { - return new Promise((resolve, reject) => { - let query = - `` + - `SELECT ` + - `c.name,` + - `c.valid_at_height,` + - `c.height,` + - `p.name as channel,` + - `c.publisher_id as channelId,` + - `c.bid_state,` + - `c.effective_amount,` + - `c.claim_id as claimId,` + - `c.value_as_json as value, ` + - `c.transaction_hash_id, ` + // txhash and vout needed to leverage old format for comparison. - `c.vout, ` + - `o.value as outputValue ` + - `FROM claim c ` + - `LEFT JOIN claim p on p.claim_id = c.publisher_id ` + - `LEFT JOIN output o on (o.transaction_hash=c.transaction_hash_id and o.vout=c.vout) ` + - `WHERE c.created_at >='` + - time + - `'`; - // Outputs full query to console for copy/paste into chainquery (debugging) - // console.log(query); - rp(`https://chainquery.lbry.io/api/sql?query=` + query) - .then(function(htmlString) { - resolve(htmlString); - }) - .catch(function(err) { - console.log('error', '[Importer] Error getting updated claims. ' + err); - reject(err); - }); - }); -} diff --git a/config/default.example.json b/config/default.example.json new file mode 100644 index 0000000..e0d3d1f --- /dev/null +++ b/config/default.example.json @@ -0,0 +1,82 @@ +{ + // Bot configuration + "bot": { + "token": "", + "prefix": "!", + "debug": false + }, + "moderation": { + "perms": ["Moderator Team", "LBRY TEAM"], // Roles that have access to all commands. + "logchannel": "371620338263523328" // Channel to log the bots moderation.. + }, + "lbrycrd": { + "host": "localhost", + "port": 9245, + "user": "USERHERE", + "pass": "PASSWORDHERE" + }, + "mongodb": { + "url": "mongodb://localhost:27017/wunderbot" + }, + "Channels": { + "verification": "363050496023592961", + "mining": "363049669636390913", + "random": "363084227518136322" + }, + "speechbot": { + "channels": [ + "363089721313722387", + "363085078403874823", + "363086945976320010", + "363086925428555776", + "363086752518242308", + "369896313082478594", + "363087606239461377", + "363088045366312962", + "363084227518136322", + "363084262028607488", + "371620338263523328" + ], // Channels speech bot is allowed to post in + "mainchannel": "363085078403874823" // Main Speech Bot channel for directing with help message + }, + "pricebot": { + "channels": ["363050205043621908", "369896313082478594", "371620338263523328"], // Chanels price bot is allowed to post in + "mainchannel": "363050205043621908" // Main Price Bot channel for directing with help message + }, + "gitrelease": { + "channel": "370779899650375681" // Channel to send release info to using + }, + "spamdetection": { + "channels": ["363089721313722387", "363044238486798336", "363086719391629326", "363044275363119105", "363044260938776576", "372067478542745601", "369896313082478594", "371620338263523328"], // Channels excluded from Spam Detection + "users": ["244245498746241025"] // Users to exclude from Spam Detection (include other bots here) + }, + "hashbot": { + "channels": ["363049669636390913", "369896313082478594", "371620338263523328"], // Channels Hash Bot is allowed to post in + "mainchannel": "363049669636390913" // Main Hash Bot channel for directing with help message + }, + "statsbot": { + "channels": ["363050205043621908", "369896313082478594", "371620338263523328"], // Channels Stats Bot is allowed to post in + "mainchannel": "363050205043621908" // Main Stats Bot channel for directing with help message + }, + "claimbot": { + "channels": ["363086719391629326"] + }, + "rolelist": { + "baserole": "LBRYian", + "allowedroles": ["NSFW", "Traders", "Miners", "Off-Topic Chats", "International", "Dev"] + }, + "irc": { + "nickname": "wunderbot", + "server": "chat.freenode.net", + "discordToken": "", + "ircOptions": { + "userName": "wunderbot", + "nick": "wunderbot", + "password": "", + "sasl": true + }, + "channelMapping": { + "#shared": "#lbry" + } + } +} diff --git a/config/default.json.example b/config/default.json.example deleted file mode 100644 index e844279..0000000 --- a/config/default.json.example +++ /dev/null @@ -1,101 +0,0 @@ -{ - // Bot configuration - "bot": { - "token": "discordbottoken", - "prefix": "!", - "debug": false - }, - "moderation": { - "perms": ["Moderator Team","LBRY TEAM"], // Roles that have access to all commands. - "logchannel": "371620338263523328" // Channel to log the bots moderation.. - }, - //define channels for Commands.js usage - "Channels": { - "verification": "363050496023592961", - "mining": "363049669636390913", - "random": "363084227518136322", - "content": "377938982111019010" - }, - "speechbot": { - "channels": [ - "363089721313722387", - "363085078403874823", - "363086945976320010", - "363086925428555776", - "363086752518242308", - "369896313082478594", - "363087606239461377", - "363088045366312962", - "363084227518136322", - "363084262028607488", - "371620338263523328" - ], // Channels speech bot is allowed to post in - "mainchannel": "363085078403874823" // Main Speech Bot channel for directing with help message - }, - "pricebot": { - "channels": [ - "363050205043621908", - "369896313082478594", - "371620338263523328" - ], // Chanels price bot is allowed to post in - "mainchannel": "363050205043621908" // Main Price Bot channel for directing with help message - }, - "gitrelease": { - "channel": "370779899650375681" // Channel to send release info to using - }, - "spamdetection": { - "channels": [ - "363089721313722387", - "363044238486798336", - "363086719391629326", - "363044275363119105", - "363044260938776576", - "372067478542745601", - "369896313082478594", - "371620338263523328" - ], // Channels excluded from Spam Detection - "users": [ - "244245498746241025" - ] // Users to exclude from Spam Detection (include other bots here) - }, - "hashbot": { - "channels": [ - "363049669636390913", - "369896313082478594", - "371620338263523328" - ], // Channels Hash Bot is allowed to post in - "mainchannel": "363049669636390913" // Main Hash Bot channel for directing with help message - }, - "statsbot": { - "channels": [ - "363050205043621908", - "369896313082478594", - "371620338263523328" - ], // Channels Stats Bot is allowed to post in - "mainchannel": "363050205043621908" // Main Stats Bot channel for directing with help message - }, - "rolelist": { - // The roles here are Case Sensitive to how they are in your Discord Server! - "baserole": "LBRYian", - "allowedroles": ["NSFW", "Marketers", "Miners", "Off-Topic Chats", "International", "Dev"] - }, - "claimbot": { - "channels": [ - "377938982111019010" - ] - }, - "mongodb": { - "url": "mongodb://HOST:PORT/DATABASE" - }, - "irc": { - "nickname": "nick", - "server": "chat.freenode.net", - "discordToken": "tokenhere", - "autoSendCommands": [ - ["PRIVMSG", "NickServ", "IDENTIFY password"] - ], - "channelMapping": { - "#shared": "#lbry" - } - } -} diff --git a/package-lock.json b/package-lock.json index 29fd3e8..cf2183d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -606,9 +606,9 @@ } }, "bson": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz", - "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.0.tgz", + "integrity": "sha512-9Aeai9TacfNtWXOYarkFJRW2CWo+dRon+fuLZYJmvLV3+MiUp0bEI6IAZfXEIg7/Pl/7IWlLaDnhzTsD81etQA==" }, "buffer-shims": { "version": "1.0.0", @@ -664,7 +664,7 @@ }, "callsites": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "dev": true }, @@ -844,9 +844,9 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "config": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/config/-/config-2.0.1.tgz", - "integrity": "sha512-aTaviJnC8ZjQYx8kQf4u6tWqIxWolyQQ3LqXgnCLAsIb78JrUshHG0YuzIarzTaVVe1Pazms3TXImfYra8UsyQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/config/-/config-2.0.2.tgz", + "integrity": "sha512-duIbkKb0gls0bOtGwd1vaD4236MwepQlZcrMheOGrn3/9Px7oYFh8G4LB3ylGOlPr5wGoJRm8Grb2RihJZxuHQ==", "requires": { "json5": "^1.0.1" }, @@ -1183,7 +1183,7 @@ }, "expand-range": { "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "optional": true, "requires": { @@ -1970,9 +1970,9 @@ } }, "husky": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/husky/-/husky-1.1.4.tgz", - "integrity": "sha512-cZjGpS7qsaBSo3fOMUuR7erQloX3l5XzL1v/RkIqU6zrQImDdU70z5Re9fGDp7+kbYlM2EtS4aYMlahBeiCUGw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-1.2.0.tgz", + "integrity": "sha512-/ib3+iycykXC0tYIxsyqierikVa9DA2DrT32UEirqNEFVqOj1bFMTgP3jAz8HM7FgC/C8pc/BTUa9MV2GEkZaA==", "dev": true, "requires": { "cosmiconfig": "^5.0.6", @@ -2503,6 +2503,12 @@ "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", "optional": true }, + "memory-pager": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.1.0.tgz", + "integrity": "sha512-Mf9OHV/Y7h6YWDxTzX/b4ZZ4oh9NSXblQL8dtPCOomOtZciEHxePR78+uHFLLlsk01A6jVHhHsQZZ/WcIPpnzg==", + "optional": true + }, "micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", @@ -2583,51 +2589,23 @@ "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" }, "mongodb": { - "version": "2.2.34", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.34.tgz", - "integrity": "sha1-o09Zu+thdUrsQy3nLD/iFSakTBo=", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.1.10.tgz", + "integrity": "sha512-Uml42GeFxhTGQVml1XQ4cD0o/rp7J2ROy0fdYUcVitoE7vFqEhKH4TYVqRDpQr/bXtCJVxJdNQC1ntRxNREkPQ==", "requires": { - "es6-promise": "3.2.1", - "mongodb-core": "2.1.18", - "readable-stream": "2.2.7" - }, - "dependencies": { - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" - }, - "readable-stream": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", - "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", - "requires": { - "buffer-shims": "~1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "~5.1.0" - } - } + "mongodb-core": "3.1.9", + "safe-buffer": "^5.1.2" } }, "mongodb-core": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz", - "integrity": "sha1-TEYTm986HwMt7ZHbSfOO7AFlkFA=", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.9.tgz", + "integrity": "sha512-MJpciDABXMchrZphh3vMcqu8hkNf/Mi+Gk6btOimVg1XMxLXh87j6FAvRm+KmwD1A9fpu3qRQYcbQe4egj23og==", "requires": { - "bson": "~1.0.4", - "require_optional": "~1.0.0" + "bson": "^1.1.0", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" } }, "mongoose": { @@ -2657,6 +2635,57 @@ "requires": { "lodash": "^4.14.0" } + }, + "bson": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz", + "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==" + }, + "mongodb": { + "version": "2.2.34", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.34.tgz", + "integrity": "sha1-o09Zu+thdUrsQy3nLD/iFSakTBo=", + "requires": { + "es6-promise": "3.2.1", + "mongodb-core": "2.1.18", + "readable-stream": "2.2.7" + } + }, + "mongodb-core": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz", + "integrity": "sha1-TEYTm986HwMt7ZHbSfOO7AFlkFA=", + "requires": { + "bson": "~1.0.4", + "require_optional": "~1.0.0" + } + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "readable-stream": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", + "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", + "requires": { + "buffer-shims": "~1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "~5.1.0" + } } } }, @@ -3606,6 +3635,15 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "saslprep": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.2.tgz", + "integrity": "sha512-4cDsYuAjXssUSjxHKRe4DTZC0agDwsCqcMqtJAQPzC74nJ7LfAJflAtC1Zed5hMzEQKj82d3tuzqdGNRsLJ4Gw==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -3834,6 +3872,15 @@ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } + }, "spdx-correct": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", @@ -3996,7 +4043,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" diff --git a/package.json b/package.json index 2fe2e2d..0f5d38d 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "request": "^2.85.0", "request-promise": "^4.2.2", "sleep": "^5.1.1", - "wget": "^0.0.1" + "wget": "^0.0.1", + "mongodb": "latest" }, "scripts": { "prettier": "prettier --write \"{bot,.}/**/*.{js,json}\" --single-quote --print-width 240",