mirror of
https://github.com/iptv-org/iptv.git
synced 2025-05-12 10:00:05 -04:00
Update scripts
This commit is contained in:
parent
5d52197f9c
commit
3fd1a03eea
5 changed files with 109 additions and 69 deletions
|
@ -7,11 +7,15 @@ import validUrl from 'valid-url'
|
||||||
let processedIssues = new Collection()
|
let processedIssues = new Collection()
|
||||||
let streams: Collection
|
let streams: Collection
|
||||||
let groupedChannels: Dictionary
|
let groupedChannels: Dictionary
|
||||||
|
let issues: Collection
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const logger = new Logger({ disabled: true })
|
const logger = new Logger({ disabled: true })
|
||||||
const loader = new IssueLoader()
|
const loader = new IssueLoader()
|
||||||
|
|
||||||
|
logger.info('loading issues...')
|
||||||
|
issues = await loader.load()
|
||||||
|
|
||||||
logger.info('loading channels from api...')
|
logger.info('loading channels from api...')
|
||||||
const dataStorage = new Storage(DATA_DIR)
|
const dataStorage = new Storage(DATA_DIR)
|
||||||
const channelsContent = await dataStorage.json('channels.json')
|
const channelsContent = await dataStorage.json('channels.json')
|
||||||
|
@ -51,8 +55,10 @@ async function main() {
|
||||||
main()
|
main()
|
||||||
|
|
||||||
async function removeStreams(loader: IssueLoader) {
|
async function removeStreams(loader: IssueLoader) {
|
||||||
const issues = await loader.load({ labels: ['streams:remove', 'approved'] })
|
const requests = issues.filter(
|
||||||
issues.forEach((issue: Issue) => {
|
issue => issue.labels.includes('streams:remove') && issue.labels.includes('approved')
|
||||||
|
)
|
||||||
|
requests.forEach((issue: Issue) => {
|
||||||
const data = issue.data
|
const data = issue.data
|
||||||
if (data.missing('broken_links')) return
|
if (data.missing('broken_links')) return
|
||||||
|
|
||||||
|
@ -72,8 +78,10 @@ async function removeStreams(loader: IssueLoader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function editStreams(loader: IssueLoader) {
|
async function editStreams(loader: IssueLoader) {
|
||||||
const issues = await loader.load({ labels: ['streams:edit', 'approved'] })
|
const requests = issues.filter(
|
||||||
issues.forEach((issue: Issue) => {
|
issue => issue.labels.includes('streams:edit') && issue.labels.includes('approved')
|
||||||
|
)
|
||||||
|
requests.forEach((issue: Issue) => {
|
||||||
const data = issue.data
|
const data = issue.data
|
||||||
|
|
||||||
if (data.missing('stream_url')) return
|
if (data.missing('stream_url')) return
|
||||||
|
@ -106,8 +114,10 @@ async function editStreams(loader: IssueLoader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addStreams(loader: IssueLoader) {
|
async function addStreams(loader: IssueLoader) {
|
||||||
const issues = await loader.load({ labels: ['streams:add', 'approved'] })
|
const requests = issues.filter(
|
||||||
issues.forEach((issue: Issue) => {
|
issue => issue.labels.includes('streams:add') && issue.labels.includes('approved')
|
||||||
|
)
|
||||||
|
requests.forEach((issue: Issue) => {
|
||||||
const data = issue.data
|
const data = issue.data
|
||||||
if (data.missing('channel_id') || data.missing('stream_url')) return
|
if (data.missing('channel_id') || data.missing('stream_url')) return
|
||||||
if (streams.includes((_stream: Stream) => _stream.url === data.getString('stream_url'))) return
|
if (streams.includes((_stream: Stream) => _stream.url === data.getString('stream_url'))) return
|
||||||
|
|
|
@ -9,31 +9,34 @@ async function main() {
|
||||||
|
|
||||||
const storage = new Storage(DATA_DIR)
|
const storage = new Storage(DATA_DIR)
|
||||||
|
|
||||||
logger.info('loading channels from api...')
|
logger.info('loading issues...')
|
||||||
const channelsContent = await storage.json('channels.json')
|
const issues = await loader.load()
|
||||||
const groupedChannels = new Collection(channelsContent)
|
|
||||||
.map(data => new Channel(data))
|
|
||||||
.groupBy((channel: Channel) => channel.id)
|
|
||||||
|
|
||||||
logger.info('loading blocklist from api...')
|
|
||||||
const blocklistContent = await storage.json('blocklist.json')
|
|
||||||
const groupedBlocklist = new Collection(blocklistContent)
|
|
||||||
.map(data => new Blocked(data))
|
|
||||||
.groupBy((blocked: Blocked) => blocked.channel)
|
|
||||||
|
|
||||||
logger.info('loading streams...')
|
logger.info('loading streams...')
|
||||||
const streamsStorage = new Storage(STREAMS_DIR)
|
const streamsStorage = new Storage(STREAMS_DIR)
|
||||||
const parser = new PlaylistParser({ storage: streamsStorage })
|
const parser = new PlaylistParser({ storage: streamsStorage })
|
||||||
const files = await streamsStorage.list('**/*.m3u')
|
const files = await streamsStorage.list('**/*.m3u')
|
||||||
const streams = await parser.parse(files)
|
const streams = await parser.parse(files)
|
||||||
const groupedStreams = streams.groupBy((stream: Stream) => stream.url)
|
const streamsGroupedByUrl = streams.groupBy((stream: Stream) => stream.url)
|
||||||
|
const streamsGroupedByChannel = streams.groupBy((stream: Stream) => stream.channel)
|
||||||
|
|
||||||
|
logger.info('loading channels from api...')
|
||||||
|
const channelsContent = await storage.json('channels.json')
|
||||||
|
const channelsGroupedById = new Collection(channelsContent)
|
||||||
|
.map(data => new Channel(data))
|
||||||
|
.groupBy((channel: Channel) => channel.id)
|
||||||
|
|
||||||
|
logger.info('loading blocklist from api...')
|
||||||
|
const blocklistContent = await storage.json('blocklist.json')
|
||||||
|
const blocklistGroupedByChannel = new Collection(blocklistContent)
|
||||||
|
.map(data => new Blocked(data))
|
||||||
|
.groupBy((blocked: Blocked) => blocked.channel)
|
||||||
|
|
||||||
logger.info('creating report...')
|
|
||||||
let report = new Collection()
|
let report = new Collection()
|
||||||
|
|
||||||
logger.info('checking streams:add requests...')
|
logger.info('checking streams:add requests...')
|
||||||
const addRequests = await loader.load({ labels: ['streams:add'] })
|
const addRequests = issues.filter(issue => issue.labels.includes('streams:add'))
|
||||||
const buffer = new Dictionary()
|
const addRequestsBuffer = new Dictionary()
|
||||||
addRequests.forEach((issue: Issue) => {
|
addRequests.forEach((issue: Issue) => {
|
||||||
const channelId = issue.data.getString('channel_id') || undefined
|
const channelId = issue.data.getString('channel_id') || undefined
|
||||||
const streamUrl = issue.data.getString('stream_url')
|
const streamUrl = issue.data.getString('stream_url')
|
||||||
|
@ -42,24 +45,25 @@ async function main() {
|
||||||
issueNumber: issue.number,
|
issueNumber: issue.number,
|
||||||
type: 'streams:add',
|
type: 'streams:add',
|
||||||
channelId,
|
channelId,
|
||||||
status: undefined
|
streamUrl,
|
||||||
|
status: 'pending'
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!channelId) result.set('status', 'missing_id')
|
if (!channelId) result.set('status', 'missing_id')
|
||||||
else if (!streamUrl) result.set('status', 'missing_link')
|
else if (!streamUrl) result.set('status', 'missing_link')
|
||||||
else if (groupedBlocklist.has(channelId)) result.set('status', 'blocked')
|
else if (blocklistGroupedByChannel.has(channelId)) result.set('status', 'blocked')
|
||||||
else if (groupedChannels.missing(channelId)) result.set('status', 'invalid_id')
|
else if (channelsGroupedById.missing(channelId)) result.set('status', 'wrong_id')
|
||||||
else if (groupedStreams.has(streamUrl)) result.set('status', 'fullfilled')
|
else if (streamsGroupedByUrl.has(streamUrl)) result.set('status', 'on_playlist')
|
||||||
else if (buffer.has(streamUrl)) result.set('status', 'duplicate')
|
else if (addRequestsBuffer.has(streamUrl)) result.set('status', 'duplicate')
|
||||||
else result.set('status', 'pending')
|
else result.set('status', 'pending')
|
||||||
|
|
||||||
buffer.set(streamUrl, true)
|
addRequestsBuffer.set(streamUrl, true)
|
||||||
|
|
||||||
report.add(result.data())
|
report.add(result.data())
|
||||||
})
|
})
|
||||||
|
|
||||||
logger.info('checking streams:edit requests...')
|
logger.info('checking streams:edit requests...')
|
||||||
const editRequests = await loader.load({ labels: ['streams:edit'] })
|
const editRequests = issues.filter(issue => issue.labels.find(label => label === 'streams:edit'))
|
||||||
editRequests.forEach((issue: Issue) => {
|
editRequests.forEach((issue: Issue) => {
|
||||||
const channelId = issue.data.getString('channel_id') || undefined
|
const channelId = issue.data.getString('channel_id') || undefined
|
||||||
const streamUrl = issue.data.getString('stream_url') || undefined
|
const streamUrl = issue.data.getString('stream_url') || undefined
|
||||||
|
@ -68,37 +72,82 @@ async function main() {
|
||||||
issueNumber: issue.number,
|
issueNumber: issue.number,
|
||||||
type: 'streams:edit',
|
type: 'streams:edit',
|
||||||
channelId,
|
channelId,
|
||||||
status: undefined
|
streamUrl,
|
||||||
|
status: 'pending'
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!streamUrl) result.set('status', 'missing_link')
|
if (!streamUrl) result.set('status', 'missing_link')
|
||||||
else if (groupedStreams.missing(streamUrl)) result.set('status', 'invalid_link')
|
else if (streamsGroupedByUrl.missing(streamUrl)) result.set('status', 'invalid_link')
|
||||||
else if (channelId && groupedChannels.missing(channelId)) result.set('status', 'invalid_id')
|
else if (channelId && channelsGroupedById.missing(channelId)) result.set('status', 'invalid_id')
|
||||||
else result.set('status', 'pending')
|
|
||||||
|
|
||||||
report.add(result.data())
|
report.add(result.data())
|
||||||
})
|
})
|
||||||
|
|
||||||
logger.info('checking broken streams reports...')
|
logger.info('checking broken streams reports...')
|
||||||
const brokenStreamReports = await loader.load({ labels: ['broken stream'] })
|
const brokenStreamReports = issues.filter(issue =>
|
||||||
|
issue.labels.find(label => label === 'broken stream')
|
||||||
|
)
|
||||||
brokenStreamReports.forEach((issue: Issue) => {
|
brokenStreamReports.forEach((issue: Issue) => {
|
||||||
const brokenLinks = issue.data.getString('broken_links') || undefined
|
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')
|
||||||
|
|
||||||
const result = new Dictionary({
|
const result = new Dictionary({
|
||||||
issueNumber: issue.number,
|
issueNumber: issue.number,
|
||||||
type: 'broken stream',
|
type: 'channel search',
|
||||||
channelId: undefined,
|
channelId,
|
||||||
status: undefined
|
streamUrl: undefined,
|
||||||
|
status: 'pending'
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!brokenLinks) result.set('status', 'missing_link')
|
if (!channelId) result.set('status', 'missing_id')
|
||||||
else if (groupedStreams.missing(brokenLinks)) result.set('status', 'invalid_link')
|
else if (channelsGroupedById.missing(channelId)) result.set('status', 'invalid_id')
|
||||||
else result.set('status', 'pending')
|
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')
|
||||||
|
|
||||||
|
channelSearchRequestsBuffer.set(channelId, true)
|
||||||
|
|
||||||
report.add(result.data())
|
report.add(result.data())
|
||||||
})
|
})
|
||||||
|
|
||||||
report = report.orderBy(item => item.issueNumber)
|
report = report.orderBy(item => item.issueNumber).filter(item => item.status !== 'pending')
|
||||||
|
|
||||||
console.table(report.all())
|
console.table(report.all())
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,6 @@ export class IssueData {
|
||||||
getArray(key: string): string[] {
|
getArray(key: string): string[] {
|
||||||
const deleteSymbol = '~'
|
const deleteSymbol = '~'
|
||||||
|
|
||||||
return this._data.get(key) === deleteSymbol ? [] : this._data.get(key).split(';')
|
return this._data.get(key) === deleteSymbol ? [] : this._data.get(key).split('\r\n')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,33 +9,14 @@ const CustomOctokit = Octokit.plugin(paginateRest, restEndpointMethods)
|
||||||
const octokit = new CustomOctokit()
|
const octokit = new CustomOctokit()
|
||||||
|
|
||||||
export class IssueLoader {
|
export class IssueLoader {
|
||||||
async load({ labels }: { labels: string[] | string }) {
|
async load(props?: { labels: string | string[] }) {
|
||||||
labels = Array.isArray(labels) ? labels.join(',') : labels
|
let labels = ''
|
||||||
|
if (props && props.labels) {
|
||||||
|
labels = Array.isArray(props.labels) ? props.labels.join(',') : props.labels
|
||||||
|
}
|
||||||
let issues: object[] = []
|
let issues: object[] = []
|
||||||
if (TESTING) {
|
if (TESTING) {
|
||||||
switch (labels) {
|
issues = (await import('../../tests/__data__/input/issues/all.js')).default
|
||||||
case 'streams:add':
|
|
||||||
issues = (await import('../../tests/__data__/input/issues/streams_add.js')).default
|
|
||||||
break
|
|
||||||
case 'streams:edit':
|
|
||||||
issues = (await import('../../tests/__data__/input/issues/streams_edit.js')).default
|
|
||||||
break
|
|
||||||
case 'broken stream':
|
|
||||||
issues = (await import('../../tests/__data__/input/issues/broken_stream.js')).default
|
|
||||||
break
|
|
||||||
case 'streams:add,approved':
|
|
||||||
issues = (await import('../../tests/__data__/input/issues/streams_add_approved.js'))
|
|
||||||
.default
|
|
||||||
break
|
|
||||||
case 'streams:edit,approved':
|
|
||||||
issues = (await import('../../tests/__data__/input/issues/streams_edit_approved.js'))
|
|
||||||
.default
|
|
||||||
break
|
|
||||||
case 'streams:remove,approved':
|
|
||||||
issues = (await import('../../tests/__data__/input/issues/streams_remove_approved.js'))
|
|
||||||
.default
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
issues = await octokit.paginate(octokit.rest.issues.listForRepo, {
|
issues = await octokit.paginate(octokit.rest.issues.listForRepo, {
|
||||||
owner: OWNER,
|
owner: OWNER,
|
||||||
|
|
|
@ -25,11 +25,11 @@ const FIELDS = new Dictionary({
|
||||||
|
|
||||||
export class IssueParser {
|
export class IssueParser {
|
||||||
parse(issue: { number: number; body: string; labels: { name: string }[] }): Issue {
|
parse(issue: { number: number; body: string; labels: { name: string }[] }): Issue {
|
||||||
const fields = issue.body.split('###')
|
const fields = typeof issue.body === 'string' ? issue.body.split('###') : []
|
||||||
|
|
||||||
const data = new Dictionary()
|
const data = new Dictionary()
|
||||||
fields.forEach((field: string) => {
|
fields.forEach((field: string) => {
|
||||||
const parsed = field.split(/\r?\n/).filter(Boolean)
|
const parsed = typeof field === 'string' ? field.split(/\r?\n/).filter(Boolean) : []
|
||||||
let _label = parsed.shift()
|
let _label = parsed.shift()
|
||||||
_label = _label ? _label.trim() : ''
|
_label = _label ? _label.trim() : ''
|
||||||
let _value = parsed.join('\r\n')
|
let _value = parsed.join('\r\n')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue