Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ jobs:
run: npm install
- name: update data
id: db-update
env:
GITHUB_TOKEN: ${{ env.ACT && github.token || steps.create-app-token.outputs.token }}
run: |
npm run db:update
echo "processed_issues=$(cat temp/logs/update.log)" >> $GITHUB_OUTPUT
Expand Down
5 changes: 3 additions & 2 deletions scripts/commands/issue/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ function validateAddChannelRequest(dataSet: DataSet) {
}

const channelId = createChannelId(channelName, countryCode)
if (channelId && data.channelsKeyById.get(channelId)) {
if (channelId && data.channelsKeyByIdLowerCase.has(channelId.toLowerCase())) {
errors.push(
`The database already contains a channel with name "${channelName}" and country code "${countryCode}"`
)
Expand Down Expand Up @@ -571,7 +571,7 @@ function validateEditChannelRequest(dataSet: DataSet) {
const channelName = dataSet.getString('channel_name')
const countryCode = dataSet.getString('country')
const newChannelId = createChannelId(channelName, countryCode)
if (newChannelId && data.channelsKeyById.get(newChannelId)) {
if (newChannelId && data.channelsKeyByIdLowerCase.has(newChannelId.toLowerCase())) {
errors.push(
`The database already contains a channel with name "${channelName}" and country code "${countryCode}"`
)
Expand All @@ -580,6 +580,7 @@ function validateEditChannelRequest(dataSet: DataSet) {

if (
dataSet.missing([
'channel_name',
'alt_names',
'network',
'owners',
Expand Down
7 changes: 7 additions & 0 deletions scripts/core/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ let data: DatabaseData = {
feedsGroupedByChannelId: new Dictionary<Feed[]>(),
feedsKeyByStreamId: new Dictionary<Feed>(),
channelsKeyById: new Dictionary<Channel>(),
channelsKeyByIdLowerCase: new Dictionary<Channel>(),
countriesKeyByCode: new Dictionary<Country>(),
subdivisionsKeyByCode: new Dictionary<Subdivision>(),
categoriesKeyById: new Dictionary<Category>(),
Expand Down Expand Up @@ -67,6 +68,7 @@ let cache: DatabaseData = {
feedsGroupedByChannelId: new Dictionary<Feed[]>(),
feedsKeyByStreamId: new Dictionary<Feed>(),
channelsKeyById: new Dictionary<Channel>(),
channelsKeyByIdLowerCase: new Dictionary<Channel>(),
countriesKeyByCode: new Dictionary<Country>(),
subdivisionsKeyByCode: new Dictionary<Subdivision>(),
categoriesKeyById: new Dictionary<Category>(),
Expand Down Expand Up @@ -165,6 +167,9 @@ async function loadData(): Promise<DatabaseData> {
}

data.channelsKeyById = data.channels.keyBy((channel: Channel) => channel.id)
data.channelsKeyByIdLowerCase = data.channels.keyBy((channel: Channel) =>
channel.id.toLowerCase()
)
data.feedsGroupedByChannelId = data.feeds.groupBy((feed: Feed) => feed.channel)
data.feedsKeyByStreamId = data.feeds.keyBy((feed: Feed) => feed.getStreamId())
data.categoriesKeyById = data.categories.keyBy((category: Category) => category.id)
Expand Down Expand Up @@ -219,6 +224,7 @@ function cacheData() {
feedsGroupedByChannelId: data.feedsGroupedByChannelId.clone(),
feedsKeyByStreamId: data.feedsKeyByStreamId.clone(),
channelsKeyById: data.channelsKeyById.clone(),
channelsKeyByIdLowerCase: data.channelsKeyByIdLowerCase.clone(),
countriesKeyByCode: data.countriesKeyByCode.clone(),
subdivisionsKeyByCode: data.subdivisionsKeyByCode.clone(),
categoriesKeyById: data.categoriesKeyById.clone(),
Expand Down Expand Up @@ -249,6 +255,7 @@ function resetData() {
feedsGroupedByChannelId: cache.feedsGroupedByChannelId,
feedsKeyByStreamId: cache.feedsKeyByStreamId,
channelsKeyById: cache.channelsKeyById,
channelsKeyByIdLowerCase: cache.channelsKeyByIdLowerCase,
countriesKeyByCode: cache.countriesKeyByCode,
subdivisionsKeyByCode: cache.subdivisionsKeyByCode,
categoriesKeyById: cache.categoriesKeyById,
Expand Down
4 changes: 3 additions & 1 deletion scripts/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ export async function loadIssues(props?: {
typeof octokit.rest.issues.listForRepo
>[number]
const CustomOctokit = Octokit.plugin(paginateRest, restEndpointMethods)
const octokit = new CustomOctokit()
const octokit = new CustomOctokit({
auth: process.env.GITHUB_TOKEN
})

let labels = ''
if (props && props.labels) {
Expand Down
1 change: 1 addition & 0 deletions scripts/types/db.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export type DatabaseData = {
citiesKeyByWikidataId: Dictionary<City>
citiesKeyByCode: Dictionary<City>
channelsKeyById: Dictionary<Channel>
channelsKeyByIdLowerCase: Dictionary<Channel>
countriesKeyByCode: Dictionary<Country>
subdivisionsKeyByCode: Dictionary<Subdivision>
categoriesKeyById: Dictionary<Category>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The request contains error(s):
- The database already contains a channel with name "0 tv" and country code "DK"
3 changes: 2 additions & 1 deletion tests/__data__/input/issue/validate/data/channels.csv
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ SagarmathaTV.np,Sagarmatha TV,,,,NP,general,FALSE,,,,
24HorasCanarias.es,24 Horas Canarias,,,,ES,general,FALSE,,,,
SonySportsTen4.in,Sony Sports Ten 4,Ten4;Ten,Sony,Sony Inc.,IN,general,FALSE,2024-09-01,2025-07-01,24HorasCanarias.es,https://sony.com/
FuboSportsNetwork.us,Fubo Sports Network,,,,US,general,FALSE,,,,
OmkarTV.np,Omkar TV,,,,NP,general,FALSE,,,,
OmkarTV.np,Omkar TV,,,,NP,general,FALSE,,,,
TochkaRF.ru,TochkaRF,,,,RU,general,FALSE,,,,
2 changes: 2 additions & 0 deletions tests/__data__/input/issue/validate/data/timezones.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
id,utc_offset,countries
Africa/Abidjan,+00:00,CI;BF;GH;GM;GN;IS;ML;MR;SH;SL;SN;TG
182 changes: 182 additions & 0 deletions tests/__data__/input/issue/validate/issues.js
Original file line number Diff line number Diff line change
Expand Up @@ -3535,5 +3535,187 @@ module.exports = [
performed_via_github_app: null,
state_reason: null,
pinned_comment: null
},
{
url: 'https://api.github.com/repos/iptv-org/database/issues/31990',
repository_url: 'https://api.github.com/repos/iptv-org/database',
labels_url: 'https://api.github.com/repos/iptv-org/database/issues/31990/labels{/name}',
comments_url: 'https://api.github.com/repos/iptv-org/database/issues/31990/comments',
events_url: 'https://api.github.com/repos/iptv-org/database/issues/31990/events',
html_url: 'https://github.com/iptv-org/database/issues/31990',
id: 5167003676,
node_id: 'I_kwDOG1Kwp88AAAABM_o4HA',
number: 31990,
title: 'Edit: One Media Network (PH)',
user: {
login: 'LPhilip1999',
id: 107766357,
node_id: 'U_kgDOBmxiVQ',
avatar_url: 'https://avatars.githubusercontent.com/u/107766357?v=4',
gravatar_id: '',
url: 'https://api.github.com/users/LPhilip1999',
html_url: 'https://github.com/LPhilip1999',
followers_url: 'https://api.github.com/users/LPhilip1999/followers',
following_url: 'https://api.github.com/users/LPhilip1999/following{/other_user}',
gists_url: 'https://api.github.com/users/LPhilip1999/gists{/gist_id}',
starred_url: 'https://api.github.com/users/LPhilip1999/starred{/owner}{/repo}',
subscriptions_url: 'https://api.github.com/users/LPhilip1999/subscriptions',
organizations_url: 'https://api.github.com/users/LPhilip1999/orgs',
repos_url: 'https://api.github.com/users/LPhilip1999/repos',
events_url: 'https://api.github.com/users/LPhilip1999/events{/privacy}',
received_events_url: 'https://api.github.com/users/LPhilip1999/received_events',
type: 'User',
user_view_type: 'public',
site_admin: false
},
labels: [
{
id: 5303574335,
node_id: 'LA_kwDOG1Kwp88AAAABPB4fPw',
url: 'https://api.github.com/repos/iptv-org/database/labels/channels:edit',
name: 'channels:edit',
color: 'D50289',
default: false,
description: 'Request to edit channel description'
},
{
id: 5366738347,
node_id: 'LA_kwDOG1Kwp88AAAABP-Htqw',
url: 'https://api.github.com/repos/iptv-org/database/labels/approved',
name: 'approved',
color: '85DDDE',
default: false,
description: ''
}
],
state: 'open',
locked: false,
assignees: [],
milestone: null,
comments: 0,
created_at: '2026-08-17T00:01:23Z',
updated_at: '2026-08-17T01:42:55Z',
closed_at: null,
assignee: null,
author_association: 'CONTRIBUTOR',
issue_field_values: [],
type: null,
active_lock_reason: null,
sub_issues_summary: { total: 0, completed: 0, percent_completed: 0 },
issue_dependencies_summary: {
blocked_by: 0,
total_blocked_by: 1,
blocking: 0,
total_blocking: 0
},
body: '### Channel ID (required)\n\nTochkaRF.ru\n\n### Channel Name\n\nTochka.rf\n\n### Alternative Names\n\n_No response_\n\n### Network\n\n_No response_\n\n### Owners\n\n_No response_\n\n### Country\n\n_No response_\n\n### Categories\n\n_No response_\n\n### NSFW\n\n_No response_\n\n### Launched\n\n_No response_\n\n### Closed\n\n_No response_\n\n### Replaced By\n\n_No response_\n\n### Website\n\n_No response_\n\n### Notes\n\n_No response_',
closed_by: null,
reactions: {
url: 'https://api.github.com/repos/iptv-org/database/issues/31990/reactions',
total_count: 0,
'+1': 0,
'-1': 0,
laugh: 0,
hooray: 0,
confused: 0,
heart: 0,
rocket: 0,
eyes: 0
},
timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/31990/timeline',
performed_via_github_app: null,
state_reason: null,
pinned_comment: null
},
{
url: 'https://api.github.com/repos/iptv-org/database/issues/31991',
repository_url: 'https://api.github.com/repos/iptv-org/database',
labels_url: 'https://api.github.com/repos/iptv-org/database/issues/31991/labels{/name}',
comments_url: 'https://api.github.com/repos/iptv-org/database/issues/31991/comments',
events_url: 'https://api.github.com/repos/iptv-org/database/issues/31991/events',
html_url: 'https://github.com/iptv-org/database/issues/31991',
id: 5163645890,
node_id: 'I_kwDOG1Kwp88AAAABM8b7wg',
number: 31991,
title: 'Add: DEEWANA',
user: {
login: 'cancerbikash-oss',
id: 268401535,
node_id: 'U_kgDOD_97fw',
avatar_url: 'https://avatars.githubusercontent.com/u/268401535?v=4',
gravatar_id: '',
url: 'https://api.github.com/users/cancerbikash-oss',
html_url: 'https://github.com/cancerbikash-oss',
followers_url: 'https://api.github.com/users/cancerbikash-oss/followers',
following_url: 'https://api.github.com/users/cancerbikash-oss/following{/other_user}',
gists_url: 'https://api.github.com/users/cancerbikash-oss/gists{/gist_id}',
starred_url: 'https://api.github.com/users/cancerbikash-oss/starred{/owner}{/repo}',
subscriptions_url: 'https://api.github.com/users/cancerbikash-oss/subscriptions',
organizations_url: 'https://api.github.com/users/cancerbikash-oss/orgs',
repos_url: 'https://api.github.com/users/cancerbikash-oss/repos',
events_url: 'https://api.github.com/users/cancerbikash-oss/events{/privacy}',
received_events_url: 'https://api.github.com/users/cancerbikash-oss/received_events',
type: 'User',
user_view_type: 'public',
site_admin: false
},
labels: [
{
id: 4480954589,
node_id: 'LA_kwDOG1Kwp88AAAABCxXw3Q',
url: 'https://api.github.com/repos/iptv-org/database/labels/need%20more%20info',
name: 'need more info',
color: '11607C',
default: false,
description: ''
},
{
id: 5303575699,
node_id: 'LA_kwDOG1Kwp88AAAABPB4kkw',
url: 'https://api.github.com/repos/iptv-org/database/labels/channels:add',
name: 'channels:add',
color: '017ff8',
default: false,
description: 'Request to add a channel into the database'
}
],
state: 'open',
locked: false,
assignees: [],
milestone: null,
comments: 2,
created_at: '2026-08-16T09:31:16Z',
updated_at: '2026-08-17T06:25:31Z',
closed_at: null,
assignee: null,
author_association: 'NONE',
issue_field_values: [],
type: null,
active_lock_reason: null,
sub_issues_summary: { total: 0, completed: 0, percent_completed: 0 },
issue_dependencies_summary: {
blocked_by: 0,
total_blocked_by: 0,
blocking: 0,
total_blocking: 0
},
body: '### Channel Name\n\n0 tv\n\n### Alternative Names (optional)\n\n_No response_\n\n### Network (optional)\n\n_No response_\n\n### Owners (optional)\n\n_No response_\n\n### Country\n\nDK\n\n### Categories (optional)\n\n_No response_\n\n### NSFW\n\nFALSE\n\n### Launched (optional)\n\n_No response_\n\n### Closed (optional)\n\n_No response_\n\n### Replaced By (optional)\n\n_No response_\n\n### Website (optional)\n\n_No response_\n\n### Feed Name\n\nSD\n\n### Feed Alternative Names (optional)\n\nNepal \n\n### Broadcast Area\n\nc/DK\n\n### Timezones\n\nAfrica/Abidjan\n\n### Languages\n\neng\n\n### Format\n\n720p\n\n### Logo URL\n\nhttps://i.imgur.com/xIYITQ9.png\n\n### In Use\n\nTRUE\n\n### Logo Tags (optional)\n\n_No response_\n\n### Notes (optional)\n\n_No response_',
closed_by: null,
reactions: {
url: 'https://api.github.com/repos/iptv-org/database/issues/31991/reactions',
total_count: 0,
'+1': 0,
'-1': 0,
laugh: 0,
hooray: 0,
confused: 0,
heart: 0,
rocket: 0,
eyes: 0
},
timeline_url: 'https://api.github.com/repos/iptv-org/database/issues/31991/timeline',
performed_via_github_app: null,
state_reason: null,
pinned_comment: null
}
]
31 changes: 31 additions & 0 deletions tests/commands/issue/validate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,23 @@ describe('issue:validate', () => {
}
})

it('can handle channels:add request with duplicate', () => {
const body = issues.find(issue => issue.number === 31991)?.body
const cmd = `${ENV_VAR} npm run issue:validate --- --body="${body}" --labels="approved,channels:add"`

if (process.env.DEBUG === 'true') console.log(cmd)
try {
const stdout = execSync(cmd, { encoding: 'utf8' })
if (process.env.DEBUG === 'true') console.log(stdout)
process.exit(0)
} catch (error) {
if (process.env.DEBUG === 'true') console.log(error)
expect(content('tests/__data__/output/logs/errors.txt')).toBe(
content('tests/__data__/expected/issue/validate/logs/channels_add_duplicate.txt')
)
}
})

it('can handle channels:edit request', () => {
const body = issues.find(issue => issue.number === 31760)?.body
const cmd = `${ENV_VAR} npm run issue:validate --- --body="${body}" --labels="approved,channels:edit"`
Expand All @@ -46,6 +63,20 @@ describe('issue:validate', () => {
}
})

it('can handle channels:edit request with new channel name only', () => {
const body = issues.find(issue => issue.number === 31990)?.body
const cmd = `${ENV_VAR} npm run issue:validate --- --body="${body}" --labels="approved,channels:edit"`

if (process.env.DEBUG === 'true') console.log(cmd)
try {
const stdout = execSync(cmd, { encoding: 'utf8' })
if (process.env.DEBUG === 'true') console.log(stdout)
} catch (error) {
if (process.env.DEBUG === 'true') console.log(error)
process.exit(0)
}
})

it('can handle channels:edit request without changes', () => {
const body = issues.find(issue => issue.number === 31767)?.body
const cmd = `${ENV_VAR} npm run issue:validate --- --body="${body}" --labels="approved,channels:edit"`
Expand Down
Loading