Move meta-information to MediaWiki object
This commit is contained in:
parent
9138636c03
commit
57a0913f6f
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "interlanguage-checker",
|
||||
"version": "1.6.0",
|
||||
"version": "1.7.0",
|
||||
"description": "Check the consistency of MediaWiki interlanguage links in a simple overview.",
|
||||
"author": "Felix W. Dekker",
|
||||
"browser": "bundle.js",
|
||||
|
|
|
@ -52,7 +52,7 @@ doAfterLoad(async () => {
|
|||
messageHandler.handle("progress", `Initializing <code>${urlInput.getValue()}</code>`);
|
||||
|
||||
try {
|
||||
const mw = new MediaWiki(urlInput.getValue());
|
||||
const mw = await new MediaWiki(urlInput.getValue()).init();
|
||||
mwm = await new MediaWikiManager().init(mw);
|
||||
} catch (error) {
|
||||
messageHandler.handle("error", error);
|
||||
|
|
|
@ -76,37 +76,38 @@ export class Redirect {
|
|||
/**
|
||||
* A map of interwiki links.
|
||||
*
|
||||
* @property map {Object.<string, string>} maps interwiki abbreviations to URLs
|
||||
* @property map {Array<{prefix: string, url: string}>} maps interwiki abbreviations to URLs
|
||||
*/
|
||||
export class InterwikiMap {
|
||||
/**
|
||||
* Constructs a new interwiki map.
|
||||
*
|
||||
* @param map {Object.<string, string>} the mapping from interwiki abbreviations to URLs to store in this map
|
||||
* @param map {Array<{prefix: string, url: string}>} the mapping from interwiki abbreviations to URLs to store in
|
||||
* this map
|
||||
*/
|
||||
constructor(map) {
|
||||
this.map = Object.assign({}, map);
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the URL for the given abbreviation, or `undefined` if the abbreviation could not be found.
|
||||
* Returns the URL for the given prefix, or `undefined` if the prefix could not be found.
|
||||
*
|
||||
* @param abbr {string} the abbreviation to return the URL of
|
||||
* @returns {string} the URL for the given abbreviation, or `undefined` if the abbreviation could not be found
|
||||
* @param prefix {string} the prefix to return the URL of
|
||||
* @returns {string} the URL for the given prefix, or `undefined` if the prefix could not be found
|
||||
*/
|
||||
getUrl(abbr) {
|
||||
return this.map[abbr];
|
||||
getUrl(prefix) {
|
||||
return this.map.find(it => it.prefix === prefix).url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if and only if this map has a URL for the given abbreviation.
|
||||
* Returns `true` if and only if this map has a URL for the given prefix.
|
||||
*
|
||||
* @param abbr {string} the abbreviation to check for
|
||||
* @returns {boolean} `true` if and only if this map has a URL for the given abbreviation
|
||||
* @param prefix {string} the prefix to check for
|
||||
* @returns {boolean} `true` if and only if this map has a URL for the given prefix
|
||||
*/
|
||||
hasUrl(abbr) {
|
||||
return this.map[abbr] !== undefined;
|
||||
hasUrl(prefix) {
|
||||
return this.map.find(it => it.prefix === prefix) !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,13 +117,13 @@ export class InterwikiMap {
|
|||
* @return a new `InterwikiMap` with all entries from both this map and the given map
|
||||
*/
|
||||
mergeWith(other) {
|
||||
const conflicts = Object.keys(this.map)
|
||||
.filter(key => other.map.hasOwnProperty(key))
|
||||
.filter(key => this.map[key] !== other.map[key]);
|
||||
if (conflicts.length !== 0)
|
||||
const conflicts = this.map
|
||||
.filter(({prefix}) => other.hasUrl(prefix))
|
||||
.filter(({prefix, url}) => url !== other.getUrl(prefix));
|
||||
if (conflicts.length > 0)
|
||||
console.warn("iw map merge conflict(s)", conflicts);
|
||||
|
||||
return new InterwikiMap(Object.assign({}, this.map, other.map));
|
||||
return new InterwikiMap(this.map.concat(other.map));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,7 +268,7 @@ export class InterlangNetwork {
|
|||
return mergeStates(state, newStatus);
|
||||
}, "present");
|
||||
|
||||
switch(state) {
|
||||
switch (state) {
|
||||
case "present":
|
||||
return "complete";
|
||||
case "absent":
|
||||
|
@ -286,6 +287,9 @@ export class InterlangNetwork {
|
|||
*
|
||||
* @property baseUrl {string} the origin of the wiki's API
|
||||
* @property apiPath {string} the path relative to the wiki's API; starts with a `/`
|
||||
* @property general {Object} the general information, retrieved from the API
|
||||
* @property interwikiMap {InterwikiMap} the interwiki map of this wiki
|
||||
* @property namespaces {Object[]} the namespaces on this wiki
|
||||
*/
|
||||
export class MediaWiki {
|
||||
/**
|
||||
|
@ -299,6 +303,20 @@ export class MediaWiki {
|
|||
this.apiPath = urlObj.pathname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this `MediaWiki` object with the necessary information from the API.
|
||||
*
|
||||
* @returns {MediaWiki} this `MediaWiki` object
|
||||
*/
|
||||
async init() {
|
||||
const query = await this.getSiteInfo("general", "interwikimap", "namespaces");
|
||||
this.general = query.general;
|
||||
this.interwikiMap = new InterwikiMap(query.interwikimap);
|
||||
this.namespaces = query.namespaces;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a request to the MediaWiki API and runs the given callback on the response.
|
||||
|
@ -358,30 +376,14 @@ export class MediaWiki {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns this wiki's general information.
|
||||
* Returns this wiki's site information.
|
||||
*
|
||||
* @return {Object} this wiki's general information
|
||||
* @param props {...string} the site information properties to retrieve, such as "general" or "interwikimap"
|
||||
* @returns {Object} the wiki's site information, with each property corresponding to an argument to this method
|
||||
*/
|
||||
getGeneralInfo() {
|
||||
return this.request({action: "query", meta: "siteinfo", siprop: "general"})
|
||||
.then(response => response.query.general);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests this wiki's interwiki map.
|
||||
*
|
||||
* @return {Promise<InterwikiMap>} this wiki's interwiki map
|
||||
*/
|
||||
getIwMap() {
|
||||
return this
|
||||
.request({action: "query", meta: "siteinfo", siprop: "interwikimap"})
|
||||
.then(response =>
|
||||
response.query.interwikimap.reduce((map, mapping) => {
|
||||
map[mapping["prefix"]] = mapping["url"];
|
||||
return map;
|
||||
}, {})
|
||||
)
|
||||
.then(map => new InterwikiMap(map));
|
||||
getSiteInfo(...props) {
|
||||
return this.request({action: "query", meta: "siteinfo", siprop: props.join("|")})
|
||||
.then(response => response.query);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,7 +403,7 @@ export class MediaWikiManager {
|
|||
*/
|
||||
constructor() {
|
||||
this.mws = {};
|
||||
this._iwMap = new InterwikiMap({});
|
||||
this._iwMap = new InterwikiMap([]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -411,18 +413,16 @@ export class MediaWikiManager {
|
|||
* @return {MediaWikiManager} this `MediaWikiManager`
|
||||
*/
|
||||
async init(baseMw) {
|
||||
const general = await baseMw.getGeneralInfo();
|
||||
|
||||
this.basePath = [...(baseMw.apiPath)]
|
||||
.map((it, i) => it === general.articlepath[i] ? it : "")
|
||||
.map((it, i) => it === baseMw.general.articlepath[i] ? it : "")
|
||||
.join("")
|
||||
.slice(0, -1);
|
||||
this.articlePath = general.articlepath.slice(this.basePath.length);
|
||||
this.articlePath = baseMw.general.articlepath.slice(this.basePath.length);
|
||||
this.apiPath = baseMw.apiPath.slice(this.basePath.length);
|
||||
this.baseLang = general.lang;
|
||||
this.baseLang = baseMw.general.lang;
|
||||
|
||||
this.mws[general.lang] = baseMw;
|
||||
await this._importIwMap(baseMw);
|
||||
this.mws[baseMw.general.lang] = baseMw;
|
||||
this._updateIwMap();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@ -443,8 +443,8 @@ export class MediaWikiManager {
|
|||
return undefined;
|
||||
|
||||
const url = this._iwMap.getUrl(lang);
|
||||
this.mws[lang] = new MediaWiki(url.slice(0, -this.articlePath.length) + this.apiPath);
|
||||
await this._importIwMap(this.mws[lang]);
|
||||
this.mws[lang] = await new MediaWiki(url.slice(0, -this.articlePath.length) + this.apiPath).init();
|
||||
this._updateIwMap();
|
||||
|
||||
return this.mws[lang];
|
||||
}
|
||||
|
@ -471,13 +471,11 @@ export class MediaWikiManager {
|
|||
|
||||
|
||||
/**
|
||||
* Imports the interwiki map from the given wiki, fetching it from the server and merging it into this manager's
|
||||
* main interwiki map.
|
||||
*
|
||||
* @param mw {MediaWiki} the `MediaWiki` to import the interwiki map of
|
||||
* Updates the `_iwMap` property with the entries in `MediaWiki` instances in this manager.
|
||||
*/
|
||||
async _importIwMap(mw) {
|
||||
this._iwMap = this._iwMap.mergeWith(await mw.getIwMap());
|
||||
_updateIwMap() {
|
||||
const maps = Object.keys(this.mws).map(key => this.mws[key].interwikiMap.map);
|
||||
this._iwMap = new InterwikiMap([].concat(...maps));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue