mirror of https://github.com/iptv-org/iptv
Update scripts
parent
f9e3da182c
commit
a9a8af8fa3
@ -0,0 +1,43 @@
|
||||
import { City, Stream, Playlist } from '../models'
|
||||
import { Collection, Storage, File } from '@freearhey/core'
|
||||
import { PUBLIC_DIR, EOL } from '../constants'
|
||||
import { Generator } from './generator'
|
||||
|
||||
type CitiesGeneratorProps = {
|
||||
streams: Collection
|
||||
cities: Collection
|
||||
logFile: File
|
||||
}
|
||||
|
||||
export class CitiesGenerator implements Generator {
|
||||
streams: Collection
|
||||
cities: Collection
|
||||
storage: Storage
|
||||
logFile: File
|
||||
|
||||
constructor({ streams, cities, logFile }: CitiesGeneratorProps) {
|
||||
this.streams = streams.clone()
|
||||
this.cities = cities
|
||||
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.cities.forEach(async (city: City) => {
|
||||
const cityStreams = streams.filter((stream: Stream) => stream.isBroadcastInCity(city))
|
||||
|
||||
if (cityStreams.isEmpty()) return
|
||||
|
||||
const playlist = new Playlist(cityStreams, { public: true })
|
||||
const filepath = `cities/${city.code.toLowerCase()}.m3u`
|
||||
await this.storage.save(filepath, playlist.toString())
|
||||
this.logFile.append(
|
||||
JSON.stringify({ type: 'city', filepath, count: playlist.streams.count() }) + EOL
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,189 @@
|
||||
import { Storage, Collection, Dictionary } from '@freearhey/core'
|
||||
import { City, Country, Subdivision } from '../models'
|
||||
import { LOGS_DIR, README_DIR } from '../constants'
|
||||
import { LogParser, LogItem } from '../core'
|
||||
import { Table } from './table'
|
||||
|
||||
type CountriesTableProps = {
|
||||
countriesKeyByCode: Dictionary
|
||||
subdivisionsKeyByCode: Dictionary
|
||||
countries: Collection
|
||||
subdivisions: Collection
|
||||
cities: Collection
|
||||
}
|
||||
|
||||
export class CountriesTable implements Table {
|
||||
countriesKeyByCode: Dictionary
|
||||
subdivisionsKeyByCode: Dictionary
|
||||
countries: Collection
|
||||
subdivisions: Collection
|
||||
cities: Collection
|
||||
|
||||
constructor({
|
||||
countriesKeyByCode,
|
||||
subdivisionsKeyByCode,
|
||||
countries,
|
||||
subdivisions,
|
||||
cities
|
||||
}: CountriesTableProps) {
|
||||
this.countriesKeyByCode = countriesKeyByCode
|
||||
this.subdivisionsKeyByCode = subdivisionsKeyByCode
|
||||
this.countries = countries
|
||||
this.subdivisions = subdivisions
|
||||
this.cities = cities
|
||||
}
|
||||
|
||||
async make() {
|
||||
const parser = new LogParser()
|
||||
const logsStorage = new Storage(LOGS_DIR)
|
||||
const generatorsLog = await logsStorage.load('generators.log')
|
||||
const parsed = parser.parse(generatorsLog)
|
||||
const logCountries = parsed.filter((logItem: LogItem) => logItem.type === 'country')
|
||||
const logSubdivisions = parsed.filter((logItem: LogItem) => logItem.type === 'subdivision')
|
||||
const logCities = parsed.filter((logItem: LogItem) => logItem.type === 'city')
|
||||
|
||||
let items = new Collection()
|
||||
this.countries.forEach((country: Country) => {
|
||||
const countriesLogItem = logCountries.find(
|
||||
(logItem: LogItem) => logItem.filepath === `countries/${country.code.toLowerCase()}.m3u`
|
||||
)
|
||||
|
||||
let countryItem = {
|
||||
index: country.name,
|
||||
count: 0,
|
||||
link: `https://iptv-org.github.io/iptv/countries/${country.code.toLowerCase()}.m3u`,
|
||||
name: `${country.flag} ${country.name}`,
|
||||
children: new Collection()
|
||||
}
|
||||
|
||||
if (countriesLogItem) {
|
||||
countryItem.count = countriesLogItem.count
|
||||
}
|
||||
|
||||
const countrySubdivisions = this.subdivisions.filter(
|
||||
(subdivision: Subdivision) => subdivision.countryCode === country.code
|
||||
)
|
||||
const countryCities = this.cities.filter((city: City) => city.countryCode === country.code)
|
||||
if (countrySubdivisions.notEmpty()) {
|
||||
this.subdivisions.forEach((subdivision: Subdivision) => {
|
||||
if (subdivision.countryCode !== country.code) return
|
||||
const subdivisionCities = countryCities.filter(
|
||||
(city: City) =>
|
||||
(city.subdivisionCode && city.subdivisionCode === subdivision.code) ||
|
||||
city.countryCode === subdivision.countryCode
|
||||
)
|
||||
const subdivisionsLogItem = logSubdivisions.find(
|
||||
(logItem: LogItem) =>
|
||||
logItem.filepath === `subdivisions/${subdivision.code.toLowerCase()}.m3u`
|
||||
)
|
||||
|
||||
let subdivisionItem = {
|
||||
index: subdivision.name,
|
||||
name: subdivision.name,
|
||||
count: 0,
|
||||
link: `https://iptv-org.github.io/iptv/subdivisions/${subdivision.code.toLowerCase()}.m3u`,
|
||||
children: new Collection()
|
||||
}
|
||||
|
||||
if (subdivisionsLogItem) {
|
||||
subdivisionItem.count = subdivisionsLogItem.count
|
||||
}
|
||||
|
||||
subdivisionCities.forEach((city: City) => {
|
||||
if (city.countryCode !== country.code || city.subdivisionCode !== subdivision.code)
|
||||
return
|
||||
const citiesLogItem = logCities.find(
|
||||
(logItem: LogItem) => logItem.filepath === `cities/${city.code.toLowerCase()}.m3u`
|
||||
)
|
||||
|
||||
if (!citiesLogItem) return
|
||||
|
||||
subdivisionItem.children.add({
|
||||
index: city.name,
|
||||
name: city.name,
|
||||
count: citiesLogItem.count,
|
||||
link: `https://iptv-org.github.io/iptv/${citiesLogItem.filepath}`
|
||||
})
|
||||
})
|
||||
|
||||
if (subdivisionItem.count > 0 || subdivisionItem.children.notEmpty()) {
|
||||
countryItem.children.add(subdivisionItem)
|
||||
}
|
||||
})
|
||||
} else if (countryCities.notEmpty()) {
|
||||
countryCities.forEach((city: City) => {
|
||||
const citiesLogItem = logCities.find(
|
||||
(logItem: LogItem) => logItem.filepath === `cities/${city.code.toLowerCase()}.m3u`
|
||||
)
|
||||
|
||||
if (!citiesLogItem) return
|
||||
|
||||
countryItem.children.add({
|
||||
index: city.name,
|
||||
name: city.name,
|
||||
count: citiesLogItem.count,
|
||||
link: `https://iptv-org.github.io/iptv/${citiesLogItem.filepath}`,
|
||||
children: new Collection()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (countryItem.count > 0 || countryItem.children.notEmpty()) {
|
||||
items.add(countryItem)
|
||||
}
|
||||
})
|
||||
|
||||
const internationalLogItem = logCountries.find(
|
||||
(logItem: LogItem) => logItem.filepath === 'countries/int.m3u'
|
||||
)
|
||||
|
||||
if (internationalLogItem) {
|
||||
items.push({
|
||||
index: 'ZZ',
|
||||
name: '🌐 International',
|
||||
count: internationalLogItem.count,
|
||||
link: `https://iptv-org.github.io/iptv/${internationalLogItem.filepath}`,
|
||||
children: new Collection()
|
||||
})
|
||||
}
|
||||
|
||||
const undefinedLogItem = logCountries.find(
|
||||
(logItem: LogItem) => logItem.filepath === `countries/undefined.m3u`
|
||||
)
|
||||
|
||||
if (undefinedLogItem) {
|
||||
items.push({
|
||||
index: 'ZZZ',
|
||||
name: 'Undefined',
|
||||
count: undefinedLogItem.count,
|
||||
link: `https://iptv-org.github.io/iptv/${undefinedLogItem.filepath}`,
|
||||
children: new Collection()
|
||||
})
|
||||
}
|
||||
|
||||
items = items.orderBy(item => item.index)
|
||||
|
||||
const output = items
|
||||
.map(item => {
|
||||
let row = `- ${item.name} <code>${item.link}</code>`
|
||||
|
||||
item.children
|
||||
.orderBy(item => item.index)
|
||||
.forEach(item => {
|
||||
row += `\r\n\ - ${item.name} <code>${item.link}</code>`
|
||||
|
||||
item.children
|
||||
.orderBy(item => item.index)
|
||||
.forEach(item => {
|
||||
row += `\r\n\ - ${item.name} <code>${item.link}</code>`
|
||||
})
|
||||
})
|
||||
|
||||
return row
|
||||
})
|
||||
.join('\r\n')
|
||||
|
||||
const readmeStorage = new Storage(README_DIR)
|
||||
await readmeStorage.save('_countries.md', output)
|
||||
}
|
||||
}
|
||||
@ -1,65 +0,0 @@
|
||||
import { Storage, Collection, File } from '@freearhey/core'
|
||||
import { HTMLTable, LogParser, LogItem } from '../core'
|
||||
import { Country } from '../models'
|
||||
import { DATA_DIR, LOGS_DIR, README_DIR } from '../constants'
|
||||
import { Table } from './table'
|
||||
|
||||
export class CountryTable 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 parser = new LogParser()
|
||||
const logsStorage = new Storage(LOGS_DIR)
|
||||
const generatorsLog = await logsStorage.load('generators.log')
|
||||
const parsed = parser.parse(generatorsLog)
|
||||
|
||||
let data = new Collection()
|
||||
|
||||
parsed
|
||||
.filter((logItem: LogItem) => logItem.type === 'country')
|
||||
.forEach((logItem: LogItem) => {
|
||||
const file = new File(logItem.filepath)
|
||||
const code = file.name().toUpperCase()
|
||||
const [countryCode] = code.split('-') || ['', '']
|
||||
const country = countriesGroupedByCode.get(countryCode)
|
||||
|
||||
if (country) {
|
||||
data.add([
|
||||
country.name,
|
||||
`${country.flag} ${country.name}`,
|
||||
logItem.count,
|
||||
`<code>https://iptv-org.github.io/iptv/${logItem.filepath}</code>`
|
||||
])
|
||||
} else {
|
||||
data.add([
|
||||
'ZZ',
|
||||
'Undefined',
|
||||
logItem.count,
|
||||
`<code>https://iptv-org.github.io/iptv/${logItem.filepath}</code>`
|
||||
])
|
||||
}
|
||||
})
|
||||
|
||||
data = data
|
||||
.orderBy(item => item[0])
|
||||
.map(item => {
|
||||
item.shift()
|
||||
return item
|
||||
})
|
||||
|
||||
const table = new HTMLTable(data.all(), [
|
||||
{ name: 'Country' },
|
||||
{ name: 'Channels', align: 'right' },
|
||||
{ name: 'Playlist', nowrap: true }
|
||||
])
|
||||
|
||||
const readmeStorage = new Storage(README_DIR)
|
||||
await readmeStorage.save('_countries.md', table.toString())
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
export * from './categoryTable'
|
||||
export * from './countryTable'
|
||||
export * from './languageTable'
|
||||
export * from './regionTable'
|
||||
export * from './subdivisionTable'
|
||||
export * from './categoriesTable'
|
||||
export * from './countriesTable'
|
||||
export * from './languagesTable'
|
||||
export * from './regionsTable'
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
import { Storage, Collection, File } from '@freearhey/core'
|
||||
import { HTMLTable, LogParser, LogItem } from '../core'
|
||||
import { Region } from '../models'
|
||||
import { DATA_DIR, LOGS_DIR, README_DIR } from '../constants'
|
||||
import { Table } from './table'
|
||||
|
||||
export class RegionTable implements Table {
|
||||
constructor() {}
|
||||
|
||||
async make() {
|
||||
const dataStorage = new Storage(DATA_DIR)
|
||||
const regionsContent = await dataStorage.json('regions.json')
|
||||
const regions = new Collection(regionsContent).map(data => new Region(data))
|
||||
const regionsGroupedByCode = regions.keyBy((region: Region) => region.code)
|
||||
|
||||
const parser = new LogParser()
|
||||
const logsStorage = new Storage(LOGS_DIR)
|
||||
const generatorsLog = await logsStorage.load('generators.log')
|
||||
|
||||
let data = new Collection()
|
||||
parser
|
||||
.parse(generatorsLog)
|
||||
.filter((logItem: LogItem) => logItem.type === 'region')
|
||||
.forEach((logItem: LogItem) => {
|
||||
const file = new File(logItem.filepath)
|
||||
const regionCode = file.name().toUpperCase()
|
||||
const region: Region = regionsGroupedByCode.get(regionCode)
|
||||
|
||||
if (region) {
|
||||
data.add([
|
||||
region.name,
|
||||
region.name,
|
||||
logItem.count,
|
||||
`<code>https://iptv-org.github.io/iptv/${logItem.filepath}</code>`
|
||||
])
|
||||
} else {
|
||||
data.add([
|
||||
'ZZZ',
|
||||
'Undefined',
|
||||
logItem.count,
|
||||
`<code>https://iptv-org.github.io/iptv/${logItem.filepath}</code>`
|
||||
])
|
||||
}
|
||||
})
|
||||
|
||||
data = data
|
||||
.orderBy(item => item[0])
|
||||
.map(item => {
|
||||
item.shift()
|
||||
return item
|
||||
})
|
||||
|
||||
const table = new HTMLTable(data.all(), [
|
||||
{ name: 'Region', align: 'left' },
|
||||
{ name: 'Channels', align: 'right' },
|
||||
{ name: 'Playlist', align: 'left', nowrap: true }
|
||||
])
|
||||
|
||||
const readmeStorage = new Storage(README_DIR)
|
||||
await readmeStorage.save('_regions.md', table.toString())
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
import { Storage, Collection, File } from '@freearhey/core'
|
||||
import { HTMLTable, LogParser, LogItem } from '../core'
|
||||
import { LOGS_DIR, README_DIR } from '../constants'
|
||||
import { Region } from '../models'
|
||||
import { Table } from './table'
|
||||
|
||||
type RegionsTableProps = {
|
||||
regions: Collection
|
||||
}
|
||||
|
||||
export class RegionsTable implements Table {
|
||||
regions: Collection
|
||||
|
||||
constructor({ regions }: RegionsTableProps) {
|
||||
this.regions = regions
|
||||
}
|
||||
|
||||
async make() {
|
||||
const parser = new LogParser()
|
||||
const logsStorage = new Storage(LOGS_DIR)
|
||||
const generatorsLog = await logsStorage.load('generators.log')
|
||||
const parsed = parser.parse(generatorsLog)
|
||||
const logRegions = parsed.filter((logItem: LogItem) => logItem.type === 'region')
|
||||
|
||||
let items = new Collection()
|
||||
this.regions.forEach((region: Region) => {
|
||||
const logItem = logRegions.find(
|
||||
(logItem: LogItem) => logItem.filepath === `regions/${region.code.toLowerCase()}.m3u`
|
||||
)
|
||||
|
||||
if (!logItem) return
|
||||
|
||||
items.add({
|
||||
index: region.name,
|
||||
name: region.name,
|
||||
count: logItem.count,
|
||||
link: `https://iptv-org.github.io/iptv/${logItem.filepath}`
|
||||
})
|
||||
})
|
||||
|
||||
items = items.orderBy(item => item.index)
|
||||
|
||||
const output = items
|
||||
.map(item => {
|
||||
return `- ${item.name} <code>${item.link}</code>`
|
||||
})
|
||||
.join('\r\n')
|
||||
|
||||
const readmeStorage = new Storage(README_DIR)
|
||||
await readmeStorage.save('_regions.md', output)
|
||||
}
|
||||
}
|
||||
@ -1,72 +0,0 @@
|
||||
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`
|
||||
|
||||
const 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())
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue