Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/macbre/nodemw

MediaWiki API and WikiData client written in Node.js
https://github.com/macbre/nodemw

bot fandom-wiki javascript mediawiki mediawiki-api nodejs nodemw wikia-api wikidata

Last synced: 3 days ago
JSON representation

MediaWiki API and WikiData client written in Node.js

Awesome Lists containing this project

README

        

# nodemw

![Node.js CI](https://github.com/macbre/nodemw/workflows/Node.js%20CI/badge.svg)
[![Coverage Status](https://coveralls.io/repos/github/macbre/nodemw/badge.svg?branch=devel)](https://coveralls.io/github/macbre/nodemw?branch=devel)
![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)

[MediaWiki API](https://www.mediawiki.org/wiki/API:Main_page) client written in node.js

## Requirements

- At minimum [Node.js at the maintenance version](https://github.com/nodejs/release#release-schedule)

## Installation

### Using npm

```bash
npm install nodemw
```

Or [Download the latest stable version](https://github.com/macbre/nodemw/releases) via GitHub.

### Development version

```bash
git clone https://github.com/macbre/nodemw.git
```

## Features

- HTTP requests are stored in the queue and performed in parallel with limited number of "threads" (i.e. there's no risk of flooding the server)
- articles creation / edit / move / delete
- file uploads (using given content or via provided URL)
- Special:Log processing
- listing articles in categories
- and much more
- getting claims from [WikiData](https://www.wikidata.org/wiki/Wikidata:Introduction)

## Where it's used

- Over 10k edits on [Poznań Wiki](http://poznan.wikia.com) as [Pyrabot](http://poznan.wikia.com/wiki/Specjalna:Wkład/Pyrabot) - [scripts repository](https://github.com/macbre/pyrabot)

## First script

An example script can be found in `/examples` directory.

```bash
cd examples
node pagesInCategory.js
```

You can enter **debug mode** by setting `DEBUG` enviromental variable:

```bash
DEBUG=1 node examples/pagesInCategory.js
```

You can enter **dry-run mode** (all "write" operations like edits and uploads will be disabled) by setting `DRY_RUN` environmental variable (or `dryRun` entry in the config):

```bash
DRY_RUN=1 node examples/pagesInCategory.js
```

## Running unit tests

```bash
npm test
```

## How to use it?

### Creating a bot instance

```js
var bot = require("nodemw");

// pass configuration object
var client = new bot({
protocol: "https", // Wikipedia now enforces HTTPS
server: "en.wikipedia.org", // host name of MediaWiki-powered site
path: "/w", // path to api.php script
debug: false, // is more verbose when set to true
});

client.getArticle("foo", function (err, data) {
// error handling
if (err) {
console.error(err);
return;
}

// ...
});
```

#### Config file

nodemw can use config files as well as objects directly provided to `bot` object constructor.

```js
// read config from external file
var client = new bot("config.js");
```

Config file is a JSON-encoded object with the following fields (see `/examples/config-DIST.js` file):

```js
{
"protocol": "https", // default to 'http'
"server": "en.wikipedia.org", // host name of MediaWiki-powered site
"path": "/w", // path to api.php script
"debug": false, // is more verbose when set to true
"username": "foo", // account to be used when logIn is called (optional)
"password": "bar", // password to be used when logIn is called (optional)
"domain" : "auth.bar.net", // domain to be used when logIn is called (optional)
"userAgent": "Custom UA", // define custom bot's user agent
"concurrency": 5 // how many API requests can be run in parallel (defaults to 3)
}
```

## Making direct API calls

nodemw allows you make direct calls to MediaWiki API ([example querying Semantic MediaWiki API](https://github.com/macbre/nodemw/blob/master/examples/smw.js)):

```js
var bot = require("nodemw"),
client = new bot({
server: "semantic-mediawiki.org",
path: "/w",
}),
params = {
action: "ask",
query:
"[[Modification date::+]]|?Modification date|sort=Modification date|order=desc",
};

client.api.call(
params /* api.php parameters */,
function (
err /* Error instance or null */,
info /* processed query result */,
next /* more results? */,
data /* raw data */,
) {
console.log(data && data.query && data.query.results);
},
);
```

## Bot methods

The last parameter of each function in nodemw API is a callback which will be fired when the requested action is done.

**Callbacks use node.js style** - `err` is always passed as the first argument.

### bot.logIn(username, password, callback)

Log-in using given credentials - [read more](http://www.mediawiki.org/wiki/API:Login)

### bot.getCategories(prefix, callback)

Gets the list of all categories on a wiki

### bot.getAllPages(callback)

Gets the list of all pages from the main namespace (excludes redirects) - [read more](https://www.mediawiki.org/wiki/API:Allpages)

### bot.getPagesInCategory(category, callback)

Gets the list of pages in a given category - [read more](http://www.mediawiki.org/wiki/API:Properties#revisions_.2F_rv)

### bot.getPagesInNamespace(namespace, callback)

Gets the list of pages in a given namespace - [read more](http://www.mediawiki.org/wiki/API:Allpages)

### bot.getPagesByPrefix(prefix, callback)

Gets the list of pages by a given prefix - [read more](https://www.mediawiki.org/wiki/API:Allpages)

### bot.getPagesTranscluding(page, callback)

Gets the list of pages that transclude the given pages - [read more](https://www.mediawiki.org/wiki/API:Transcludedin)

### bot.getArticle(title, [redirect,] callback)

Gets article content and redirect info - [read more](https://www.mediawiki.org/wiki/API:Query#Resolving_redirects)

### bot.getArticleRevisions(title, callback)

Gets all revisions of a given article - [read more](http://www.mediawiki.org/wiki/API:Revisions)

### bot.getArticleCategories(title, callback)

Gets all categories a given article is in - [read more](http://www.mediawiki.org/wiki/API:Property/Categories)

### bot.getArticleInfo(title, callback)

Gets all info of a given article - [read more](https://www.mediawiki.org/wiki/API:Info)

### bot.edit(title, content, summary, minor, callback)

Creates / edits an article (and mark the edit as minor if _minor_ is set to true) - [read more](http://www.mediawiki.org/wiki/API:Edit)

### bot.append(title, content, summary, callback)

Adds given content to the end of the page - [read more](http://www.mediawiki.org/wiki/API:Edit)

### bot.prepend(title, content, summary, callback)

Adds given content to the beginning of the page - [read more](http://www.mediawiki.org/wiki/API:Edit)

### bot.addFlowTopic(title, topic, content, callback)

Add a Flow topic - [read more](http://www.mediawiki.org/wiki/API:Flow)

### bot.delete(title, reason, callback)

Deletes an article - [read more](http://www.mediawiki.org/wiki/API:Delete)

### bot.purge(titles, callback)

Purge a given list of articles (titles or page IDs can be provided) - [read more](https://www.mediawiki.org/wiki/API:Purge)

> By providing `Category:Foo` as `titles` argument you can purge all pages in a given category (available since [MW 1.21](https://github.com/wikimedia/mediawiki/commit/62216932c197f1c248ca2d95bc230f87a79ccd71))

### bot.protect(title, protections, options, callback)

Protect a page (A title or page ID can be provided) - [read more](https://www.mediawiki.org/wiki/API:Protect)

The `protections` value is an Array of protection information in the format:

```
{
action: string,
level?: string = 'all',
expiry?: string | number = 'never'
}
```

Calls to the Protect endpoint are not additive. Each call must include a list of _all_ intended protections, including any already in place. Each call will _replace_ all existing protections.

### bot.sendEmail(username, subject, text, callback)

Send an email to an user - [read more](http://www.mediawiki.org/wiki/API:Email)

### bot.getToken(title, action, callback)

Returns token required for a number of MediaWiki API operations - [read more]() / [for MW 1.24+](https://www.mediawiki.org/wiki/API:Tokens)

### bot.whoami(callback)

Gets information about current bot's user (including rights and rate limits) - [read more](http://www.mediawiki.org/wiki/API:Meta#userinfo_.2F_ui)

### bot.whois(username, callback)

Gets information about a specific user (including rights, current block, groups) - [read more](https://www.mediawiki.org/wiki/API:Users)

### bot.whoare(usernames, callback)

Gets information about specific users (including rights, current block, groups) - [read more](https://www.mediawiki.org/wiki/API:Users)

### bot.createAccount(username, password, callback)

Create account using given credentials - [read more](https://www.mediawiki.org/wiki/API:Account_creation)

### bot.move(from, to, summary, callback)

Moves (aka renames) given article - [read more](http://www.mediawiki.org/wiki/API:Move)

### bot.getImages(callback)

Gets list of all images on a wiki

### bot.getImageUsage(filename, callback)

Gets list of all articles using given image

### bot.getImagesFromArticle(title, callback)

Get list of all images that are used on a given page - [read more](http://www.mediawiki.org/wiki/API:Properties#images_.2F_im)

### bot.getImageInfo(filename, callback)

Gets metadata (including uploader, size, dimensions and EXIF data) of given image

### bot.getLog(type, start, callback)

Get entries form Special:Log - [read more](http://www.mediawiki.org/wiki/API:Logevents)

### bot.expandTemplates(content, title, callback)

Returns XML with preprocessed wikitext - [read more](https://www.mediawiki.org/wiki/API:Parsing_wikitext#expandtemplates)

### bot.parse(content, title, callback)

Returns parsed wikitext - [read more](https://www.mediawiki.org/wiki/API:Parsing_wikitext#parse)

### bot.fetchUrl(url, callback)

Makes a GET request to provided resource and returns its content.

### bot.getRecentChanges(start, callback)

Returns entries from recent changes (starting from a given point)

### bot.getSiteInfo(props, callback)

Returns site information entries - [read more](http://www.mediawiki.org/wiki/API:Siteinfo)

### bot.getSiteStats(props, callback)

Returns site statistics (number of articles, edits etc) - [read more](http://www.mediawiki.org/wiki/API:Siteinfo)

### bot.getMediaWikiVersion(callback)

Returns the version of MediaWiki given site uses - [read more](http://www.mediawiki.org/wiki/API:Siteinfo)

### client.getQueryPage(queryPage, callback)

Returns entries from [QueryPage-based special pages](http://www.mediawiki.org/wiki/API:Querypage)

### bot.upload(filename, content, summary _/* or extraParams */_, callback)

Uploads a given raw content as a File:[filename] - [read more](http://www.mediawiki.org/wiki/API:Upload)

### bot.uploadByUrl(filename, url, summary _/* or extraParams */_, callback)

Uploads a given external resource as a File:[filename]

### bot.uploadVideo(fileName, url, callback)

Uploads a given video as a File:[filename] (Wikia-specific API)

### bot.getTemplateParamFromXml(tmplXml, paramName)

Gets a value of a given template parameter from article's preparsed content (see expandTemplates)

### bot.getExternalLinks(title, callback)

Gets all external links used in article

### bot.getBacklinks(title, callback)

Gets all articles that links to given article

### bot.search(query, callback)

Performs a search

## Helpers

### bot.getConfig(key, def)

Gets config entry value (returns `def` value if not found)

### bot.setConfig(key, val)

Sets config entry value

### bot.diff(old, current)

Returns a diff colored using ANSI colors (powered by [diff](https://www.npmjs.com/package/diff))

## [Wikia-specific](https://community.fandom.com/api/v1) bot methods

> They're grouped in `bot.wikia` "namespace".

### bot.wikia.getWikiVariables(callback)

Get wiki-specific settings (like ThemeDesigner colors and hubs).

### bot.wikia.getUser(userId, callback)

Get information (avatar, number of edits) about a given user

### bot.wikia.getUsers(userIds, callback)

Get information (avatar, number of edits) about a given set of users (by their IDs)

## [WikiData](https://www.wikidata.org/wiki/Wikidata:Introduction)

This API is Promise-based, use `await` keyword.

Examples:

```js
const wikidata = require("nodemw/lib/wikidata");
const client = new wikidata();

// Where is Saksun, Faroe Islands located?
const geo = await client.getEntityClaim(
"Q928875" /* Saksun */,
"P625" /* place location */,
);

// will give you the geolocation of the place
expect(geo[0].mainsnak.datavalue.value).toMatchObject({
latitude: 62.248888888889,
longitude: -7.1758333333333,
});

// When was Albert Einstein born?
const res = await client.getArticleClaims("Albert Einstein");

const dateOfBirth = res.P569[0].mainsnak.datavalue.value;
expect(dateOfBirth.time).toMatch(/1879-03-14/);

const dateOfDeath = res.P570[0].mainsnak.datavalue.value;
expect(dateOfDeath.time).toMatch(/1955-04-18/);

// interwiki links for a given artlice
const links = await client.getArticleSitelinks("Albert Einstein");
console.log(links.enwiki); // {site: "enwiki", title: "Albert Einstein", badges: ["Q17437798"]}
```

##

##

## Stargazers over time

[![Stargazers over time](https://starchart.cc/macbre/nodemw.svg)](https://starchart.cc/macbre/nodemw)