Update scripts

pull/19986/head
freearhey 2 months ago
parent 5d52197f9c
commit 3fd1a03eea

@ -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 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)
logger.info('loading channels from api...') logger.info('loading channels from api...')
const channelsContent = await storage.json('channels.json') const channelsContent = await storage.json('channels.json')
const groupedChannels = new Collection(channelsContent) const channelsGroupedById = new Collection(channelsContent)
.map(data => new Channel(data)) .map(data => new Channel(data))
.groupBy((channel: Channel) => channel.id) .groupBy((channel: Channel) => channel.id)
logger.info('loading blocklist from api...') logger.info('loading blocklist from api...')
const blocklistContent = await storage.json('blocklist.json') const blocklistContent = await storage.json('blocklist.json')
const groupedBlocklist = new Collection(blocklistContent) const blocklistGroupedByChannel = new Collection(blocklistContent)
.map(data => new Blocked(data)) .map(data => new Blocked(data))
.groupBy((blocked: Blocked) => blocked.channel) .groupBy((blocked: Blocked) => blocked.channel)
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 groupedStreams = streams.groupBy((stream: Stream) => stream.url)
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…
Cancel
Save