Add scripts used for fetching URLs based on query type

pull/73/head
MillenniumEarl 2021-02-25 12:04:42 +01:00
parent 8cb92ebd3c
commit 973318706c
3 changed files with 157 additions and 0 deletions

View File

@ -0,0 +1,41 @@
"use strict";
// Modules from file
import HandiworkSearchQuery from "../classes/query/handiwork-search-query";
import LatestSearchQuery from "../classes/query/latest-search-query";
import ThreadSearchQuery from "../classes/query/thread-search-query";
import fetchLatestHandiworkURLs from "./fetch-latest.js";
import fetchThreadHandiworkURLs from "./fetch-thread.js";
/**
* Gets the URLs of the handiworks that match the passed parameters.
* You *must* be logged.
* @param {LatestSearchQuery} query
* Query used for the search
* @param {Number} limit
* Maximum number of items to get. Default: 30
* @returns {Promise<String[]>} URLs of the handiworks
*/
export default async function fetchHandiworkURLs(query: HandiworkSearchQuery, limit: number = 30): Promise<string[]> {
// Local variables
let urls: string[] = null;
const searchType = query.selectSearchType();
// Convert the query
if (searchType === "latest") {
// Cast the query
const castedQuery = query.cast<LatestSearchQuery>();
// Fetch the urls
urls = await fetchLatestHandiworkURLs(castedQuery, limit);
}
else {
// Cast the query
const castedQuery = query.cast<ThreadSearchQuery>();
// Fetch the urls
urls = await fetchThreadHandiworkURLs(castedQuery, limit);
}
return urls;
}

View File

@ -0,0 +1,41 @@
"use strict";
// Modules from files
import fetchHandiworkURLs from "./fetch-handiwork.js";
import fetchLatestHandiworkURLs from "./fetch-latest.js";
import fetchThreadHandiworkURLs from "./fetch-thread.js";
import HandiworkSearchQuery from "../classes/query/handiwork-search-query.js";
import LatestSearchQuery from "../classes/query/latest-search-query.js";
import ThreadSearchQuery from "../classes/query/thread-search-query.js";
//#region Public methods
export default async function executeQuery(query: LatestSearchQuery, limit: number): Promise<string[]>
export default async function executeQuery(query: ThreadSearchQuery, limit: number): Promise<string[]>
export default async function executeQuery(query: HandiworkSearchQuery, limit: number): Promise<string[]>
/**
* @param query Query used for the search
* @param limit Maximum number of items to get. Default: 30
* @returns URLs of the fetched games
*/
export default async function executeQuery(query: any, limit: number = 30): Promise<string[]> {
// Local variables
const searchMap = {
"latest": fetchLatestHandiworkURLs,
"thread": fetchThreadHandiworkURLs,
"handiwork": fetchHandiworkURLs,
}
// Find the key for the mapping dict
const key = query instanceof LatestSearchQuery ?
"latest" :
(query instanceof ThreadSearchQuery ?
"thread" :
"handiwork");
// Fetch and return the urls
return await searchMap[key](query, limit);
}
//#endregion

View File

@ -0,0 +1,75 @@
"use strict";
// Public modules from npm
import cheerio from "cheerio";
// Modules from file
import { fetchHTML } from "../network-helper.js";
import shared from "../shared.js";
import { selectors as f95Selector } from "../constants/css-selector.js";
import { urls as f95urls } from "../constants/url.js";
import ThreadSearchQuery from "../classes/query/thread-search-query.js";
//#region Public methods
/**
* Gets the URLs of the handiwork' threads that match the passed parameters.
* You *must* be logged.
* @param {ThreadSearchQuery} query
* Query used for the search
* @param {number} limit
* Maximum number of items to get. Default: 30
* @returns {Promise<String[]>} URLs of the handiworks
*/
export default async function fetchThreadHandiworkURLs(query: ThreadSearchQuery, limit:number = 30): Promise<string[]> {
// Get the query
const url = query.createURL().toString();
// Fetch the results from F95 and return the handiwork urls
return await fetchResultURLs(url, limit);
}
//#endregion Public methods
//#region Private methods
/**
* Gets the URLs of the threads resulting from the F95Zone search.
* @param {number} limit
* Maximum number of items to get. Default: 30
* @return {Promise<String[]>} List of URLs
*/
async function fetchResultURLs(url: string, limit: number = 30): Promise<string[]> {
shared.logger.trace(`Fetching ${url}...`);
// Fetch HTML and prepare Cheerio
const html = await fetchHTML(url);
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.slice(0, limit).map((idx, el) => {
const elementSelector = $(el);
return extractLinkFromResult(elementSelector);
}).get();
return urls;
}
/**
* 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: cheerio.Cheerio): string {
shared.logger.trace("Extracting thread link from result...");
const partialLink = selector
.find(f95Selector.GS_RESULT_THREAD_TITLE)
.attr("href")
.trim();
// Compose and return the URL
return new URL(partialLink, f95urls.F95_BASE_URL).toString();
}
//#endregion Private methods