2020-11-12 07:54:49 +00:00
|
|
|
|
2020-11-24 22:35:44 +00:00
|
|
|
import { getFetch, escapeFilename } from './utils'
|
2020-11-24 10:35:23 +00:00
|
|
|
|
2020-11-24 07:29:37 +00:00
|
|
|
export abstract class ScoreInfo {
|
2020-11-24 09:03:06 +00:00
|
|
|
private readonly IPNS_KEY = 'QmSdXtvzC8v8iTTZuj5cVmiugnzbR1QATYRcGix4bBsioP';
|
|
|
|
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
|
|
|
|
2020-11-24 07:59:19 +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
|
|
|
}
|
|
|
|
|
|
|
|
get msczIpfsRef (): string {
|
2020-11-24 09:03:06 +00:00
|
|
|
return `/ipns/${this.IPNS_KEY}/${this.idLastDigit}/${this.id}.mscz`
|
2020-11-24 07:29:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
get msczCidUrl (): string {
|
|
|
|
return `https://ipfs.infura.io:5001/api/v0/block/stat?arg=${this.msczIpfsRef}`
|
|
|
|
}
|
2020-11-24 09:03:06 +00:00
|
|
|
|
2020-11-24 21:50:52 +00:00
|
|
|
public msczUrl: string;
|
|
|
|
public loadMsczUrl (cidRes: { Key: string; Message: string }): string {
|
2020-11-24 09:03:06 +00:00
|
|
|
const cid = cidRes.Key
|
2020-11-24 09:12:31 +00:00
|
|
|
if (!cid) {
|
|
|
|
// read further error msg
|
|
|
|
const err = cidRes.Message
|
|
|
|
if (err.includes('no link named')) { // file not found
|
|
|
|
throw new Error('score not in dataset')
|
|
|
|
} else {
|
|
|
|
throw new Error(err)
|
|
|
|
}
|
|
|
|
}
|
2020-11-24 21:50:52 +00:00
|
|
|
this.msczUrl = `https://ipfs.infura.io/ipfs/${cid}`
|
|
|
|
return this.msczUrl
|
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 {
|
|
|
|
constructor (public id: number, public title: string) { super() }
|
|
|
|
}
|
|
|
|
|
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
|
2020-11-24 06:24:34 +00:00
|
|
|
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
|
2020-11-24 06:24:34 +00:00
|
|
|
return el.content
|
2020-11-24 07:29:37 +00:00
|
|
|
}
|
2020-11-24 08:17:50 +00:00
|
|
|
}
|
|
|
|
|
2020-11-24 10:35:23 +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> {
|
|
|
|
const r = await _fetch(url)
|
|
|
|
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
|
|
|
|
const imgtype = thumbnail.match(/\.(\w+)$/)![1]
|
|
|
|
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 {
|
2020-11-24 07:10:56 +00:00
|
|
|
// url to the image of the first page
|
2020-11-24 07:31:31 +00:00
|
|
|
const el = this.document.querySelector('link[as=image]') as HTMLLinkElement
|
|
|
|
const url = el.href
|
2020-11-24 07:10:56 +00:00
|
|
|
return url.split('@')[0]
|
2020-11-24 07:29:37 +00:00
|
|
|
}
|
2020-05-18 22:44:45 +00:00
|
|
|
}
|