Added prefix parser
							parent
							
								
									8c1d39b98d
								
							
						
					
					
						commit
						34d065f84c
					
				
							
								
								
									
										12
									
								
								app/index.js
								
								
								
								
							
							
						
						
									
										12
									
								
								app/index.js
								
								
								
								
							| 
						 | 
				
			
			@ -13,13 +13,13 @@ const Credentials = require("./scripts/classes/credentials.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");
 | 
			
		||||
const TagParser = require("./scripts/classes/tag-parser.js");
 | 
			
		||||
const PrefixParser = require("./scripts/classes/prefix-parser.js");
 | 
			
		||||
 | 
			
		||||
//#region Export classes
 | 
			
		||||
module.exports.GameInfo = GameInfo;
 | 
			
		||||
module.exports.LoginResult = LoginResult;
 | 
			
		||||
module.exports.UserData = UserData;
 | 
			
		||||
module.exports.TagParser = TagParser;
 | 
			
		||||
module.exports.PrefixParser = PrefixParser;
 | 
			
		||||
//#endregion Export classes
 | 
			
		||||
 | 
			
		||||
//#region Export properties
 | 
			
		||||
| 
						 | 
				
			
			@ -187,7 +187,6 @@ module.exports.getUserData = async function () {
 | 
			
		|||
 * Use `0` to select no time limit.
 | 
			
		||||
 * @param {String[]} [args.prefixes]
 | 
			
		||||
 * Prefixes to be included in the search.
 | 
			
		||||
 * **Currently not supported**
 | 
			
		||||
 * @param {String} [args.sorting]
 | 
			
		||||
 * Method of sorting the results between (default: `date`):
 | 
			
		||||
 * `date`, `likes`, `views`, `name`, `rating`
 | 
			
		||||
| 
						 | 
				
			
			@ -199,8 +198,7 @@ module.exports.getLatestUpdates = async function(args, limit) {
 | 
			
		|||
    if(limit <= 0) throw new Error("limit must be greater than 0");
 | 
			
		||||
 | 
			
		||||
    // Prepare the parser
 | 
			
		||||
    const tp = new TagParser();
 | 
			
		||||
    tp.fetch();
 | 
			
		||||
    const parser = new PrefixParser();
 | 
			
		||||
 | 
			
		||||
    // Get the closest date limit
 | 
			
		||||
    let filterDate = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -216,8 +214,8 @@ module.exports.getLatestUpdates = async function(args, limit) {
 | 
			
		|||
 | 
			
		||||
    // Fetch the games
 | 
			
		||||
    const query = {
 | 
			
		||||
        tags: args.tags ? tp.tagsToIDs(args.tags) : [],
 | 
			
		||||
        prefixes: [], // TODO: Add prefix parser
 | 
			
		||||
        tags: args.tags ? parser.prefixesToIDs(args.tags) : [],
 | 
			
		||||
        prefixes: args.prefixes ? parser.prefixesToIDs(args.prefixes) : [],
 | 
			
		||||
        sort: args.sorting ? args.sorting : "date",
 | 
			
		||||
        date: filterDate,
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,72 @@
 | 
			
		|||
"use strict";
 | 
			
		||||
 | 
			
		||||
// Modules from file
 | 
			
		||||
const shared = require("../shared.js");
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert prefixes and platform tags from string to ID and vice versa.
 | 
			
		||||
 */
 | 
			
		||||
class PrefixParser {
 | 
			
		||||
    constructor() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //#region Private methods
 | 
			
		||||
    /**
 | 
			
		||||
     * @private
 | 
			
		||||
     * Gets the key associated with a given value from a dictionary.
 | 
			
		||||
     * @param {Object} object Dictionary to search 
 | 
			
		||||
     * @param {Any} value Value associated with the key
 | 
			
		||||
     * @returns {String|undefined} Key found or undefined
 | 
			
		||||
     */
 | 
			
		||||
    _getKeyByValue(object, value) {
 | 
			
		||||
        return Object.keys(object).find(key => object[key] === value);
 | 
			
		||||
    }
 | 
			
		||||
    //#endregion Private methods
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @public
 | 
			
		||||
     * Convert a list of prefixes to their respective IDs.
 | 
			
		||||
     * @param {String[]} prefixes 
 | 
			
		||||
     */
 | 
			
		||||
    prefixesToIDs(prefixes) {
 | 
			
		||||
        const ids = [];
 | 
			
		||||
        for(const p of prefixes) {
 | 
			
		||||
            // Check what dict contains the value
 | 
			
		||||
            let dict = null;
 | 
			
		||||
            if(Object.values(shared.statuses).includes(p)) dict = shared.statuses;
 | 
			
		||||
            else if (Object.values(shared.engines).includes(p)) dict = shared.engines;
 | 
			
		||||
            else if (Object.values(shared.tags).includes(p)) dict = shared.tags;
 | 
			
		||||
            else if (Object.values(shared.others).includes(p)) dict = shared.others;
 | 
			
		||||
            else continue;
 | 
			
		||||
 | 
			
		||||
            // Extract the key from the dict
 | 
			
		||||
            const key = this._getKeyByValue(dict, p);
 | 
			
		||||
            if(key) ids.push(parseInt(key));
 | 
			
		||||
        }
 | 
			
		||||
        return ids.sort((a, b) => a - b); // JS sort alphabetically, same old problem
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @public
 | 
			
		||||
     * It converts a list of IDs into their respective prefixes.
 | 
			
		||||
     * @param {number[]} ids 
 | 
			
		||||
     */
 | 
			
		||||
    idsToPrefixes(ids) {
 | 
			
		||||
        const prefixes = [];
 | 
			
		||||
        for(const id of ids) {
 | 
			
		||||
            // Check what dict contains the key
 | 
			
		||||
            let dict = null;
 | 
			
		||||
            if (Object.keys(shared.statuses).includes(id)) dict = shared.statuses;
 | 
			
		||||
            else if (Object.keys(shared.engines).includes(id)) dict = shared.engines;
 | 
			
		||||
            else if (Object.keys(shared.tags).includes(id)) dict = shared.tags;
 | 
			
		||||
            else if (Object.keys(shared.others).includes(id)) dict = shared.others;
 | 
			
		||||
            else continue;
 | 
			
		||||
 | 
			
		||||
            // Check if the key exists in the dict
 | 
			
		||||
            if (id in dict) prefixes.push(dict[id]);
 | 
			
		||||
        }
 | 
			
		||||
        return prefixes.sort();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = PrefixParser;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,92 +0,0 @@
 | 
			
		|||
"use strict";
 | 
			
		||||
 | 
			
		||||
// Public modules from npm
 | 
			
		||||
const cheerio = require("cheerio");
 | 
			
		||||
 | 
			
		||||
// Modules from file
 | 
			
		||||
const { fetchHTML } = require("../network-helper.js");
 | 
			
		||||
const f95Selector = require("../constants/css-selector.js");
 | 
			
		||||
const { F95_LATEST_UPDATES } = require("../constants/url.js");
 | 
			
		||||
 | 
			
		||||
class TagParser {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        /**
 | 
			
		||||
         * Dictionary mapping the keys to the F95API game tags.
 | 
			
		||||
         * @type Object.<number,string>
 | 
			
		||||
         */
 | 
			
		||||
        this._tagsDict = {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //#region Private methods
 | 
			
		||||
    /**
 | 
			
		||||
     * @private
 | 
			
		||||
     * Gets the key associated with a given value from a dictionary.
 | 
			
		||||
     * @param {Object} object Dictionary to search 
 | 
			
		||||
     * @param {Any} value Value associated with the key
 | 
			
		||||
     * @returns {String|undefined} Key found or undefined
 | 
			
		||||
     */
 | 
			
		||||
    _getKeyByValue(object, value) {
 | 
			
		||||
        return Object.keys(object).find(key => object[key] === value);
 | 
			
		||||
    }
 | 
			
		||||
    //#endregion Private methods
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @public
 | 
			
		||||
     * Gets all tags, with their IDs, from F95Zone.
 | 
			
		||||
     */
 | 
			
		||||
    async fetch() {
 | 
			
		||||
        // Clean dictionary
 | 
			
		||||
        this._tagsDict = {};
 | 
			
		||||
 | 
			
		||||
        // Load the HTML
 | 
			
		||||
        const html = await fetchHTML(F95_LATEST_UPDATES);
 | 
			
		||||
        const $ = cheerio.load(html);
 | 
			
		||||
 | 
			
		||||
        // Search for the tags
 | 
			
		||||
        const unparsedText = $(f95Selector.LU_TAGS_SCRIPT).html().trim();
 | 
			
		||||
        const startIndex = unparsedText.indexOf("{");
 | 
			
		||||
        const endIndex = unparsedText.lastIndexOf("}");
 | 
			
		||||
        const parsedText = unparsedText.substring(startIndex, endIndex + 1);
 | 
			
		||||
        const data = JSON.parse(parsedText);
 | 
			
		||||
        
 | 
			
		||||
        // Extract only the data we need
 | 
			
		||||
        this._tagsDict = data.tags;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @public
 | 
			
		||||
     * Convert a list of tags to their respective IDs.
 | 
			
		||||
     * @param {String[]} tags 
 | 
			
		||||
     */
 | 
			
		||||
    tagsToIDs(tags) {
 | 
			
		||||
        const ids = [];
 | 
			
		||||
        for(const tag of tags) {
 | 
			
		||||
            // Extract the key from the value
 | 
			
		||||
            const key = this._getKeyByValue(this._tagsDict, tag);
 | 
			
		||||
            /* istanbul ignore next */
 | 
			
		||||
            if(key) ids.push(parseInt(key));
 | 
			
		||||
        }
 | 
			
		||||
        return ids.sort((a, b) => a - b); // JS sort alphabetically, same old problem
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @public
 | 
			
		||||
     * It converts a list of IDs into their respective tags.
 | 
			
		||||
     * @param {number[]} ids 
 | 
			
		||||
     */
 | 
			
		||||
    idsToTags(ids) {
 | 
			
		||||
        const tags = [];
 | 
			
		||||
        for(const id of ids) {
 | 
			
		||||
            // Check if the key exists in the dict
 | 
			
		||||
            const exist = id in this._tagsDict;
 | 
			
		||||
            /* istanbul ignore next */
 | 
			
		||||
            if (!exist) continue;
 | 
			
		||||
 | 
			
		||||
            // Save the value
 | 
			
		||||
            tags.push(this._tagsDict[id]);
 | 
			
		||||
        }
 | 
			
		||||
        return tags.sort();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = TagParser;
 | 
			
		||||
		Loading…
	
		Reference in New Issue