Skip to content

Commit

Permalink
Move hasCoordinates to Mediawiki singleton
Browse files Browse the repository at this point in the history
  • Loading branch information
VadimKovalenkoSNF committed Aug 29, 2023
1 parent 77a064a commit 7c2bd3f
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 27 deletions.
33 changes: 9 additions & 24 deletions src/Downloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import https from 'https'
import { normalizeMwResponse, DB_ERROR, WEAK_ETAG_REGEX, stripHttpFromUrl, isBitmapImageMimeType, isImageUrl, getMimeType, isWebpCandidateImageMimeType } from './util/index.js'
import S3 from './S3.js'
import * as logger from './Logger.js'
import MediaWiki from './MediaWiki.js'
import MediaWiki, { QueryOpts } from './MediaWiki.js'
import ApiURLDirector from './util/builders/url/api.director.js'
import basicURLDirector from './util/builders/url/basic.director.js'
import urlHelper from './util/url.helper.js'
Expand Down Expand Up @@ -88,7 +88,6 @@ class Downloader {
private readonly uaString: string
private activeRequests = 0
private maxActiveRequests = 1
private hasCoordinates = true
private readonly backoffOptions: BackoffOptions
private readonly optimisationCacheUrl: string
private s3: S3
Expand Down Expand Up @@ -165,19 +164,6 @@ class Downloader {
}
}

public async checkCoordinatesAvailability(): Promise<void> {
// Coordinate fetching
const reqOpts = this.getArticleQueryOpts()

const resp = await this.getJSON<MwApiResponse>(this.apiUrlDirector.buildQueryURL(reqOpts))

const isCoordinateWarning = resp.warnings && resp.warnings.query && (resp.warnings.query['*'] || '').includes('coordinates')
if (isCoordinateWarning) {
logger.info('Coordinates not available on this wiki')
this.hasCoordinates = false
}
}

public async setBaseUrls() {
//* Objects order in array matters!
this.baseUrl = basicURLDirector.buildDownloaderBaseUrl([
Expand Down Expand Up @@ -211,9 +197,9 @@ class Downloader {

while (true) {
const queryOpts: KVS<any> = {
...this.getArticleQueryOpts(shouldGetThumbnail, true),
...(await this.getArticleQueryOpts(shouldGetThumbnail, true)),
titles: articleIds.join('|'),
...(this.hasCoordinates ? { colimit: 'max' } : {}),
...((await MediaWiki.hasCoordinates(this)) ? { colimit: 'max' } : {}),
...(MediaWiki.getCategories
? {
cllimit: 'max',
Expand Down Expand Up @@ -252,8 +238,8 @@ class Downloader {

while (true) {
const queryOpts: KVS<any> = {
...this.getArticleQueryOpts(),
...(this.hasCoordinates ? { colimit: 'max' } : {}),
...(await this.getArticleQueryOpts()),
...((await MediaWiki.hasCoordinates(this)) ? { colimit: 'max' } : {}),
...(MediaWiki.getCategories
? {
cllimit: 'max',
Expand Down Expand Up @@ -394,13 +380,12 @@ class Downloader {
if (resp.error) logger.log(`Got error from MW Query ${JSON.stringify(resp.warnings, null, '\t')}`)
}

private getArticleQueryOpts(includePageimages = false, redirects = false) {
private async getArticleQueryOpts(includePageimages = false, redirects = false): Promise<QueryOpts> {
const validNamespaceIds = MediaWiki.namespacesToMirror.map((ns) => MediaWiki.namespaces[ns].num)
const prop = `${includePageimages ? '|pageimages' : ''}${(await MediaWiki.hasCoordinates(this)) ? '|coordinates' : ''}${MediaWiki.getCategories ? '|categories' : ''}`
return {
action: 'query',
format: 'json',
prop: `redirects|revisions${includePageimages ? '|pageimages' : ''}${this.hasCoordinates ? '|coordinates' : ''}${MediaWiki.getCategories ? '|categories' : ''}`,
rdlimit: 'max',
...MediaWiki.queryOpts,
prop: MediaWiki.queryOpts.prop.concat(prop),
rdnamespace: validNamespaceIds.join('|'),
redirects: redirects ? true : undefined,
}
Expand Down
40 changes: 40 additions & 0 deletions src/MediaWiki.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ import DesktopURLDirector from './util/builders/url/desktop.director.js'
import VisualEditorURLDirector from './util/builders/url/visual-editor.director.js'
import { checkApiAvailability } from './util/mw-api.js'

export interface QueryOpts {
action: string
format: string
prop: string
rdlimit: string
rdnamespace: string | number
redirects?: boolean
}

class MediaWiki {
private static instance: MediaWiki

Expand All @@ -30,6 +39,7 @@ class MediaWiki {
public namespaces: MWNamespaces = {}
public namespacesToMirror: string[] = []
public apiCheckArticleId: string
public queryOpts: QueryOpts

#wikiPath: string
#restApiPath: string
Expand All @@ -50,6 +60,7 @@ class MediaWiki {

#hasWikimediaDesktopRestApi: boolean | null
#hasVisualEditorApi: boolean | null
#hasCoordinates: boolean | null

set username(value: string) {
this.#username = value
Expand Down Expand Up @@ -97,8 +108,18 @@ class MediaWiki {
this.#wikiPath = 'wiki/'
this.apiCheckArticleId = 'MediaWiki:Sidebar'

this.queryOpts = {
action: 'query',
format: 'json',
prop: 'redirects|revisions',
rdlimit: 'max',
rdnamespace: 0,
redirects: false,
}

this.#hasWikimediaDesktopRestApi = null
this.#hasVisualEditorApi = null
this.#hasCoordinates = null
}

private constructor() {
Expand All @@ -121,6 +142,25 @@ class MediaWiki {
return this.#hasVisualEditorApi
}

public async hasCoordinates(downloader: Downloader): Promise<boolean> {
if (this.#hasCoordinates === null) {
const validNamespaceIds = this.namespacesToMirror.map((ns) => this.namespaces[ns].num)
const reqOpts = {
...this.queryOpts,
rdnamespace: validNamespaceIds,
}

const resp = await downloader.getJSON<MwApiResponse>(this.apiUrlDirector.buildQueryURL(reqOpts))
const isCoordinateWarning = resp.warnings && resp.warnings.query && (resp.warnings.query['*'] || '').includes('coordinates')
if (isCoordinateWarning) {
logger.info('Coordinates not available on this wiki')
return (this.#hasCoordinates = false)

Check warning on line 157 in src/MediaWiki.ts

View check run for this annotation

Codecov / codecov/patch

src/MediaWiki.ts#L156-L157

Added lines #L156 - L157 were not covered by tests
}
return (this.#hasCoordinates = true)
}
return this.#hasCoordinates
}

private initMWApis() {
const baseUrlDirector = new BaseURLDirector(this.baseUrl.href)
this.webUrl = baseUrlDirector.buildURL(this.#wikiPath)
Expand Down
1 change: 1 addition & 0 deletions src/mwoffliner.lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ async function execute(argv: any) {
}

MediaWiki.apiCheckArticleId = mwMetaData.mainPage
await MediaWiki.hasCoordinates(downloader)
await MediaWiki.hasWikimediaDesktopRestApi()
await MediaWiki.hasVisualEditorApi()

Expand Down
1 change: 1 addition & 0 deletions test/unit/downloader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ describe('Downloader class', () => {
downloader = new Downloader({ uaString: `${config.userAgent} ([email protected])`, speed: 1, reqTimeout: 1000 * 60, webp: true, optimisationCacheUrl: '' })

await MediaWiki.getMwMetaData(downloader)
await MediaWiki.hasCoordinates(downloader)
await MediaWiki.hasWikimediaDesktopRestApi()
await MediaWiki.hasVisualEditorApi()
await downloader.setBaseUrls()
Expand Down
2 changes: 1 addition & 1 deletion test/unit/mwApi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ describe('mwApi', () => {
downloader = new Downloader({ uaString: `${config.userAgent} ([email protected])`, speed: 1, reqTimeout: 1000 * 60, webp: false, optimisationCacheUrl: '' })

await MediaWiki.getMwMetaData(downloader)
await MediaWiki.hasCoordinates(downloader)
await MediaWiki.hasWikimediaDesktopRestApi()
await MediaWiki.hasVisualEditorApi()
await downloader.checkCoordinatesAvailability()

await MediaWiki.getNamespaces([], downloader)
})
Expand Down
1 change: 1 addition & 0 deletions test/unit/renderers/renderer.builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ describe('RendererBuilder', () => {

it('should throw an error for unknown RendererAPI in specific mode', async () => {
const { downloader, MediaWiki } = await setupScrapeClasses() // en wikipedia
await MediaWiki.hasCoordinates(downloader)
await MediaWiki.hasWikimediaDesktopRestApi()
await MediaWiki.hasVisualEditorApi()
await downloader.setBaseUrls()
Expand Down
2 changes: 2 additions & 0 deletions test/unit/saveArticles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe('saveArticles', () => {

test('Article html processing', async () => {
const { MediaWiki, downloader, dump } = await setupScrapeClasses() // en wikipedia
await MediaWiki.hasCoordinates(downloader)
await MediaWiki.hasWikimediaDesktopRestApi()
await MediaWiki.hasVisualEditorApi()
await downloader.setBaseUrls()
Expand Down Expand Up @@ -131,6 +132,7 @@ describe('saveArticles', () => {

test('--customFlavour', async () => {
const { MediaWiki, downloader, dump } = await setupScrapeClasses({ format: 'nopic' }) // en wikipedia
await MediaWiki.hasCoordinates(downloader)
await MediaWiki.hasWikimediaDesktopRestApi()
await MediaWiki.hasVisualEditorApi()
await downloader.setBaseUrls()
Expand Down
2 changes: 1 addition & 1 deletion test/unit/urlRewriting.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@ describe('Styles', () => {
await articleDetailXId.flush()
await redisStore.redirectsXId.flush()
const { MediaWiki, downloader, dump } = await setupScrapeClasses() // en wikipedia
await MediaWiki.hasCoordinates(downloader)
await MediaWiki.hasWikimediaDesktopRestApi()
await MediaWiki.hasVisualEditorApi()
await downloader.checkCoordinatesAvailability()
await downloader.setBaseUrls()

await getArticleIds(downloader, redisStore, '', ['London', 'British_Museum', 'Natural_History_Museum,_London', 'Farnborough/Aldershot_built-up_area'])
Expand Down
2 changes: 1 addition & 1 deletion test/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ export async function setupScrapeClasses({ mwUrl = 'https://en.wikipedia.org', f
const downloader = new Downloader({ uaString: `${config.userAgent} ([email protected])`, speed: 1, reqTimeout: 1000 * 60, webp: false, optimisationCacheUrl: '' })

await MediaWiki.getMwMetaData(downloader)
await MediaWiki.hasCoordinates(downloader)
await MediaWiki.hasWikimediaDesktopRestApi()
await MediaWiki.hasVisualEditorApi()
await downloader.checkCoordinatesAvailability()

const dump = new Dump(format, {} as any, MediaWiki.metaData)

Expand Down

0 comments on commit 7c2bd3f

Please sign in to comment.