Update JSDOC and url names
parent
0a57d2b2ec
commit
ca11a442ed
|
@ -1,27 +1,27 @@
|
||||||
export declare const urls: {
|
export declare const urls: {
|
||||||
F95_BASE_URL: string;
|
BASE: string;
|
||||||
F95_2FA_LOGIN: string;
|
LOGIN_2FA: string;
|
||||||
F95_SEARCH_URL: string;
|
SEARCH: string;
|
||||||
F95_LATEST_UPDATES: string;
|
LATEST_UPDATES: string;
|
||||||
F95_THREADS: string;
|
THREADS: string;
|
||||||
F95_LOGIN_URL: string;
|
LOGIN: string;
|
||||||
F95_WATCHED_THREADS: string;
|
WATCHED_THREADS: string;
|
||||||
F95_LATEST_PHP: string;
|
LATEST_PHP: string;
|
||||||
F95_BOOKMARKS: string;
|
BOOKMARKS: string;
|
||||||
/**
|
/**
|
||||||
* Add the unique ID of the post to
|
* Add the unique ID of the post to
|
||||||
* get the thread page where the post
|
* get the thread page where the post
|
||||||
* is present.
|
* is present.
|
||||||
*/
|
*/
|
||||||
F95_POSTS: string;
|
POSTS: string;
|
||||||
/**
|
/**
|
||||||
* @todo
|
* @todo
|
||||||
*/
|
*/
|
||||||
F95_CONVERSATIONS: string;
|
CONVERSATIONS: string;
|
||||||
/**
|
/**
|
||||||
* @todo
|
* @todo
|
||||||
*/
|
*/
|
||||||
F95_ALERTS: string;
|
ALERTS: string;
|
||||||
F95_POSTS_NUMBER: string;
|
POSTS_NUMBER: string;
|
||||||
F95_MEMBERS: string;
|
MEMBERS: string;
|
||||||
};
|
};
|
||||||
|
|
|
@ -148,7 +148,7 @@ export default class PlatformUser {
|
||||||
if (!this.id && this.id < 1) throw new Error("Invalid user ID");
|
if (!this.id && this.id < 1) throw new Error("Invalid user ID");
|
||||||
|
|
||||||
// Prepare the URL
|
// Prepare the URL
|
||||||
const url = new URL(this.id.toString(), `${urls.F95_MEMBERS}/`).toString();
|
const url = new URL(this.id.toString(), `${urls.MEMBERS}/`).toString();
|
||||||
|
|
||||||
// Fetch the page
|
// Fetch the page
|
||||||
const htmlResponse = await fetchHTML(url);
|
const htmlResponse = await fetchHTML(url);
|
||||||
|
|
|
@ -96,7 +96,7 @@ export default class Post {
|
||||||
*/
|
*/
|
||||||
public async fetch(): Promise<void> {
|
public async fetch(): Promise<void> {
|
||||||
// Fetch HTML page containing the post
|
// Fetch HTML page containing the post
|
||||||
const url = new URL(this.id.toString(), urls.F95_POSTS).toString();
|
const url = new URL(this.id.toString(), urls.POSTS).toString();
|
||||||
const htmlResponse = await fetchHTML(url);
|
const htmlResponse = await fetchHTML(url);
|
||||||
|
|
||||||
if (htmlResponse.isSuccess()) {
|
if (htmlResponse.isSuccess()) {
|
||||||
|
|
|
@ -139,7 +139,7 @@ export default class Thread {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send POST request
|
// Send POST request
|
||||||
const response = await fetchPOSTResponse(urls.F95_POSTS_NUMBER, params);
|
const response = await fetchPOSTResponse(urls.POSTS_NUMBER, params);
|
||||||
if (response.isFailure()) throw response.value;
|
if (response.isFailure()) throw response.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ export default class Thread {
|
||||||
*/
|
*/
|
||||||
public async fetch(): Promise<void> {
|
public async fetch(): Promise<void> {
|
||||||
// Prepare the url
|
// Prepare the url
|
||||||
this._url = new URL(this.id.toString(), urls.F95_THREADS).toString();
|
this._url = new URL(this.id.toString(), urls.THREADS).toString();
|
||||||
|
|
||||||
// Fetch the HTML source
|
// Fetch the HTML source
|
||||||
const htmlResponse = await fetchHTML(this.url);
|
const htmlResponse = await fetchHTML(this.url);
|
||||||
|
|
|
@ -105,7 +105,7 @@ export default class UserProfile extends PlatformUser {
|
||||||
|
|
||||||
private async fetchUserID(): Promise<number> {
|
private async fetchUserID(): Promise<number> {
|
||||||
// Local variables
|
// Local variables
|
||||||
const url = new URL(urls.F95_BASE_URL).toString();
|
const url = new URL(urls.BASE).toString();
|
||||||
|
|
||||||
// fetch and parse page
|
// fetch and parse page
|
||||||
const htmlResponse = await fetchHTML(url);
|
const htmlResponse = await fetchHTML(url);
|
||||||
|
@ -120,7 +120,7 @@ export default class UserProfile extends PlatformUser {
|
||||||
|
|
||||||
private async fetchWatchedThread(): Promise<IWatchedThread[]> {
|
private async fetchWatchedThread(): Promise<IWatchedThread[]> {
|
||||||
// Prepare and fetch URL
|
// Prepare and fetch URL
|
||||||
const url = new URL(urls.F95_WATCHED_THREADS);
|
const url = new URL(urls.WATCHED_THREADS);
|
||||||
url.searchParams.set("unread", "0");
|
url.searchParams.set("unread", "0");
|
||||||
|
|
||||||
const htmlResponse = await fetchHTML(url.toString());
|
const htmlResponse = await fetchHTML(url.toString());
|
||||||
|
@ -177,10 +177,7 @@ export default class UserProfile extends PlatformUser {
|
||||||
.map((idx, el) => {
|
.map((idx, el) => {
|
||||||
// Parse the URL
|
// Parse the URL
|
||||||
const partialURL = $(el).find(WATCHED_THREAD.URL).attr("href");
|
const partialURL = $(el).find(WATCHED_THREAD.URL).attr("href");
|
||||||
const url = new URL(
|
const url = new URL(partialURL.replace("unread", ""), `${urls.BASE}`).toString();
|
||||||
partialURL.replace("unread", ""),
|
|
||||||
`${urls.F95_BASE_URL}`
|
|
||||||
).toString();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
url: url.toString(),
|
url: url.toString(),
|
||||||
|
|
|
@ -110,7 +110,7 @@ export default class LatestSearchQuery implements IQuery {
|
||||||
*/
|
*/
|
||||||
private prepareGETurl(): URL {
|
private prepareGETurl(): URL {
|
||||||
// Create the URL
|
// Create the URL
|
||||||
const url = new URL(urls.F95_LATEST_PHP);
|
const url = new URL(urls.LATEST_PHP);
|
||||||
url.searchParams.set("cmd", "list");
|
url.searchParams.set("cmd", "list");
|
||||||
|
|
||||||
// Set the category
|
// Set the category
|
||||||
|
|
|
@ -88,7 +88,7 @@ export default class ThreadSearchQuery implements IQuery {
|
||||||
const params = this.preparePOSTParameters();
|
const params = this.preparePOSTParameters();
|
||||||
|
|
||||||
// Return the POST response
|
// Return the POST response
|
||||||
return fetchPOSTResponse(urls.F95_SEARCH_URL, params);
|
return fetchPOSTResponse(urls.SEARCH, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#endregion Public methods
|
//#endregion Public methods
|
||||||
|
|
|
@ -4,29 +4,66 @@
|
||||||
// https://opensource.org/licenses/MIT
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
export const urls = {
|
export const urls = {
|
||||||
F95_BASE_URL: "https://f95zone.to",
|
/**
|
||||||
F95_2FA_LOGIN: "https://f95zone.to/login/two-step",
|
* Page with the list of alerts for the user currently logged.
|
||||||
F95_SEARCH_URL: "https://f95zone.to/search/search/",
|
*/
|
||||||
F95_LATEST_UPDATES: "https://f95zone.to/latest",
|
ALERTS: "https://f95zone.to/account/alerts",
|
||||||
F95_THREADS: "https://f95zone.to/threads/",
|
/**
|
||||||
F95_LOGIN_URL: "https://f95zone.to/login/login",
|
* Basic URL of the platform.
|
||||||
F95_WATCHED_THREADS: "https://f95zone.to/watched/threads",
|
*/
|
||||||
F95_LATEST_PHP: "https://f95zone.to/new_latest.php",
|
BASE: "https://f95zone.to",
|
||||||
F95_BOOKMARKS: "https://f95zone.to/account/bookmarks",
|
/**
|
||||||
|
* Page with the list of favorite posts of the user currently logged.
|
||||||
|
*/
|
||||||
|
BOOKMARKS: "https://f95zone.to/account/bookmarks",
|
||||||
|
/**
|
||||||
|
* Page with the list of conversations of the currently logged user.
|
||||||
|
*/
|
||||||
|
CONVERSATIONS: "https://f95zone.to/conversations/",
|
||||||
|
/**
|
||||||
|
* URL of the script used for searching for content
|
||||||
|
* in the "Latest Updates" section of the platform.
|
||||||
|
*/
|
||||||
|
LATEST_PHP: "https://f95zone.to/new_latest.php",
|
||||||
|
/**
|
||||||
|
* Page with the latest updated platform content.
|
||||||
|
*/
|
||||||
|
LATEST_UPDATES: "https://f95zone.to/latest",
|
||||||
|
/**
|
||||||
|
* Page used for user login.
|
||||||
|
*/
|
||||||
|
LOGIN: "https://f95zone.to/login/login",
|
||||||
|
/**
|
||||||
|
* Page used for entering the OTP code in the case of two-factor authentication.
|
||||||
|
*/
|
||||||
|
LOGIN_2FA: "https://f95zone.to/login/two-step",
|
||||||
|
/**
|
||||||
|
* Summary page of users registered on the platform.
|
||||||
|
* Used for the search for a specific member through ID.
|
||||||
|
*/
|
||||||
|
MEMBERS: "https://f95zone.to/members",
|
||||||
/**
|
/**
|
||||||
* Add the unique ID of the post to
|
* Add the unique ID of the post to
|
||||||
* get the thread page where the post
|
* get the thread page where the post
|
||||||
* is present.
|
* is present.
|
||||||
*/
|
*/
|
||||||
F95_POSTS: "https://f95zone.to/posts/",
|
POSTS: "https://f95zone.to/posts/",
|
||||||
/**
|
/**
|
||||||
* @todo
|
* URL used to send a POST request and change
|
||||||
|
* the number of posts that can be viewed per
|
||||||
|
* page of a specific thread.
|
||||||
*/
|
*/
|
||||||
F95_CONVERSATIONS: "https://f95zone.to/conversations/",
|
POSTS_NUMBER: "https://f95zone.to/account/dpp-update",
|
||||||
/**
|
/**
|
||||||
* @todo
|
* URL used to search the platform by POST request.
|
||||||
*/
|
*/
|
||||||
F95_ALERTS: "https://f95zone.to/account/alerts",
|
SEARCH: "https://f95zone.to/search/search/",
|
||||||
F95_POSTS_NUMBER: "https://f95zone.to/account/dpp-update",
|
/**
|
||||||
F95_MEMBERS: "https://f95zone.to/members"
|
* Add the unique ID of the thread to get it's page.
|
||||||
|
*/
|
||||||
|
THREADS: "https://f95zone.to/threads/",
|
||||||
|
/**
|
||||||
|
* Page with the list of watched threads of the currently logged user.
|
||||||
|
*/
|
||||||
|
WATCHED_THREADS: "https://f95zone.to/watched/threads"
|
||||||
};
|
};
|
||||||
|
|
|
@ -41,7 +41,7 @@ export default async function fetchLatestHandiworkURLs(
|
||||||
|
|
||||||
data.map((e, idx) => {
|
data.map((e, idx) => {
|
||||||
if (fetchedResults < limit) {
|
if (fetchedResults < limit) {
|
||||||
const gameURL = new URL(e.thread_id.toString(), urls.F95_THREADS).href;
|
const gameURL = new URL(e.thread_id.toString(), urls.THREADS).href;
|
||||||
resultURLs.push(gameURL);
|
resultURLs.push(gameURL);
|
||||||
|
|
||||||
fetchedResults += 1;
|
fetchedResults += 1;
|
||||||
|
|
|
@ -58,7 +58,7 @@ export default async function fetchPlatformData(): Promise<void> {
|
||||||
// Check if the data are cached
|
// Check if the data are cached
|
||||||
if (!readCache(shared.cachePath)) {
|
if (!readCache(shared.cachePath)) {
|
||||||
// Load the HTML
|
// Load the HTML
|
||||||
const html = await fetchHTML(f95url.F95_LATEST_UPDATES);
|
const html = await fetchHTML(f95url.LATEST_UPDATES);
|
||||||
|
|
||||||
// Parse data
|
// Parse data
|
||||||
if (html.isSuccess()) {
|
if (html.isSuccess()) {
|
||||||
|
|
|
@ -77,7 +77,7 @@ function extractLinkFromResult(selector: cheerio.Cheerio): string {
|
||||||
const partialLink = selector.find(THREAD_SEARCH.THREAD_TITLE).attr("href").trim();
|
const partialLink = selector.find(THREAD_SEARCH.THREAD_TITLE).attr("href").trim();
|
||||||
|
|
||||||
// Compose and return the URL
|
// Compose and return the URL
|
||||||
return new URL(partialLink, f95urls.F95_BASE_URL).toString();
|
return new URL(partialLink, f95urls.BASE).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
//#endregion Private methods
|
//#endregion Private methods
|
||||||
|
|
|
@ -98,7 +98,7 @@ export async function authenticate(
|
||||||
throw new InvalidF95Token(`Invalid token for auth: ${credentials.token}`);
|
throw new InvalidF95Token(`Invalid token for auth: ${credentials.token}`);
|
||||||
|
|
||||||
// Secure the URL
|
// Secure the URL
|
||||||
const secureURL = enforceHttpsUrl(urls.F95_LOGIN_URL);
|
const secureURL = enforceHttpsUrl(urls.LOGIN);
|
||||||
|
|
||||||
// Prepare the parameters to send to the platform to authenticate
|
// Prepare the parameters to send to the platform to authenticate
|
||||||
const params = {
|
const params = {
|
||||||
|
@ -117,7 +117,7 @@ export async function authenticate(
|
||||||
let authResult: LoginResult = null;
|
let authResult: LoginResult = null;
|
||||||
try {
|
try {
|
||||||
// Fetch the response to the login request
|
// Fetch the response to the login request
|
||||||
const response = await fetchPOSTResponse(urls.F95_LOGIN_URL, params, force);
|
const response = await fetchPOSTResponse(urls.LOGIN, params, force);
|
||||||
|
|
||||||
// Parse the response
|
// Parse the response
|
||||||
const result = response.applyOnSuccess((r) => manageLoginPOSTResponse(r));
|
const result = response.applyOnSuccess((r) => manageLoginPOSTResponse(r));
|
||||||
|
@ -149,7 +149,7 @@ export async function send2faCode(
|
||||||
): Promise<Result<GenericAxiosError, LoginResult>> {
|
): Promise<Result<GenericAxiosError, LoginResult>> {
|
||||||
// Prepare the parameters to send via POST request
|
// Prepare the parameters to send via POST request
|
||||||
const params = {
|
const params = {
|
||||||
_xfRedirect: urls.F95_BASE_URL,
|
_xfRedirect: urls.BASE,
|
||||||
_xfRequestUri: "/login/two-step?_xfRedirect=https%3A%2F%2Ff95zone.to%2F&remember=1",
|
_xfRequestUri: "/login/two-step?_xfRedirect=https%3A%2F%2Ff95zone.to%2F&remember=1",
|
||||||
_xfResponseType: "json",
|
_xfResponseType: "json",
|
||||||
_xfToken: token,
|
_xfToken: token,
|
||||||
|
@ -162,7 +162,7 @@ export async function send2faCode(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send 2FA params
|
// Send 2FA params
|
||||||
const response = await fetchPOSTResponse(urls.F95_2FA_LOGIN, params);
|
const response = await fetchPOSTResponse(urls.LOGIN_2FA, params);
|
||||||
return response.applyOnSuccess((r: AxiosResponse<any>) => {
|
return response.applyOnSuccess((r: AxiosResponse<any>) => {
|
||||||
// r.data.status is 'ok' if the authentication is successful
|
// r.data.status is 'ok' if the authentication is successful
|
||||||
const result = r.data.status === "ok";
|
const result = r.data.status === "ok";
|
||||||
|
@ -182,7 +182,7 @@ export async function send2faCode(
|
||||||
*/
|
*/
|
||||||
export async function getF95Token(): Promise<string> {
|
export async function getF95Token(): Promise<string> {
|
||||||
// Fetch the response of the platform
|
// Fetch the response of the platform
|
||||||
const response = await fetchGETResponse(urls.F95_LOGIN_URL);
|
const response = await fetchGETResponse(urls.LOGIN);
|
||||||
|
|
||||||
if (response.isSuccess()) {
|
if (response.isSuccess()) {
|
||||||
// The response is a HTML page, we need to find the <input> with name "_xfToken"
|
// The response is a HTML page, we need to find the <input> with name "_xfToken"
|
||||||
|
@ -274,7 +274,7 @@ export function enforceHttpsUrl(url: string): string {
|
||||||
* Check if the url belongs to the domain of the F95 platform.
|
* Check if the url belongs to the domain of the F95 platform.
|
||||||
*/
|
*/
|
||||||
export function isF95URL(url: string): boolean {
|
export function isF95URL(url: string): boolean {
|
||||||
return url.toString().startsWith(urls.F95_BASE_URL);
|
return url.toString().startsWith(urls.BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -358,7 +358,7 @@ function manageLoginPOSTResponse(response: AxiosResponse<any>) {
|
||||||
const $ = cheerio.load(response.data as string);
|
const $ = cheerio.load(response.data as string);
|
||||||
|
|
||||||
// Check if 2 factor authentication is required
|
// Check if 2 factor authentication is required
|
||||||
if (response.config.url.startsWith(urls.F95_2FA_LOGIN)) {
|
if (response.config.url.startsWith(urls.LOGIN_2FA)) {
|
||||||
return new LoginResult(
|
return new LoginResult(
|
||||||
false,
|
false,
|
||||||
LoginResult.REQUIRE_2FA,
|
LoginResult.REQUIRE_2FA,
|
||||||
|
|
Loading…
Reference in New Issue