Update scripts

This commit is contained in:
freearhey 2025-07-20 20:28:58 +03:00
parent d2a0fe08db
commit 0a6212100a
10 changed files with 157 additions and 50 deletions

View File

@ -9,13 +9,14 @@ import {
IndexCategoryGenerator,
IndexLanguageGenerator,
IndexCountryGenerator,
SubdivisionsGenerator,
IndexRegionGenerator,
CategoriesGenerator,
CountriesGenerator,
LanguagesGenerator,
RegionsGenerator,
IndexGenerator,
SourcesGenerator,
IndexGenerator,
RawGenerator
} from '../../generators'
@ -32,6 +33,7 @@ async function main() {
feedsGroupedByChannelId,
logosGroupedByStreamId,
channelsKeyById,
subdivisions,
categories,
countries,
regions
@ -71,6 +73,9 @@ async function main() {
logger.info('generating categories/...')
await new CategoriesGenerator({ categories, streams, logFile }).generate()
logger.info('generating languages/...')
await new LanguagesGenerator({ streams, logFile }).generate()
logger.info('generating countries/...')
await new CountriesGenerator({
countries,
@ -78,8 +83,12 @@ async function main() {
logFile
}).generate()
logger.info('generating languages/...')
await new LanguagesGenerator({ streams, logFile }).generate()
logger.info('generating subdivisions/...')
await new SubdivisionsGenerator({
subdivisions,
streams,
logFile
}).generate()
logger.info('generating regions/...')
await new RegionsGenerator({

View File

@ -1,5 +1,11 @@
import { Logger } from '@freearhey/core'
import { CategoryTable, CountryTable, LanguageTable, RegionTable } from '../../tables'
import {
CategoryTable,
CountryTable,
LanguageTable,
RegionTable,
SubdivisionTable
} from '../../tables'
import { Markdown } from '../../core'
import { README_DIR } from '../../constants'
import path from 'path'
@ -9,10 +15,12 @@ async function main() {
logger.info('creating category table...')
await new CategoryTable().make()
logger.info('creating country table...')
await new CountryTable().make()
logger.info('creating language table...')
await new LanguageTable().make()
logger.info('creating country table...')
await new CountryTable().make()
logger.info('creating subdivision table...')
await new SubdivisionTable().make()
logger.info('creating region table...')
await new RegionTable().make()

View File

@ -25,7 +25,7 @@ export class DataProcessor {
const languages = new Collection(data.languages).map(data => new Language(data))
const languagesKeyByCode = languages.keyBy((language: Language) => language.code)
const subdivisions = new Collection(data.subdivisions).map(data => new Subdivision(data))
let subdivisions = new Collection(data.subdivisions).map(data => new Subdivision(data))
const subdivisionsKeyByCode = subdivisions.keyBy((subdivision: Subdivision) => subdivision.code)
const subdivisionsGroupedByCountryCode = subdivisions.groupBy(
(subdivision: Subdivision) => subdivision.countryCode
@ -42,6 +42,10 @@ export class DataProcessor {
)
const countriesKeyByCode = countries.keyBy((country: Country) => country.code)
subdivisions = subdivisions.map((subdivision: Subdivision) =>
subdivision.withCountry(countriesKeyByCode)
)
const timezones = new Collection(data.timezones).map(data =>
new Timezone(data).withCountries(countriesKeyByCode)
)

View File

@ -40,21 +40,6 @@ export class CountriesGenerator implements Generator {
this.logFile.append(
JSON.stringify({ type: 'country', filepath, count: playlist.streams.count() }) + EOL
)
country.getSubdivisions().forEach(async (subdivision: Subdivision) => {
const subdivisionStreams = streams.filter((stream: Stream) =>
stream.isBroadcastInSubdivision(subdivision)
)
if (subdivisionStreams.isEmpty()) return
const playlist = new Playlist(subdivisionStreams, { public: true })
const filepath = `subdivisions/${subdivision.code.toLowerCase()}.m3u`
await this.storage.save(filepath, playlist.toString())
this.logFile.append(
JSON.stringify({ type: 'subdivision', filepath, count: playlist.streams.count() }) + EOL
)
})
})
const undefinedStreams = streams.filter((stream: Stream) => !stream.hasBroadcastArea())

View File

@ -10,3 +10,4 @@ export * from './languagesGenerator'
export * from './rawGenerator'
export * from './regionsGenerator'
export * from './sourcesGenerator'
export * from './subdivisionsGenerator'

View File

@ -0,0 +1,46 @@
import { Country, Subdivision, Stream, Playlist } from '../models'
import { Collection, Storage, File } from '@freearhey/core'
import { PUBLIC_DIR } from '../constants'
import { Generator } from './generator'
import { EOL } from 'node:os'
type SubdivisionsGeneratorProps = {
streams: Collection
subdivisions: Collection
logFile: File
}
export class SubdivisionsGenerator implements Generator {
streams: Collection
subdivisions: Collection
storage: Storage
logFile: File
constructor({ streams, subdivisions, logFile }: SubdivisionsGeneratorProps) {
this.streams = streams.clone()
this.subdivisions = subdivisions
this.storage = new Storage(PUBLIC_DIR)
this.logFile = logFile
}
async generate(): Promise<void> {
const streams = this.streams
.orderBy((stream: Stream) => stream.getTitle())
.filter((stream: Stream) => stream.isSFW())
this.subdivisions.forEach(async (subdivision: Subdivision) => {
const subdivisionStreams = streams.filter((stream: Stream) =>
stream.isBroadcastInSubdivision(subdivision)
)
if (subdivisionStreams.isEmpty()) return
const playlist = new Playlist(subdivisionStreams, { public: true })
const filepath = `subdivisions/${subdivision.code.toLowerCase()}.m3u`
await this.storage.save(filepath, playlist.toString())
this.logFile.append(
JSON.stringify({ type: 'subdivision', filepath, count: playlist.streams.count() }) + EOL
)
})
}
}

View File

@ -190,8 +190,15 @@ export class Feed {
isBroadcastInSubdivision(subdivision: Subdivision): boolean {
if (this.isInternational()) return false
if (this.broadcastSubdivisionCodes.includes(subdivision.code)) return true
if (
this.broadcastSubdivisionCodes.isEmpty() &&
subdivision.country &&
this.isBroadcastInCountry(subdivision.country)
)
return true
return this.broadcastSubdivisionCodes.includes(subdivision.code)
return false
}
isBroadcastInCountry(country: Country): boolean {

View File

@ -1,6 +1,6 @@
import { Storage, Collection, File } from '@freearhey/core'
import { HTMLTable, LogParser, LogItem } from '../core'
import { Country, Subdivision } from '../models'
import { Country } from '../models'
import { DATA_DIR, LOGS_DIR, README_DIR } from '../constants'
import { Table } from './table'
@ -13,11 +13,6 @@ export class CountryTable implements Table {
const countriesContent = await dataStorage.json('countries.json')
const countries = new Collection(countriesContent).map(data => new Country(data))
const countriesGroupedByCode = countries.keyBy((country: Country) => country.code)
const subdivisionsContent = await dataStorage.json('subdivisions.json')
const subdivisions = new Collection(subdivisionsContent).map(data => new Subdivision(data))
const subdivisionsGroupedByCode = subdivisions.keyBy(
(subdivision: Subdivision) => subdivision.code
)
const parser = new LogParser()
const logsStorage = new Storage(LOGS_DIR)
@ -26,27 +21,6 @@ export class CountryTable implements Table {
let data = new Collection()
parsed
.filter((logItem: LogItem) => logItem.type === 'subdivision')
.forEach((logItem: LogItem) => {
const file = new File(logItem.filepath)
const code = file.name().toUpperCase()
const [countryCode, subdivisionCode] = code.split('-') || ['', '']
const country = countriesGroupedByCode.get(countryCode)
if (country && subdivisionCode) {
const subdivision = subdivisionsGroupedByCode.get(code)
if (subdivision) {
data.add([
`${country.name}/${subdivision.name}`,
`&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${subdivision.name}`,
logItem.count,
`<code>https://iptv-org.github.io/iptv/${logItem.filepath}</code>`
])
}
}
})
parsed
.filter((logItem: LogItem) => logItem.type === 'country')
.forEach((logItem: LogItem) => {

View File

@ -2,3 +2,4 @@ export * from './categoryTable'
export * from './countryTable'
export * from './languageTable'
export * from './regionTable'
export * from './subdivisionTable'

View File

@ -0,0 +1,72 @@
import { Storage, Collection, File } from '@freearhey/core'
import { HTMLTable, LogParser, LogItem } from '../core'
import { Country, Subdivision } from '../models'
import { DATA_DIR, LOGS_DIR, README_DIR } from '../constants'
import { Table } from './table'
export class SubdivisionTable implements Table {
constructor() {}
async make() {
const dataStorage = new Storage(DATA_DIR)
const countriesContent = await dataStorage.json('countries.json')
const countries = new Collection(countriesContent).map(data => new Country(data))
const countriesGroupedByCode = countries.keyBy((country: Country) => country.code)
const subdivisionsContent = await dataStorage.json('subdivisions.json')
const subdivisions = new Collection(subdivisionsContent).map(data => new Subdivision(data))
const subdivisionsGroupedByCode = subdivisions.keyBy(
(subdivision: Subdivision) => subdivision.code
)
const parser = new LogParser()
const logsStorage = new Storage(LOGS_DIR)
const generatorsLog = await logsStorage.load('generators.log')
const parsed = parser.parse(generatorsLog)
const parsedSubdivisions = parsed.filter((logItem: LogItem) => logItem.type === 'subdivision')
let output = ''
countries.forEach((country: Country) => {
const parsedCountrySubdivisions = parsedSubdivisions.filter((logItem: LogItem) =>
logItem.filepath.includes(`subdivisions/${country.code.toLowerCase()}`)
)
if (!parsedCountrySubdivisions.length) return
output += `\r\n<details>\r\n\<summary>${country.name}</summary>\r\n`
let data = new Collection()
parsedCountrySubdivisions.forEach((logItem: LogItem) => {
const file = new File(logItem.filepath)
const code = file.name().toUpperCase()
const [countryCode, subdivisionCode] = code.split('-') || ['', '']
const country = countriesGroupedByCode.get(countryCode)
if (country && subdivisionCode) {
const subdivision = subdivisionsGroupedByCode.get(code)
if (subdivision) {
data.add([
subdivision.name,
logItem.count,
`<code>https://iptv-org.github.io/iptv/${logItem.filepath}</code>`
])
}
}
})
const table = new HTMLTable(data.all(), [
{ name: 'Subdivision' },
{ name: 'Channels', align: 'right' },
{ name: 'Playlist', nowrap: true }
])
output += table.toString()
output += '\r\n</details>'
})
const readmeStorage = new Storage(README_DIR)
await readmeStorage.save('_subdivisions.md', output.trim())
}
}