chore: revert back to typedef

This commit is contained in:
Bronya-Rand 2024-04-27 22:01:11 +01:00
parent fc158ca176
commit fe533b7c7f
1 changed files with 166 additions and 36 deletions

View File

@ -3,43 +3,25 @@ import { renderExtensionTemplateAsync } from './extensions.js';
import { POPUP_RESULT, POPUP_TYPE, callGenericPopup } from './popup.js';
import { isValidUrl } from './utils.js';
export class Scraper {
constructor(id, name, description, iconClass, iconAvailable) {
this.id = id;
this.name = name;
this.description = description;
this.iconClass = iconClass;
this.iconAvailable = iconAvailable;
}
/**
* @typedef {Object} Scraper
* @property {string} id
* @property {string} name
* @property {string} description
* @property {string} iconClass
* @property {boolean} iconAvailable
* @property {() => Promise<boolean>} isAvailable
* @property {() => Promise<File[]>} scrape
*/
/**
* Check if the scraper is available.
* @returns {Promise<boolean>}
*/
async isAvailable() {
// Implement in subclass
return false;
}
/**
* Create a text file from a string.
* @returns {Promise<File[]>} File attachments scraped from the text
*/
async scrape() {
// Implement in subclass
return [];
}
}
export class ScraperInfo {
constructor(id, name, description, iconClass, iconAvailable) {
this.id = id;
this.name = name;
this.description = description;
this.iconClass = iconClass;
this.iconAvailable = iconAvailable;
}
}
/**
* @typedef {Object} ScraperInfo
* @property {string} id
* @property {string} name
* @property {string} description
* @property {string} iconClass
* @property {boolean} iconAvailable
*/
export class ScraperManager {
/**
@ -363,6 +345,153 @@ class FandomScraper {
}
}
/**
* Scrapes data from the miHoYo/HoYoverse HoYoLAB wiki.
* @implements {Scraper}
*/
class miHoYoScraper {
constructor() {
this.id = 'mihoyo';
this.name = 'miHoYo';
this.description = 'Scrapes a page from the miHoYo/HoYoverse HoYoLAB wiki.';
this.iconClass = 'img/mihoyo.svg';
this.iconAvailable = false; // There is no miHoYo icon in Font Awesome
}
/**
* Check if the scraper is available.
* @returns {Promise<boolean>}
*/
async isAvailable() {
try {
const result = await fetch('/api/plugins/hoyoverse/probe', {
method: 'POST',
headers: getRequestHeaders(),
});
return result.ok;
} catch (error) {
console.debug('Could not probe miHoYo plugin', error);
return false;
}
}
/**
* Outputs Data Information in a human-readable format.
* @param {Object} m Data to be parsed
* @returns {string} Human-readable format of the data
*/
parseOutput(m) {
let temp = '';
for (const d in m) {
if (m[d].key === "") {
temp += `- ${m[d].value}\n`;
continue;
}
temp += `- ${m[d].key}: ${m[d].value}\n`;
}
return temp;
}
/** Scrape data from the miHoYo/HoYoverse HoYoLAB wiki.
* @returns {Promise<File[]>} File attachments scraped from the wiki.
*/
async scrape() {
let miHoYoWiki = '';
let miHoYoWikiID = '';
const template = $(await renderExtensionTemplateAsync('attachments', 'mihoyo-scrape', {}));
template.find('select[name="mihoyoScrapeWikiDropdown"]').on('change', function () {
miHoYoWiki = String($(this).val());
});
template.find('input[name="mihoyoScrapeWikiID"]').on('input', function () {
miHoYoWikiID = String($(this).val());
});
const confirm = await callGenericPopup(template, POPUP_TYPE.CONFIRM, '', { wide: false, large: false });
if (confirm !== POPUP_RESULT.AFFIRMATIVE) {
return;
}
if (!miHoYoWiki) {
toastr.error('A specific HoYoLab wiki is required');
return;
}
if (!miHoYoWikiID) {
toastr.error('A specific HoYoLab wiki ID is required');
return;
}
if (miHoYoWiki === 'genshin') {
toastr.error('The Genshin Impact parser has not been implemented *yet*');
return;
}
let toast;
if (miHoYoWiki === 'hsr') {
toast = toastr.info(`Scraping the Honkai: Star Rail HoYoLAB wiki for Wiki Entry ID: ${miHoYoWikiID}`);
} else {
toast = toastr.info(`Scraping the Genshin Impact wiki for Wiki Entry ID: ${miHoYoWikiID}`);
}
let result;
if (miHoYoWiki === 'hsr') {
result = await fetch('/api/plugins/hoyoverse/silver-wolf', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({ miHoYoWiki, miHoYoWikiID }),
});
} else if (miHoYoWiki === 'genshin') {
result = await fetch('/api/plugins/hoyoverse/furina', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({ miHoYoWiki, miHoYoWikiID }),
});
} else {
throw new Error('Unknown wiki name identifier');
}
if (!result.ok) {
const error = await result.text();
throw new Error(error);
}
const data = await result.json();
toastr.clear(toast);
const fileName = data[0].name;
const dataContent = data[0].content;
//parse the data as a long string of data
let combinedContent = '';
combinedContent += `Name: ${data[0].name}\n`;
if (dataContent.description !== "") {
combinedContent += `Description: ${dataContent.description}\n\n`;
}
if (dataContent.modules != []) {
for (const m in dataContent.modules) {
if (dataContent.modules[m].data.length === 0) {
continue;
}
combinedContent += dataContent.modules[m].name + '\n';
combinedContent += this.parseOutput(dataContent.modules[m].data);
combinedContent += '\n';
}
}
const file = new File([combinedContent], `${fileName}.txt`, { type: 'text/plain' });
return [file];
}
}
/**
* Scrape transcript from a YouTube video.
* @implements {Scraper}
@ -438,4 +567,5 @@ ScraperManager.registerDataBankScraper(new FileScraper());
ScraperManager.registerDataBankScraper(new Notepad());
ScraperManager.registerDataBankScraper(new WebScraper());
ScraperManager.registerDataBankScraper(new FandomScraper());
ScraperManager.registerDataBankScraper(new miHoYoScraper());
ScraperManager.registerDataBankScraper(new YouTubeScraper());