UNPKG

wiki-img

Version:

Easily search & download wikipedia images (Zero dependency lib)

121 lines (107 loc) 3.11 kB
import { get } from "node:https"; import { createWriteStream } from "node:fs"; import path from "node:path"; export interface Thumbnail { mimetype: string; size: null | number; width: number; height: number; duration: null | number; url: string; } export interface Page { id: number; key: string; title: string; excerpt: string; description: string; thumbnail?: Thumbnail; } interface SearchResult { pages: Array<Page>; } // //u.wiki.org/wiki/commons/thumb/2/23/elon.jpg/121px-elon.jpg const parseRawImg = (src: string) => { const splitted = src.split("/"); splitted.pop(); // we dont need the last 121px-elon splitted.splice(5, 1); // get rid of thumb return `https:${splitted.join("/")}`; // put everything back }; const saveImg = (page: Page, dir: string) => { const rawThumbUrl = parseRawImg(page.thumbnail.url); // eg image/jpeg const fileExt = page.thumbnail.mimetype.split("/")[1]; return new Promise((resolve, reject) => { const addr = new URL(rawThumbUrl); const imgreq = get( { host: addr.host, method: "GET", port: 443, path: addr.pathname, headers: { Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "User-Agent": "Mozilla/5.0 ", }, }, (res) => { if (res.statusCode == 200) { const imgPath = path.resolve(dir, `${page.key}.${fileExt}`); const fstream = createWriteStream(imgPath, { encoding: "binary", }); // res.pipe(process.stdout); res.pipe(fstream); fstream.on("error", reject); fstream.on("finish", () => { resolve(true); }); return; } reject(`Failed to get img with status ${res.statusMessage}`); } ); imgreq.end(); }); }; /** * Query and download image from wikipedia * @param {string} query - Search term for wikipedia * @param {string} dir - Relative path of image to be saved * @returns {Promise} Promise with info about the search * @example // get lady gaga image in celebs directory getWikiImg("Lady gaga", "./celebs") .then((res) => console.log(res)) .catch((err) => console.log("failed to get img", err)); */ export const getWikiImg = ( query: string, dir: string = "./" ): Promise<Page | Error> => { return new Promise((resolve, reject) => { const path = "https://api.wikimedia.org/core/v1/wikipedia/en/search"; const imgreq = get(`${path}/title?q=${query}&limit=1`); imgreq.on("response", (res) => { let body = ""; res.on("data", (d) => { body += d; }); res.on("end", async () => { const json: SearchResult = JSON.parse(body); const page = json.pages[0]; const thumb = page?.thumbnail?.url; if (!thumb) { return reject("No thumbnail found"); } try { await saveImg(page, dir); resolve(page); } catch (err) { reject(err); } }); }); }); };