// 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, source, 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); }); }