Implement elaborateResponse

pull/77/head
MillenniumEarl 2021-03-10 10:19:02 +01:00
parent 144547f3bf
commit c5d449d411
4 changed files with 86 additions and 58 deletions

View File

@ -157,15 +157,19 @@ export default class PlatformUser implements ILazy {
const url = new URL(this.id.toString(), `${urls.MEMBERS}/`).toString(); const url = new URL(this.id.toString(), `${urls.MEMBERS}/`).toString();
// Fetch the page // Fetch the page
const htmlResponse = await fetchHTML(url); const response = await fetchHTML(url);
const result = htmlResponse.applyOnSuccess(this.elaborateResponse); const result = response.applyOnSuccess(this.elaborateResponse);
if (result.isFailure()) throw htmlResponse.value; if (result.isFailure()) throw response.value;
} }
//#endregion Public methods //#endregion Public methods
//#region Private methods //#region Private methods
/**
* Process the HTML code received as
* an answer and gets the data contained in it.
*/
private elaborateResponse(html: string): void { private elaborateResponse(html: string): void {
// Prepare cheerio // Prepare cheerio
const $ = cheerio.load(html); const $ = cheerio.load(html);

View File

@ -103,31 +103,38 @@ export default class Post implements ILazy {
// Fetch HTML page containing the post // Fetch HTML page containing the post
const url = new URL(this.id.toString(), urls.POSTS).toString(); const url = new URL(this.id.toString(), urls.POSTS).toString();
const htmlResponse = await fetchHTML(url); const response = await fetchHTML(url);
if (htmlResponse.isSuccess()) { const result = response.applyOnSuccess(this.elaborateResponse);
// Load cheerio and find post if (result.isFailure()) throw response.value;
const $ = cheerio.load(htmlResponse.value);
const post = $(THREAD.POSTS_IN_PAGE)
.toArray()
.find((el, idx) => {
// Fetch the ID and check if it is what we are searching
const sid: string = $(el).find(POST.ID).attr("id").replace("post-", "");
const id = parseInt(sid, 10);
if (id === this.id) return el;
});
// Finally parse the post
await this.parsePost($, $(post));
} else throw htmlResponse.value;
} }
//#endregion Public methods //#endregion Public methods
//#region Private methods //#region Private methods
/**
* Process the HTML code received as
* an answer and gets the data contained in it.
*/
private async elaborateResponse(html: string) {
// Load cheerio and find post
const $ = cheerio.load(html);
const post = $(THREAD.POSTS_IN_PAGE)
.toArray()
.find((el, idx) => {
// Fetch the ID and check if it is what we are searching
const sid: string = $(el).find(POST.ID).attr("id").replace("post-", "");
const id = parseInt(sid, 10);
if (id === this.id) return el;
});
// Finally parse the post
await this.parsePost($, $(post));
}
private async parsePost($: cheerio.Root, post: cheerio.Cheerio): Promise<void> { private async parsePost($: cheerio.Root, post: cheerio.Cheerio): Promise<void> {
// Find post's ID // Find post's ID
const sid: string = post.find(POST.ID).attr("id").replace("post-", ""); const sid: string = post.find(POST.ID).attr("id").replace("post-", "");

View File

@ -189,6 +189,36 @@ export default class Thread implements ILazy {
return name.trim(); return name.trim();
} }
/**
* Process the HTML code received as
* an answer and gets the data contained in it.
*/
private async elaborateResponse(html: string) {
// Load the HTML
const $ = cheerio.load(html);
// Fetch data from selectors
const ownerID = $(THREAD.OWNER_ID).attr("data-user-id");
const tagArray = $(THREAD.TAGS).toArray();
const prefixArray = $(THREAD.PREFIXES).toArray();
const JSONLD = getJSONLD($("body"));
const published = JSONLD["datePublished"] as string;
const modified = JSONLD["dateModified"] as string;
// Parse the thread's data
this._title = this.cleanHeadline(JSONLD["headline"] as string);
this._tags = tagArray.map((el) => $(el).text().trim());
this._prefixes = prefixArray.map((el) => $(el).text().trim());
this._owner = new PlatformUser(parseInt(ownerID, 10));
await this._owner.fetch();
this._rating = this.parseRating(JSONLD);
this._category = JSONLD["articleSection"] as TCategory;
// Validate the dates
if (DateTime.fromISO(modified).isValid) this._modified = new Date(modified);
if (DateTime.fromISO(published).isValid) this._publication = new Date(published);
}
//#endregion Private methods //#endregion Private methods
//#region Public methods //#region Public methods
@ -204,33 +234,9 @@ export default class Thread implements ILazy {
this._url = new URL(this.id.toString(), urls.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 response = await fetchHTML(this.url);
const result = response.applyOnSuccess(this.elaborateResponse);
if (htmlResponse.isSuccess()) { if (result.isFailure()) throw result.value;
// Load the HTML
const $ = cheerio.load(htmlResponse.value);
// Fetch data from selectors
const ownerID = $(THREAD.OWNER_ID).attr("data-user-id");
const tagArray = $(THREAD.TAGS).toArray();
const prefixArray = $(THREAD.PREFIXES).toArray();
const JSONLD = getJSONLD($("body"));
const published = JSONLD["datePublished"] as string;
const modified = JSONLD["dateModified"] as string;
// Parse the thread's data
this._title = this.cleanHeadline(JSONLD["headline"] as string);
this._tags = tagArray.map((el) => $(el).text().trim());
this._prefixes = prefixArray.map((el) => $(el).text().trim());
this._owner = new PlatformUser(parseInt(ownerID, 10));
await this._owner.fetch();
this._rating = this.parseRating(JSONLD);
this._category = JSONLD["articleSection"] as TCategory;
// Validate the dates
if (DateTime.fromISO(modified).isValid) this._modified = new Date(modified);
if (DateTime.fromISO(published).isValid) this._publication = new Date(published);
} else throw htmlResponse.value;
} }
/** /**

View File

@ -112,31 +112,39 @@ export default class UserProfile extends PlatformUser {
//#region Private methods //#region Private methods
/**
* Gets the ID of the user currently logged.
*/
private async fetchUserID(): Promise<number> { private async fetchUserID(): Promise<number> {
// Local variables // Local variables
const url = new URL(urls.BASE).toString(); const url = new URL(urls.BASE).toString();
// fetch and parse page // Fetch and parse page
const htmlResponse = await fetchHTML(url); const response = await fetchHTML(url);
if (htmlResponse.isSuccess()) { const result = response.applyOnSuccess((html) => {
// Load page with cheerio // Load page with cheerio
const $ = cheerio.load(htmlResponse.value); const $ = cheerio.load(html);
const sid = $(GENERIC.CURRENT_USER_ID).attr("data-user-id").trim(); const sid = $(GENERIC.CURRENT_USER_ID).attr("data-user-id").trim();
return parseInt(sid, 10); return parseInt(sid, 10);
} else throw htmlResponse.value; });
if (result.isFailure()) throw result.value;
else return result.value;
} }
/**
* Gets the list of threads followed by the user currently logged.
*/
private async fetchWatchedThread(): Promise<IWatchedThread[]> { private async fetchWatchedThread(): Promise<IWatchedThread[]> {
// Prepare and fetch URL // Prepare and fetch URL
const url = new URL(urls.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 response = await fetchHTML(url.toString());
const result = response.applyOnSuccess(async (html) => {
if (htmlResponse.isSuccess()) {
// Load page in cheerio // Load page in cheerio
const $ = cheerio.load(htmlResponse.value); const $ = cheerio.load(html);
// Fetch the pages // Fetch the pages
const lastPage = parseInt($(WATCHED_THREAD.LAST_PAGE).text().trim(), 10); const lastPage = parseInt($(WATCHED_THREAD.LAST_PAGE).text().trim(), 10);
@ -148,7 +156,10 @@ export default class UserProfile extends PlatformUser {
}); });
return [].concat(...watchedThreads); return [].concat(...watchedThreads);
} else throw htmlResponse.value; });
if (result.isFailure()) throw result.value;
else return result.value as Promise<IWatchedThread[]>;
} }
/** /**