Update scripts

This commit is contained in:
freearhey 2025-03-30 03:01:05 +03:00
parent e0b0de6b2b
commit f32a3f9e77
5 changed files with 64 additions and 23 deletions

View file

@ -57,7 +57,7 @@ async function main() {
streams = streams.orderBy( streams = streams.orderBy(
[ [
(stream: Stream) => stream.name, (stream: Stream) => stream.name,
(stream: Stream) => stream.getHorizontalResolution(), (stream: Stream) => stream.getVerticalResolution(),
(stream: Stream) => stream.getLabel(), (stream: Stream) => stream.getLabel(),
(stream: Stream) => stream.url (stream: Stream) => stream.url
], ],

View file

@ -89,7 +89,7 @@ async function main() {
regionsGroupedByCode, regionsGroupedByCode,
subdivisionsGroupedByCode subdivisionsGroupedByCode
) )
.withBroadcastRegions(regions, regionsGroupedByCode) .withBroadcastRegions(regions)
.withBroadcastSubdivisions(subdivisionsGroupedByCode) .withBroadcastSubdivisions(subdivisionsGroupedByCode)
) )
const feedsGroupedByChannelId = feeds.groupBy((feed: Feed) => const feedsGroupedByChannelId = feeds.groupBy((feed: Feed) =>
@ -106,14 +106,16 @@ async function main() {
const files = await storage.list('**/*.m3u') const files = await storage.list('**/*.m3u')
let streams = await parser.parse(files) let streams = await parser.parse(files)
const totalStreams = streams.count() const totalStreams = streams.count()
streams = streams.uniqBy((stream: Stream) => stream.getId() || uniqueId()) streams = streams.uniqBy((stream: Stream) =>
stream.hasId() ? stream.getChannelId() + stream.getFeedId() : uniqueId()
)
logger.info(`found ${totalStreams} streams (including ${streams.count()} unique)`) logger.info(`found ${totalStreams} streams (including ${streams.count()} unique)`)
logger.info('sorting streams...') logger.info('sorting streams...')
streams = streams.orderBy( streams = streams.orderBy(
[ [
(stream: Stream) => stream.getId(), (stream: Stream) => stream.getId(),
(stream: Stream) => stream.getHorizontalResolution(), (stream: Stream) => stream.getVerticalResolution(),
(stream: Stream) => stream.getLabel() (stream: Stream) => stream.getLabel()
], ],
['asc', 'asc', 'desc'] ['asc', 'asc', 'desc']

View file

@ -26,7 +26,7 @@ export class IndexRegionGenerator implements Generator {
let groupedStreams = new Collection() let groupedStreams = new Collection()
this.streams this.streams
.orderBy((stream: Stream) => stream.getTitle()) .orderBy((stream: Stream) => stream.getTitle())
.filter((stream: Stream) => stream.isSFW()) .filter((stream: Stream) => stream.isSFW() && !stream.isInternational())
.forEach((stream: Stream) => { .forEach((stream: Stream) => {
if (!stream.hasBroadcastArea()) { if (!stream.hasBroadcastArea()) {
const streamClone = stream.clone() const streamClone = stream.clone()

View file

@ -122,17 +122,15 @@ export class Feed {
return this return this
} }
withBroadcastRegions(regions: Collection, regionsGroupedByCode: Dictionary): this { withBroadcastRegions(regions: Collection): this {
if (!this.broadcastCountries) return this if (!this.broadcastCountries) return this
const countriesCodes = this.broadcastCountries.map((country: Country) => country.code) const countriesCodes = this.broadcastCountries.map((country: Country) => country.code)
const broadcastRegions = regions.filter((region: Region) => this.broadcastRegions = regions.filter((region: Region) => {
region.countryCodes.intersects(countriesCodes) if (region.code === 'INT') return false
)
if (this.isInternational()) broadcastRegions.add(regionsGroupedByCode.get('INT')) return region.countryCodes.intersects(countriesCodes)
})
this.broadcastRegions = broadcastRegions
return this return this
} }

View file

@ -14,7 +14,8 @@ export class Stream {
filepath?: string filepath?: string
line: number line: number
label?: string label?: string
quality?: string verticalResolution?: number
isInterlaced?: boolean
httpReferrer?: string httpReferrer?: string
httpUserAgent?: string httpUserAgent?: string
removed: boolean = false removed: boolean = false
@ -25,6 +26,7 @@ export class Stream {
const [channelId, feedId] = data.tvg.id.split('@') const [channelId, feedId] = data.tvg.id.split('@')
const { name, label, quality } = parseTitle(data.name) const { name, label, quality } = parseTitle(data.name)
const { verticalResolution, isInterlaced } = parseQuality(quality)
this.id = data.tvg.id || undefined this.id = data.tvg.id || undefined
this.feedId = feedId || undefined this.feedId = feedId || undefined
@ -32,7 +34,8 @@ export class Stream {
this.line = data.line this.line = data.line
this.label = label || undefined this.label = label || undefined
this.name = name this.name = name
this.quality = quality || undefined this.verticalResolution = verticalResolution || undefined
this.isInterlaced = isInterlaced || undefined
this.url = data.url this.url = data.url
this.httpReferrer = data.http.referrer || undefined this.httpReferrer = data.http.referrer || undefined
this.httpUserAgent = data.http['user-agent'] || undefined this.httpUserAgent = data.http['user-agent'] || undefined
@ -52,7 +55,7 @@ export class Stream {
const channelFeeds = feedsGroupedByChannelId.get(this.channelId) || [] const channelFeeds = feedsGroupedByChannelId.get(this.channelId) || []
if (this.feedId) this.feed = channelFeeds.find((feed: Feed) => feed.id === this.feedId) if (this.feedId) this.feed = channelFeeds.find((feed: Feed) => feed.id === this.feedId)
if (!this.feed) this.feed = channelFeeds.find((feed: Feed) => feed.isMain) if (!this.feedId && !this.feed) this.feed = channelFeeds.find((feed: Feed) => feed.isMain)
return this return this
} }
@ -82,7 +85,10 @@ export class Stream {
} }
setQuality(quality: string): this { setQuality(quality: string): this {
this.quality = quality const { verticalResolution, isInterlaced } = parseQuality(quality)
this.verticalResolution = verticalResolution || undefined
this.isInterlaced = isInterlaced || undefined
return this return this
} }
@ -113,6 +119,16 @@ export class Stream {
return this return this
} }
getChannelId(): string {
return this.channelId || ''
}
getFeedId(): string {
if (this.feedId) return this.feedId
if (this.feed) return this.feed.id
return ''
}
getFilepath(): string { getFilepath(): string {
return this.filepath || '' return this.filepath || ''
} }
@ -126,14 +142,25 @@ export class Stream {
} }
getQuality(): string { getQuality(): string {
return this.quality || '' if (!this.verticalResolution) return ''
let quality = this.verticalResolution.toString()
if (this.isInterlaced) quality += 'i'
else quality += 'p'
return quality
}
hasId(): boolean {
return !!this.id
} }
hasQuality(): boolean { hasQuality(): boolean {
return !!this.quality return !!this.verticalResolution
} }
getHorizontalResolution(): number { getVerticalResolution(): number {
if (!this.hasQuality()) return 0 if (!this.hasQuality()) return 0
return parseInt(this.getQuality().replace(/p|i/, '')) return parseInt(this.getQuality().replace(/p|i/, ''))
@ -257,8 +284,8 @@ export class Stream {
getTitle(): string { getTitle(): string {
let title = `${this.name}` let title = `${this.name}`
if (this.quality) { if (this.getQuality()) {
title += ` (${this.quality})` title += ` (${this.getQuality()})`
} }
if (this.label) { if (this.label) {
@ -284,7 +311,8 @@ export class Stream {
filepath: this.filepath, filepath: this.filepath,
label: this.label, label: this.label,
name: this.name, name: this.name,
quality: this.quality, verticalResolution: this.verticalResolution,
isInterlaced: this.isInterlaced,
url: this.url, url: this.url,
httpReferrer: this.httpReferrer, httpReferrer: this.httpReferrer,
httpUserAgent: this.httpUserAgent, httpUserAgent: this.httpUserAgent,
@ -333,7 +361,11 @@ export class Stream {
} }
} }
function parseTitle(title: string): { name: string; label: string; quality: string } { function parseTitle(title: string): {
name: string
label: string
quality: string
} {
const [, label] = title.match(/ \[(.*)\]$/) || [null, ''] const [, label] = title.match(/ \[(.*)\]$/) || [null, '']
title = title.replace(new RegExp(` \\[${escapeRegExp(label)}\\]$`), '') title = title.replace(new RegExp(` \\[${escapeRegExp(label)}\\]$`), '')
const [, quality] = title.match(/ \(([0-9]+p)\)$/) || [null, ''] const [, quality] = title.match(/ \(([0-9]+p)\)$/) || [null, '']
@ -345,3 +377,12 @@ function parseTitle(title: string): { name: string; label: string; quality: stri
function escapeRegExp(text) { function escapeRegExp(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
} }
function parseQuality(quality: string): { verticalResolution: number; isInterlaced: boolean } {
let [, verticalResolutionString] = quality.match(/^(\d+)/) || [null, undefined]
const isInterlaced = /i$/i.test(quality)
let verticalResolution = 0
if (verticalResolutionString) verticalResolution = parseInt(verticalResolutionString)
return { verticalResolution, isInterlaced }
}