Files
iptv/scripts/commands/report/create.ts

160 lines
5.5 KiB
TypeScript
Raw Normal View History

2023-09-22 05:17:22 +03:00
import { Logger, Storage, Collection, Dictionary } from '@freearhey/core'
2023-09-17 04:08:50 +03:00
import { DATA_DIR, STREAMS_DIR } from '../../constants'
2023-09-22 05:17:22 +03:00
import { IssueLoader, PlaylistParser } from '../../core'
2023-09-17 04:08:50 +03:00
import { Blocked, Channel, Issue, Stream } from '../../models'
2023-09-15 18:40:35 +03:00
async function main() {
2023-09-17 04:08:50 +03:00
const logger = new Logger()
2023-09-15 18:40:35 +03:00
const loader = new IssueLoader()
const storage = new Storage(DATA_DIR)
2025-02-27 20:55:39 +03:00
logger.info('loading issues...')
const issues = await loader.load()
logger.info('loading streams...')
const streamsStorage = new Storage(STREAMS_DIR)
const parser = new PlaylistParser({ storage: streamsStorage })
const files = await streamsStorage.list('**/*.m3u')
const streams = await parser.parse(files)
const streamsGroupedByUrl = streams.groupBy((stream: Stream) => stream.url)
const streamsGroupedByChannel = streams.groupBy((stream: Stream) => stream.channel)
2023-09-17 04:08:50 +03:00
logger.info('loading channels from api...')
2023-09-15 18:40:35 +03:00
const channelsContent = await storage.json('channels.json')
2025-02-27 20:55:39 +03:00
const channelsGroupedById = new Collection(channelsContent)
2023-09-15 18:40:35 +03:00
.map(data => new Channel(data))
.groupBy((channel: Channel) => channel.id)
2023-09-17 04:08:50 +03:00
logger.info('loading blocklist from api...')
2023-09-15 18:40:35 +03:00
const blocklistContent = await storage.json('blocklist.json')
2025-02-27 20:55:39 +03:00
const blocklistGroupedByChannel = new Collection(blocklistContent)
2023-09-15 18:40:35 +03:00
.map(data => new Blocked(data))
.groupBy((blocked: Blocked) => blocked.channel)
2023-09-18 18:24:40 +03:00
let report = new Collection()
logger.info('checking streams:add requests...')
2025-02-27 20:55:39 +03:00
const addRequests = issues.filter(issue => issue.labels.includes('streams:add'))
const addRequestsBuffer = new Dictionary()
2023-09-18 18:24:40 +03:00
addRequests.forEach((issue: Issue) => {
2025-02-22 12:54:00 +03:00
const channelId = issue.data.getString('channel_id') || undefined
const streamUrl = issue.data.getString('stream_url')
2023-09-15 18:40:35 +03:00
const result = new Dictionary({
2023-09-17 04:08:50 +03:00
issueNumber: issue.number,
2023-09-18 18:24:40 +03:00
type: 'streams:add',
2023-09-15 18:40:35 +03:00
channelId,
2025-02-27 20:55:39 +03:00
streamUrl,
status: 'pending'
2023-09-15 18:40:35 +03:00
})
2023-09-18 18:24:40 +03:00
if (!channelId) result.set('status', 'missing_id')
else if (!streamUrl) result.set('status', 'missing_link')
2025-02-27 20:55:39 +03:00
else if (blocklistGroupedByChannel.has(channelId)) result.set('status', 'blocked')
else if (channelsGroupedById.missing(channelId)) result.set('status', 'wrong_id')
else if (streamsGroupedByUrl.has(streamUrl)) result.set('status', 'on_playlist')
else if (addRequestsBuffer.has(streamUrl)) result.set('status', 'duplicate')
2023-09-15 18:40:35 +03:00
else result.set('status', 'pending')
2025-02-27 20:55:39 +03:00
addRequestsBuffer.set(streamUrl, true)
2023-09-15 18:40:35 +03:00
2023-09-18 18:24:40 +03:00
report.add(result.data())
2023-09-15 18:40:35 +03:00
})
2023-09-18 18:24:40 +03:00
logger.info('checking streams:edit requests...')
2025-02-27 20:55:39 +03:00
const editRequests = issues.filter(issue => issue.labels.find(label => label === 'streams:edit'))
2023-09-18 18:24:40 +03:00
editRequests.forEach((issue: Issue) => {
2025-02-22 12:54:00 +03:00
const channelId = issue.data.getString('channel_id') || undefined
const streamUrl = issue.data.getString('stream_url') || undefined
2023-09-18 18:24:40 +03:00
const result = new Dictionary({
issueNumber: issue.number,
type: 'streams:edit',
channelId,
2025-02-27 20:55:39 +03:00
streamUrl,
status: 'pending'
2023-09-18 18:24:40 +03:00
})
if (!streamUrl) result.set('status', 'missing_link')
2025-02-27 20:55:39 +03:00
else if (streamsGroupedByUrl.missing(streamUrl)) result.set('status', 'invalid_link')
else if (channelId && channelsGroupedById.missing(channelId)) result.set('status', 'invalid_id')
2023-09-18 18:24:40 +03:00
report.add(result.data())
})
logger.info('checking broken streams reports...')
2025-02-27 20:55:39 +03:00
const brokenStreamReports = issues.filter(issue =>
issue.labels.find(label => label === 'broken stream')
)
2023-09-18 18:24:40 +03:00
brokenStreamReports.forEach((issue: Issue) => {
2025-02-27 20:55:39 +03:00
const brokenLinks = issue.data.getArray('broken_links') || []
if (!brokenLinks.length) {
const result = new Dictionary({
issueNumber: issue.number,
type: 'broken stream',
channelId: undefined,
streamUrl: undefined,
status: 'missing_link'
})
report.add(result.data())
} else {
for (const streamUrl of brokenLinks) {
const result = new Dictionary({
issueNumber: issue.number,
type: 'broken stream',
channelId: undefined,
streamUrl: undefined,
status: 'pending'
})
if (streamsGroupedByUrl.missing(streamUrl)) {
result.set('streamUrl', streamUrl)
result.set('status', 'wrong_link')
}
report.add(result.data())
}
}
})
logger.info('checking channel search requests...')
const channelSearchRequests = issues.filter(issue =>
issue.labels.find(label => label === 'channel search')
)
const channelSearchRequestsBuffer = new Dictionary()
channelSearchRequests.forEach((issue: Issue) => {
const channelId = issue.data.getString('channel_id')
2023-09-18 18:24:40 +03:00
const result = new Dictionary({
issueNumber: issue.number,
2025-02-27 20:55:39 +03:00
type: 'channel search',
channelId,
streamUrl: undefined,
status: 'pending'
2023-09-18 18:24:40 +03:00
})
2025-02-27 20:55:39 +03:00
if (!channelId) result.set('status', 'missing_id')
else if (channelsGroupedById.missing(channelId)) result.set('status', 'invalid_id')
else if (channelSearchRequestsBuffer.has(channelId)) result.set('status', 'duplicate')
else if (blocklistGroupedByChannel.has(channelId)) result.set('status', 'blocked')
else if (streamsGroupedByChannel.has(channelId)) result.set('status', 'fulfilled')
2025-02-27 22:05:31 +03:00
else {
const channelData = channelsGroupedById.get(channelId)
if (channelData.length && channelData[0].closed) result.set('status', 'closed')
}
2025-02-27 20:55:39 +03:00
channelSearchRequestsBuffer.set(channelId, true)
2023-09-18 18:24:40 +03:00
report.add(result.data())
})
2025-02-27 20:55:39 +03:00
report = report.orderBy(item => item.issueNumber).filter(item => item.status !== 'pending')
2023-09-18 18:24:40 +03:00
2023-09-15 18:40:35 +03:00
console.table(report.all())
}
main()