add user feed capability
This commit is contained in:
parent
2da61e392d
commit
d5fcb2482f
@ -1,6 +1,6 @@
|
|||||||
# Mercury
|
# Mercury
|
||||||
|
|
||||||
Simple & Customisable RSS Parser for IRC.
|
Simple & Customisable RSS Client for IRC.
|
||||||
|
|
||||||
This bot is not completed, expect bugs/crashes/errors. Use in production is disadvised at this stage.
|
This bot is not completed, expect bugs/crashes/errors. Use in production is disadvised at this stage.
|
||||||
|
|
||||||
@ -8,8 +8,9 @@ This bot is not completed, expect bugs/crashes/errors. Use in production is disa
|
|||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
- `m!feed [FEED] [ENTRIES]` - Return the last x amount of entries from any RSS feed.
|
- `m!feed [USER/FEED] [ENTRIES]` - Return the last x amount of entries from any RSS feed or your own saved feeds (if you have saved feeds)
|
||||||
- `m!twitter [USER] [ENTRIES]` - Return the last x amount of tweets from a particular user.
|
- `m!twitter [USER] [ENTRIES]` - Return the last x amount of tweets from a particular user.
|
||||||
|
- `m!set [CATEGORY] [OPTION] [VALUE]` - Control bot settings, see wiki for info on usage.
|
||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
|
41
bot.js
41
bot.js
@ -22,6 +22,16 @@ var bot = new irc.Client(config.irc.server, config.irc.nickname, {
|
|||||||
|
|
||||||
const timer = ms => new Promise(res => setTimeout(res, ms))
|
const timer = ms => new Promise(res => setTimeout(res, ms))
|
||||||
|
|
||||||
|
const isValidUrl = urlString=> {
|
||||||
|
var urlPattern = new RegExp('^(https?:\\/\\/)?'+ // validate protocol
|
||||||
|
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // validate domain name
|
||||||
|
'((\\d{1,3}\\.){3}\\d{1,3}))'+ // validate OR ip (v4) address
|
||||||
|
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // validate port and path
|
||||||
|
'(\\?[;&a-z\\d%_.~+=-]*)?'+ // validate query string
|
||||||
|
'(\\#[-a-z\\d_]*)?$','i'); // validate fragment locator
|
||||||
|
return !!urlPattern.test(urlString);
|
||||||
|
}
|
||||||
|
|
||||||
async function help(chan, sub) {
|
async function help(chan, sub) {
|
||||||
if (sub === undefined) {
|
if (sub === undefined) {
|
||||||
var sub = "default"
|
var sub = "default"
|
||||||
@ -32,9 +42,10 @@ async function help(chan, sub) {
|
|||||||
bot.say(chan, ' / / / / / / __/ / / /__/ /_/ / / / /_/ / ')
|
bot.say(chan, ' / / / / / / __/ / / /__/ /_/ / / / /_/ / ')
|
||||||
bot.say(chan, '/_/ /_/ /_/\\___/_/ \\___/\\__,_/_/ \\__, / ')
|
bot.say(chan, '/_/ /_/ /_/\\___/_/ \\___/\\__,_/_/ \\__, / ')
|
||||||
bot.say(chan, ' /____/ ')
|
bot.say(chan, ' /____/ ')
|
||||||
bot.say(chan, 'Mercury - https://git.supernets.org/hogwart7/mercury')
|
bot.say(chan, 'Mercury RSS Client - https://git.supernets.org/hogwart7/mercury')
|
||||||
bot.say(chan, 'm!feed [FEED] [ENTRIES] - Return the last x amount of entries from any RSS feed')
|
bot.say(chan, 'm!feed [USER/FEED] [ENTRIES] - Return the last x amount of entries from any RSS feed or your own saved feeds (if you have saved feeds)')
|
||||||
bot.say(chan, "m!twitter [USER] [ENTRIES] - Return the last x amount of tweets from a particular user")
|
bot.say(chan, "m!twitter [USER] [ENTRIES] - Return the last x amount of tweets from a particular user")
|
||||||
|
bot.say(chan, "m!set [CATEGORY] [OPTION] [VALUE] - Control bot settings, see wiki for info on usage.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,30 +66,46 @@ async function opt(chan, user, setting, setting2, value) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
worker.once('message', (string) => {
|
worker.once('message', (string) => {
|
||||||
console.log('Received output from last5 worker, posting.');
|
console.log('Received output from options worker, posting.');
|
||||||
bot.say(chan, string);
|
bot.say(chan, string);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function feed(chan, provfeed, n) {
|
async function feed(chan, nick, provfeed, n) {
|
||||||
if (provfeed === undefined) {
|
if (provfeed === undefined) {
|
||||||
bot.say(chan, errorMsg+" No feed has been provided.")
|
bot.say(chan, errorMsg+" No feed has been provided.")
|
||||||
return;
|
return;
|
||||||
|
} else if (provfeed === 'me' ) {
|
||||||
|
var provfeed = nick;
|
||||||
}
|
}
|
||||||
if (n === undefined) {
|
if (n === undefined) {
|
||||||
var n = config.feed.default_amount;
|
var n = config.feed.default_amount;
|
||||||
}
|
}
|
||||||
const worker = new Worker('./commands/feed.js', {
|
if (isValidUrl(provfeed) === false) {
|
||||||
|
const worker = new Worker('./commands/feed-list.js', {
|
||||||
|
workerData: {
|
||||||
|
provfeed,
|
||||||
|
n,
|
||||||
|
nick
|
||||||
|
}
|
||||||
|
});
|
||||||
|
worker.once('message', (string) => {
|
||||||
|
console.log('Received output from feed-list worker, posting.');
|
||||||
|
bot.say(chan, string);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const worker = new Worker('./commands/feed-preset.js', {
|
||||||
workerData: {
|
workerData: {
|
||||||
provfeed,
|
provfeed,
|
||||||
n
|
n
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
worker.once('message', (string) => {
|
worker.once('message', (string) => {
|
||||||
console.log('Received output from last5 worker, posting.');
|
console.log('Received output from feed-preset worker, posting.');
|
||||||
bot.say(chan, string);
|
bot.say(chan, string);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function twitter(chan, provfeed, n) {
|
async function twitter(chan, provfeed, n) {
|
||||||
if (provfeed === undefined) {
|
if (provfeed === undefined) {
|
||||||
@ -105,7 +132,7 @@ bot.addListener('message', function(nick, to, text, from) {
|
|||||||
if (args[0] === config.irc.prefix+'help') {
|
if (args[0] === config.irc.prefix+'help') {
|
||||||
help(to, args[1]);
|
help(to, args[1]);
|
||||||
} else if (args[0] === config.irc.prefix+'feed') {
|
} else if (args[0] === config.irc.prefix+'feed') {
|
||||||
feed(to, args[1], args[2]);
|
feed(to, nick, args[1], args[2]);
|
||||||
} else if (args[0] === config.irc.prefix+'twitter') {
|
} else if (args[0] === config.irc.prefix+'twitter') {
|
||||||
twitter(to, args[1], args[2])
|
twitter(to, args[1], args[2])
|
||||||
} else if (args[0] === config.irc.prefix+'set') {
|
} else if (args[0] === config.irc.prefix+'set') {
|
||||||
|
120
commands/feed-list.js
Normal file
120
commands/feed-list.js
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
const config = require('../config/default.json')
|
||||||
|
const uconfig = require('../config/usersettings.json')
|
||||||
|
const { parentPort, workerData } = require('worker_threads');
|
||||||
|
const { provfeed, n, nick } = workerData;
|
||||||
|
let Parser = require('rss-parser');
|
||||||
|
let parser = new Parser({
|
||||||
|
headers: {'User-Agent': config.feed.useragent},
|
||||||
|
});
|
||||||
|
const striptags = require("striptags");
|
||||||
|
const moment = require('moment');
|
||||||
|
const tz = require('moment-timezone');
|
||||||
|
const timer = ms => new Promise(res => setTimeout(res, ms))
|
||||||
|
const editJsonFile = require("edit-json-file");
|
||||||
|
const { isNumber } = require('util');
|
||||||
|
|
||||||
|
warningMsg = ''+config.colours.brackets+'['+config.colours.warning+'WARNING'+config.colours.brackets+']'
|
||||||
|
errorMsg = ''+config.colours.brackets+'['+config.colours.error+'ERROR'+config.colours.brackets+']'
|
||||||
|
|
||||||
|
async function sendUpstream(content) {
|
||||||
|
var output = content.join("\n")
|
||||||
|
parentPort.postMessage(output);
|
||||||
|
process.exit()
|
||||||
|
}
|
||||||
|
|
||||||
|
function errorMessage(error, code, extra) {
|
||||||
|
console.log(error.code)
|
||||||
|
if (code == "404") {
|
||||||
|
var error = errorMsg+" 404: " + extra + " not found"
|
||||||
|
} else if (error.code == "ECONNREFUSED") {
|
||||||
|
var error = errorMsg+" Connection Refused ("+extra+")"
|
||||||
|
} else if (error.code == "ERR_UNESCAPED_CHARACTERS"){
|
||||||
|
var error = errorMsg+" Unescaped Characters"
|
||||||
|
} else if (error == "NOFEEDS") {
|
||||||
|
var error = errorMsg+" No saved feeds for "+provfeed
|
||||||
|
} else {
|
||||||
|
var error = errorMsg+" Unknown error"
|
||||||
|
}
|
||||||
|
|
||||||
|
parentPort.postMessage(error);
|
||||||
|
process.exit()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchFeed(feedURL, n, nick) {
|
||||||
|
var content = [];
|
||||||
|
try {
|
||||||
|
var feedsArr = uconfig[nick].feeds
|
||||||
|
} catch (e) {
|
||||||
|
errorMessage(e, "NOFEEDS", nick);
|
||||||
|
}
|
||||||
|
var n = n/feedsArr.length
|
||||||
|
for (let i = 0; i < feedsArr.length; i++) {
|
||||||
|
try {
|
||||||
|
var newFeed = await parser.parseURL(feedsArr[i]);
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code !== undefined) {
|
||||||
|
errorMessage(e, feedsArr[i])
|
||||||
|
} else {
|
||||||
|
errorMessage(e, "404", feedsArr[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n > newFeed.items.length) {
|
||||||
|
var n = newFeed.items.length;
|
||||||
|
content.push(warningMsg+" Your requested post amount exceeded the total available. Reverting to " + newFeed.items.length);
|
||||||
|
} else if (n < 1) {
|
||||||
|
var n = config.feed.default_amount
|
||||||
|
content.push(warningMsg+" You requested a number less than 1. Reverting to default ("+config.feed.default_amount+")");
|
||||||
|
}
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
var data = newFeed.items[i]
|
||||||
|
var title = data.title.replace(/(\r\n|\n|\r)/gm, " ") //remove line breaks
|
||||||
|
.replace(/\s{2,}/g, ' ') //idk
|
||||||
|
var title = striptags(title);
|
||||||
|
var body = data.contentSnippet.replace(/(\r\n|\n|\r)/gm, " ") //remove line breaks
|
||||||
|
.replace(/\s{2,}/g, ' ') //idk
|
||||||
|
var body = striptags(body);
|
||||||
|
if (data.isoDate !== undefined) {
|
||||||
|
var date = moment(data.isoDate)
|
||||||
|
var syncDate = date.tz(config.feed.timezone)
|
||||||
|
console.log(syncDate.format())
|
||||||
|
var date = syncDate.format(config.feed.time_format)
|
||||||
|
} else {
|
||||||
|
var date = data.pubDate
|
||||||
|
}
|
||||||
|
if (body.length >= config.feed.body_max_chars) {
|
||||||
|
var truncatedString = body.substring(0,config.feed.body_max_chars);
|
||||||
|
var body = truncatedString + "..."
|
||||||
|
}
|
||||||
|
date = ''+config.colours.brackets+'['+config.colours.date+date+''+config.colours.brackets+'] '
|
||||||
|
title = ''+config.colours.title+title+' '
|
||||||
|
author = ''+config.colours.author+data.creator+' '
|
||||||
|
body = ''+config.colours.body+body+' '
|
||||||
|
link = ''+config.colours.link+data.link+' '
|
||||||
|
//console.log(data);
|
||||||
|
//var string = "15[11" + date + "15] 08" + title + " " + body + " " + data.link;
|
||||||
|
var string = date+title+body+link;
|
||||||
|
content.push(string)
|
||||||
|
console.log(content)
|
||||||
|
}
|
||||||
|
//sendUpstream(content);
|
||||||
|
}
|
||||||
|
sendUpstream(content);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//var file = editJsonFile('/home/node/app/config/usersettings.json');
|
||||||
|
//async function getAllFeeds(nick, n) {
|
||||||
|
// console.log(nick)
|
||||||
|
// var feedsArr = uconfig[nick].feeds
|
||||||
|
// console.log(feedsArr)
|
||||||
|
// var num = n/feedsArr.length
|
||||||
|
// for (let i = 0; i < feedsArr.length; i++) {
|
||||||
|
// fetchFeed(feedsArr[i], num);
|
||||||
|
// }
|
||||||
|
// await sendUpstream(content);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//getAllFeeds(nick, n)
|
||||||
|
fetchFeed(provfeed, n, provfeed);
|
@ -1,4 +1,5 @@
|
|||||||
const config = require('../config/default.json')
|
const config = require('../config/default.json')
|
||||||
|
const uconfig = require('../config/usersettings.json')
|
||||||
const { parentPort, workerData } = require('worker_threads');
|
const { parentPort, workerData } = require('worker_threads');
|
||||||
const { user, setting, setting2, value } = workerData;
|
const { user, setting, setting2, value } = workerData;
|
||||||
const fs = require('fs-extra')
|
const fs = require('fs-extra')
|
||||||
@ -6,18 +7,13 @@ let Parser = require('rss-parser');
|
|||||||
let parser = new Parser({
|
let parser = new Parser({
|
||||||
headers: {'User-Agent': config.feed.useragent},
|
headers: {'User-Agent': config.feed.useragent},
|
||||||
});
|
});
|
||||||
const striptags = require("striptags");
|
|
||||||
const moment = require('moment');
|
|
||||||
const tz = require('moment-timezone');
|
|
||||||
const editJsonFile = require("edit-json-file");
|
const editJsonFile = require("edit-json-file");
|
||||||
const timer = ms => new Promise(res => setTimeout(res, ms))
|
const timer = ms => new Promise(res => setTimeout(res, ms))
|
||||||
|
|
||||||
warningMsg = ''+config.colours.brackets+'['+config.colours.warning+'WARNING'+config.colours.brackets+']'
|
warningMsg = ''+config.colours.brackets+'['+config.colours.warning+'WARNING'+config.colours.brackets+']'
|
||||||
errorMsg = ''+config.colours.brackets+'['+config.colours.error+'ERROR'+config.colours.brackets+']'
|
errorMsg = ''+config.colours.brackets+'['+config.colours.error+'ERROR'+config.colours.brackets+']'
|
||||||
|
|
||||||
|
|
||||||
async function sendUpstream(content) {
|
async function sendUpstream(content) {
|
||||||
//var output = content.join("\n")
|
|
||||||
parentPort.postMessage(content);
|
parentPort.postMessage(content);
|
||||||
process.exit()
|
process.exit()
|
||||||
}
|
}
|
||||||
@ -32,6 +28,8 @@ function errorMessage(error, code, extra) {
|
|||||||
var error = errorMsg+" Unescaped Characters"
|
var error = errorMsg+" Unescaped Characters"
|
||||||
} else if (code == "INVALID") {
|
} else if (code == "INVALID") {
|
||||||
var error = errorMsg+' '+extra+' either does not exist or is not a valid feed.'
|
var error = errorMsg+' '+extra+' either does not exist or is not a valid feed.'
|
||||||
|
} else if (code == "ALREADYEXISTS" ) {
|
||||||
|
var error = errorMsg+' '+extra+' already exists in your feed list.'
|
||||||
} else {
|
} else {
|
||||||
var error = errorMsg+" Unknown error"
|
var error = errorMsg+" Unknown error"
|
||||||
}
|
}
|
||||||
@ -53,19 +51,16 @@ async function feed(nick, setting, value) {
|
|||||||
if (setting === 'add') {
|
if (setting === 'add') {
|
||||||
await testFeed(value);
|
await testFeed(value);
|
||||||
var file = editJsonFile('/home/node/app/config/usersettings.json');
|
var file = editJsonFile('/home/node/app/config/usersettings.json');
|
||||||
|
var feedsArr = uconfig[nick].feeds
|
||||||
|
if (feedsArr.includes(value) == true) {
|
||||||
|
errorMessage("null", "ALREADYEXISTS", value)
|
||||||
|
} else {
|
||||||
file.append(nick+".feeds", value);
|
file.append(nick+".feeds", value);
|
||||||
file.save();
|
file.save();
|
||||||
sendUpstream(value + ' added to your feed list')
|
sendUpstream(value + ' added to your feed list')
|
||||||
//file.custom.feed.nick = value;
|
|
||||||
//fs.writeFile(file, JSON.stringify({ feed: value }))
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//fs.readFile('../config/feeds.json').catch(() =>
|
|
||||||
// fs.writeFile('../config/feeds.json', '')
|
|
||||||
//);
|
|
||||||
|
|
||||||
if (setting === 'feed') {
|
if (setting === 'feed') {
|
||||||
feed(user, setting2, value);
|
feed(user, setting2, value);
|
||||||
|
Loading…
Reference in New Issue
Block a user