From f383afbc6efdf5515c20f328e1b569eb4a21d7a1 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Mon, 21 Sep 2026 13:08:38 +0300 Subject: [PATCH 1/4] Update tests/__data__ --- .../validate/logs/channels_add_duplicate.txt | 2 + .../input/issue/validate/data/channels.csv | 3 +- .../input/issue/validate/data/timezones.csv | 2 + tests/__data__/input/issue/validate/issues.js | 182 ++++++++++++++++++ 4 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 tests/__data__/expected/issue/validate/logs/channels_add_duplicate.txt create mode 100644 tests/__data__/input/issue/validate/data/timezones.csv diff --git a/tests/__data__/expected/issue/validate/logs/channels_add_duplicate.txt b/tests/__data__/expected/issue/validate/logs/channels_add_duplicate.txt new file mode 100644 index 0000000000..361e4d3e23 --- /dev/null +++ b/tests/__data__/expected/issue/validate/logs/channels_add_duplicate.txt @@ -0,0 +1,2 @@ +The request contains error(s): +- The database already contains a channel with name "0 tv" and country code "DK" \ No newline at end of file diff --git a/tests/__data__/input/issue/validate/data/channels.csv b/tests/__data__/input/issue/validate/data/channels.csv index e36ada9966..7db13b2203 100644 --- a/tests/__data__/input/issue/validate/data/channels.csv +++ b/tests/__data__/input/issue/validate/data/channels.csv @@ -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,,,, \ No newline at end of file +OmkarTV.np,Omkar TV,,,,NP,general,FALSE,,,, +TochkaRF.ru,TochkaRF,,,,RU,general,FALSE,,,, \ No newline at end of file diff --git a/tests/__data__/input/issue/validate/data/timezones.csv b/tests/__data__/input/issue/validate/data/timezones.csv new file mode 100644 index 0000000000..727bf54721 --- /dev/null +++ b/tests/__data__/input/issue/validate/data/timezones.csv @@ -0,0 +1,2 @@ +id,utc_offset,countries +Africa/Abidjan,+00:00,CI;BF;GH;GM;GN;IS;ML;MR;SH;SL;SN;TG \ No newline at end of file diff --git a/tests/__data__/input/issue/validate/issues.js b/tests/__data__/input/issue/validate/issues.js index b60cc58c01..922be49406 100644 --- a/tests/__data__/input/issue/validate/issues.js +++ b/tests/__data__/input/issue/validate/issues.js @@ -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 } ] From 631ec55dffa961a6467edd2d1f21ecac68fb6653 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Mon, 21 Sep 2026 13:08:44 +0300 Subject: [PATCH 2/4] Update validate.test.ts --- tests/commands/issue/validate.test.ts | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/commands/issue/validate.test.ts b/tests/commands/issue/validate.test.ts index 22a3ebc682..dcbea60fa6 100644 --- a/tests/commands/issue/validate.test.ts +++ b/tests/commands/issue/validate.test.ts @@ -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"` @@ -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"` From 6f51bd863da9910753ab355bcf7972eff67afd27 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Mon, 21 Sep 2026 13:08:59 +0300 Subject: [PATCH 3/4] Update scripts --- scripts/commands/issue/validate.ts | 5 +++-- scripts/core/db.ts | 7 +++++++ scripts/core/utils.ts | 4 +++- scripts/types/db.d.ts | 1 + 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/scripts/commands/issue/validate.ts b/scripts/commands/issue/validate.ts index 36b9668343..36711d3a6c 100644 --- a/scripts/commands/issue/validate.ts +++ b/scripts/commands/issue/validate.ts @@ -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}"` ) @@ -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}"` ) @@ -580,6 +580,7 @@ function validateEditChannelRequest(dataSet: DataSet) { if ( dataSet.missing([ + 'channel_name', 'alt_names', 'network', 'owners', diff --git a/scripts/core/db.ts b/scripts/core/db.ts index 8e8eb3ff18..2e1bb3e863 100644 --- a/scripts/core/db.ts +++ b/scripts/core/db.ts @@ -38,6 +38,7 @@ let data: DatabaseData = { feedsGroupedByChannelId: new Dictionary(), feedsKeyByStreamId: new Dictionary(), channelsKeyById: new Dictionary(), + channelsKeyByIdLowerCase: new Dictionary(), countriesKeyByCode: new Dictionary(), subdivisionsKeyByCode: new Dictionary(), categoriesKeyById: new Dictionary(), @@ -67,6 +68,7 @@ let cache: DatabaseData = { feedsGroupedByChannelId: new Dictionary(), feedsKeyByStreamId: new Dictionary(), channelsKeyById: new Dictionary(), + channelsKeyByIdLowerCase: new Dictionary(), countriesKeyByCode: new Dictionary(), subdivisionsKeyByCode: new Dictionary(), categoriesKeyById: new Dictionary(), @@ -165,6 +167,9 @@ async function loadData(): Promise { } 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) @@ -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(), @@ -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, diff --git a/scripts/core/utils.ts b/scripts/core/utils.ts index fc0605a322..bd8e8e7759 100644 --- a/scripts/core/utils.ts +++ b/scripts/core/utils.ts @@ -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) { diff --git a/scripts/types/db.d.ts b/scripts/types/db.d.ts index d2d8970c93..2eeb230341 100644 --- a/scripts/types/db.d.ts +++ b/scripts/types/db.d.ts @@ -35,6 +35,7 @@ export type DatabaseData = { citiesKeyByWikidataId: Dictionary citiesKeyByCode: Dictionary channelsKeyById: Dictionary + channelsKeyByIdLowerCase: Dictionary countriesKeyByCode: Dictionary subdivisionsKeyByCode: Dictionary categoriesKeyById: Dictionary From 271b73f251eb2ff8551c9cf31ced2d1621196bff Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Mon, 21 Sep 2026 13:09:02 +0300 Subject: [PATCH 4/4] Update update.yml --- .github/workflows/update.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index 089acc81f4..ac4acc95a9 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -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