F95API/app/scripts/searcher.js

96 lines
3.0 KiB
JavaScript
Raw Normal View History

2020-10-30 19:41:56 +00:00
"use strict";
// Public modules from npm
const cheerio = require("cheerio");
// Modules from file
const { fetchHTML } = require("./network-helper.js");
2020-10-31 15:00:26 +00:00
const shared = require("./shared.js");
2020-10-30 19:41:56 +00:00
const f95Selector = require("./constants/css-selector.js");
const { F95_BASE_URL } = require("./constants/url.js");
2020-10-30 19:41:56 +00:00
2020-10-31 15:00:26 +00:00
//#region Public methods
2020-10-30 19:41:56 +00:00
/**
* @protected
* Search for a game on F95Zone and return a list of URLs, one for each search result.
* @param {String} name Game name
* @returns {Promise<String[]>} URLs of results
*/
module.exports.searchGame = async function (name) {
2020-10-30 19:41:56 +00:00
shared.logger.info(`Searching games with name ${name}`);
// Replace the whitespaces with +
2020-10-31 15:00:26 +00:00
const searchName = encodeURIComponent(name.toUpperCase());
2020-10-30 19:41:56 +00:00
// Prepare the URL (only title, search in the "Games" section, order by relevance)
2020-11-12 13:20:35 +00:00
const url = `https://f95zone.to/search/83456043/?q="${searchName}"&t=post&c[child_nodes]=1&c[nodes][0]=2&c[title_only]=1&o=relevance`;
2020-10-30 19:41:56 +00:00
// Fetch and parse the result URLs
return await fetchResultURLs(url);
2020-10-30 19:41:56 +00:00
};
/**
* @protected
* Search for a mod on F95Zone and return a list of URLs, one for each search result.
* @param {String} name Mod name
* @returns {Promise<String[]>} URLs of results
*/
module.exports.searchMod = async function (name) {
2020-10-30 19:41:56 +00:00
shared.logger.info(`Searching mods with name ${name}`);
2020-10-31 15:00:26 +00:00
2020-10-30 19:41:56 +00:00
// Replace the whitespaces with +
2020-10-31 15:00:26 +00:00
const searchName = encodeURIComponent(name.toUpperCase());
2020-10-30 19:41:56 +00:00
// Prepare the URL (only title, search in the "Mods" section, order by relevance)
2020-11-12 13:20:35 +00:00
const url = `https://f95zone.to/search/83459796/?q="${searchName}"&t=post&c[child_nodes]=1&c[nodes][0]=41&c[title_only]=1&o=relevance`;
2020-10-30 19:41:56 +00:00
// Fetch and parse the result URLs
return await fetchResultURLs(url);
2020-10-30 19:41:56 +00:00
};
2020-10-31 15:00:26 +00:00
//#endregion Public methods
2020-10-30 19:41:56 +00:00
//#region Private methods
/**
* @private
* Gets the URLs of the threads resulting from the F95Zone search.
* @param {String} url Search URL
* @return {Promise<String[]>} List of URLs
*/
async function fetchResultURLs(url) {
shared.logger.trace(`Fetching ${url}...`);
2020-10-30 19:41:56 +00:00
// Fetch HTML and prepare Cheerio
const html = await fetchHTML(url);
2020-10-30 19:41:56 +00:00
const $ = cheerio.load(html);
// Here we get all the DIV that are the body of the various query results
const results = $("body").find(f95Selector.GS_RESULT_BODY);
// Than we extract the URLs
const urls = results.map((idx, el) => {
const elementSelector = $(el);
return extractLinkFromResult(elementSelector);
}).get();
return urls;
}
/**
* @private
* Look for the URL to the thread referenced by the item.
* @param {cheerio.Cheerio} selector Element to search
* @returns {String} URL to thread
*/
function extractLinkFromResult(selector) {
shared.logger.trace("Extracting thread link from result...");
const partialLink = selector
2020-10-30 19:41:56 +00:00
.find(f95Selector.GS_RESULT_THREAD_TITLE)
.attr("href")
.trim();
// Compose and return the URL
return new URL(partialLink, F95_BASE_URL).toString();
2020-10-30 19:41:56 +00:00
}
//#endregion Private methods