diff --git a/app/index.js b/app/index.js index 1037ff8..14c472c 100644 --- a/app/index.js +++ b/app/index.js @@ -1,28 +1,28 @@ -'use strict'; +"use strict"; // Core modules -const fs = require('fs'); +const fs = require("fs"); // Modules from file -const shared = require('./scripts/shared.js'); -const constURLs = require('./scripts/constants/urls.js'); -const selectors = require('./scripts/constants/css-selectors.js'); +const shared = require("./scripts/shared.js"); +const constURLs = require("./scripts/constants/urls.js"); +const selectors = require("./scripts/constants/css-selectors.js"); const { isStringAValidURL, urlExists, - isF95URL -} = require('./scripts/urls-helper.js'); -const scraper = require('./scripts/game-scraper.js'); + isF95URL, +} = require("./scripts/urls-helper.js"); +const scraper = require("./scripts/game-scraper.js"); const { prepareBrowser, - preparePage -} = require('./scripts/puppeteer-helper.js'); -const searcher = require('./scripts/game-searcher.js'); + preparePage, +} = require("./scripts/puppeteer-helper.js"); +const searcher = require("./scripts/game-searcher.js"); // Classes from file -const GameInfo = require('./scripts/classes/game-info.js'); -const LoginResult = require('./scripts/classes/login-result.js'); -const UserData = require('./scripts/classes/user-data.js'); +const GameInfo = require("./scripts/classes/game-info.js"); +const LoginResult = require("./scripts/classes/login-result.js"); +const UserData = require("./scripts/classes/user-data.js"); //#region Export classes module.exports.GameInfo = GameInfo; @@ -99,27 +99,27 @@ var _browser = null; */ module.exports.login = async function (username, password) { if (shared.isLogged) { - if (shared.debug) console.log('Already logged in'); + if (shared.debug) console.log("Already logged in"); const result = new LoginResult(); result.success = true; - result.message = 'Already logged in'; + result.message = "Already logged in"; return result; } // If cookies are loaded, use them to authenticate shared.cookies = loadCookies(); if (shared.cookies !== null) { - if (shared.debug) console.log('Valid session, no need to re-authenticate'); + if (shared.debug) console.log("Valid session, no need to re-authenticate"); shared.isLogged = true; const result = new LoginResult(); result.success = true; - result.message = 'Logged with cookies'; + result.message = "Logged with cookies"; return result; } // Else, log in throught browser if (shared.debug) - console.log('No saved sessions or expired session, login on the platform'); + console.log("No saved sessions or expired session, login on the platform"); if (_browser === null && !shared.isolation) _browser = await prepareBrowser(); const browser = shared.isolation ? await prepareBrowser() : _browser; @@ -130,9 +130,9 @@ module.exports.login = async function (username, password) { if (result.success) { // Reload cookies shared.cookies = loadCookies(); - if (shared.debug) console.log('User logged in through the platform'); + if (shared.debug) console.log("User logged in through the platform"); } else { - console.warn('Error during authentication: ' + result.message); + console.warn("Error during authentication: " + result.message); } if (shared.isolation) await browser.close(); return result; @@ -146,11 +146,11 @@ module.exports.login = async function (username, password) { */ module.exports.loadF95BaseData = async function () { if (!shared.isLogged || !shared.cookies) { - console.warn('User not authenticated, unable to continue'); + console.warn("User not authenticated, unable to continue"); return false; } - if (shared.debug) console.log('Loading base data...'); + if (shared.debug) console.log("Loading base data..."); // Prepare a new web page if (_browser === null && !shared.isolation) _browser = await prepareBrowser(); @@ -161,7 +161,7 @@ module.exports.loadF95BaseData = async function () { // Go to latest update page and wait for it to load await page.goto(constURLs.F95_LATEST_UPDATES, { - waitUntil: shared.WAIT_STATEMENT + waitUntil: shared.WAIT_STATEMENT, }); // Obtain engines (disc/online) @@ -170,7 +170,7 @@ module.exports.loadF95BaseData = async function () { page, shared.enginesCachePath, selectors.ENGINE_ID_SELECTOR, - 'engines' + "engines" ); // Obtain statuses (disc/online) @@ -179,11 +179,11 @@ module.exports.loadF95BaseData = async function () { page, shared.statusesCachePath, selectors.STATUS_ID_SELECTOR, - 'statuses' + "statuses" ); if (shared.isolation) await browser.close(); - if (shared.debug) console.log('Base data loaded'); + if (shared.debug) console.log("Base data loaded"); return true; }; /** @@ -195,7 +195,7 @@ module.exports.loadF95BaseData = async function () { */ module.exports.chekIfGameHasUpdate = async function (info) { if (!shared.isLogged || !shared.cookies) { - console.warn('user not authenticated, unable to continue'); + console.warn("user not authenticated, unable to continue"); return info.version; } @@ -225,7 +225,7 @@ module.exports.chekIfGameHasUpdate = async function (info) { */ module.exports.getGameData = async function (name, includeMods) { if (!shared.isLogged || !shared.cookies) { - console.warn('user not authenticated, unable to continue'); + console.warn("user not authenticated, unable to continue"); return null; } @@ -262,13 +262,13 @@ module.exports.getGameData = async function (name, includeMods) { */ module.exports.getGameDataFromURL = async function (url) { if (!shared.isLogged || !shared.cookies) { - console.warn('user not authenticated, unable to continue'); + console.warn("user not authenticated, unable to continue"); return null; } // Check URL if (!urlExists(url)) return null; - if (!isF95URL(url)) throw new Error(url + ' is not a valid F95Zone URL'); + if (!isF95URL(url)) throw new Error(url + " is not a valid F95Zone URL"); // Gets the search results of the game being searched for if (_browser === null && !shared.isolation) _browser = await prepareBrowser(); @@ -288,7 +288,7 @@ module.exports.getGameDataFromURL = async function (url) { */ module.exports.getUserData = async function () { if (!shared.isLogged || !shared.cookies) { - console.warn('user not authenticated, unable to continue'); + console.warn("user not authenticated, unable to continue"); return null; } @@ -313,7 +313,7 @@ module.exports.getUserData = async function () { const avatarSrc = await page.evaluate( /* istanbul ignore next */ (selector) => - document.querySelector(selector).getAttribute('src'), + document.querySelector(selector).getAttribute("src"), selectors.AVATAR_PIC ); @@ -334,7 +334,7 @@ module.exports.getUserData = async function () { */ module.exports.logout = async function () { if (!shared.isLogged || !shared.cookies) { - console.warn('user not authenticated, unable to continue'); + console.warn("user not authenticated, unable to continue"); return; } shared.isLogged = false; @@ -385,14 +385,14 @@ function isCookieExpired(cookie) { // Ignore cookies that never expire const expirationUnixTimestamp = cookie.expire; - if (expirationUnixTimestamp !== '-1') { + if (expirationUnixTimestamp !== "-1") { // Convert UNIX epoch timestamp to normal Date const expirationDate = new Date(expirationUnixTimestamp * 1000); if (expirationDate < Date.now()) { if (shared.debug) console.log( - 'Cookie ' + cookie.name + ' expired, you need to re-authenticate' + "Cookie " + cookie.name + " expired, you need to re-authenticate" ); expiredCookies = true; } @@ -421,7 +421,7 @@ async function loadValuesFromLatestPage( elementRequested ) { // If the values already exist they are loaded from disk without having to connect to F95 - if (shared.debug) console.log('Load ' + elementRequested + ' from disk...'); + if (shared.debug) console.log("Load " + elementRequested + " from disk..."); if (fs.existsSync(path)) { const valueJSON = fs.readFileSync(path); return JSON.parse(valueJSON); @@ -429,11 +429,11 @@ async function loadValuesFromLatestPage( // Otherwise, connect and download the data from the portal if (shared.debug) - console.log('No ' + elementRequested + ' cached, downloading...'); + console.log("No " + elementRequested + " cached, downloading..."); const values = await getValuesFromLatestPage( page, selector, - 'Getting ' + elementRequested + ' from page' + "Getting " + elementRequested + " from page" ); fs.writeFileSync(path, JSON.stringify(values)); return values; @@ -489,7 +489,7 @@ async function loginF95(browser, username, password) { await Promise.all([ page.click(selectors.LOGIN_BUTTON), // Click on the login button page.waitForNavigation({ - waitUntil: shared.WAIT_STATEMENT + waitUntil: shared.WAIT_STATEMENT, }), // Wait for page to load ]); @@ -507,7 +507,7 @@ async function loginF95(browser, username, password) { if (result.success) { const c = await page.cookies(); fs.writeFileSync(shared.cookiesCachePath, JSON.stringify(c)); - result.message = 'Authentication successful'; + result.message = "Authentication successful"; } else if ( // Obtain the error message await page.evaluate( @@ -522,15 +522,15 @@ async function loginF95(browser, username, password) { selectors.LOGIN_MESSAGE_ERROR ); - if (errorMessage === 'Incorrect password. Please try again.') { - result.message = 'Incorrect password'; + if (errorMessage === "Incorrect password. Please try again.") { + result.message = "Incorrect password"; } else if ( errorMessage === 'The requested user "' + username + '" could not be found.' ) { - result.message = 'Incorrect username'; + result.message = "Incorrect username"; } else result.message = errorMessage; - } else result.message = 'Unknown error'; + } else result.message = "Unknown error"; await page.close(); // Close the page return result; @@ -557,7 +557,7 @@ async function getUserWatchedGameThreads(browser) { // Set the filters await page.evaluate( /* istanbul ignore next */ (selector) => - document.querySelector(selector).removeAttribute('checked'), + document.querySelector(selector).removeAttribute("checked"), selectors.UNREAD_THREAD_CHECKBOX ); // Also read the threads already read @@ -578,7 +578,7 @@ async function getUserWatchedGameThreads(browser) { handle ); // If 'unread' is left, it will redirect to the last unread post - const url = src.replace('/unread', ''); + const url = src.replace("/unread", ""); urls.push(url); } diff --git a/app/scripts/classes/game-download.js b/app/scripts/classes/game-download.js index d3b1032..4cc5868 100644 --- a/app/scripts/classes/game-download.js +++ b/app/scripts/classes/game-download.js @@ -1,16 +1,16 @@ /* istanbul ignore file */ -'use strict'; +"use strict"; // Core modules -const fs = require('fs'); +const fs = require("fs"); // Public modules from npm // const { File } = require('megajs'); // Modules from file -const { prepareBrowser, preparePage } = require('../puppeteer-helper.js'); -const shared = require('../shared.js'); +const { prepareBrowser, preparePage } = require("../puppeteer-helper.js"); +const shared = require("../shared.js"); class GameDownload { constructor() { @@ -19,7 +19,7 @@ class GameDownload { * Platform that hosts game files * @type String */ - this.hosting = ''; + this.hosting = ""; /** * @public * Link to game files @@ -43,9 +43,9 @@ class GameDownload { * @return {Promise} Result of the operation */ async download(path) { - if (this.link.includes('mega.nz')) + if (this.link.includes("mega.nz")) return await downloadMEGA(this.link, path); - else if (this.link.includes('nopy.to')) + else if (this.link.includes("nopy.to")) return await downloadNOPY(this.link, path); } } @@ -57,13 +57,13 @@ async function downloadMEGA(url, savepath) { const page = await preparePage(browser); await page.setCookie(...shared.cookies); // Set cookies to avoid login await page.goto(url); - await page.waitForSelector('a.host_link'); + await page.waitForSelector("a.host_link"); // Obtain the link for the unmasked page and click it - const link = await page.$('a.host_link'); + const link = await page.$("a.host_link"); await link.click(); await page.goto(url, { - waitUntil: shared.WAIT_STATEMENT + waitUntil: shared.WAIT_STATEMENT, }); // Go to the game page and wait until it loads // Obtain the URL after the redirect @@ -84,22 +84,22 @@ async function downloadNOPY(url, savepath) { const browser = await prepareBrowser(); const page = await preparePage(browser); await page.goto(url); - await page.waitForSelector('#download'); + await page.waitForSelector("#download"); // Set the save path - await page._client.send('Page.setDownloadBehavior', { - behavior: 'allow', - downloadPath: path.basename(path.dirname(savepath)) // It's a directory + await page._client.send("Page.setDownloadBehavior", { + behavior: "allow", + downloadPath: path.basename(path.dirname(savepath)), // It's a directory }); // Obtain the download button and click it - const downloadButton = await page.$('#download'); + const downloadButton = await page.$("#download"); await downloadButton.click(); // Await for all the connections to close await page.waitForNavigation({ - waitUntil: 'networkidle0', - timeout: 0 // Disable timeout + waitUntil: "networkidle0", + timeout: 0, // Disable timeout }); // Close browser and page diff --git a/app/scripts/classes/game-info.js b/app/scripts/classes/game-info.js index 8601986..f13aedf 100644 --- a/app/scripts/classes/game-info.js +++ b/app/scripts/classes/game-info.js @@ -1,6 +1,6 @@ -'use strict'; +"use strict"; -const UNKNOWN = 'Unknown'; +const UNKNOWN = "Unknown"; class GameInfo { constructor() { @@ -103,7 +103,7 @@ class GameInfo { isMod: this.isMod, changelog: this.changelog, gameDir: this.gameDir, - downloadInfo: this.downloadInfo + downloadInfo: this.downloadInfo, }; } diff --git a/app/scripts/classes/login-result.js b/app/scripts/classes/login-result.js index 4916b9b..15eb311 100644 --- a/app/scripts/classes/login-result.js +++ b/app/scripts/classes/login-result.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /** * Object obtained in response to an attempt to login to the portal. @@ -14,7 +14,7 @@ class LoginResult { * Login response message * @type String */ - this.message = ''; + this.message = ""; } } module.exports = LoginResult; diff --git a/app/scripts/constants/css-selectors.js b/app/scripts/constants/css-selectors.js index 9297e1c..8b268c3 100644 --- a/app/scripts/constants/css-selectors.js +++ b/app/scripts/constants/css-selectors.js @@ -1,32 +1,32 @@ module.exports = Object.freeze({ - AVATAR_INFO: 'span.avatar', + AVATAR_INFO: "span.avatar", AVATAR_PIC: 'a[href="/account/"] > span.avatar > img[class^="avatar"]', ENGINE_ID_SELECTOR: 'div[id^="btn-prefix_1_"]>span', FILTER_THREADS_BUTTON: 'button[class="button--primary button"]', GAME_IMAGES: 'img[src^="https://attachments.f95zone.to"]', - GAME_TAGS: 'a.tagItem', - GAME_TITLE: 'h1.p-title-value', + GAME_TAGS: "a.tagItem", + GAME_TITLE: "h1.p-title-value", GAME_TITLE_PREFIXES: 'h1.p-title-value > a.labelLink > span[dir="auto"]', - LOGIN_BUTTON: 'button.button--icon--login', + LOGIN_BUTTON: "button.button--icon--login", LOGIN_MESSAGE_ERROR: - 'div.blockMessage.blockMessage--error.blockMessage--iconic', + "div.blockMessage.blockMessage--error.blockMessage--iconic", ONLY_GAMES_THREAD_OPTION: 'select[name="nodes[]"] > option[value="2"]', PASSWORD_INPUT: 'input[name="password"]', - SEARCH_BUTTON: 'form.block > * button.button--icon--search', + SEARCH_BUTTON: "form.block > * button.button--icon--search", SEARCH_FORM_TEXTBOX: 'input[name="keywords"]', STATUS_ID_SELECTOR: 'div[id^="btn-prefix_4_"]>span', THREAD_POSTS: - 'article.message-body:first-child > div.bbWrapper:first-of-type', - THREAD_TITLE: 'h3.contentRow-title', + "article.message-body:first-child > div.bbWrapper:first-of-type", + THREAD_TITLE: "h3.contentRow-title", TITLE_ONLY_CHECKBOX: 'form.block > * input[name="c[title_only]"]', UNREAD_THREAD_CHECKBOX: 'input[type="checkbox"][name="unread"]', USERNAME_ELEMENT: 'a[href="/account/"] > span.p-navgroup-linkText', USERNAME_INPUT: 'input[name="login"]', - WATCHED_THREAD_FILTER_POPUP_BUTTON: 'a.filterBar-menuTrigger', - WATCHED_THREAD_NEXT_PAGE: 'a.pageNav-jump--next', + WATCHED_THREAD_FILTER_POPUP_BUTTON: "a.filterBar-menuTrigger", + WATCHED_THREAD_NEXT_PAGE: "a.pageNav-jump--next", WATCHED_THREAD_URLS: 'a[href^="/threads/"][data-tp-primary]', DOWNLOAD_LINKS_CONTAINER: 'span[style="font-size: 18px"]', - SEARCH_THREADS_RESULTS_BODY: 'div.contentRow-main', - SEARCH_THREADS_MEMBERSHIP: 'li > a:not(.username)', - THREAD_LAST_CHANGELOG: 'div.bbCodeBlock-content > div:first-of-type' + SEARCH_THREADS_RESULTS_BODY: "div.contentRow-main", + SEARCH_THREADS_MEMBERSHIP: "li > a:not(.username)", + THREAD_LAST_CHANGELOG: "div.bbCodeBlock-content > div:first-of-type", }); diff --git a/app/scripts/constants/urls.js b/app/scripts/constants/urls.js index 88856c0..816a00a 100644 --- a/app/scripts/constants/urls.js +++ b/app/scripts/constants/urls.js @@ -1,7 +1,7 @@ module.exports = Object.freeze({ - F95_BASE_URL: 'https://f95zone.to', - F95_SEARCH_URL: 'https://f95zone.to/search', - F95_LATEST_UPDATES: 'https://f95zone.to/latest', - F95_LOGIN_URL: 'https://f95zone.to/login', - F95_WATCHED_THREADS: 'https://f95zone.to/watched/threads' + F95_BASE_URL: "https://f95zone.to", + F95_SEARCH_URL: "https://f95zone.to/search", + F95_LATEST_UPDATES: "https://f95zone.to/latest", + F95_LOGIN_URL: "https://f95zone.to/login", + F95_WATCHED_THREADS: "https://f95zone.to/watched/threads", }); diff --git a/app/scripts/game-scraper.js b/app/scripts/game-scraper.js index 0282dd9..7cd2bb8 100644 --- a/app/scripts/game-scraper.js +++ b/app/scripts/game-scraper.js @@ -1,16 +1,16 @@ -'use strict'; +"use strict"; // Public modules from npm -const HTMLParser = require('node-html-parser'); -const puppeteer = require('puppeteer'); // skipcq: JS-0128 +const HTMLParser = require("node-html-parser"); +const puppeteer = require("puppeteer"); // skipcq: JS-0128 // Modules from file -const shared = require('./shared.js'); -const selectors = require('./constants/css-selectors.js'); -const { preparePage } = require('./puppeteer-helper.js'); -const GameDownload = require('./classes/game-download.js'); -const GameInfo = require('./classes/game-info.js'); -const { isStringAValidURL, isF95URL, urlExists } = require('./urls-helper.js'); +const shared = require("./shared.js"); +const selectors = require("./constants/css-selectors.js"); +const { preparePage } = require("./puppeteer-helper.js"); +const GameDownload = require("./classes/game-download.js"); +const GameInfo = require("./classes/game-info.js"); +const { isStringAValidURL, isF95URL, urlExists } = require("./urls-helper.js"); /** * @protected @@ -21,17 +21,17 @@ const { isStringAValidURL, isF95URL, urlExists } = require('./urls-helper.js'); * looking for or null if the URL doesn't exists */ module.exports.getGameInfo = async function (browser, url) { - if (shared.debug) console.log('Obtaining game info'); + if (shared.debug) console.log("Obtaining game info"); // Verify the correctness of the URL - if (!isF95URL(url)) throw new Error(url + ' is not a valid F95Zone URL'); + if (!isF95URL(url)) throw new Error(url + " is not a valid F95Zone URL"); const exists = await urlExists(url); if (!exists) return null; const page = await preparePage(browser); // Set new isolated page await page.setCookie(...shared.cookies); // Set cookies to avoid login await page.goto(url, { - waitUntil: shared.WAIT_STATEMENT + waitUntil: shared.WAIT_STATEMENT, }); // Go to the game page and wait until it loads // It asynchronously searches for the elements and @@ -59,7 +59,7 @@ module.exports.getGameInfo = async function (browser, url) { ? parsedInfos.UPDATED : parsedInfos.THREAD_UPDATED; info.previewSource = await previewSource; - info.changelog = (await changelog) || 'Unknown changelog'; + info.changelog = (await changelog) || "Unknown changelog"; //info.downloadInfo = await downloadData; /* Downloading games without going directly to * the platform appears to be prohibited by @@ -67,7 +67,7 @@ module.exports.getGameInfo = async function (browser, url) { * keep the links for downloading the games. */ await page.close(); // Close the page - if (shared.debug) console.log('Founded data for ' + info.name); + if (shared.debug) console.log("Founded data for " + info.name); return info; }; @@ -81,7 +81,7 @@ module.exports.getGameVersionFromTitle = async function (browser, info) { const page = await preparePage(browser); // Set new isolated page await page.setCookie(...shared.cookies); // Set cookies to avoid login await page.goto(info.f95url, { - waitUntil: shared.WAIT_STATEMENT + waitUntil: shared.WAIT_STATEMENT, }); // Go to the game page and wait until it loads // Get the title @@ -93,10 +93,10 @@ module.exports.getGameVersionFromTitle = async function (browser, info) { const title = HTMLParser.parse(titleHTML).childNodes.pop().rawText; // The title is in the following format: [PREFIXES] NAME GAME [VERSION] [AUTHOR] - const startIndex = title.indexOf('[') + 1; - const endIndex = title.indexOf(']', startIndex); + const startIndex = title.indexOf("[") + 1; + const endIndex = title.indexOf("]", startIndex); let version = title.substring(startIndex, endIndex).trim().toUpperCase(); - if (version.startsWith('V')) version = version.replace('V', ''); // Replace only the first occurrence + if (version.startsWith("V")) version = version.replace("V", ""); // Replace only the first occurrence return version; }; @@ -112,9 +112,9 @@ module.exports.getGameVersionFromTitle = async function (browser, info) { function getOverview(text, isMod) { // Get overview (different parsing for game and mod) let overviewEndIndex; - if (isMod) overviewEndIndex = text.indexOf('Updated'); - else overviewEndIndex = text.indexOf('Thread Updated'); - return text.substring(0, overviewEndIndex).replace('Overview:\n', '').trim(); + if (isMod) overviewEndIndex = text.indexOf("Updated"); + else overviewEndIndex = text.indexOf("Thread Updated"); + return text.substring(0, overviewEndIndex).replace("Overview:\n", "").trim(); } /** @@ -156,7 +156,7 @@ async function getGameAuthor(page) { const gameTitle = structuredTitle.childNodes.pop().rawText; // The last square brackets contain the author - const startTitleIndex = gameTitle.lastIndexOf('[') + 1; + const startTitleIndex = gameTitle.lastIndexOf("[") + 1; return gameTitle.substring(startTitleIndex, gameTitle.length - 1).trim(); } @@ -171,17 +171,17 @@ function parseConversationPage(text) { const dataPairs = {}; // The information searched in the game post are one per line - const splittedText = text.split('\n'); + const splittedText = text.split("\n"); for (const line of splittedText) { - if (!line.includes(':')) continue; + if (!line.includes(":")) continue; // Create pair key/value - const splitted = line.split(':'); - const key = splitted[0].trim().toUpperCase().replaceAll(' ', '_'); // Uppercase to avoid mismatch + const splitted = line.split(":"); + const key = splitted[0].trim().toUpperCase().replaceAll(" ", "_"); // Uppercase to avoid mismatch const value = splitted[1].trim(); // Add pair to the dict if valid - if (value !== '') dataPairs[key] = value; + if (value !== "") dataPairs[key] = value; } return dataPairs; @@ -200,7 +200,7 @@ async function getGamePreviewSource(page) { // Get the firs image available const img = document.querySelector(selector); - if (img) return img.getAttribute('src'); + if (img) return img.getAttribute("src"); else return null; }, selectors.GAME_IMAGES @@ -227,7 +227,7 @@ async function getGameTitle(page) { // The last element **shoud be** the title without prefixes (engines, status, other...) const gameTitle = structuredTitle.childNodes.pop().rawText; - const endTitleIndex = gameTitle.indexOf('['); + const endTitleIndex = gameTitle.indexOf("["); return gameTitle.substring(0, endTitleIndex).trim(); } @@ -261,10 +261,10 @@ async function getGameTags(page) { * @returns {Promise} GameInfo object passed in to which the identified information has been added */ async function parsePrefixes(page, info) { - const MOD_PREFIX = 'MOD'; + const MOD_PREFIX = "MOD"; // The 'Ongoing' status is not specified, only 'Abandoned'/'OnHold'/'Complete' - info.status = 'Ongoing'; + info.status = "Ongoing"; for (const handle of await page.$$(selectors.GAME_TITLE_PREFIXES)) { const value = await page.evaluate( /* istanbul ignore next */ @@ -273,7 +273,7 @@ async function parsePrefixes(page, info) { ); // Clean the prefix - const prefix = value.toUpperCase().replace('[', '').replace(']', '').trim(); + const prefix = value.toUpperCase().replace("[", "").replace("]", "").trim(); // Getting infos... if (shared.statuses.includes(prefix)) info.status = prefix; @@ -303,7 +303,7 @@ async function getLastChangelog(page) { spoiler ); const parsedText = HTMLParser.parse(changelogHTML).structuredText; - return parsedText.replace('Spoiler', '').trim(); + return parsedText.replace("Spoiler", "").trim(); } /** @@ -316,17 +316,17 @@ async function getLastChangelog(page) { async function getGameDownloadLink(page) { // Most used hosting platforms const hostingPlatforms = [ - 'MEGA', - 'NOPY', - 'FILESUPLOAD', - 'MIXDROP', - 'UPLOADHAVEN', - 'PIXELDRAIN', - 'FILESFM' + "MEGA", + "NOPY", + "FILESUPLOAD", + "MIXDROP", + "UPLOADHAVEN", + "PIXELDRAIN", + "FILESFM", ]; // Supported OS platforms - const platformOS = ['WIN', 'LINUX', 'MAC', 'ALL']; + const platformOS = ["WIN", "LINUX", "MAC", "ALL"]; // Gets the which contains the download links const temp = await page.$$(selectors.DOWNLOAD_LINKS_CONTAINER); @@ -383,13 +383,13 @@ async function getGameDownloadLink(page) { * @returns {GameDownload[]} List of game download links for the selected platform */ function extractGameHostingData(platform, text) { - const PLATFORM_BOLD_OPEN = ''; - const CONTAINER_SPAN_CLOSE = ''; - const LINK_OPEN = '} List of URL of possible games obtained from the preliminary research on the F95 portal */ module.exports.getSearchGameResults = async function (browser, gamename) { - if (shared.debug) console.log('Searching ' + gamename + ' on F95Zone'); + if (shared.debug) console.log("Searching " + gamename + " on F95Zone"); const page = await preparePage(browser); // Set new isolated page await page.setCookie(...shared.cookies); // Set cookies to avoid login await page.goto(constURLs.F95_SEARCH_URL, { - waitUntil: shared.WAIT_STATEMENT + waitUntil: shared.WAIT_STATEMENT, }); // Go to the search form and wait for it // Explicitly wait for the required items to load @@ -36,7 +36,7 @@ module.exports.getSearchGameResults = async function (browser, gamename) { await Promise.all([ page.click(selectors.SEARCH_BUTTON), // Execute search page.waitForNavigation({ - waitUntil: shared.WAIT_STATEMENT + waitUntil: shared.WAIT_STATEMENT, }), // Wait for page to load ]); @@ -44,13 +44,13 @@ module.exports.getSearchGameResults = async function (browser, gamename) { const resultsThread = await page.$$(selectors.SEARCH_THREADS_RESULTS_BODY); // For each element found extract the info about the conversation - if (shared.debug) console.log('Extracting info from conversations'); + if (shared.debug) console.log("Extracting info from conversations"); const results = []; for (const element of resultsThread) { const gameUrl = await getOnlyGameThreads(page, element); if (gameUrl !== null) results.push(gameUrl); } - if (shared.debug) console.log('Find ' + results.length + ' conversations'); + if (shared.debug) console.log("Find " + results.length + " conversations"); await page.close(); // Close the page return results; @@ -71,7 +71,7 @@ async function getOnlyGameThreads(page, divHandle) { // Get the forum where the thread was posted const forum = await getMembershipForum(page, forumHandle); - if (forum !== 'GAMES' && forum !== 'MODS') return null; + if (forum !== "GAMES" && forum !== "MODS") return null; // Get the URL of the thread from the title return await getThreadURL(page, titleHandle); @@ -92,13 +92,13 @@ async function getMembershipForum(page, handle) { let link = await page.evaluate( /* istanbul ignore next */ - (e) => e.getAttribute('href'), + (e) => e.getAttribute("href"), handle ); // Parse link - link = link.replace('/forums/', ''); - const endIndex = link.indexOf('.'); + link = link.replace("/forums/", ""); + const endIndex = link.indexOf("."); const forum = link.substring(0, endIndex); return forum.toUpperCase(); @@ -114,7 +114,7 @@ async function getMembershipForum(page, handle) { async function getThreadURL(page, handle) { const relativeURLThread = await page.evaluate( /* istanbul ignore next */ - (e) => e.querySelector('a').href, + (e) => e.querySelector("a").href, handle ); diff --git a/app/scripts/puppeteer-helper.js b/app/scripts/puppeteer-helper.js index 2764566..18a40a4 100644 --- a/app/scripts/puppeteer-helper.js +++ b/app/scripts/puppeteer-helper.js @@ -1,10 +1,10 @@ -'use strict'; +"use strict"; // Public modules from npm -const puppeteer = require('puppeteer'); +const puppeteer = require("puppeteer"); // Modules from file -const shared = require('./shared.js'); +const shared = require("./shared.js"); /** * @protected @@ -18,11 +18,11 @@ module.exports.prepareBrowser = async function () { if (shared.chromiumLocalPath) { browser = await puppeteer.launch({ executablePath: shared.chromiumLocalPath, - headless: !shared.debug // Use GUI when debug = true + headless: !shared.debug, // Use GUI when debug = true }); } else { browser = await puppeteer.launch({ - headless: !shared.debug // Use GUI when debug = true + headless: !shared.debug, // Use GUI when debug = true }); } @@ -42,9 +42,9 @@ module.exports.preparePage = async function (browser) { // Block image download await page.setRequestInterception(true); - page.on('request', (request) => { - if (request.resourceType() === 'image') request.abort(); - else if (request.resourceType === 'font') request.abort(); + page.on("request", (request) => { + if (request.resourceType() === "image") request.abort(); + else if (request.resourceType === "font") request.abort(); // else if (request.resourceType() == 'stylesheet') request.abort(); // else if(request.resourceType == 'media') request.abort(); else request.continue(); @@ -52,8 +52,8 @@ module.exports.preparePage = async function (browser) { // Set custom user-agent const userAgent = - 'Mozilla/5.0 (X11; Linux x86_64)' + - 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.39 Safari/537.36'; + "Mozilla/5.0 (X11; Linux x86_64)" + + "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.39 Safari/537.36"; await page.setUserAgent(userAgent); return page; diff --git a/app/scripts/urls-helper.js b/app/scripts/urls-helper.js index e7a0ca7..b5fa93d 100644 --- a/app/scripts/urls-helper.js +++ b/app/scripts/urls-helper.js @@ -1,12 +1,12 @@ -'use strict'; +"use strict"; // Public modules from npm -const ky = require('ky-universal').create({ - throwHttpErrors: false +const ky = require("ky-universal").create({ + throwHttpErrors: false, }); // Modules from file -const { F95_BASE_URL } = require('./constants/urls.js'); +const { F95_BASE_URL } = require("./constants/urls.js"); /** * @protected diff --git a/test/user-test.js b/test/user-test.js index 90692cd..07717e7 100644 --- a/test/user-test.js +++ b/test/user-test.js @@ -5,7 +5,7 @@ const { getGameData, loadF95BaseData, getUserData, - logout + logout, } = require("../app/index.js"); const GameDownload = require("../app/scripts/classes/game-download.js");