From f04da64b21e26c135d5a366d73d82752df1c4b8c Mon Sep 17 00:00:00 2001 From: reality Date: Thu, 19 Dec 2013 18:48:49 +0000 Subject: [PATCH] something something reddit feeds --- modules/reddit/config.json | 3 +- modules/reddit/reddit.js | 145 ++++++++++++++++++++++++++++++++++++ modules/reddit/strings.json | 14 +++- 3 files changed, 160 insertions(+), 2 deletions(-) diff --git a/modules/reddit/config.json b/modules/reddit/config.json index 5a94458..3cdb249 100644 --- a/modules/reddit/config.json +++ b/modules/reddit/config.json @@ -1,4 +1,5 @@ { "outputPrefix": "\u000312reddit\u000f", - "dependencies": [ "link" ] + "dependencies": [ "link" ], + "dbType": "redis" } diff --git a/modules/reddit/reddit.js b/modules/reddit/reddit.js index 0598592..2ae8197 100644 --- a/modules/reddit/reddit.js +++ b/modules/reddit/reddit.js @@ -9,6 +9,71 @@ var reddit = function(dbot) { this.ApiRoot = 'http://reddit.com/'; this.UserAgent = 'dbot by u/realitone'; + this.internalAPI = { + 'getChannelFeeds': function(server, cName, callback) { + dbot.api.users.resolveChannel(server, cName, function(channel) { + if(channel) { + this.db.read('reddit_feeds', channel.id, function(err, cFeeds) { + if(err || !cFeeds) { + callback(null, { + 'id': channel.id, + 'server': server, + 'channel': cName, + 'feeds': {} + }); + } else { + callback(null, cFeeds); + } + }); + } else { + callback('NoSuchChannel', null); + } + }.bind(this)); + }.bind(this), + + 'updateChannelFeeds': function(cFeeds, callback) { + this.db.update('reddit_feeds', cFeeds.id, cFeeds, callback); + }.bind(this), + + 'reloadChannelFeeds': function() { + var channels = [], + checkTimes = []; + + this.db.scan('reddit_feeds', function(channel) { + if(channel) { + console.log(channel); + channels.push(channel); + } + }, function() { + _.each(channels, function(channel) { + checkTimes[channel.id] = {}; + _.each(channel.feeds, function(feed) { + checkTimes[channel.id][feed.subreddit] = Date.now(); + dbot.api.timers.addTimer(30000, function() { + this.api.getNewPosts(feed.subreddit, checkTimes[channel.id][feed.subreddit], function(err, posts) { + if(!err && posts.length > 0) { + _.each(posts, function(post) { + dbot.say(channel.server, channel.channel, dbot.t('about_post', { + 'title': post.title.trim(), + 'poster': post.author, + 'subreddit': post.subreddit, + 'comments': post.num_comments, + 'score': post.score, + 'up': post.ups, + 'down': post.downs, + 'url': this.ApiRoot + post.id + })); + }, this); + checkTimes[channel.id][feed.subreddit] = Date.now(); + } + }.bind(this)); + }.bind(this)); + }.bind(this)); + }.bind(this)); + }.bind(this)); + }.bind(this) + }; + this.api = { 'getSubredditInfo': function(name, callback) { request.get({ @@ -53,10 +118,90 @@ var reddit = function(dbot) { callback(body[1].data.children[0].data); } }); + }, + + 'getNewPosts': function(sr, last, callback) { + request.get({ + 'url': this.ApiRoot + 'r/' + sr + '/new.json', + 'json': true, + 'headers': { + 'User-Agent': this.UserAgent + } + }, function(err, response, body) { + if(!err && body && body.kind === 'Listing') { + var posts = _.pluck(body.data.children, 'data'); + newPosts = _.filter(posts, function(post) { + console.log(post.created_utc + ' vs ' + (last / + 1000)); + return post.created_utc > (last / 1000); + }); + callback(null, newPosts); + } else { + callback(true, null); + } + }); } }; + this.commands = { + '~addredditfeed': function(event) { + var channel = event.input[1], + subreddit = event.input[2].replace('r/', ''), + interval = event.input[3] * 60000; + + this.internalAPI.getChannelFeeds(event.server, channel, function(err, channel) { + if(!err) { + if(!_.has(channel.feeds, subreddit)) { + channel.feeds[subreddit] = { + 'subreddit': subreddit, + 'interval': interval + }; + this.internalAPI.updateChannelFeeds(channel, function() { + this.internalAPI.reloadChannelFeeds(); + }.bind(this)); + event.reply(dbot.t('added_channel_feed', { + 'subreddit': subreddit, + 'interval': interval / 60000, + 'channel': channel.channel + })); + } else { + event.reply(dbot.t('feed_already_watched')); + } + } else { + if(err === 'NoSuchChannel') { + event.reply(dbot.t('no_such_channel')); + } + } + }.bind(this)); + }, + + '~rmredditfeed': function(event) { + var channel = event.input[1], + subreddit = event.input[2].replace('r/', ''); + + this.internalAPI.getChannelFeeds(event.server, channel, function(err, channel) { + if(!err && channel && _.has(channel.feeds, subreddit)) { + delete channel.feeds[subreddit]; + this.internalAPI.updateChannelFeeds(channel, function() { + this.internalAPI.reloadChannelFeeds(); + }.bind(this)); + + event.reply(dbot.t('removed_channel_feed', { + 'subreddit': subreddit, + 'channel': channel.channel + })); + } else { + event.reply(dbot.t('no_such_feed')); + } + }.bind(this)); + } + }; + this.commands['~addredditfeed'].regex = [/^~addredditfeed ([^ ]+) ([^ ]+) ([^ ]+)$/, 4]; + this.commands['~rmredditfeed'].regex = [/^~rmredditfeed ([^ ]+) ([^ ]+)$/, 3]; + this.onLoad = function() { + this.internalAPI.reloadChannelFeeds(); + var rHandler = function(matches, name, callback) { if(matches[6]) { // It's a comment this.api.getCommentInfo(matches[4], matches[6], function(info) { diff --git a/modules/reddit/strings.json b/modules/reddit/strings.json index aea6b60..946630f 100644 --- a/modules/reddit/strings.json +++ b/modules/reddit/strings.json @@ -7,7 +7,7 @@ "it": "[{display_name} ha {subscribers} abonnati ({active} activo/i)]" }, "about_post": { - "en": "[Post by {poster} in {subreddit} — Comments: {comments}, Score: {score} (\u00039▲{up}\u000f|\u000312{down}▼\u000f)] — {url}", + "en": "[{title}] [Post by {poster} in {subreddit} — Comments: {comments}, Score: {score} (\u00039▲{up}\u000f|\u000312{down}▼\u000f)] — {url}", "cy": "[Postio gan {poster} yn {subreddit} - Sylwadau: {comments}, Sgôr: {score} (\u00039]▲{up}\u000f|\u000312{down}▼\u000f)] — {url}", "de": "[Beitrag von {poster} in {subreddit} — Kommentare: {comments}, Bewertung: {score} (\u00039▲{up}\u000f|\u000312{down}▼\u000f)] — {url}", "fr": "[Message de {poster} dans {subreddit} — Commentaires: {comments}, Score: {score} (\u00039▲{up}\u000f|\u000312{down}▼\u000f)] — {url}", @@ -27,5 +27,17 @@ "cy": "[Anniogel Ar Gwaith (AAG)]", "fr": "[Risqué Pour le Travail (NSFW)]", "it": "[Rischioso per il lavoro (NSFW)]" + }, + "added_channel_feed": { + "en": "Added r/{subreddit} feed to {channel} every {interval} minute(s)." + }, + "removed_channel_feed": { + "en": "Removed r/{subreddit} feed from {channel}." + }, + "no_such_feed": { + "en": "No such feed..." + }, + "feed_already_watched": { + "en": "This feed already exists..." } }