Merge pull request #73 from MillenniumEarl/2.0.0-ts-cf-autofix
Apply fixes from CodeFactorpull/74/head
commit
a3cb6ab416
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
to use this example, create an .env file
|
||||
/*
|
||||
to use this example, create an .env file
|
||||
in the project root with the following values:
|
||||
|
||||
F95_USERNAME = YOUR_USERNAME
|
||||
|
@ -12,12 +12,12 @@ F95_PASSWORD = YOUR_PASSWORD
|
|||
import dotenv from "dotenv";
|
||||
|
||||
// Modules from file
|
||||
import { login,
|
||||
getUserData,
|
||||
getLatestUpdates,
|
||||
LatestSearchQuery,
|
||||
Game,
|
||||
searchHandiwork,
|
||||
import { login,
|
||||
getUserData,
|
||||
getLatestUpdates,
|
||||
LatestSearchQuery,
|
||||
Game,
|
||||
searchHandiwork,
|
||||
HandiworkSearchQuery
|
||||
} from "./index.js";
|
||||
|
||||
|
|
24
src/index.ts
24
src/index.ts
|
@ -59,7 +59,7 @@ export function isLogged(): boolean { return shared.isLogged; };
|
|||
|
||||
/**
|
||||
* Log in to the F95Zone platform.
|
||||
*
|
||||
*
|
||||
* This **must** be the first operation performed before accessing any other script functions.
|
||||
*/
|
||||
export async function login(username: string, password: string): Promise<LoginResult> {
|
||||
|
@ -102,7 +102,7 @@ export async function login(username: string, password: string): Promise<LoginRe
|
|||
|
||||
/**
|
||||
* Chek if exists a new version of the handiwork.
|
||||
*
|
||||
*
|
||||
* You **must** be logged in to the portal before calling this method.
|
||||
*/
|
||||
export async function checkIfHandiworkHasUpdate(hw: HandiWork): Promise<boolean> {
|
||||
|
@ -127,9 +127,9 @@ export async function checkIfHandiworkHasUpdate(hw: HandiWork): Promise<boolean>
|
|||
|
||||
/**
|
||||
* Search for one or more handiworks identified by a specific query.
|
||||
*
|
||||
*
|
||||
* You **must** be logged in to the portal before calling this method.
|
||||
*
|
||||
*
|
||||
* @param {HandiworkSearchQuery} query Parameters used for the search.
|
||||
* @param {Number} limit Maximum number of results. Default: 10
|
||||
*/
|
||||
|
@ -137,12 +137,12 @@ export async function searchHandiwork<T extends IBasic>(query: HandiworkSearchQu
|
|||
// Check if the user is logged
|
||||
if (!shared.isLogged) throw new UserNotLogged(USER_NOT_LOGGED);
|
||||
|
||||
return await search<T>(query, limit);
|
||||
return search<T>(query, limit);
|
||||
};
|
||||
|
||||
/**
|
||||
* Given the url, it gets all the information about the handiwork requested.
|
||||
*
|
||||
*
|
||||
* You **must** be logged in to the portal before calling this method.
|
||||
*/
|
||||
export async function getHandiworkFromURL<T extends IBasic>(url: string): Promise<T> {
|
||||
|
@ -155,14 +155,14 @@ export async function getHandiworkFromURL<T extends IBasic>(url: string): Promis
|
|||
if (!isF95URL(url)) throw new Error(`${url} is not a valid F95Zone URL`);
|
||||
|
||||
// Get game data
|
||||
return await getHandiworkInformation<T>(url);
|
||||
return getHandiworkInformation<T>(url);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the data of the currently logged in user.
|
||||
*
|
||||
*
|
||||
* You **must** be logged in to the portal before calling this method.
|
||||
*
|
||||
*
|
||||
* @returns {Promise<UserProfile>} Data of the user currently logged in
|
||||
*/
|
||||
export async function getUserData(): Promise<UserProfile> {
|
||||
|
@ -178,9 +178,9 @@ export async function getUserData(): Promise<UserProfile> {
|
|||
|
||||
/**
|
||||
* Gets the latest updated games that match the specified parameters.
|
||||
*
|
||||
*
|
||||
* You **must** be logged in to the portal before calling this method.
|
||||
*
|
||||
*
|
||||
* @param {LatestSearchQuery} query Parameters used for the search.
|
||||
* @param {Number} limit Maximum number of results. Default: 10
|
||||
*/
|
||||
|
@ -196,7 +196,7 @@ export async function getLatestUpdates<T extends IBasic>(query: LatestSearchQuer
|
|||
|
||||
// Get the data from urls
|
||||
const promiseList = urls.map((u: string) => getHandiworkInformation<T>(u));
|
||||
return await Promise.all(promiseList);
|
||||
return Promise.all(promiseList);
|
||||
};
|
||||
|
||||
//#endregion
|
||||
|
|
|
@ -45,7 +45,7 @@ export default class Thread {
|
|||
public get id() { return this._id; }
|
||||
/**
|
||||
* URL of the thread.
|
||||
*
|
||||
*
|
||||
* It may vary depending on any versions of the contained product.
|
||||
*/
|
||||
public get url() { return this._url; }
|
||||
|
@ -85,8 +85,8 @@ export default class Thread {
|
|||
//#endregion Getters
|
||||
|
||||
/**
|
||||
* Initializes an object for mapping a thread.
|
||||
*
|
||||
* Initializes an object for mapping a thread.
|
||||
*
|
||||
* The unique ID of the thread must be specified.
|
||||
*/
|
||||
constructor(id: number) { this._id = id; }
|
||||
|
@ -167,7 +167,7 @@ export default class Thread {
|
|||
}
|
||||
|
||||
/**
|
||||
* It processes the rating of the thread
|
||||
* It processes the rating of the thread
|
||||
* starting from the data contained in the JSON+LD tag.
|
||||
*/
|
||||
private parseRating(data: TJsonLD): TRating {
|
||||
|
@ -241,7 +241,7 @@ export default class Thread {
|
|||
|
||||
/**
|
||||
* Gets the post in the `index` position with respect to the posts in the thread.
|
||||
*
|
||||
*
|
||||
* `index` must be greater or equal to 1.
|
||||
* If the post is not found, `null` is returned.
|
||||
*/
|
||||
|
|
|
@ -149,7 +149,7 @@ export default class UserProfile extends PlatformUser {
|
|||
}
|
||||
|
||||
// Wait for the promises to resolve
|
||||
return await Promise.all(responsePromiseList);
|
||||
return Promise.all(responsePromiseList);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,7 +11,7 @@ export default class PrefixParser {
|
|||
//#region Private methods
|
||||
/**
|
||||
* Gets the key associated with a given value from a dictionary.
|
||||
* @param {Object} object Dictionary to search
|
||||
* @param {Object} object Dictionary to search
|
||||
* @param {Any} value Value associated with the key
|
||||
* @returns {String|undefined} Key found or undefined
|
||||
*/
|
||||
|
@ -43,7 +43,7 @@ export default class PrefixParser {
|
|||
}
|
||||
|
||||
/**
|
||||
* Search within the platform prefixes for the
|
||||
* Search within the platform prefixes for the
|
||||
* desired element and return the dictionary that contains it.
|
||||
* @param element Element to search in the prefixes as a key or as a value
|
||||
*/
|
||||
|
|
|
@ -13,21 +13,21 @@ import ThreadSearchQuery, { TThreadOrder } from './thread-search-query.js';
|
|||
|
||||
// Type definitions
|
||||
/**
|
||||
* Method of sorting results. Try to unify the two types of
|
||||
* sorts in the "Latest" section and in the "Thread search"
|
||||
* section. Being dynamic research, if a sorting type is not
|
||||
* Method of sorting results. Try to unify the two types of
|
||||
* sorts in the "Latest" section and in the "Thread search"
|
||||
* section. Being dynamic research, if a sorting type is not
|
||||
* available, the replacement sort is chosen.
|
||||
*
|
||||
*
|
||||
* `date`: Order based on the latest update
|
||||
*
|
||||
* `likes`: Order based on the number of likes received. Replacement: `replies`.
|
||||
*
|
||||
*
|
||||
* `relevance`: Order based on the relevance of the result (or rating).
|
||||
*
|
||||
*
|
||||
* `replies`: Order based on the number of answers to the thread. Replacement: `views`.
|
||||
*
|
||||
*
|
||||
* `title`: Order based on the growing alphabetical order of the titles.
|
||||
*
|
||||
*
|
||||
* `views`: Order based on the number of visits. Replacement: `replies`.
|
||||
*/
|
||||
type THandiworkOrder = "date" | "likes" | "relevance" | "replies" | "title" | "views";
|
||||
|
@ -80,8 +80,8 @@ export default class HandiworkSearchQuery implements IQuery {
|
|||
//#region Public methods
|
||||
|
||||
/**
|
||||
* Select what kind of search should be
|
||||
* performed based on the properties of
|
||||
* Select what kind of search should be
|
||||
* performed based on the properties of
|
||||
* the query.
|
||||
*/
|
||||
public selectSearchType(): "latest" | "thread" {
|
||||
|
@ -89,8 +89,8 @@ export default class HandiworkSearchQuery implements IQuery {
|
|||
const MAX_TAGS_LATEST_SEARCH = 5;
|
||||
const DEFAULT_SEARCH_TYPE = "latest";
|
||||
|
||||
// If the keywords are set or the number
|
||||
// of included tags is greather than 5,
|
||||
// If the keywords are set or the number
|
||||
// of included tags is greather than 5,
|
||||
// we must perform a thread search
|
||||
if (this.keywords || this.includedTags.length > MAX_TAGS_LATEST_SEARCH) return "thread";
|
||||
|
||||
|
@ -156,7 +156,7 @@ export default class HandiworkSearchQuery implements IQuery {
|
|||
private castToThread(): ThreadSearchQuery {
|
||||
// Cast the basic query object and copy common values
|
||||
const query: ThreadSearchQuery = new ThreadSearchQuery;
|
||||
Object.keys(this).forEach(key => {
|
||||
Object.keys(this).forEach(key => {
|
||||
if (query.hasOwnProperty(key)) {
|
||||
query[key] = this[key];
|
||||
}
|
||||
|
|
|
@ -29,15 +29,15 @@ export default class LatestSearchQuery implements IQuery {
|
|||
|
||||
public category: TCategory = 'games';
|
||||
/**
|
||||
* Ordering type.
|
||||
*
|
||||
* Ordering type.
|
||||
*
|
||||
* Default: `date`.
|
||||
*/
|
||||
public order: TLatestOrder = 'date';
|
||||
/**
|
||||
* Date limit in days, to be understood as "less than".
|
||||
* Use `1` to indicate "today" or `null` to indicate "anytime".
|
||||
*
|
||||
*
|
||||
* Default: `null`
|
||||
*/
|
||||
public date: TDate = null;
|
||||
|
@ -74,7 +74,7 @@ export default class LatestSearchQuery implements IQuery {
|
|||
const decoded = decodeURIComponent(url.toString());
|
||||
|
||||
// Fetch the result
|
||||
return await fetchGETResponse(decoded);
|
||||
return fetchGETResponse(decoded);
|
||||
}
|
||||
|
||||
public findNearestDate(d: Date): TDate {
|
||||
|
@ -124,7 +124,7 @@ export default class LatestSearchQuery implements IQuery {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
private dateDiffInDays(a: Date, b: Date) {
|
||||
const MS_PER_DAY = 1000 * 60 * 60 * 24;
|
||||
|
|
|
@ -82,7 +82,7 @@ export default class ThreadSearchQuery implements IQuery {
|
|||
const params = this.preparePOSTParameters();
|
||||
|
||||
// Return the POST response
|
||||
return await fetchPOSTResponse(urls.F95_SEARCH_URL, params);
|
||||
return fetchPOSTResponse(urls.F95_SEARCH_URL, params);
|
||||
}
|
||||
|
||||
//#endregion Public methods
|
||||
|
|
|
@ -25,7 +25,7 @@ export const selectors = {
|
|||
|
||||
export const GENERIC = {
|
||||
/**
|
||||
* The ID of the user currently logged into
|
||||
* The ID of the user currently logged into
|
||||
* the platform in the attribute `data-user-id`.
|
||||
*/
|
||||
CURRENT_USER_ID: "span.avatar[data-user-id]",
|
||||
|
@ -41,17 +41,17 @@ export const WATCHED_THREAD = {
|
|||
*/
|
||||
BODIES: "div.structItem-cell--main",
|
||||
/**
|
||||
* Link element containing the partial URL
|
||||
* Link element containing the partial URL
|
||||
* of the thread in the `href` attribute.
|
||||
*
|
||||
*
|
||||
* It may be followed by the `/unread` segment.
|
||||
*
|
||||
*
|
||||
* For use within a `WATCHED_THREAD.BODIES` selector.
|
||||
*/
|
||||
URL: "div > a[data-tp-primary]",
|
||||
/**
|
||||
* Name of the forum to which the thread belongs as text.
|
||||
*
|
||||
*
|
||||
* For use within a `WATCHED_THREAD.BODIES` selector.
|
||||
*/
|
||||
FORUM: "div.structItem-cell--main > div.structItem-minor > ul.structItem-parts > li:last-of-type > a",
|
||||
|
@ -64,19 +64,19 @@ export const WATCHED_THREAD = {
|
|||
export const THREAD = {
|
||||
/**
|
||||
* Number of pages in the thread (as text of the element).
|
||||
*
|
||||
*
|
||||
* Two identical elements are identified.
|
||||
*/
|
||||
LAST_PAGE: "ul.pageNav-main > li:last-child > a",
|
||||
/**
|
||||
* Identify the creator of the thread.
|
||||
*
|
||||
*
|
||||
* The ID is contained in the `data-user-id` attribute.
|
||||
*/
|
||||
OWNER_ID: "div.uix_headerInner > * a.username[data-user-id]",
|
||||
/**
|
||||
* Contains the creation date of the thread.
|
||||
*
|
||||
*
|
||||
* The date is contained in the `datetime` attribute as an ISO string.
|
||||
*/
|
||||
CREATION: "div.uix_headerInner > * time",
|
||||
|
@ -94,7 +94,7 @@ export const THREAD = {
|
|||
TITLE: "h1.p-title-value",
|
||||
/**
|
||||
* JSON containing thread information.
|
||||
*
|
||||
*
|
||||
* Two different elements are found.
|
||||
*/
|
||||
JSONLD: "script[type=\"application/ld+json\"]",
|
||||
|
@ -106,44 +106,44 @@ export const THREAD = {
|
|||
|
||||
export const POST = {
|
||||
/**
|
||||
* Unique post number for the current thread.
|
||||
*
|
||||
* Unique post number for the current thread.
|
||||
*
|
||||
* For use within a `THREAD.POSTS_IN_PAGE` selector.
|
||||
*/
|
||||
NUMBER: "* ul.message-attribution-opposite > li > a:not([id])[rel=\"nofollow\"]",
|
||||
/**
|
||||
* Unique ID of the post in the F95Zone platform in the `id` attribute.
|
||||
*
|
||||
*
|
||||
* For use within a `THREAD.POSTS_IN_PAGE` selector.
|
||||
*/
|
||||
ID: "span[id^=\"post\"]",
|
||||
/**
|
||||
* Unique ID of the post author in the `data-user-id` attribute.
|
||||
*
|
||||
*
|
||||
* For use within a `THREAD.POSTS_IN_PAGE` selector.
|
||||
*/
|
||||
OWNER_ID: "* div.message-cell--user > * a[data-user-id]",
|
||||
/**
|
||||
* Main body of the post where the message written by the user is contained.
|
||||
*
|
||||
*
|
||||
* For use within a `THREAD.POSTS_IN_PAGE` selector.
|
||||
*/
|
||||
BODY: "* article.message-body > div.bbWrapper",
|
||||
/**
|
||||
* Publication date of the post contained in the `datetime` attribute as an ISO date.
|
||||
*
|
||||
*
|
||||
* For use within a `THREAD.POSTS_IN_PAGE` selector.
|
||||
*/
|
||||
PUBLISH_DATE: "* div.message-attribution-main > a > time",
|
||||
/**
|
||||
* Last modified date of the post contained in the `datetime` attribute as the ISO date.
|
||||
*
|
||||
*
|
||||
* For use within a `THREAD.POSTS_IN_PAGE` selector.
|
||||
*/
|
||||
LAST_EDIT: "* div.message-lastEdit > time",
|
||||
/**
|
||||
* Gets the element only if the post has been bookmarked.
|
||||
*
|
||||
*
|
||||
* For use within a `THREAD.POSTS_IN_PAGE` selector.
|
||||
*/
|
||||
BOOKMARKED: "* ul.message-attribution-opposite >li > a[title=\"Bookmark\"].is-bookmarked",
|
||||
|
@ -152,37 +152,37 @@ export const POST = {
|
|||
export const MEMBER = {
|
||||
/**
|
||||
* Name of the user.
|
||||
*
|
||||
*
|
||||
* It also contains the unique ID of the user in the `data-user-id` attribute.
|
||||
*/
|
||||
NAME: "span[class^=\"username\"]",
|
||||
/**
|
||||
* Title of the user in the platform.
|
||||
*
|
||||
*
|
||||
* i.e.: Member
|
||||
*/
|
||||
TITLE: "span.userTitle",
|
||||
/**
|
||||
* Avatar used by the user.
|
||||
*
|
||||
*
|
||||
* Source in the attribute `src`.
|
||||
*/
|
||||
AVATAR: "span.avatarWrapper > a.avatar > img",
|
||||
/**
|
||||
* User assigned banners.
|
||||
*
|
||||
*
|
||||
* The last element is always empty and can be ignored.
|
||||
*/
|
||||
BANNERS: "em.userBanner > strong",
|
||||
/**
|
||||
* Date the user joined the platform.
|
||||
*
|
||||
*
|
||||
* The date is contained in the `datetime` attribute as an ISO string.
|
||||
*/
|
||||
JOINED: "div.uix_memberHeader__extra > div.memberHeader-blurb:nth-child(1) > * time",
|
||||
/**
|
||||
* Last time the user connected to the platform.
|
||||
*
|
||||
*
|
||||
* The date is contained in the `datetime` attribute as an ISO string.
|
||||
*/
|
||||
LAST_SEEN: "div.uix_memberHeader__extra > div.memberHeader-blurb:nth-child(2) > * time",
|
||||
|
@ -193,14 +193,14 @@ export const MEMBER = {
|
|||
AMOUNT_DONATED: "div.pairJustifier > dl:nth-child(5) > dd",
|
||||
/**
|
||||
* Button used to follow/unfollow the user.
|
||||
*
|
||||
*
|
||||
* If the text is `Unfollow` then the user is followed.
|
||||
* If the text is `Follow` then the user is not followed.
|
||||
*/
|
||||
FOLLOWED: "div.memberHeader-buttons > div.buttonGroup:first-child > a[data-sk-follow] > span",
|
||||
/**
|
||||
* Button used to ignore/unignore the user.
|
||||
*
|
||||
*
|
||||
* If the text is `Unignore` then the user is ignored.
|
||||
* If the text is `Ignore` then the user is not ignored.
|
||||
*/
|
||||
|
|
|
@ -8,8 +8,8 @@ export const urls = {
|
|||
F95_LATEST_PHP: "https://f95zone.to/new_latest.php",
|
||||
F95_BOOKMARKS: "https://f95zone.to/account/bookmarks",
|
||||
/**
|
||||
* Add the unique ID of the post to
|
||||
* get the thread page where the post
|
||||
* Add the unique ID of the post to
|
||||
* get the thread page where the post
|
||||
* is present.
|
||||
*/
|
||||
F95_POSTS: "https://f95zone.to/posts/",
|
||||
|
|
|
@ -9,7 +9,7 @@ import { urls as f95url } from "../constants/url.js";
|
|||
* You *must* be logged.
|
||||
* @param {LatestSearchQuery} query
|
||||
* Query used for the search
|
||||
* @param {Number} limit
|
||||
* @param {Number} limit
|
||||
* Maximum number of items to get. Default: 30
|
||||
* @returns {Promise<String[]>} URLs of the handiworks
|
||||
*/
|
||||
|
|
|
@ -43,7 +43,7 @@ interface ILatestResource {
|
|||
|
||||
//#region Public methods
|
||||
/**
|
||||
* Gets the basic data used for game data processing
|
||||
* Gets the basic data used for game data processing
|
||||
* (such as graphics engines and progress statuses)
|
||||
*/
|
||||
export default async function fetchPlatformData(): Promise<void> {
|
||||
|
@ -106,7 +106,7 @@ function saveCache(path: string): void {
|
|||
|
||||
/**
|
||||
* @private
|
||||
* Given the HTML code of the response from the F95Zone,
|
||||
* Given the HTML code of the response from the F95Zone,
|
||||
* parse it and return the result.
|
||||
*/
|
||||
function parseLatestPlatformHTML(html: string): ILatestResource{
|
||||
|
|
|
@ -36,6 +36,6 @@ export default async function executeQuery(query: any, limit: number = 30): Prom
|
|||
"handiwork");
|
||||
|
||||
// Fetch and return the urls
|
||||
return await searchMap[key](query, limit);
|
||||
return searchMap[key](query, limit);
|
||||
}
|
||||
//#endregion
|
|
@ -25,7 +25,7 @@ export default async function fetchThreadHandiworkURLs(query: ThreadSearchQuery,
|
|||
const response = await query.execute();
|
||||
|
||||
// Fetch the results from F95 and return the handiwork urls
|
||||
if (response.isSuccess()) return await fetchResultURLs(response.value.data as string, limit);
|
||||
if (response.isSuccess()) return fetchResultURLs(response.value.data as string, limit);
|
||||
else throw response.value
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import { failure, Result, success } from "./classes/result.js";
|
|||
import { GenericAxiosError, InvalidF95Token, UnexpectedResponseContentType } from "./classes/errors.js";
|
||||
|
||||
// Global variables
|
||||
const userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) " +
|
||||
const userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) " +
|
||||
"AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15";
|
||||
// @ts-ignore
|
||||
axiosCookieJarSupport.default(axios);
|
||||
|
@ -61,15 +61,15 @@ export async function fetchHTML(url: string): Promise<Result<GenericAxiosError |
|
|||
error: null
|
||||
});
|
||||
|
||||
return isHTML ?
|
||||
return isHTML ?
|
||||
success(response.value.data as string) :
|
||||
failure(unexpectedResponseError);
|
||||
} else return failure(response.value as GenericAxiosError);
|
||||
}
|
||||
|
||||
/**
|
||||
* It authenticates to the platform using the credentials
|
||||
* and token obtained previously. Save cookies on your
|
||||
* It authenticates to the platform using the credentials
|
||||
* and token obtained previously. Save cookies on your
|
||||
* device after authentication.
|
||||
* @param {module:./classes/credentials.ts:Credentials} credentials Platform access credentials
|
||||
* @param {Boolean} force Specifies whether the request should be forced, ignoring any saved cookies
|
||||
|
@ -173,7 +173,7 @@ export function isF95URL(url: string): boolean {
|
|||
};
|
||||
|
||||
/**
|
||||
* Checks if the string passed by parameter has a
|
||||
* Checks if the string passed by parameter has a
|
||||
* properly formatted and valid path to a URL (HTTP/HTTPS).
|
||||
* @param {String} url String to check for correctness
|
||||
*/
|
||||
|
@ -187,7 +187,7 @@ export function isStringAValidURL(url: string): boolean {
|
|||
/**
|
||||
* Check if a particular URL is valid and reachable on the web.
|
||||
* @param {string} url URL to check
|
||||
* @param {boolean} [checkRedirect]
|
||||
* @param {boolean} [checkRedirect]
|
||||
* If true, the function will consider redirects a violation and return false.
|
||||
* Default: false
|
||||
* @returns {Promise<Boolean>} true if the URL exists, false otherwise
|
||||
|
|
|
@ -87,7 +87,7 @@ function toUpperCaseArray(a: string[]): string[] {
|
|||
|
||||
/**
|
||||
* Check if the string `s` is in the dict `a`.
|
||||
*
|
||||
*
|
||||
* Case insensitive.
|
||||
*/
|
||||
function stringInDict(s: string, a: TPrefixDict): boolean {
|
||||
|
@ -99,7 +99,7 @@ function stringInDict(s: string, a: TPrefixDict): boolean {
|
|||
|
||||
/**
|
||||
* Convert a string to a boolean.
|
||||
*
|
||||
*
|
||||
* Check also for `yes`/`no` and `1`/`0`.
|
||||
*/
|
||||
function stringToBoolean(s: string): boolean {
|
||||
|
@ -116,7 +116,7 @@ function stringToBoolean(s: string): boolean {
|
|||
|
||||
/**
|
||||
* Gets the element with the given name or `undefined`.
|
||||
*
|
||||
*
|
||||
* Case-insensitive.
|
||||
*/
|
||||
function getPostElementByName(elements: IPostElement[], name: string): IPostElement | undefined {
|
||||
|
@ -127,7 +127,7 @@ function getPostElementByName(elements: IPostElement[], name: string): IPostElem
|
|||
|
||||
/**
|
||||
* Parse the post prefixes.
|
||||
*
|
||||
*
|
||||
* In particular, it elaborates the following prefixes for games:
|
||||
* `Engine`, `Status`, `Mod`.
|
||||
*/
|
||||
|
@ -174,7 +174,7 @@ function fillWithPrefixes(hw: HandiWork, prefixes: string[]) {
|
|||
/**
|
||||
* Compiles a HandiWork object with the data extracted
|
||||
* from the main post of the HandiWork page.
|
||||
*
|
||||
*
|
||||
* The values that will be added are:
|
||||
* `Overview`, `OS`, `Language`, `Version`, `Installation`,
|
||||
* `Pages`, `Resolution`, `Lenght`, `Genre`, `Censored`,
|
||||
|
|
|
@ -21,11 +21,11 @@ export interface ILink extends IPostElement {
|
|||
* Given a post of a thread page it extracts the information contained in the body.
|
||||
*/
|
||||
export function parseF95ThreadPost($: cheerio.Root, post: cheerio.Cheerio): IPostElement[] {
|
||||
// The data is divided between "tag" and "text" elements.
|
||||
// Simple data is composed of a "tag" element followed
|
||||
// by a "text" element, while more complex data (contained
|
||||
// in spoilers) is composed of a "tag" element, followed
|
||||
// by a text containing only ":" and then by an additional
|
||||
// The data is divided between "tag" and "text" elements.
|
||||
// Simple data is composed of a "tag" element followed
|
||||
// by a "text" element, while more complex data (contained
|
||||
// in spoilers) is composed of a "tag" element, followed
|
||||
// by a text containing only ":" and then by an additional
|
||||
// "tag" element having as the first term "Spoiler"
|
||||
|
||||
// First fetch all the elements in the post
|
||||
|
@ -44,13 +44,13 @@ export function parseF95ThreadPost($: cheerio.Root, post: cheerio.Cheerio): IPos
|
|||
//#region Private methods
|
||||
|
||||
/**
|
||||
* Process a spoiler element by getting its text broken
|
||||
* Process a spoiler element by getting its text broken
|
||||
* down by any other spoiler elements present.
|
||||
*/
|
||||
function parseCheerioSpoilerNode($: cheerio.Root, spoiler: cheerio.Cheerio): IPostElement {
|
||||
// A spoiler block is composed of a div with class "bbCodeSpoiler",
|
||||
// containing a div "bbCodeSpoiler-content" containing, in cascade,
|
||||
// a div with class "bbCodeBlock--spoiler" and a div with class "bbCodeBlock-content".
|
||||
// A spoiler block is composed of a div with class "bbCodeSpoiler",
|
||||
// containing a div "bbCodeSpoiler-content" containing, in cascade,
|
||||
// a div with class "bbCodeBlock--spoiler" and a div with class "bbCodeBlock-content".
|
||||
// This last tag contains the required data.
|
||||
|
||||
// Local variables
|
||||
|
@ -94,7 +94,7 @@ function parseCheerioSpoilerNode($: cheerio.Root, spoiler: cheerio.Cheerio): IPo
|
|||
}
|
||||
|
||||
/**
|
||||
* Check if the node passed as a parameter is of text type.
|
||||
* Check if the node passed as a parameter is of text type.
|
||||
* This also includes formatted nodes (i.e. `<b>`).
|
||||
*/
|
||||
function isTextNode(node: cheerio.Element): boolean {
|
||||
|
@ -106,7 +106,7 @@ function isTextNode(node: cheerio.Element): boolean {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the text of the node only, excluding child nodes.
|
||||
* Gets the text of the node only, excluding child nodes.
|
||||
* Also includes formatted text elements (i.e. `<b>`).
|
||||
*/
|
||||
function getCheerioNonChildrenText(node: cheerio.Cheerio): string {
|
||||
|
@ -120,7 +120,7 @@ function getCheerioNonChildrenText(node: cheerio.Cheerio): string {
|
|||
}
|
||||
|
||||
/**
|
||||
* Process a node and see if it contains a
|
||||
* Process a node and see if it contains a
|
||||
* link or image. If not, it returns `null`.
|
||||
*/
|
||||
function parseCheerioLinkNode(element: cheerio.Cheerio): ILink | null {
|
||||
|
@ -149,7 +149,7 @@ function parseCheerioLinkNode(element: cheerio.Cheerio): ILink | null {
|
|||
}
|
||||
|
||||
/**
|
||||
* Collapse an `IPostElement` element with a single subnode
|
||||
* Collapse an `IPostElement` element with a single subnode
|
||||
* in the `Content` field in case it has no information.
|
||||
*/
|
||||
function reducePostElement(element: IPostElement): IPostElement {
|
||||
|
@ -234,7 +234,7 @@ function parseCheerioNode($: cheerio.Root, node: cheerio.Element, reduce = true)
|
|||
}
|
||||
|
||||
/**
|
||||
* It simplifies the `IPostElement` elements by associating
|
||||
* It simplifies the `IPostElement` elements by associating
|
||||
* the corresponding value to each characterizing element (i.e. author).
|
||||
*/
|
||||
function parsePostElements(elements: IPostElement[]): IPostElement[] {
|
||||
|
|
Loading…
Reference in New Issue