mirror of
				https://scm.univ-tours.fr/22107988t/rappaurio-sae501_502.git
				synced 2025-11-04 13:45:21 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			212 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			212 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import { api } from './util.js';
 | 
						|
const processors = {
 | 
						|
    extracts: data => {
 | 
						|
        return { extract: data.extract };
 | 
						|
    },
 | 
						|
    links: data => {
 | 
						|
        return { links: data.links.map(e => e.title) };
 | 
						|
    },
 | 
						|
    extlinks: data => {
 | 
						|
        return { extlinks: data.extlinks.map(e => e['*']) };
 | 
						|
    },
 | 
						|
    langlinks: data => {
 | 
						|
        return {
 | 
						|
            langlinks: data.langlinks.map(link => {
 | 
						|
                return {
 | 
						|
                    lang: link.lang,
 | 
						|
                    title: link['*'],
 | 
						|
                    url: link.url
 | 
						|
                };
 | 
						|
            })
 | 
						|
        };
 | 
						|
    },
 | 
						|
    coordinates: data => {
 | 
						|
        if (data.coordinates) {
 | 
						|
            return { coordinates: data.coordinates[0] };
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            return {};
 | 
						|
        }
 | 
						|
    },
 | 
						|
    categories: data => {
 | 
						|
        return { categories: data.categories.map(e => e.title) };
 | 
						|
    },
 | 
						|
    pageimages: data => {
 | 
						|
        return {
 | 
						|
            image: {
 | 
						|
                name: data.pageimage,
 | 
						|
                thumbnail: data.thumbnail,
 | 
						|
                original: data.original
 | 
						|
            }
 | 
						|
        };
 | 
						|
    }
 | 
						|
};
 | 
						|
function process(props, rawPageData) {
 | 
						|
    const data = { title: rawPageData.title };
 | 
						|
    return props.reduce((memo, prop) => {
 | 
						|
        if (processors[prop])
 | 
						|
            Object.assign(memo, processors[prop](rawPageData));
 | 
						|
        return memo;
 | 
						|
    }, data);
 | 
						|
}
 | 
						|
/**
 | 
						|
 * Chain API requests together
 | 
						|
 * @example
 | 
						|
 * // Get page summary and images in same request
 | 
						|
 * wiki.page('batman').then(page => page.chain().summary().image().request()).then(console.log);
 | 
						|
 * @namespace QueryChain
 | 
						|
 */
 | 
						|
export default class QueryChain {
 | 
						|
    constructor(apiOptions, id) {
 | 
						|
        this.id = id;
 | 
						|
        this.apiOptions = apiOptions;
 | 
						|
        this._params = { pageids: id };
 | 
						|
        this.props = new Set();
 | 
						|
    }
 | 
						|
    params() {
 | 
						|
        const prop = [...this.props].join('|');
 | 
						|
        return Object.assign({}, this._params, { prop });
 | 
						|
    }
 | 
						|
    direct(key, ...args) {
 | 
						|
        return this[key](...args)
 | 
						|
            .request()
 | 
						|
            .then(res => res[key]);
 | 
						|
    }
 | 
						|
    // TODO: Add page searches for root calls - generators
 | 
						|
    // TODO: Add pagination helper method
 | 
						|
    /**
 | 
						|
     * Make combined API request
 | 
						|
     * @method QueryChain#request
 | 
						|
     * @returns {Object|Array} - Data object(s) depending on where the chain was created from
 | 
						|
     */
 | 
						|
    request() {
 | 
						|
        const props = [...this.props];
 | 
						|
        return api(this.apiOptions, this.params())
 | 
						|
            .then(res => {
 | 
						|
            if (this.id) {
 | 
						|
                return res.query.pages[this.id];
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                return Object.values(res.query.pages);
 | 
						|
            }
 | 
						|
        })
 | 
						|
            .then(data => {
 | 
						|
            if (Array.isArray(data)) {
 | 
						|
                return data.map(e => process(props, e));
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                return process(props, data);
 | 
						|
            }
 | 
						|
        });
 | 
						|
    }
 | 
						|
    chain(prop, params = {}) {
 | 
						|
        if (prop) {
 | 
						|
            this.props.add(prop);
 | 
						|
        }
 | 
						|
        Object.assign(this._params, params);
 | 
						|
        return this;
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * @summary Finds pages near a specific point
 | 
						|
     * @method QueryChain#geosearch
 | 
						|
     * @returns {QueryChain}
 | 
						|
     */
 | 
						|
    geosearch(latitude, longitude, radius) {
 | 
						|
        return this.chain(undefined, {
 | 
						|
            generator: 'geosearch',
 | 
						|
            ggsradius: radius,
 | 
						|
            ggscoord: `${latitude}|${longitude}`
 | 
						|
        });
 | 
						|
    }
 | 
						|
    search(query, limit = 50) {
 | 
						|
        return this.chain(undefined, {
 | 
						|
            list: 'search',
 | 
						|
            srsearch: query,
 | 
						|
            srlimit: limit
 | 
						|
        });
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * @summary Useful for extracting structured section content
 | 
						|
     * @method QueryChain#content
 | 
						|
     * @returns {QueryChain}
 | 
						|
     */
 | 
						|
    content() {
 | 
						|
        return this.chain('extracts', {
 | 
						|
            explaintext: '1'
 | 
						|
        });
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * @summary Useful for extracting summary content
 | 
						|
     * @method QueryChain#summary
 | 
						|
     * @returns {QueryChain}
 | 
						|
     */
 | 
						|
    summary() {
 | 
						|
        return this.chain('extracts', {
 | 
						|
            explaintext: '1',
 | 
						|
            exintro: '1'
 | 
						|
        });
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * @summary Extract image
 | 
						|
     * @method QueryChain#image
 | 
						|
     * @returns {QueryChain}
 | 
						|
     */
 | 
						|
    image(types = { thumbnail: true, original: false, name: true }) {
 | 
						|
        return this.chain('pageimages', {
 | 
						|
            piprop: Object.keys(types)
 | 
						|
                .filter(k => types[k])
 | 
						|
                .join('|')
 | 
						|
        });
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * @summary Extract external links
 | 
						|
     * @method QueryChain#extlinks
 | 
						|
     * @returns {QueryChain}
 | 
						|
     */
 | 
						|
    extlinks() {
 | 
						|
        return this.chain('extlinks', {
 | 
						|
            ellimit: 'max'
 | 
						|
        });
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * @summary Extract page links
 | 
						|
     * @method QueryChain#links
 | 
						|
     * @returns {QueryChain}
 | 
						|
     */
 | 
						|
    links(limit = 100) {
 | 
						|
        return this.chain('links', {
 | 
						|
            plnamespace: 0,
 | 
						|
            pllimit: limit
 | 
						|
        });
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * @summary Extract categories
 | 
						|
     * @method QueryChain#categories
 | 
						|
     * @returns {QueryChain}
 | 
						|
     */
 | 
						|
    categories(limit = 100) {
 | 
						|
        return this.chain('categories', {
 | 
						|
            pllimit: limit
 | 
						|
        });
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * @summary Extract coordinates
 | 
						|
     * @method QueryChain#coordinates
 | 
						|
     * @returns {QueryChain}
 | 
						|
     */
 | 
						|
    coordinates() {
 | 
						|
        return this.chain('coordinates');
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * @summary Get list of links to different translations
 | 
						|
     * @method QueryChain#langlinks
 | 
						|
     * @returns {QueryChain}
 | 
						|
     */
 | 
						|
    langlinks() {
 | 
						|
        return this.chain('langlinks', {
 | 
						|
            lllimit: 'max',
 | 
						|
            llprop: 'url'
 | 
						|
        });
 | 
						|
    }
 | 
						|
}
 |