Files
iptv/scripts/commands/playlist/generate.ts
T
Sanaei 994b12fb25 fix: correct Live 24/7 handling and label regressions
- stream.updateWithIssue: 'Live 24/7: Yes' meant the stream IS 24/7, but it
  was assigned straight to isNot247, inverting the label. A 'No' answer was
  also ignored because the guard skipped falsy values.
- dataSet.getBoolean: an unanswered dropdown is stored as '' by
  parseIssueBody, which getBoolean read as false. Treat it as undefined so
  'no answer' means 'leave unchanged' instead of 'Not 24/7'.
- update.addStream: has() is true for an unanswered field, so it produced
  isNot247 = true for issues that left the dropdown blank.
- generate: sortBy got five orders for four iteratees.
- 2_streams_edit.yml: restore the '~' reset option dropped from the quality
  dropdown when the Label field was removed.
- stream.getLabels: use const to satisfy prefer-const.
2026-09-04 18:02:35 +02:00

102 lines
3.3 KiB
TypeScript

import { LOGS_DIR, STREAMS_DIR } from '../../constants'
import { Storage, File } from '@freearhey/storage-js'
import { PlaylistParser } from '../../core'
import { loadData, data } from '../../api'
import { Logger } from '@freearhey/core'
import uniqueId from 'lodash.uniqueid'
import { Stream } from '../../models'
import {
IndexCategoryGenerator,
IndexLanguageGenerator,
IndexCountryGenerator,
SubdivisionsGenerator,
CategoriesGenerator,
CountriesGenerator,
LanguagesGenerator,
RegionsGenerator,
SourcesGenerator,
CitiesGenerator,
IndexGenerator,
RawGenerator
} from '../../generators'
async function main() {
const logger = new Logger()
const logFile = new File('generators.log')
logger.info('loading data from api...')
await loadData()
logger.info('loading streams...')
const streamsStorage = new Storage(STREAMS_DIR)
const parser = new PlaylistParser({
storage: streamsStorage
})
const files = await streamsStorage.list('**/*.m3u')
let streams = await parser.parse(files)
streams = streams.map((stream: Stream) => {
stream.setGuides(data.guidesGroupedByStreamId.get(stream.getId()))
return stream
})
const totalStreams = streams.count()
logger.info(`found ${totalStreams} streams`)
logger.info('generating raw/...')
await new RawGenerator({ streams, logFile }).generate()
logger.info('sorting streams...')
streams = streams.sortBy(
[
(stream: Stream) => stream.getId(),
(stream: Stream) => (stream.isGeoBlocked ? -1 : 0),
(stream: Stream) => (stream.isNot247 ? -1 : 0),
(stream: Stream) => stream.getVerticalResolution()
],
['asc', 'desc', 'desc', 'desc']
)
logger.info('filtering streams...')
streams = streams.uniqBy((stream: Stream) => stream.getId() || uniqueId())
const { categories, countries, subdivisions, cities, regions } = data
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, streams, logFile }).generate()
logger.info('generating subdivisions/...')
await new SubdivisionsGenerator({ subdivisions, streams, logFile }).generate()
logger.info('generating cities/...')
await new CitiesGenerator({ cities, streams, logFile }).generate()
logger.info('generating regions/...')
await new RegionsGenerator({ streams, regions, logFile }).generate()
logger.info('generating sources/...')
await new SourcesGenerator({ streams, logFile }).generate()
logger.info('generating index.m3u...')
await new IndexGenerator({ streams, logFile }).generate()
logger.info('generating index.category.m3u...')
await new IndexCategoryGenerator({ streams, logFile }).generate()
logger.info('generating index.country.m3u...')
await new IndexCountryGenerator({ streams, logFile }).generate()
logger.info('generating index.language.m3u...')
await new IndexLanguageGenerator({ streams, logFile }).generate()
logger.info('saving generators.log...')
const logStorage = new Storage(LOGS_DIR)
logStorage.saveFile(logFile)
}
main()