281 lines
7.9 KiB
JavaScript
281 lines
7.9 KiB
JavaScript
// JD Requires
|
|
let Parser = require('rss-parser');
|
|
const axios = require('axios');
|
|
let parser = new Parser();
|
|
const { FeedStorage, PostStorage } = require("./libStorage");
|
|
const libUtils = require("./libUtils");
|
|
const { createHash } = require("crypto");
|
|
const { all } = require('axios');
|
|
|
|
const { DebugBuilder } = require("./utilities/debugBuilder");
|
|
const log = new DebugBuilder("server", "libCore");
|
|
|
|
// Setup Storage handlers
|
|
var feedStorage = new FeedStorage();
|
|
var postStorage = new PostStorage();
|
|
|
|
/**
|
|
* Adds or updates new source url to configured storage
|
|
* @constructor
|
|
* @param {string} title - Title/Name of the RSS feed.
|
|
* @param {string} link - URL of RSS feed.
|
|
* @param {string} category - Category of RSS feed.
|
|
*/
|
|
exports.addSource = async (title, link, category, guildId, channelId, callback) => {
|
|
feedStorage.create([{
|
|
"fields": {
|
|
"title": title,
|
|
"link": link,
|
|
"category": category,
|
|
'guild_id': guildId,
|
|
"channel_id": channelId
|
|
}
|
|
}], function (err, record) {
|
|
if (err) {
|
|
log.ERROR("Error in create:", err);
|
|
return callback(err, undefined);
|
|
}
|
|
|
|
if (!record) return callback(undefined, false);
|
|
|
|
log.DEBUG("Record ID:", record.getId());
|
|
|
|
return callback(undefined, record);
|
|
});
|
|
|
|
}
|
|
|
|
/**
|
|
* Deletes a new source url by title
|
|
* @constructor
|
|
* @param {string} title - Title/Name of the RSS feed.
|
|
*/
|
|
exports.deleteSource = function (title, callback) {
|
|
feedStorage.getRecordBy('title', title, (err, results) => {
|
|
if (err) return callback(err, undefined);
|
|
|
|
if (!results?.id) {
|
|
log.DEBUG("No record found for title: ", title)
|
|
return callback(undefined, undefined);
|
|
}
|
|
|
|
feedStorage.destroy(results.id, function (err, deletedRecord) {
|
|
if (err) {
|
|
log.ERROR(err);
|
|
return callback(err, undefined);
|
|
}
|
|
log.DEBUG("Deleted Record: ", deletedRecord);
|
|
return callback(undefined, deletedRecord ?? true);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Update channels with new posts from sources
|
|
*/
|
|
exports.updateFeeds = async (client) => {
|
|
if (!client) throw new Error("Client object not passed");
|
|
feedStorage.getAllRecords(async (err, records) => {
|
|
// Load the posts from each RSS source
|
|
for (const source of records) {
|
|
log.DEBUG('Record title: ', source.title);
|
|
log.DEBUG('Record link: ', source.link);
|
|
log.DEBUG('Record category: ', source.category);
|
|
log.DEBUG('Record guild ID: ', source.guild_id);
|
|
log.DEBUG('Record channel ID: ', source.channel_id);
|
|
|
|
await parser.parseURL(source.link, async (err, parsedFeed) => {
|
|
if (err) {
|
|
log.ERROR("Parser Error: ", source.link, err);
|
|
//return;
|
|
}
|
|
|
|
try{
|
|
log.DEBUG("Parsed Feed Keys", Object.keys(parsedFeed), parsedFeed?.title);
|
|
|
|
if (parsedFeed?.items){
|
|
for (const post of parsedFeed.items){
|
|
log.VERBOSE("Post from feed: ", post);
|
|
if (post.title && post.link && post.content && ( post.postId || post.guid || post.id ) && post.pubDate){
|
|
post.postId = post.postId ?? post.guid ?? post.id;
|
|
postStorage.getRecordBy('post_guid', post.postId, (err, existingRecord) => {
|
|
if (err) throw err;
|
|
log.DEBUG("Existing post record: ", existingRecord);
|
|
if (!existingRecord){
|
|
const channel = client.channels.cache.get(source.channel_id);
|
|
libUtils.sendPost(post, channel, (err, sendResults) =>{
|
|
if (err) throw err;
|
|
|
|
if (sendResults){
|
|
log.DEBUG("Saving post to database: ", sendResults, post.title, source.channel_id);
|
|
|
|
postStorage.savePost(post, (err, saveResults) => {
|
|
if(err) throw err;
|
|
|
|
if (saveResults) {
|
|
log.DEBUG("Saved results: ", saveResults);
|
|
}
|
|
});
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}catch (err) {
|
|
log.ERROR("Error Parsing Feed: ", source.link, err);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Search a state for any weather alerts
|
|
*
|
|
* @param {*} state The state to search for any weather alerts in
|
|
* @returns
|
|
*/
|
|
exports.weatherAlert = async function (state) {
|
|
|
|
var answerURL = `https://api.weather.gov/alerts/active?area=${state}`;
|
|
log.DEBUG(answerURL);
|
|
answerData = [];
|
|
|
|
await axios.get(answerURL)
|
|
.then(response => {
|
|
response.data.features.forEach(feature => {
|
|
answerData.push(feature);
|
|
})
|
|
|
|
return answerData;
|
|
})
|
|
.catch(error => {
|
|
log.DEBUG(error);
|
|
});
|
|
return answerData;
|
|
}
|
|
|
|
/**
|
|
* Gets a random food recipe
|
|
*
|
|
* @returns
|
|
*/
|
|
exports.getFood = async function () {
|
|
|
|
var answerURL = `https://www.themealdb.com/api/json/v1/1/random.php`;
|
|
log.DEBUG(answerURL);
|
|
answerData = {
|
|
text: `No answer found try using a simpler search term`,
|
|
source: ``
|
|
}
|
|
await axios.get(answerURL)
|
|
.then(response => {
|
|
//log.DEBUG(response.data.RelatedTopics[0].Text);
|
|
//log.DEBUG(response.data.RelatedTopics[0].FirstURL);
|
|
|
|
// if (response.data.meals.length != 0) {
|
|
|
|
answerData = {
|
|
strMeal: `No Data`,
|
|
strSource: `-`,
|
|
strInstructions: `-`,
|
|
strMealThumb: `-`,
|
|
strCategory: `-`
|
|
}
|
|
|
|
answerData = {
|
|
strMeal: `${unescape(response.data.meals[0].strMeal)}`,
|
|
strSource: `${unescape(response.data.meals[0].strSource)}`,
|
|
strInstructions: `${unescape(response.data.meals[0].strInstructions)}`,
|
|
strMealThumb: `${unescape(response.data.meals[0].strMealThumb)}`,
|
|
strCategory: `${unescape(response.data.meals[0].strCategory)}`
|
|
}
|
|
// } else {
|
|
|
|
//}
|
|
return answerData;
|
|
})
|
|
.catch(error => {
|
|
log.DEBUG(error);
|
|
});
|
|
return answerData;
|
|
}
|
|
|
|
/**
|
|
* Search Urban dictionary for a phrase
|
|
*
|
|
* @param {*} question The phrase to search urban dictionary for
|
|
* @returns
|
|
*/
|
|
exports.getSlang = async function (question) {
|
|
|
|
var answerURL = `https://api.urbandictionary.com/v0/define?term=${question}`;
|
|
log.DEBUG(answerURL);
|
|
slangData = {
|
|
definition: `No answer found try using a simpler search term`,
|
|
example: ``
|
|
}
|
|
await axios.get(answerURL)
|
|
.then(response => {
|
|
log.DEBUG(response.data.list[0]);
|
|
|
|
slangData = {
|
|
definition: `${unescape(response.data.list[0].definition) ? unescape(response.data.list[0].definition) : ''}`,
|
|
example: `${unescape(response.data.list[0].example) ? unescape(response.data.list[0].example) : ''}`,
|
|
thumbs_down: `${unescape(response.data.list[0].thumbs_down)}`,
|
|
thumbs_up: `${unescape(response.data.list[0].thumbs_up)}`
|
|
}
|
|
|
|
return slangData;
|
|
})
|
|
.catch(error => {
|
|
log.DEBUG(error);
|
|
});
|
|
return slangData;
|
|
}
|
|
|
|
/**
|
|
* getSources - Get the RSS sources currently in use
|
|
* @constructor
|
|
*/
|
|
exports.getSources = function () {
|
|
feedStorage.getAllRecords((err, records) => {
|
|
if (err) throw err;
|
|
return records;
|
|
})
|
|
}
|
|
|
|
/**
|
|
* getQuotes - Get a random quote from the local list
|
|
* @constructor
|
|
*/
|
|
exports.getQuotes = async function (quote_url) {
|
|
|
|
var data = [];
|
|
await axios.get(quote_url)
|
|
.then(response => {
|
|
log.DEBUG(response.data[0].q);
|
|
log.DEBUG(response.data[0].a);
|
|
data = response.data;
|
|
|
|
return data;
|
|
})
|
|
.catch(error => {
|
|
log.DEBUG(error);
|
|
});
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* getCategories - Returns feed categories
|
|
* @constructor
|
|
*/
|
|
exports.getCategories = async (callback) => {
|
|
feedStorage.getUniqueByKey("category", (err, results) => {
|
|
if (err) return callback(err, undefined);
|
|
|
|
return callback(undefined, results);
|
|
});
|
|
} |