From 31b22ca792e3d26a586dea11f3134826ea051747 Mon Sep 17 00:00:00 2001 From: Yami Date: Sun, 16 Aug 2015 19:51:44 -0400 Subject: [PATCH 01/10] Adding some basic logic Doesn't work yet though. --- plugins/powerlevel.js | 73 ++++++++++++++++++++++++++++----- test/plugins/powerlevelTest.js | 75 +++++++++++++++++++++++++++++++++- 2 files changed, 137 insertions(+), 11 deletions(-) diff --git a/plugins/powerlevel.js b/plugins/powerlevel.js index 2e3c35d7..17c9bb85 100644 --- a/plugins/powerlevel.js +++ b/plugins/powerlevel.js @@ -10,6 +10,7 @@ */ const utils = require('../lib/utils'); +const async = require('async'); const internals = { browser: null, @@ -49,27 +50,27 @@ const userActions = { exports.defaultConfig = { trustLevel: 2, requirements: { - tl1: { - topics: 5, - posts: 30, + 1: { + topicsRead: 5, + postsRead: 30, time: 10, likesGiven: 0, likesReceived: 0, replies: 0, days: 0 }, - tl2: { - topics: 20, - posts: 100, + 2: { + topicsRead: 20, + postsRead: 100, time: 60, likesGiven: 1, likesReceived: 1, replies: 3, days: 15 }, - tl3: { - topics: 10, - posts: 0, + 3: { + topicsRead: 10, + postsRead: 0, postPercentage: 25, topicPercentage: 25, time: 60, @@ -107,7 +108,59 @@ exports.prepare = function prepare(config, _, events, browser) { * Start the plugin after login */ exports.start = function start() { - exports.updateSelf(); + exports.updateSelf(function() { + if (internals.configuration.trustLevel < internals.me.trustLevel) { + exports.increaseTrustLevel(); + } + }); +}; + +exports.giveLikes = function(numLikes, callback) { + internals.browser.createPrivateMessage(internals.username, + 'Spamming for likes, ignore me', + 'Spamming for likes (' + Math.random() + ')', + function(err, response) { + if (err) { + callback(err); + return; + } + const postID = response.id; + + internals.browser.postAction(2, postID, '', function() { + async.times(numLikes - 1, function(n, next) { + internals.browser.createPost(postID, + null, + 'Spamming for likes (' + Math.random() + ')', + function(error, resp1) { + if (error) { + next(error); + } + internals.browser.postAction(2, resp1.id, '', next); + }); + }, function(error) { + callback(error); + }); + }); + }); +}; + +exports.increaseTrustLevel = function(callback) { + //Figure out why we're not high enough + const requirements = internals.configuration.requirements[exports.config.trustLevel]; + + //Guess easy shit first + if (internals.me.likesGiven < requirements.likesGiven) { + exports.giveLikes(requirements.likesGiven - internals.me.likesGiven, function() { + exports.updateSelf(); + }); + } + + if (internals.me.likesReceived < requirements.likesReceived) { + exports.giveLikes(requirements.likesReceived - internals.me.likesReceived, function() { + exports.updateSelf(); + }); + } + callback(); }; /** diff --git a/test/plugins/powerlevelTest.js b/test/plugins/powerlevelTest.js index 543b4298..efb7109f 100644 --- a/test/plugins/powerlevelTest.js +++ b/test/plugins/powerlevelTest.js @@ -14,7 +14,8 @@ const powerlevel = require('../../plugins/powerlevel'), describe('Powerlevel plugin', () => { describe('exports', () => { - const fns = ['prepare', 'start', 'stop', 'updateSelf'], + const fns = ['prepare', 'start', 'stop', 'updateSelf', + 'giveLikes', 'increaseTrustLevel'], objs = ['internals', 'defaultConfig']; fns.forEach(fn => it('should export ' + fn + '()', () => { expect(powerlevel[fn]).to.be.a('function'); @@ -164,4 +165,76 @@ describe('Powerlevel plugin', () => { }); }); }); + + describe('giveLikes()', () => { + let sandbox; + const config = { + core: { + username: 'yamikuronue' + } + }; + + beforeEach(() => { + sandbox = sinon.sandbox.create(); + sandbox.stub(utils, 'mergeObjects'); + }); + + afterEach(() => sandbox.restore()); + + it('Should start a PM chain to like', () => { + const fakeBrowser = { + createPrivateMessage: sandbox.stub().yields(null, {id: 15}), + createPost: sandbox.stub().yields(null, {id: 16}), + postAction:sandbox.stub().yields() + }; + + powerlevel.prepare(null, config, {}, fakeBrowser); + + powerlevel.giveLikes(1, function(err) { + expect(fakeBrowser.createPrivateMessage).to.have.been.calledOnce;//Create the PM + expect(fakeBrowser.postAction).to.have.been.calledWith(2, 15, ''); //Like on the post + expect(fakeBrowser.createPost).not.to.have.been.called; //reply: none needed + expect(err).to.be.falsey; + }); + }); + + it('Should reply to the same PM for the second like', (done) => { + const fakeBrowser = { + createPrivateMessage: sandbox.stub().yields(null, {id: 15}), + createPost: sandbox.stub().yields(null, {id: 16}), + postAction:sandbox.stub().yields() + }; + + powerlevel.prepare(null, config, {}, fakeBrowser); + + powerlevel.giveLikes(2, function(err) { + expect(fakeBrowser.createPrivateMessage).to.have.been.calledOnce; + expect(fakeBrowser.createPost).to.have.been.calledOnce; + expect(fakeBrowser.createPost).to.have.been.calledWith(15); + expect(fakeBrowser.postAction).to.have.been.calledWith(2, 15, ''); //Like on the post + expect(fakeBrowser.postAction).to.have.been.calledWith(2, 16, ''); //Like on the rely + expect(err).to.be.falsey; + done(); + }); + }); + + it('Should gather the correct amount of likes', (done) => { + const numLikes = Math.ceil(Math.random * 5 + 2); + const fakeBrowser = { + createPrivateMessage: sandbox.stub().yields(null, {id: 15}), + createPost: sandbox.stub().yields(null, {id: 16}), + postAction:sandbox.stub().yields() + }; + + powerlevel.prepare(null, config, {}, fakeBrowser); + + powerlevel.giveLikes(numLikes, function(err) { + expect(err).to.be.falsey; + expect(fakeBrowser.createPrivateMessage).to.have.been.calledOnce; + expect(fakeBrowser.createPost).to.have.callCount(numLikes - 1); + expect(fakeBrowser.postAction).to.have.callCount(numLikes); + done(); + }); + }); + }); }); From 2017f261ea645a2984d3f74b11f00a51445f4d1d Mon Sep 17 00:00:00 2001 From: RaceProUK Date: Sat, 12 Sep 2015 17:26:34 +0000 Subject: [PATCH 02/10] Fix signature on post edit Fixes #252 --- lib/browser.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/browser.js b/lib/browser.js index 32e5a1a1..70795169 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -427,12 +427,13 @@ function editPost(postId, content, editReason, callback) { if (typeof callback !== 'function') { throw new Error('callback must be supplied'); } + const signature = internals.signature.replace('%NOW%', new Date().toISOString()); this.queue.push({ method: 'PUT', url: '/posts/' + postId, form: { post: { - raw: content + internals.signature, + raw: content + signature, 'edit_reason': editReason } }, From cb1bd659453649e8d54b0801df9f8b7e046336a7 Mon Sep 17 00:00:00 2001 From: Yamikuronue Date: Thu, 24 Sep 2015 14:44:52 -0400 Subject: [PATCH 03/10] Removing in-progress and unsupported powerlevel plugin The work in progress has been moved to its own branch so we stop shipping half-finished code --- plugins/powerlevel.js | 211 ---------------------------- test/plugins/powerlevelTest.js | 245 --------------------------------- 2 files changed, 456 deletions(-) delete mode 100644 plugins/powerlevel.js delete mode 100644 test/plugins/powerlevelTest.js diff --git a/plugins/powerlevel.js b/plugins/powerlevel.js deleted file mode 100644 index efb72317..00000000 --- a/plugins/powerlevel.js +++ /dev/null @@ -1,211 +0,0 @@ -'use strict'; -/** - * PowerLevel plugin - * - * Attempts to obtain and maintain a trust level - * - * @module powerlevel - * @author Yamikuronue - * @license MIT - */ - - -const utils = require('../lib/utils'); -const async = require('async'); - -const internals = { - browser: null, - configuration: exports.defaultConfig, - username: null, - me: { - trustLevel: 0, - topicsCreated: 0, - postsMade: 0, - timeSpent: 0, - likesGiven: 0, - likeReceived: 0, - replies: 0, - days: 0 - } -}; -exports.internals = internals; - -const userActions = { - likeGiven: 1, - likeReceived: 2, - bookmarked: 3, - createTopic: 4, - reply: 5, - repliedTo: 6, - mentioned: 7, - quote: 9, - edited: 11, - msgSent: 12, - msgReceived: 13, - pending: 14 -}; - -/** - * Default plugin configuration - */ -exports.defaultConfig = { - trustLevel: 2, - requirements: { - 1: { - topicsRead: 5, - postsRead: 30, - time: 10, - likesGiven: 0, - likesReceived: 0, - replies: 0, - days: 0 - }, - 2: { - topicsRead: 20, - postsRead: 100, - time: 60, - likesGiven: 1, - likesReceived: 1, - replies: 3, - days: 15 - }, - 3: { - topicsRead: 10, - postsRead: 0, - postPercentage: 25, - topicPercentage: 25, - time: 60, - likesGiven: 30, - likesReceived: 20, - replies: 3, - days: 50 - } - } -}; - -/** - * Prepare Plugin prior to login - * - * @param {*} plugConfig Plugin specific configuration - * @param {Config} config Overall Bot Configuration - * @param {externals.events.SockEvents} events EventEmitter used for the bot - * @param {Browser} browser Web browser for communicating with discourse - */ -exports.prepare = function prepare(plugConfig, config, events, browser) { - if (plugConfig === null) { - plugConfig = {}; - } - internals.browser = browser; - internals.configuration = config.mergeObjects(exports.defaultConfig, plugConfig); - - if (!config || !config.core || !config.core.username) { - throw new Error('Invalid config provided!'); - } else { - internals.username = config.core.username; - } -}; - -/** - * Start the plugin after login - */ -exports.start = function start() { - exports.updateSelf(function() { - if (internals.configuration.trustLevel < internals.me.trustLevel) { - exports.increaseTrustLevel(); - } - }); -}; - -exports.giveLikes = function(numLikes, callback) { - internals.browser.createPrivateMessage(internals.username, - 'Spamming for likes, ignore me', - 'Spamming for likes (' + Math.random() + ')', - function(err, response) { - if (err) { - callback(err); - return; - } - const postID = response.id; - - internals.browser.postAction(2, postID, '', function() { - async.times(numLikes - 1, function(n, next) { - internals.browser.createPost(postID, - null, - 'Spamming for likes (' + Math.random() + ')', - function(error, resp1) { - if (error) { - next(error); - } - internals.browser.postAction(2, resp1.id, '', next); - }); - }, function(error) { - callback(error); - }); - }); - }); -}; - -exports.increaseTrustLevel = function(callback) { - //Figure out why we're not high enough - const requirements = internals.configuration.requirements[exports.config.trustLevel]; - - //Guess easy shit first - if (internals.me.likesGiven < requirements.likesGiven) { - exports.giveLikes(requirements.likesGiven - internals.me.likesGiven, function() { - exports.updateSelf(); - }); - } - - if (internals.me.likesReceived < requirements.likesReceived) { - exports.giveLikes(requirements.likesReceived - internals.me.likesReceived, function() { - exports.updateSelf(); - }); - } - callback(); -}; - -/** - * Update your internal representation of yourself - * @param {Function} callback The callback - */ -exports.updateSelf = function(callback) { - //Fetch my stats - internals.browser.getUser(internals.username, function(myData) { - - //Discourse doesn't follow our linting rules: - /*eslint-disable camelCase */ - internals.me.trustLevel = myData.user.trust_level; - myData.user.stats.forEach(stat => { - - switch (stat.action_type) { - case userActions.createTopic: - internals.me.topicsCreated = stat.count; - internals.me.postsMade += stat.count; - break; - case userActions.reply: - internals.me.postsMade += stat.count; - break; - case userActions.repliedTo: - internals.me.replies = stat.count; - break; - case userActions.likeReceived: - internals.me.likesReceived = stat.count; - break; - case userActions.likeGiven: - internals.me.likesGiven = stat.count; - break; - } - }); - - /*istanbul ignore else*/ - if (callback) { - callback(null); - } - /*eslint-enable camelCase */ - }); -}; - -/** - * Stop the plugin prior to exit or reload - */ -exports.stop = function stop() {}; diff --git a/test/plugins/powerlevelTest.js b/test/plugins/powerlevelTest.js deleted file mode 100644 index ef3bf277..00000000 --- a/test/plugins/powerlevelTest.js +++ /dev/null @@ -1,245 +0,0 @@ -'use strict'; -/*globals describe, it, beforeEach, afterEach*/ - -const sinon = require('sinon'), - chai = require('chai'); -chai.should(); -const expect = chai.expect; -const sinonChai = require('sinon-chai'); -chai.use(sinonChai); - -// The thing we're testing -const powerlevel = require('../../plugins/powerlevel'), - utils = require('../../lib/utils'); -const dummyCfg = {mergeObjects: utils.mergeObjects}; - -describe('Powerlevel plugin', () => { - describe('exports', () => { - const fns = ['prepare', 'start', 'stop', 'updateSelf', - 'giveLikes', 'increaseTrustLevel'], - objs = ['internals', 'defaultConfig']; - fns.forEach(fn => it('should export ' + fn + '()', () => { - expect(powerlevel[fn]).to.be.a('function'); - })); - objs.forEach(obj => it('should export ' + obj, () => { - expect(powerlevel[obj]).to.be.an('object'); - })); - it('should only export expected keys', () => { - powerlevel.should.have.all.keys(fns.concat(objs)); - }); - }); - describe('start()', () => { - let sandbox; - beforeEach(() => { - sandbox = sinon.sandbox.create(); - sandbox.stub(utils, 'mergeObjects'); - }); - afterEach(() => sandbox.restore()); - it('should call updateSelf', () => { - const updateSelfStub = sandbox.stub(powerlevel, 'updateSelf'); - powerlevel.start(); - expect(updateSelfStub).to.have.been.called; - }); - }); - describe('stop()', () => { - it('should be a stub function', () => { - powerlevel.stop(); - }); - }); - describe('prepare()', () => { - let sandbox, events; - beforeEach(() => { - sandbox = sinon.sandbox.create(); - sandbox.stub(utils, 'mergeObjects'); - events = { - onNotification: sinon.spy() - }; - }); - afterEach(() => sandbox.restore()); - it('should set browser', () => { - const browser = {}; - const config = { - core: { - username: 'foo' - }, - mergeObjects: utils.mergeObjects - }; - powerlevel.prepare(null, config, events, browser); - expect(powerlevel.internals.browser).to.equal(browser); - }); - it('should reject a lack of config', () => { - const browser = {}; - expect(() => { - powerlevel.prepare(null, dummyCfg, events, browser); - }).to.throw(Error); - }); - it('should accept plugin config', () => { - const browser = {}; - const config = { - core: { - username: 'foo' - }, - mergeObjects: utils.mergeObjects - }; - powerlevel.prepare({}, config, events, browser); - expect(powerlevel.internals.browser).to.equal(browser); - }); - }); - describe('updateSelf()', () => { - let sandbox; - - beforeEach(() => { - sandbox = sinon.sandbox.create(); - sandbox.stub(utils, 'mergeObjects'); - }); - afterEach(() => sandbox.restore()); - - it('should call getUser', () => { - const fakeBrowser = { - getUser: sandbox.stub() - }; - const config = { - core: { - username: 'foo' - }, - mergeObjects: utils.mergeObjects - }; - - powerlevel.prepare(null, config, {}, fakeBrowser); - powerlevel.updateSelf(); - expect(fakeBrowser.getUser).to.have.been.called; - }); - - - it('should parse response from getUser', () => { - const topicsCreated = Math.ceil(5 + Math.random() * 10), - likesGiven = Math.ceil(5 + Math.random() * 10), - likesReceived = Math.ceil(5 + Math.random() * 10), - repliesReceived = Math.ceil(5 + Math.random() * 10), - repliesMade = Math.ceil(5 + Math.random() * 10); - - const fakeUserData = {'user': { - 'id': 788, - 'username': 'Yamikuronue', - 'stats': [ - { - 'action_type': 4, - 'count': topicsCreated, - 'id': null - }, - { - 'action_type': 5, - 'count': repliesMade, - 'id': null - }, - { - 'action_type': 6, - 'count': repliesReceived, - 'id': null - }, - { - 'action_type': 1, - 'count': likesGiven, - 'id': null - }, - { - 'action_type': 2, - 'count': likesReceived, - 'id': null - } - ]}}; - - const fakeBrowser = { - getUser: sandbox.stub().yields(fakeUserData) - }; - const config = { - core: { - username: 'yamikuronue' - }, - mergeObjects: utils.mergeObjects - }; - - powerlevel.prepare(null, config, {}, fakeBrowser); - powerlevel.updateSelf(function() { - expect(fakeBrowser.getUser).to.have.been.calledWith('yamikuronue'); - expect(powerlevel.internals.me.topicsCreated).to.equal(topicsCreated); - expect(powerlevel.internals.me.likesGiven).to.equal(likesGiven); - expect(powerlevel.internals.me.likesReceived).to.equal(likesReceived); - expect(powerlevel.internals.me.replies).to.equal(repliesReceived); - expect(powerlevel.internals.me.postsMade).to.equal(topicsCreated + repliesMade); - }); - }); - }); - - describe('giveLikes()', () => { - let sandbox; - const config = { - core: { - username: 'yamikuronue' - } - }; - - beforeEach(() => { - sandbox = sinon.sandbox.create(); - sandbox.stub(utils, 'mergeObjects'); - }); - - afterEach(() => sandbox.restore()); - - it('Should start a PM chain to like', () => { - const fakeBrowser = { - createPrivateMessage: sandbox.stub().yields(null, {id: 15}), - createPost: sandbox.stub().yields(null, {id: 16}), - postAction:sandbox.stub().yields() - }; - - powerlevel.prepare(null, config, {}, fakeBrowser); - - powerlevel.giveLikes(1, function(err) { - expect(fakeBrowser.createPrivateMessage).to.have.been.calledOnce;//Create the PM - expect(fakeBrowser.postAction).to.have.been.calledWith(2, 15, ''); //Like on the post - expect(fakeBrowser.createPost).not.to.have.been.called; //reply: none needed - expect(err).to.be.falsey; - }); - }); - - it('Should reply to the same PM for the second like', (done) => { - const fakeBrowser = { - createPrivateMessage: sandbox.stub().yields(null, {id: 15}), - createPost: sandbox.stub().yields(null, {id: 16}), - postAction:sandbox.stub().yields() - }; - - powerlevel.prepare(null, config, {}, fakeBrowser); - - powerlevel.giveLikes(2, function(err) { - expect(fakeBrowser.createPrivateMessage).to.have.been.calledOnce; - expect(fakeBrowser.createPost).to.have.been.calledOnce; - expect(fakeBrowser.createPost).to.have.been.calledWith(15); - expect(fakeBrowser.postAction).to.have.been.calledWith(2, 15, ''); //Like on the post - expect(fakeBrowser.postAction).to.have.been.calledWith(2, 16, ''); //Like on the rely - expect(err).to.be.falsey; - done(); - }); - }); - - it('Should gather the correct amount of likes', (done) => { - const numLikes = Math.ceil(Math.random * 5 + 2); - const fakeBrowser = { - createPrivateMessage: sandbox.stub().yields(null, {id: 15}), - createPost: sandbox.stub().yields(null, {id: 16}), - postAction:sandbox.stub().yields() - }; - - powerlevel.prepare(null, config, {}, fakeBrowser); - - powerlevel.giveLikes(numLikes, function(err) { - expect(err).to.be.falsey; - expect(fakeBrowser.createPrivateMessage).to.have.been.calledOnce; - expect(fakeBrowser.createPost).to.have.callCount(numLikes - 1); - expect(fakeBrowser.postAction).to.have.callCount(numLikes); - done(); - }); - }); - }); -}); From 334f8c923f9048d313088b7a1025b52ec26160ea Mon Sep 17 00:00:00 2001 From: Yamikuronue Date: Thu, 24 Sep 2015 15:19:45 -0400 Subject: [PATCH 04/10] Fixing broken likes tests. As a reminder, try to run your tests in isolation once in a while :) --- test/plugins/likesTest.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/plugins/likesTest.js b/test/plugins/likesTest.js index bc0e53ac..fbf47c4d 100644 --- a/test/plugins/likesTest.js +++ b/test/plugins/likesTest.js @@ -3,10 +3,15 @@ const chai = require('chai'), sinon = require('sinon'), - async = require('async'); + async = require('async'), + sinonChai = require('sinon-chai'); chai.should(); +chai.use(sinonChai); const expect = chai.expect; +const + + // The thing we're testing const likes = require('../../plugins/likes'), utils = require('../../lib/utils'); From cdbecb60661f359f74c373bc7722fa4b5ca2cc02 Mon Sep 17 00:00:00 2001 From: RaceProUK Date: Sat, 3 Oct 2015 10:29:15 +0000 Subject: [PATCH 05/10] Handle invalid post_stream gracefully --- lib/browser.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/browser.js b/lib/browser.js index 70795169..55eda714 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -532,6 +532,9 @@ function getPosts(topicId, eachPost, complete) { if (err2) { return next(err2); } + if (!topic2.post_stream || !Array.isArray(topic2.post_stream.posts)) { + next(new Error('Invalid post_stream; cannot continue')); + } async.eachSeries(topic2.post_stream.posts.map((p) => cleanPost(p)), (post, postNext) => { setTimeout(() => eachPost(post, (error) => postNext(error)), 0); }, next); From ac517bfc7b5e539219b6ba40c24e2edd7d5271f9 Mon Sep 17 00:00:00 2001 From: RaceProUK Date: Sat, 3 Oct 2015 10:56:07 +0000 Subject: [PATCH 06/10] Better handle invalid post_stream gracefully --- lib/browser.js | 2 +- test/lib/browserTest.js | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/browser.js b/lib/browser.js index 55eda714..8d2c5e1e 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -533,7 +533,7 @@ function getPosts(topicId, eachPost, complete) { return next(err2); } if (!topic2.post_stream || !Array.isArray(topic2.post_stream.posts)) { - next(new Error('Invalid post_stream; cannot continue')); + return next(new Error('Invalid post_stream; cannot continue')); } async.eachSeries(topic2.post_stream.posts.map((p) => cleanPost(p)), (post, postNext) => { setTimeout(() => eachPost(post, (error) => postNext(error)), 0); diff --git a/test/lib/browserTest.js b/test/lib/browserTest.js index 57a87080..b8ec646f 100644 --- a/test/lib/browserTest.js +++ b/test/lib/browserTest.js @@ -1258,6 +1258,40 @@ describe('browser', () => { }); spy.lastCall.args.should.deep.equal([null]); }); + it('should gracefully handle null post_stream', () => { + const spy = sinon.spy(), + eachSpy = sinon.stub(), + topic = { + 'post_stream': { + stream: [2] + } + }, + posts = {}; + eachSpy.yields(null); + queue.push.onFirstCall().yieldsTo('callback', null, topic); + queue.push.onSecondCall().yieldsTo('callback', null, posts); + object.getPosts(314159, eachSpy, spy); + sandbox.clock.tick(); + //No assertions needed + }); + it('should gracefully handle invalid post_stream', () => { + const spy = sinon.spy(), + eachSpy = sinon.stub(), + topic = { + 'post_stream': { + stream: [2] + } + }, + posts = { + 'post_stream': {} + }; + eachSpy.yields(null); + queue.push.onFirstCall().yieldsTo('callback', null, topic); + queue.push.onSecondCall().yieldsTo('callback', null, posts); + object.getPosts(314159, eachSpy, spy); + sandbox.clock.tick(); + //No assertions needed + }); }); }); }); From 77e65cbef96bbe64203eeb216d9b744881152c34 Mon Sep 17 00:00:00 2001 From: RaceProUK Date: Sun, 4 Oct 2015 13:54:24 +0000 Subject: [PATCH 07/10] Fix post reading to use post number not ID --- lib/browser.js | 12 ++++++------ plugins/autoreader.js | 8 ++++---- test/plugins/autoreaderTest.js | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/browser.js b/lib/browser.js index 8d2c5e1e..3d0f6fcc 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -451,21 +451,21 @@ function editPost(postId, content, editReason, callback) { * Read post * * @param {number} topicId Id of topic to read - * @param {number[]} postIds Ids of posts to read + * @param {number[]} postNumbers Numbers of posts to read * @param {postedCallback} callback Completion callback */ -function readPosts(topicId, postIds, callback) { +function readPosts(topicId, postNumbers, callback) { const ctx = this; if (typeof callback !== 'function') { throw new Error('callback must be supplied'); } - if (typeof postIds === 'number') { - postIds = [postIds]; + if (typeof postNumbers === 'number') { + postNumbers = [postNumbers]; } async.whilst(function () { - return postIds.length > 0; + return postNumbers.length > 0; }, function (next) { - const part = postIds.splice(0, 200), + const part = postNumbers.splice(0, 200), form = { 'topic_id': topicId, 'topic_time': 4242 diff --git a/plugins/autoreader.js b/plugins/autoreader.js index ecf29976..2eb41c23 100644 --- a/plugins/autoreader.js +++ b/plugins/autoreader.js @@ -119,15 +119,15 @@ exports.readify = function () { } internals.events.emit('logMessage', 'Reading topic `' + topic.slug + '`'); const now = new Date().getTime() - internals.config.minAge; - const postIds = []; + const postNumbers = []; internals.browser.getPosts(topic.id, (post, nextPost) => { if (post && !post.read && Date.parse(post.created_at) < now) { - postIds.push(post.id); + postNumbers.push(post.post_number); } nextPost(); }, () => { - if (postIds.length > 0) { - internals.browser.readPosts(topic.id, postIds, () => 0); + if (postNumbers.length > 0) { + internals.browser.readPosts(topic.id, postNumbers, () => 0); } }); nextTopic(); diff --git a/test/plugins/autoreaderTest.js b/test/plugins/autoreaderTest.js index f039398b..bf567160 100644 --- a/test/plugins/autoreaderTest.js +++ b/test/plugins/autoreaderTest.js @@ -130,7 +130,7 @@ describe('autoreader', () => { }); sandbox.stub(browser, 'getPosts', (_, each, complete) => { each({ - id: 1, + post_number: 1, read: false, created_at: '2000-01-01 00:00' }, complete); @@ -151,7 +151,7 @@ describe('autoreader', () => { }); sandbox.stub(browser, 'getPosts', (_, each, complete) => { each({ - id: 1, + post_number: 1, read: true, created_at: '2000-01-01 00:00' }, complete); @@ -170,7 +170,7 @@ describe('autoreader', () => { }); sandbox.stub(browser, 'getPosts', (_, each, complete) => { each({ - id: 1, + post_number: 1, read: false, created_at: '2100-01-01 00:00' }, complete); From c9e43bc363c4713777b9fd816c1ff191c7213900 Mon Sep 17 00:00:00 2001 From: Travis-CI Date: Tue, 6 Oct 2015 21:06:38 +0000 Subject: [PATCH 08/10] Automatically push updated documentation [ci skip] --- docs/api/lib/browser.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/lib/browser.md b/docs/api/lib/browser.md index c3a9bd53..f64795e8 100644 --- a/docs/api/lib/browser.md +++ b/docs/api/lib/browser.md @@ -20,7 +20,7 @@ Webbrowser abstraction for communicating with discourse * [~createPost(topicId, [replyTo], content, callback)](#module_browser..createPost) * [~createPrivateMessage(to, title, content, callback)](#module_browser..createPrivateMessage) * [~editPost(postId, content, [editReason], callback)](#module_browser..editPost) - * [~readPosts(topicId, postIds, callback)](#module_browser..readPosts) + * [~readPosts(topicId, postNumbers, callback)](#module_browser..readPosts) * [~getPost(postId, callback)](#module_browser..getPost) * [~getPosts(topicId, eachPost, complete)](#module_browser..getPosts) * [~getLastPosts(topicId, eachPost, complete)](#module_browser..getLastPosts) @@ -233,7 +233,7 @@ Edit an existing post. | callback | postedCallback | Completion callback | -### browser~readPosts(topicId, postIds, callback) +### browser~readPosts(topicId, postNumbers, callback) Read post **Kind**: inner method of [browser](#module_browser) @@ -241,7 +241,7 @@ Read post | Param | Type | Description | | --- | --- | --- | | topicId | number | Id of topic to read | -| postIds | Array.<number> | Ids of posts to read | +| postNumbers | Array.<number> | Numbers of posts to read | | callback | postedCallback | Completion callback | From 972b953c541dc1aabccb7933f45191fd7a47c368 Mon Sep 17 00:00:00 2001 From: RaceProUK Date: Tue, 6 Oct 2015 22:15:58 +0100 Subject: [PATCH 09/10] Bumping version number for patch release [ci skip] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e54ab2d6..5e17f203 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sockbot", - "version": "2.11.3", + "version": "2.11.4", "releaseName": "Cheery Chiffon", "description": "A sockpuppet bot to use on http://what.thedailywtf.com.", "repository": "https://github.com/SockDrawer/SockBot", From 9fac932d5bb0771fdc6dc2d1988c8c811c0a463d Mon Sep 17 00:00:00 2001 From: RaceProUK Date: Tue, 6 Oct 2015 22:31:30 +0100 Subject: [PATCH 10/10] Tweak to config documentation --- docs/configuration.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 11dd672b..ab09a4b3 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -4,7 +4,8 @@ SockBot is configured via a JSON or YAML configuration file. The configuration c one core configuration dictionary and one plugin configuration dictionary. Core configuration options are fixed and can be found described in the API documentation for [defaultConfig]. -Plugin configuration options are determined by the individual plugins and will vary from plugin to plugin. +Plugin configuration options are determined by the individual plugins and will vary from plugin to plugin; +consult each plugins' documentation for more details. [defaultConfig]: api/config/#defaultConfig