Skip to content

Commit

Permalink
Refactor Renderer builder, replace types and interfaces to the Abstra…
Browse files Browse the repository at this point in the history
…ct renderer
  • Loading branch information
VadimKovalenkoSNF committed Aug 21, 2023
1 parent 14fd7a4 commit 22f322d
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 63 deletions.
14 changes: 2 additions & 12 deletions src/Downloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,6 @@ interface BackoffOptions {
backoffHandler: (number: number, delay: number, error?: any) => void
}

export interface RenderOpts {
data?: any
articleId?: string
articleDetailXId?: RKVS<ArticleDetail>
articleDetail?: ArticleDetail | string
isMainPage?: boolean
}

export const defaultStreamRequestOptions: AxiosRequestConfig = {
headers: {
accept: 'application/octet-stream',
Expand Down Expand Up @@ -329,15 +321,13 @@ class Downloader {
throw data.error

Check warning on line 321 in src/Downloader.ts

View check run for this annotation

Codecov / codecov/patch

src/Downloader.ts#L321

Added line #L321 was not covered by tests
}

const renderOpts: RenderOpts = {
return articleRenderer.render({
data,
articleId,
articleDetailXId,
articleDetail,
isMainPage,
}

return articleRenderer.render(renderOpts)
})
}

public async getJSON<T>(_url: string): Promise<T> {
Expand Down
28 changes: 27 additions & 1 deletion src/util/renderers/abstract.renderer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@
import { RenderOpts } from './../../Downloader.js'
type renderType = 'auto' | 'desktop' | 'mobile' | 'specific'
type renderName = 'VisualEditor' | 'WikimediaDesktop' | 'WikimediaMobile'

interface RendererBuilderOptionsBase {
renderType: renderType
}

interface RendererBuilderOptionsCommon {
renderType: renderType
renderName?: never
}

interface RendererBuilderOptionsSpecific extends RendererBuilderOptionsBase {
renderType: 'specific'
renderName: renderName
}

export type RendererBuilderOptions = RendererBuilderOptionsCommon | RendererBuilderOptionsSpecific

export interface RenderOpts {
data?: any
articleId?: string
articleDetailXId?: RKVS<ArticleDetail>
articleDetail?: ArticleDetail | string
isMainPage?: boolean
}

export abstract class Renderer {
abstract render(renderOpts: RenderOpts): Promise<any>
}
24 changes: 9 additions & 15 deletions src/util/renderers/renderer.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,24 @@ import MediaWiki from './../../MediaWiki.js'
import { Renderer } from './abstract.renderer.js'
import { VisualEditorRenderer } from './visual-editor.renderer.js'
import { WikimediaDesktopRenderer } from './wikimedia-desktop.renderer.js'
import { RendererBuilderOptions } from './../saveArticles.js'
import { RendererBuilderOptions } from './abstract.renderer.js'
import * as logger from './../../Logger.js'

export class RendererBuilder {
private renderApi: 'VisualEditor' | 'WikimediaDesktop' | 'WikimediaMobile'
private renderMode: 'auto' | 'desktop' | 'mobile' | 'specific'

public async createRenderer(options: RendererBuilderOptions): Promise<Renderer> {
const { RendererMode, RendererAPI } = options

this.renderMode = RendererMode
this.renderApi = RendererAPI
const { renderType, renderName } = options

const [hasVisualEditorApi, hasWikimediaDesktopRestApi] = await Promise.all([MediaWiki.hasVisualEditorApi(), MediaWiki.hasWikimediaDesktopRestApi()])

switch (this.renderMode) {
switch (renderType) {
case 'desktop':

Check warning on line 15 in src/util/renderers/renderer.builder.ts

View check run for this annotation

Codecov / codecov/patch

src/util/renderers/renderer.builder.ts#L15

Added line #L15 was not covered by tests
if (hasWikimediaDesktopRestApi) {
// Choose WikimediaDesktopRenderer if it's present, regardless of hasVisualEditorApi value
return new WikimediaDesktopRenderer()

Check warning on line 18 in src/util/renderers/renderer.builder.ts

View check run for this annotation

Codecov / codecov/patch

src/util/renderers/renderer.builder.ts#L18

Added line #L18 was not covered by tests
} else if (hasVisualEditorApi) {
return new VisualEditorRenderer()
} else {
logger.error('No available renderer for desktop mode.')
logger.error('No available desktop renderer.')
process.exit(1)

Check warning on line 23 in src/util/renderers/renderer.builder.ts

View check run for this annotation

Codecov / codecov/patch

src/util/renderers/renderer.builder.ts#L20-L23

Added lines #L20 - L23 were not covered by tests
}
case 'mobile':

Check warning on line 25 in src/util/renderers/renderer.builder.ts

View check run for this annotation

Codecov / codecov/patch

src/util/renderers/renderer.builder.ts#L25

Added line #L25 was not covered by tests
Expand All @@ -38,12 +32,12 @@ export class RendererBuilder {
} else if (hasVisualEditorApi) {
return new VisualEditorRenderer()
} else {
logger.error('No available renderer for auto mode.')
logger.error('No render available at all.')
process.exit(1)

Check warning on line 36 in src/util/renderers/renderer.builder.ts

View check run for this annotation

Codecov / codecov/patch

src/util/renderers/renderer.builder.ts#L34-L36

Added lines #L34 - L36 were not covered by tests
}
case 'specific':

Check warning on line 38 in src/util/renderers/renderer.builder.ts

View check run for this annotation

Codecov / codecov/patch

src/util/renderers/renderer.builder.ts#L38

Added line #L38 was not covered by tests
// renderApi argument is required for 'specific' mode
switch (this.renderApi) {
// renderName argument is required for 'specific' mode
switch (renderName) {
case 'WikimediaDesktop':

Check warning on line 41 in src/util/renderers/renderer.builder.ts

View check run for this annotation

Codecov / codecov/patch

src/util/renderers/renderer.builder.ts#L41

Added line #L41 was not covered by tests
if (hasWikimediaDesktopRestApi) {
return new WikimediaDesktopRenderer()

Check warning on line 43 in src/util/renderers/renderer.builder.ts

View check run for this annotation

Codecov / codecov/patch

src/util/renderers/renderer.builder.ts#L43

Added line #L43 was not covered by tests
Expand All @@ -60,10 +54,10 @@ export class RendererBuilder {
// TODO: return WikimediaMobile renderer
return
default:
throw new Error(`Unknown RendererAPI for specific mode: ${this.renderApi}`)
throw new Error(`Unknown renderName for specific mode: ${renderName}`)

Check warning on line 57 in src/util/renderers/renderer.builder.ts

View check run for this annotation

Codecov / codecov/patch

src/util/renderers/renderer.builder.ts#L55-L57

Added lines #L55 - L57 were not covered by tests
}
default:
throw new Error(`Unknown render mode: ${this.renderMode}`)
throw new Error(`Unknown render: ${renderType}`)

Check warning on line 60 in src/util/renderers/renderer.builder.ts

View check run for this annotation

Codecov / codecov/patch

src/util/renderers/renderer.builder.ts#L59-L60

Added lines #L59 - L60 were not covered by tests
}
}
}
2 changes: 1 addition & 1 deletion src/util/renderers/visual-editor.renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DELETED_ARTICLE_ERROR } from '../const.js'
import * as logger from '../../Logger.js'
import { Renderer } from './abstract.renderer.js'
import { getStrippedTitleFromHtml } from '../misc.js'
import { RenderOpts } from './../../Downloader.js'
import { RenderOpts } from './abstract.renderer.js'

/*
Represent 'https://{wikimedia-wiki}/w/api.php?action=visualeditor&mobileformat=html&format=json&paction=parse&page={title}'
Expand Down
2 changes: 1 addition & 1 deletion src/util/renderers/wikimedia-desktop.renderer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import domino from 'domino'
import { Renderer } from './abstract.renderer.js'
import { getStrippedTitleFromHtml } from '../misc.js'
import { RenderOpts } from '../../Downloader.js'
import { RenderOpts } from './abstract.renderer.js'

// Represent 'https://{wikimedia-wiki}/api/rest_v1/page/html/'
export class WikimediaDesktopRenderer extends Renderer {
Expand Down
23 changes: 2 additions & 21 deletions src/util/saveArticles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,12 @@ import { CONCURRENCY_LIMIT, DELETED_ARTICLE_ERROR, MAX_FILE_DOWNLOAD_RETRIES } f
import ApiURLDirector from './builders/url/api.director.js'
import articleTreatment from './treatments/article.treatment.js'
import urlHelper from './url.helper.js'
import { Renderer } from './renderers/abstract.renderer.js'
import { RendererBuilderOptions, Renderer } from './renderers/abstract.renderer.js'
import { RendererBuilder } from './renderers/renderer.builder.js'

const genericJsModules = config.output.mw.js
const genericCssModules = config.output.mw.css

type RendererMode = 'auto' | 'desktop' | 'mobile' | 'specific'
type RendererAPI = 'VisualEditor' | 'WikimediaDesktop' | 'WikimediaMobile'

interface RendererBuilderOptionsBase {
RendererMode: RendererMode
}

interface RendererBuilderOptionsCommon {
RendererMode: RendererMode
RendererAPI?: never
}

interface RendererBuilderOptionsSpecific extends RendererBuilderOptionsBase {
RendererMode: 'specific'
RendererAPI: RendererAPI
}

export type RendererBuilderOptions = RendererBuilderOptionsCommon | RendererBuilderOptionsSpecific

export async function downloadFiles(fileStore: RKVS<FileDetail>, retryStore: RKVS<FileDetail>, zimCreator: ZimCreator, dump: Dump, downloader: Downloader, retryCounter = 0) {
await retryStore.flush()
const filesForAttempt = await fileStore.len()
Expand Down Expand Up @@ -276,7 +257,7 @@ export async function saveArticles(zimCreator: ZimCreator, downloader: Downloade

const rendererBuilder = new RendererBuilder()
const rendererBuilderOptions: RendererBuilderOptions = {
RendererMode: 'auto',
renderType: 'auto',
}
const mainPageRenderer = await rendererBuilder.createRenderer(rendererBuilderOptions)
// TODO: article renderer will be switched to the mobiel mode later
Expand Down
24 changes: 12 additions & 12 deletions test/unit/renderers/renderer.builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { jest } from '@jest/globals'
import { setupScrapeClasses } from '../../util.js'
import { RendererBuilder } from '../../../src/util/renderers/renderer.builder.js'
import { VisualEditorRenderer } from '../../../src/util/renderers/visual-editor.renderer.js'
import { RendererBuilderOptions } from '../../../src/util/renderers/abstract.renderer.js'
import { WikimediaDesktopRenderer } from '../../../src/util/renderers/wikimedia-desktop.renderer.js'
import { RendererBuilderOptions } from '../../../src/util/saveArticles.js'

jest.setTimeout(10000)

Expand All @@ -18,7 +18,7 @@ describe('RendererBuilder', () => {

const renderer = await rendererBuilder.createRenderer({
MediaWiki,
RendererMode: 'desktop',
renderType: 'desktop',
} as RendererBuilderOptions)
expect(renderer).toBeInstanceOf(WikimediaDesktopRenderer)
})
Expand All @@ -28,7 +28,7 @@ describe('RendererBuilder', () => {

const renderer = await rendererBuilder.createRenderer({
MediaWiki,
RendererMode: 'auto',
renderType: 'auto',
} as RendererBuilderOptions)
expect(renderer).toBeInstanceOf(WikimediaDesktopRenderer)
})
Expand All @@ -39,9 +39,9 @@ describe('RendererBuilder', () => {
expect(async () => {
await rendererBuilder.createRenderer({
MediaWiki,
RendererMode: 'unknownMode' as any,
renderType: 'unknownMode' as any,
} as RendererBuilderOptions)
}).rejects.toThrow('Unknown render mode: unknownMode')
}).rejects.toThrow('Unknown render: unknownMode')
})

it('should return VisualEditorRenderer for specific mode with RendererAPI as VisualEditor', async () => {
Expand All @@ -52,8 +52,8 @@ describe('RendererBuilder', () => {

const rendererBuilderOptions = {
MediaWiki,
RendererMode: 'specific',
RendererAPI: 'VisualEditor',
renderType: 'specific',
renderName: 'VisualEditor',
}

const renderer = await rendererBuilder.createRenderer(rendererBuilderOptions as RendererBuilderOptions)
Expand All @@ -69,8 +69,8 @@ describe('RendererBuilder', () => {

const rendererBuilderOptions = {
MediaWiki,
RendererMode: 'specific',
RendererAPI: 'WikimediaDesktop',
renderType: 'specific',
renderName: 'WikimediaDesktop',
}

const renderer = await rendererBuilder.createRenderer(rendererBuilderOptions as RendererBuilderOptions)
Expand All @@ -86,12 +86,12 @@ describe('RendererBuilder', () => {

const rendererBuilderOptions = {
MediaWiki,
RendererMode: 'specific',
RendererAPI: 'UnknownAPI', // Using an invalid RendererAPI for the test
renderType: 'specific',
renderName: 'UnknownAPI', // Using an invalid RendererAPI for the test
}

expect(async () => await rendererBuilder.createRenderer(rendererBuilderOptions as RendererBuilderOptions)).rejects.toThrow(

Check notice on line 93 in test/unit/renderers/renderer.builder.test.ts

View check run for this annotation

codefactor.io / CodeFactor

test/unit/renderers/renderer.builder.test.ts#L93

Unnecessary 'await'. (no-return-await)
`Unknown RendererAPI for specific mode: ${rendererBuilderOptions.RendererAPI}`,
`Unknown renderName for specific mode: ${rendererBuilderOptions.renderName}`,
)
})
})

0 comments on commit 22f322d

Please sign in to comment.