database/scripts/models/feed.ts
2025-04-29 00:18:35 +03:00

147 lines
4 KiB
TypeScript

import { Collection, Dictionary } from '@freearhey/core'
import { FeedData } from '../types/feed'
import { createFeedId } from '../utils'
import { Model } from './model'
import JoiDate from '@joi/date'
import BaseJoi from 'joi'
import { IssueData } from '../core'
const Joi = BaseJoi.extend(JoiDate)
export class Feed extends Model {
channelId: string
id: string
name: string
isMain: boolean
broadcastAreaCodes: Collection
timezoneIds: Collection
languageCodes: Collection
videoFormat?: string
constructor(data: FeedData) {
super()
this.channelId = data.channel
this.id = data.id
this.name = data.name
this.isMain = data.is_main
this.broadcastAreaCodes = new Collection(data.broadcast_area)
this.timezoneIds = new Collection(data.timezones)
this.languageCodes = new Collection(data.languages)
this.videoFormat = data.video_format
}
setId(id: string): this {
this.id = id
return this
}
update(issueData: IssueData): this {
const data = {
feed_name: issueData.getString('feed_name'),
is_main: issueData.getBoolean('is_main'),
broadcast_area: issueData.getArray('broadcast_area'),
timezones: issueData.getArray('timezones'),
languages: issueData.getArray('languages'),
video_format: issueData.getString('video_format')
}
if (data.feed_name !== undefined) this.name = data.feed_name
if (data.is_main !== undefined) this.isMain = data.is_main
if (data.broadcast_area !== undefined)
this.broadcastAreaCodes = new Collection(data.broadcast_area)
if (data.timezones !== undefined) this.timezoneIds = new Collection(data.timezones)
if (data.languages !== undefined) this.languageCodes = new Collection(data.languages)
if (data.video_format !== undefined) this.videoFormat = data.video_format
return this
}
hasValidId(): boolean {
const expectedId = createFeedId(this.name)
return expectedId === this.id
}
hasValidChannelId(channelsKeyById: Dictionary): boolean {
return channelsKeyById.has(this.channelId)
}
hasValidTimezones(timezonesKeyById: Dictionary): boolean {
const hasInvalid = this.timezoneIds.find((id: string) => timezonesKeyById.missing(id))
return !hasInvalid
}
hasValidBroadcastAreaCodes(
countriesKeyByCode: Dictionary,
subdivisionsKeyByCode: Dictionary,
regionsKeyByCode: Dictionary
): boolean {
const hasInvalid = this.broadcastAreaCodes.find((areaCode: string) => {
const [type, code] = areaCode.split('/')
switch (type) {
case 'c':
return countriesKeyByCode.missing(code)
case 's':
return subdivisionsKeyByCode.missing(code)
case 'r':
return regionsKeyByCode.missing(code)
}
})
return !hasInvalid
}
getStreamId(): string {
return `${this.channelId}@${this.id}`
}
data(): FeedData {
return {
channel: this.channelId,
id: this.id,
name: this.name,
is_main: this.isMain,
broadcast_area: this.broadcastAreaCodes.all(),
timezones: this.timezoneIds.all(),
languages: this.languageCodes.all(),
video_format: this.videoFormat
}
}
getSchema() {
return Joi.object({
channel: Joi.string()
.regex(/^[A-Za-z0-9]+\.[a-z]{2}$/)
.required(),
id: Joi.string()
.regex(/^[A-Za-z0-9]+$/)
.required(),
name: Joi.string()
.regex(/^[a-z0-9-!:&.+'/»#%°$@?|¡–\s_—]+$/i)
.regex(/^((?!\s-\s).)*$/)
.required(),
is_main: Joi.boolean().strict().required(),
broadcast_area: Joi.array().items(
Joi.string()
.regex(/^(s\/[A-Z]{2}-[A-Z0-9]{1,3}|c\/[A-Z]{2}|r\/[A-Z0-9]{2,7})$/)
.required()
),
timezones: Joi.array().items(
Joi.string()
.regex(/^[a-z-_/]+$/i)
.required()
),
languages: Joi.array().items(
Joi.string()
.regex(/^[a-z]{3}$/)
.required()
),
video_format: Joi.string()
.regex(/^\d+(i|p)$/)
.allow(null)
})
}
}