musescore-downloader/src/scoreinfo.ts

106 lines
2.8 KiB
TypeScript
Raw Normal View History

2020-11-24 22:35:44 +00:00
import { getFetch, escapeFilename } from './utils'
2020-11-24 07:29:37 +00:00
export abstract class ScoreInfo {
2020-11-24 09:03:06 +00:00
private readonly RADIX = 20;
2020-11-24 07:29:37 +00:00
abstract id: number;
abstract title: string;
2020-05-18 22:44:45 +00:00
public store = new Map<symbol, any>();
2020-11-24 07:29:37 +00:00
get idLastDigit (): number {
2020-11-24 09:03:06 +00:00
return (+this.id) % this.RADIX
2020-11-24 07:29:37 +00:00
}
get fileName (): string {
2020-11-24 22:35:44 +00:00
return escapeFilename(this.title)
2020-11-24 07:29:37 +00:00
}
2020-11-25 21:24:27 +00:00
public getMsczIpfsRef (mainCid: string): string {
return `/ipfs/${mainCid}/${this.idLastDigit}/${this.id}.mscz`
2020-11-24 07:29:37 +00:00
}
2020-11-25 21:24:27 +00:00
public getMsczCidUrl (mainCid: string): string {
return `https://ipfs.infura.io:5001/api/v0/block/stat?arg=${this.getMsczIpfsRef(mainCid)}`
2020-11-24 09:03:06 +00:00
}
2020-11-24 07:29:37 +00:00
}
2020-11-24 09:43:31 +00:00
export class ScoreInfoObj extends ScoreInfo {
2020-11-26 21:40:25 +00:00
constructor (public id: number = 0, public title: string = '') { super() }
2020-11-24 09:43:31 +00:00
}
2020-11-24 07:29:37 +00:00
export class ScoreInfoInPage extends ScoreInfo {
constructor (private document: Document) { super() }
get id (): number {
const el = this.document.querySelector("meta[property='al:ios:url']") as HTMLMetaElement
const m = el.content.match(/(\d+)$/) as RegExpMatchArray
return +m[1]
2020-11-24 07:29:37 +00:00
}
2020-05-18 22:44:45 +00:00
2020-11-24 07:29:37 +00:00
get title (): string {
const el = this.document.querySelector("meta[property='og:title']") as HTMLMetaElement
return el.content
2020-11-24 07:29:37 +00:00
}
2020-11-24 08:17:50 +00:00
}
export class ScoreInfoHtml extends ScoreInfo {
private readonly ID_REG = /<meta property="al:ios:url" content="musescore:\/\/score\/(\d+)">/
private readonly TITLE_REG = /<meta property="og:title" content="(.*)">/
constructor (private html: string) { super() }
get id (): number {
const m = this.html.match(this.ID_REG)
if (!m) return 0
return +m[1]
}
get title (): string {
const m = this.html.match(this.TITLE_REG)
if (!m) return ''
return m[1]
}
static async request (url: string, _fetch = getFetch()): Promise<ScoreInfoHtml> {
2020-11-29 22:00:29 +00:00
const r = await _fetch(url, {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0',
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.8',
},
})
if (!r.ok) return new ScoreInfoHtml('')
const html = await r.text()
return new ScoreInfoHtml(html)
}
}
2020-11-24 08:17:50 +00:00
export abstract class SheetInfo {
abstract pageCount: number;
abstract thumbnailUrl: string;
get imgType (): 'svg' | 'png' {
const thumbnail = this.thumbnailUrl
2020-11-25 05:36:56 +00:00
const imgtype = thumbnail.match(/score_0\.(\w+)/)![1]
2020-11-24 08:17:50 +00:00
return imgtype as 'svg' | 'png'
}
}
export class SheetInfoInPage extends SheetInfo {
constructor (private document: Document) { super() }
2020-05-18 22:44:45 +00:00
2020-11-24 07:29:37 +00:00
get pageCount (): number {
return this.document.querySelectorAll('.gXB83').length
}
2020-05-18 22:44:45 +00:00
2020-11-24 07:29:37 +00:00
get thumbnailUrl (): string {
// url to the image of the first page
const el = this.document.querySelector('link[as=image]') as HTMLLinkElement
const url = el.href
return url.split('@')[0]
2020-11-24 07:29:37 +00:00
}
2020-05-18 22:44:45 +00:00
}