FanAPI: fetch by logged-in user if target empty
This commit is contained in:
parent
7b537aade1
commit
7815c68ea8
|
@ -17,12 +17,12 @@ import BaseAPIWithImageSupport, { BaseAPIWithImageSupportParams } from '../commo
|
||||||
export { FanPageItemsResult, FanContinuationItemsResult };
|
export { FanPageItemsResult, FanContinuationItemsResult };
|
||||||
|
|
||||||
export interface FanAPIGetInfoParams {
|
export interface FanAPIGetInfoParams {
|
||||||
username: string;
|
username?: string;
|
||||||
imageFormat: string | number | ImageFormat;
|
imageFormat: string | number | ImageFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FanAPIGetItemsParams {
|
export interface FanAPIGetItemsParams {
|
||||||
target: string | FanItemsContinuation;
|
target?: string | FanItemsContinuation;
|
||||||
imageFormat?: string | number | ImageFormat;
|
imageFormat?: string | number | ImageFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,13 @@ export interface FanAPIGetItemsFullParams<T> extends FanAPIGetItemsParams {
|
||||||
export default class FanAPI extends BaseAPIWithImageSupport {
|
export default class FanAPI extends BaseAPIWithImageSupport {
|
||||||
|
|
||||||
async getInfo(params: FanAPIGetInfoParams): Promise<Fan> {
|
async getInfo(params: FanAPIGetInfoParams): Promise<Fan> {
|
||||||
|
if (!params.username) {
|
||||||
|
const username = await this.getLoggedInFanUsername();
|
||||||
|
return this.getInfo({
|
||||||
|
...params,
|
||||||
|
username
|
||||||
|
});
|
||||||
|
}
|
||||||
const imageConstants = await this.imageAPI.getConstants();
|
const imageConstants = await this.imageAPI.getConstants();
|
||||||
const fanPageUrl = FanAPI.getFanPageUrl(params.username);
|
const fanPageUrl = FanAPI.getFanPageUrl(params.username);
|
||||||
const opts = {
|
const opts = {
|
||||||
|
@ -94,6 +101,15 @@ export default class FanAPI extends BaseAPIWithImageSupport {
|
||||||
*/
|
*/
|
||||||
protected async getItems<T>(params: FanAPIGetItemsFullParams<T>): Promise<FanPageItemsResult<T> | FanContinuationItemsResult<T>> {
|
protected async getItems<T>(params: FanAPIGetItemsFullParams<T>): Promise<FanPageItemsResult<T> | FanContinuationItemsResult<T>> {
|
||||||
const { target, imageFormat, defaultImageFormat, continuationUrl } = params;
|
const { target, imageFormat, defaultImageFormat, continuationUrl } = params;
|
||||||
|
|
||||||
|
if (!target) {
|
||||||
|
const username = await this.getLoggedInFanUsername();
|
||||||
|
return this.getItems({
|
||||||
|
...params,
|
||||||
|
target: username
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const imageConstants = await this.imageAPI.getConstants();
|
const imageConstants = await this.imageAPI.getConstants();
|
||||||
const opts = {
|
const opts = {
|
||||||
imageBaseUrl: imageConstants.baseUrl,
|
imageBaseUrl: imageConstants.baseUrl,
|
||||||
|
@ -101,7 +117,7 @@ export default class FanAPI extends BaseAPIWithImageSupport {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!FanAPI.isContinuation(target)) {
|
if (!FanAPI.isContinuation(target)) {
|
||||||
const fanPageUrl = FanAPI.getFanPageUrl(target as string);
|
const fanPageUrl = FanAPI.getFanPageUrl(target);
|
||||||
const html = await this.fetch(fanPageUrl);
|
const html = await this.fetch(fanPageUrl);
|
||||||
return params.parsePageFn(html, opts);
|
return params.parsePageFn(html, opts);
|
||||||
}
|
}
|
||||||
|
@ -111,14 +127,13 @@ export default class FanAPI extends BaseAPIWithImageSupport {
|
||||||
throw new FetchError('Unable to fetch fan contents: target is continuation token but continuation URL is missing.');
|
throw new FetchError('Unable to fetch fan contents: target is continuation token but continuation URL is missing.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const continuation = target as FanItemsContinuation;
|
|
||||||
const payload = {
|
const payload = {
|
||||||
fan_id: continuation.fanId,
|
fan_id: target.fanId,
|
||||||
older_than_token: continuation.token,
|
older_than_token: target.token,
|
||||||
count: 20
|
count: 20
|
||||||
};
|
};
|
||||||
const json = await this.fetch(continuationUrl, true, FetchMethod.POST, payload);
|
const json = await this.fetch(continuationUrl, true, FetchMethod.POST, payload);
|
||||||
return params.parseContinuationFn(json, continuation, opts);
|
return params.parseContinuationFn(json, target, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -131,9 +146,17 @@ export default class FanAPI extends BaseAPIWithImageSupport {
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
protected static isContinuation(target: any) {
|
protected static isContinuation(target: any): target is FanItemsContinuation {
|
||||||
return typeof target === 'object' && target.fanId && target.token;
|
return typeof target === 'object' && target.fanId && target.token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
protected async getLoggedInFanUsername() {
|
||||||
|
const html = await this.fetch(URLS.SITE_URL);
|
||||||
|
return FanInfoParser.parseLoggedInFanUsername(html);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LimiterFanAPI extends FanAPI {
|
export class LimiterFanAPI extends FanAPI {
|
||||||
|
|
|
@ -49,4 +49,31 @@ export default class FanInfoParser {
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static parseLoggedInFanUsername(html: string) {
|
||||||
|
const $ = cheerioLoad(html);
|
||||||
|
const blob = decode($('#pagedata[data-blob]').attr('data-blob'));
|
||||||
|
let parsed;
|
||||||
|
try {
|
||||||
|
parsed = JSON.parse(blob);
|
||||||
|
}
|
||||||
|
catch (error: any) {
|
||||||
|
throw new ParseError('Failed to parse logged-in fan username: JSON error in data-blob.', html, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const identitiesData = parsed.identities || {};
|
||||||
|
const username = identitiesData.fan?.username;
|
||||||
|
if (!username || typeof username !== 'string') {
|
||||||
|
let reason;
|
||||||
|
if (identitiesData.fan === null) {
|
||||||
|
reason = 'check if valid cookie is set';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reason = 'invalid data';
|
||||||
|
}
|
||||||
|
throw new ParseError(`Failed to parse logged-in fan username: ${reason}.`, html);
|
||||||
|
}
|
||||||
|
|
||||||
|
return username;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user