// JD Requires let Parser = require('rss-parser'); const axios = require('axios'); let parser = new Parser(); const storageHandler = require("./libStorage"); const { DebugBuilder } = require("./utilities/debugBuilder"); const log = new DebugBuilder("server", "libCore"); /* OpenAI config const { Configuration, OpenAIApi } = require('openai'); const configuration = new Configuration({ organization: process.env.OPENAI_ORG, apiKey: process.env.OPENAI_API }); const openai = new OpenAIApi(configuration); */ // Data Structures var feeds = []; let rssFeedMap = []; let rssFeedCategories = []; // Precess Vars var userTable = process.env.DB_TABLE // Setup Storage handler var storageSource = new storageHandler.Storage(userTable); /** * Adds a 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 = function (title, link, category, callback) { for (i = 0; i < feeds.length; i++) { if (feeds[i].link == link) { return; } } storageSource.create([{ "fields": { "title": title, "link": link, "category": category } }], function (err, record) { if (err) { log.ERROR("Error in create:", err); callback(err, undefined); } log.DEBUG("Record ID:", record.getId()); var linkData = { title: `${title}`, link: `${link}`, category: `${category}`, id: record.getId() } log.DEBUG("Link Data:", linkData); feeds.push(linkData); log.DEBUG("pushed item to feeds"); callback(undefined, true); }); } /** * Deletes a new source url by title * @constructor * @param {string} title - Title/Name of the RSS feed. */ exports.deleteSource = function (title, callback) { var deleteRecord = ""; for (i = 0; i < feeds.length; i++) { if (feeds[i].title == title) { deleteRecord = feeds[i].id; } } storageSource.destroy(deleteRecord, function (err, deletedRecord) { if (err) { log.ERROR(err); callback(err, undefined); } log.DEBUG(deletedRecord.id); callback(undefined, deletedRecord); }); } /** * Adds a new source url to configured storage * @constructor * @param {string} feedType - Category to select Feed by. */ exports.getFeeds = function (feedType) { var linkFlayerFilteredMap = []; if (feedType == null || feedType == undefined || feedType == "") { return rssFeedMap; } else { rssFeedMap.forEach(linkFlay => { if (linkFlay.category.toLowerCase().indexOf(feedType.toLowerCase()) > -1) { linkFlayerFilteredMap.push(linkFlay); } }); return linkFlayerFilteredMap; } } /** * Load the RSS feeds */ exports.loadFeeds = function () { feeds = []; rssFeedMap = []; rssFeedCategories = []; storageSource.getAllRecords(function (err, records) { records.forEach(function (record) { try { log.DEBUG('Retrieved title: ', record.get('title')); log.DEBUG('Retrieved link:', record.get('link')); log.DEBUG('Retrieved category:', record.get('category')); var feedData = { title: `${unescape(record.get('title'))}`, link: `${unescape(record.get('link'))}`, category: `${unescape(record.get('category'))}`, id: record.getId() } var foundMatch = false; feeds.forEach(feedBlock => { if (feedBlock.link == feedData.link) { foundMatch = true; } }); if (!foundMatch) { feeds.push(feedData); } let foundCat = false; rssFeedCategories.forEach(cat => { if (cat == record.get('category')) { foundCat = true; } }); if (!foundCat) { rssFeedCategories.push(record.get('category')); } } catch (error) { log.DEBUG(error); } }); feeds.forEach(feedBlock => { (async () => { try { const feed = parser.parseURL(feedBlock.link, function (err, feed) { if (err) { log.DEBUG(err + " " + feedBlock.link); //return; } if (feed != undefined && feed.items != undefined) { feed.items.forEach(item => { var foundFeed = false; rssFeedMap.forEach(linkFlay => { if (linkFlay.link == item.link) { foundFeed = true; } }); if (!foundFeed) { var linkData = { title: `${unescape(item.title)}`, link: `${unescape(item.link)}`, category: `${unescape(feedBlock.category)}` } rssFeedMap.push(linkData); } }); } else { log.DEBUG('error parsing :' + feedBlock.link); } }) } catch (error) { log.DEBUG(error); } })().then(); }); return; //fetchNextPage(); }, function done(error) { log.DEBUG(error); }); } /** * 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; } /** * Use ChatGPT to generate a response * * @param {*} _prompt The use submitted text prompt * @param {*} param1 Default parameters can be modified * @returns */ exports.getChat = async function (_prompt, { _model = "text-davinci-003", _temperature = 0, _max_tokens = 100 }) { const response = await openai.createCompletion({ model: _model, prompt: _prompt, temperature: _temperature, max_tokens: _max_tokens }); var responseData = response.data.choices[0].text; return responseData; } /** * getSources - Get the RSS sources currently in use * @constructor */ exports.getSources = function () { return feeds; } /** * 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 = function () { return rssFeedCategories; }