Add scripts used for fetching URLs based on query type
							parent
							
								
									8cb92ebd3c
								
							
						
					
					
						commit
						973318706c
					
				| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
		Loading…
	
		Reference in New Issue