You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iptv/scripts/tables/countriesTable.ts

177 lines
6.0 KiB
TypeScript

import { LOGS_DIR, README_DIR } from '../constants'
import { Storage } from '@freearhey/storage-js'
import { Collection } from '@freearhey/core'
import { LogParser, LogItem } from '../core'
import * as sdk from '@iptv-org/sdk'
import { Table } from './table'
import { data } from '../api'
type ListItem = {
index: string
count: number
link: string
name: string
children: Collection<ListItem>
}
export class CountriesTable implements Table {
async create() {
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()
data.countries.forEach((country: sdk.Models.Country) => {
const countryCode = country.code
const countriesLogItem = logCountries.find(
(logItem: LogItem) => logItem.filepath === `countries/${countryCode.toLowerCase()}.m3u`
)
const countryItem: ListItem = {
index: country.name,
count: 0,
link: `https://iptv-org.github.io/iptv/countries/${countryCode.toLowerCase()}.m3u`,
name: `${country.flag} ${country.name}`,
children: new Collection()
}
if (countriesLogItem) {
countryItem.count = countriesLogItem.count
}
const countrySubdivisions = data.subdivisions.filter(
(subdivision: sdk.Models.Subdivision) => subdivision.country === countryCode
)
const countryCities = data.cities.filter(
(city: sdk.Models.City) => city.country === countryCode
)
if (countrySubdivisions.isNotEmpty()) {
data.subdivisions.forEach((subdivision: sdk.Models.Subdivision) => {
if (subdivision.country !== countryCode) return
const subdivisionCode = subdivision.code
const subdivisionCities = countryCities.filter(
(city: sdk.Models.City) =>
(city.subdivision && city.subdivision === subdivisionCode) ||
city.country === subdivision.country
)
const subdivisionsLogItem = logSubdivisions.find(
(logItem: LogItem) =>
logItem.filepath === `subdivisions/${subdivisionCode.toLowerCase()}.m3u`
)
const subdivisionItem: ListItem = {
index: subdivision.name,
name: subdivision.name,
count: 0,
link: `https://iptv-org.github.io/iptv/subdivisions/${subdivisionCode.toLowerCase()}.m3u`,
children: new Collection<ListItem>()
}
if (subdivisionsLogItem) {
subdivisionItem.count = subdivisionsLogItem.count
}
subdivisionCities.forEach((city: sdk.Models.City) => {
if (city.country !== countryCode || city.subdivision !== subdivisionCode) 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}`,
children: new Collection<ListItem>()
})
})
if (subdivisionItem.count > 0 || subdivisionItem.children.isNotEmpty()) {
countryItem.children.add(subdivisionItem)
}
})
} else if (countryCities.isNotEmpty()) {
countryCities.forEach((city: sdk.Models.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.isNotEmpty()) {
items.add(countryItem)
}
})
const internationalLogItem = logCountries.find(
(logItem: LogItem) => logItem.filepath === 'countries/int.m3u'
)
if (internationalLogItem) {
items.add({
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.add({
index: 'ZZZ',
name: 'Undefined',
count: undefinedLogItem.count,
link: `https://iptv-org.github.io/iptv/${undefinedLogItem.filepath}`,
children: new Collection()
})
}
items = items.sortBy(item => item.index)
const output = items
.map((item: ListItem) => {
let row = `- ${item.name} <code>${item.link}</code>`
item.children
.sortBy((item: ListItem) => item.index)
.forEach((item: ListItem) => {
row += `\r\n - ${item.name} <code>${item.link}</code>`
item.children
.sortBy((item: ListItem) => item.index)
.forEach((item: ListItem) => {
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)
}
}