diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7196aca..77dac552 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,24 +10,24 @@ ### channels -| Field | Description | Required | Example | -| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------ | -| id | Unique channel ID derived from the `name` and `country` separated by dot. May only contain Latin letters, numbers and dot. | Required | `AnhuiTV.cn` | -| name | Official channel name in English or call sign. May include: `a-z`, `0-9`, `space`, `-`, `!`, `:`, `&`, `.`, `+`, `'`, `/`, `»`, `#`, `%`, `°`, `$`, `@`, `?`, \|, `¡`, `–`. | Required | `Anhui TV` | -| alt_names | List of alternative channel names separated by `;`. May contain any characters except `,` and `"`. | Optional | `安徽卫视;AHTV` | -| network | Network of which this channel is a part. May contain any characters except `,` and `"`. | Optional | `Anhui` | -| owners | List of channel owners separated by `;`. May contain any characters except `,` and `"`. | Optional | `China Central Television` | -| country | Country code from which the channel is transmitted. A list of all supported countries and their codes can be found in [data/countries.csv](data/countries.csv) | Required | `CN` | -| subdivision | Code of the subdivision (e.g., provinces or states) from which the broadcast is transmitted. A list of all supported subdivisions and their codes can be found in [data/subdivisions.csv](data/subdivisions.csv). | Optional | `CN-AH` | -| city | The name of the city in English from which the channel is broadcast. May contain any characters except `,` and `"`. | Optional | `Hefei` | -| broadcast_area | List of codes describing the broadcasting area of the channel separated by `;`. Any combination of `r/`, `c/`, `s/`. | Required | `c/CN;r/ASIA` | -| languages | List of languages in which the channel is broadcast separated by `;`. A list of all supported languages and their codes can be found in [data/languages.csv](data/languages.csv). | Required | `zho;eng` | -| categories | List of categories to which this channel belongs separated by `;`. A list of all supported categories can be found in [data/categories.csv](data/categories.csv). | Optional | `animation;kids` | -| is_nsfw | Indicates whether the channel broadcasts adult content (`TRUE` or `FALSE`). | Required | `FALSE` | -| launched | Launch date of the channel (`YYYY-MM-DD`). | Optional | `2016-07-28` | -| closed | Date on which the channel closed (`YYYY-MM-DD`). | Optional | `2020-05-31` | -| replaced_by | The ID of the channel that this channel was replaced by. | Optional | `CCTV1.cn` | -| website | Official website URL. | Optional | `http://www.ahtv.cn/` | +| Field | Description | Required | Example | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------ | +| id | Unique channel ID derived from the `name` and `country` separated by dot. May only contain Latin letters, numbers and dot. | Required | `AnhuiTV.cn` | +| name | Official channel name in English or call sign. May include: `a-z`, `0-9`, `space`, `-`, `!`, `:`, `&`, `.`, `+`, `'`, `/`, `»`, `#`, `%`, `°`, `$`, `@`, `?`, \|, `¡`. | Required | `Anhui TV` | +| alt_names | List of alternative channel names separated by `;`. May contain any characters except `,` and `"`. | Optional | `安徽卫视;AHTV` | +| network | Network of which this channel is a part. May contain any characters except `,` and `"`. | Optional | `Anhui` | +| owners | List of channel owners separated by `;`. May contain any characters except `,` and `"`. | Optional | `China Central Television` | +| country | Country code from which the channel is transmitted. A list of all supported countries and their codes can be found in [data/countries.csv](data/countries.csv) | Required | `CN` | +| subdivision | Code of the subdivision (e.g., provinces or states) from which the broadcast is transmitted. A list of all supported subdivisions and their codes can be found in [data/subdivisions.csv](data/subdivisions.csv). | Optional | `CN-AH` | +| city | The name of the city in English from which the channel is broadcast. May contain any characters except `,` and `"`. | Optional | `Hefei` | +| broadcast_area | List of codes describing the broadcasting area of the channel separated by `;`. Any combination of `r/`, `c/`, `s/`. | Required | `c/CN;r/ASIA` | +| languages | List of languages in which the channel is broadcast separated by `;`. A list of all supported languages and their codes can be found in [data/languages.csv](data/languages.csv). | Required | `zho;eng` | +| categories | List of categories to which this channel belongs separated by `;`. A list of all supported categories can be found in [data/categories.csv](data/categories.csv). | Optional | `animation;kids` | +| is_nsfw | Indicates whether the channel broadcasts adult content (`TRUE` or `FALSE`). | Required | `FALSE` | +| launched | Launch date of the channel (`YYYY-MM-DD`). | Optional | `2016-07-28` | +| closed | Date on which the channel closed (`YYYY-MM-DD`). | Optional | `2020-05-31` | +| replaced_by | The ID of the channel that this channel was replaced by. | Optional | `CCTV1.cn` | +| website | Official website URL. | Optional | `http://www.ahtv.cn/` | | logo | Logo URL. Only URL with [HTTPS](https://ru.wikipedia.org/wiki/HTTPS) protocol are allowed. Supported image types: `PNG`, `JPEG`. Max size: 512x512 pixels. The link should not be [geo-blocked](https://en.wikipedia.org/wiki/Geo-blocking). May contain any characters except `,` and `"`. | Required | `https://example.com/logo.png` | ### categories diff --git a/data/channels.csv b/data/channels.csv index ebfdba1b..dee1cc1b 100644 --- a/data/channels.csv +++ b/data/channels.csv @@ -16543,7 +16543,7 @@ KSTVComedySeries.ua,KS TV | Comedy Series,КС ТБ | Комедійні сер KSTVConcert.ua,KS TV | Concert,КС ТБ | Концерт,,Kyivstar,UA,,Kyiv,c/UA,ukr,music,FALSE,,,,https://tv.kyivstar.ua/en/live-channels/5fd36a935414fee0a809c916-ks-tv-concert-hd,https://i.imgur.com/TWhZf9c.png KSTVCopWars.ua,KS TV | Cop Wars,КС ТБ | Ментівські війни,,Kyivstar,UA,,Kyiv,c/UA,ukr,,FALSE,,,,https://tv.kyivstar.ua/en/live-channels/6493029e8b94b9c41a08beda-ks-tv-cop-wars,https://i.imgur.com/U6xFbCa.png KSTVCrime.ua,KS TV | Crime,КС ТБ | Кримінал,,Kyivstar,UA,,Kyiv,c/UA,ukr,,FALSE,,,,https://tv.kyivstar.ua/en/live-channels/633458df50347fd195aeeb37-ks-tv-crime-hd,https://i.imgur.com/14Y1dAm.png -KSTVCrimeanbridgeitsover.ua,KS TV | Crimean bridge - it's over,КС ТБ | Кримський міст – всьо,,Kyivstar,UA,,Kyiv,c/UA,ukr,,FALSE,,,,https://tv.kyivstar.ua/en/live-channels/634155b445b4e86497aa384f-ks-tv-crimean-bridge-its-over,https://i.imgur.com/ipxyxZj.png +KSTVCrimeanbridgeitsover.ua,KS TV | Crimean bridge it's over,KS TV | Crimean bridge - it's over;КС ТБ | Кримський міст – всьо,,Kyivstar,UA,,Kyiv,c/UA,ukr,,FALSE,,,,https://tv.kyivstar.ua/en/live-channels/634155b445b4e86497aa384f-ks-tv-crimean-bridge-its-over,https://i.imgur.com/ipxyxZj.png KSTVCulinary.ua,KS TV | Culinary,КС ТБ | Кулінар,,Kyivstar,UA,,Kyiv,c/UA,ukr,cooking,FALSE,,,,https://tv.kyivstar.ua/en/live-channels/64f83591e4b0a1c5db131360-ks-tv-culinary,https://i.imgur.com/Sjsuhyr.png KSTVDetective.ua,KS TV | Detective,КС ТБ | Детектив,,Kyivstar,UA,,Kyiv,c/UA,ukr,entertainment,FALSE,,,,https://tv.kyivstar.ua/en/live-channels/60f57a58d0348f888597bae9-ks-tv-detective-hd,https://i.imgur.com/yNrx31O.png KSTVDoctorshearts.ua,KS TV | Doctors' hearts,КС ТБ | Лікарські серця,,Kyivstar,UA,,Kyiv,c/UA,ukr,,FALSE,,,,https://tv.kyivstar.ua/en/live-channels/646df4f5e4b0f13e55a40d2f-ks-tv-doctors-hearts,https://i.imgur.com/2lqkEeS.png diff --git a/package-lock.json b/package-lock.json index 1a2e9abf..5a03aa22 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "chalk": "^4.1.2", "commander": "^9.0.0", "csvtojson": "^2.0.10", - "eslint": "^9.18.0", + "eslint": "^9.19.0", "eslint-config-prettier": "^9.0.0", "fs-extra": "^11.2.0", "globals": "^15.13.0", @@ -1135,9 +1135,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", - "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz", + "integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -3085,16 +3085,16 @@ } }, "node_modules/eslint": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", - "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz", + "integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.10.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.18.0", + "@eslint/js": "9.19.0", "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -6831,9 +6831,9 @@ } }, "@eslint/js": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", - "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==" + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz", + "integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==" }, "@eslint/object-schema": { "version": "2.1.5", @@ -8265,16 +8265,16 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", - "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz", + "integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==", "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.10.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.18.0", + "@eslint/js": "9.19.0", "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", diff --git a/package.json b/package.json index 2e284597..593ea260 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "chalk": "^4.1.2", "commander": "^9.0.0", "csvtojson": "^2.0.10", - "eslint": "^9.18.0", + "eslint": "^9.19.0", "eslint-config-prettier": "^9.0.0", "fs-extra": "^11.2.0", "globals": "^15.13.0", diff --git a/scripts/schemes/channels.ts b/scripts/schemes/channels.ts index a4a5bb52..25481753 100644 --- a/scripts/schemes/channels.ts +++ b/scripts/schemes/channels.ts @@ -11,6 +11,7 @@ export default { .required(), name: Joi.string() .regex(/^[a-z0-9-!:&.+'/»#%°$@?|¡–\s_—]+$/i) + .regex(/^((?!\s-\s).)*$/) .required(), alt_names: Joi.array().items( Joi.string() diff --git a/tests/__data__/expected/api/blocklist.json b/tests/__data__/expected/api/blocklist.json index 8a66ad1a..a65c17ce 100644 --- a/tests/__data__/expected/api/blocklist.json +++ b/tests/__data__/expected/api/blocklist.json @@ -1 +1 @@ -[{"channel":"AnimalPlanetAfrica.za","ref":"https://github.com/iptv-org/iptv/issues/1831"}] \ No newline at end of file +[{"channel":"AnimalPlanetAfrica.za","ref":"https://github.com/iptv-org/iptv/issues/1831"},{"channel":"BeijingSatelliteTV.cn","ref":"https://github.com/iptv-org/iptv/issues/1831"}] \ No newline at end of file diff --git a/tests/__data__/expected/api/channels.json b/tests/__data__/expected/api/channels.json index cfad2a47..0b513021 100644 --- a/tests/__data__/expected/api/channels.json +++ b/tests/__data__/expected/api/channels.json @@ -1 +1 @@ -[{"id":"002RadioTV.do","name":"002 Radio TV","alt_names":[],"network":null,"owners":[],"country":"DO","subdivision":null,"city":null,"broadcast_area":["c/DO"],"languages":["spa"],"categories":["general"],"is_nsfw":false,"launched":null,"closed":null,"replaced_by":null,"website":"https://www.002radio.com/","logo":"https://i.imgur.com/7oNe8xj.png"},{"id":"BeijingSatelliteTV.cn","name":"Beijing Satellite TV","alt_names":["北京卫视"],"network":null,"owners":[],"country":"CN","subdivision":null,"city":"Beijing","broadcast_area":["c/CN"],"languages":["zho"],"categories":["general"],"is_nsfw":false,"launched":"1979-05-16","closed":null,"replaced_by":null,"website":"https://www.brtn.cn/btv/","logo":"https://i.imgur.com/vsktAez.png"},{"id":"M5.hu","name":"M5","alt_names":[],"network":null,"owners":[],"country":"HU","subdivision":null,"city":null,"broadcast_area":["c/HU"],"languages":["hun"],"categories":["auto"],"is_nsfw":true,"launched":null,"closed":"2001-01-01","replaced_by":null,"website":"https://www.mediaklikk.hu/m5/","logo":"https://i.imgur.com/y21wFd0.png"}] \ No newline at end of file +[{"id":"002RadioTV.do","name":"002 Radio TV","alt_names":[],"network":null,"owners":[],"country":"DO","subdivision":null,"city":null,"broadcast_area":["c/DO"],"languages":["spa"],"categories":["general"],"is_nsfw":false,"launched":null,"closed":null,"replaced_by":null,"website":"https://www.002radio.com/","logo":"https://i.imgur.com/7oNe8xj.png"},{"id":"BeijingSatelliteTV.cn","name":"Beijing Satellite TV","alt_names":["北京卫视"],"network":null,"owners":[],"country":"CN","subdivision":null,"city":"Beijing","broadcast_area":["c/CN"],"languages":["zho"],"categories":["general"],"is_nsfw":false,"launched":"1979-05-16","closed":null,"replaced_by":null,"website":"https://www.brtn.cn/btv/","logo":"https://i.imgur.com/vsktAez.png"},{"id":"M5.hu","name":"M5","alt_names":[],"network":null,"owners":[],"country":"HU","subdivision":null,"city":null,"broadcast_area":["c/HU"],"languages":["hun"],"categories":["auto"],"is_nsfw":true,"launched":null,"closed":"2001-01-01","replaced_by":"BeijingSatelliteTV.cn","website":"https://www.mediaklikk.hu/m5/","logo":"https://i.imgur.com/y21wFd0.png"}] \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index b05cc960..4d2c1598 100644 --- a/yarn.lock +++ b/yarn.lock @@ -357,10 +357,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@^9.16.0", "@eslint/js@9.18.0": - version "9.18.0" - resolved "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz" - integrity sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA== +"@eslint/js@^9.16.0", "@eslint/js@9.19.0": + version "9.19.0" + resolved "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz" + integrity sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ== "@eslint/object-schema@^2.1.5": version "2.1.5" @@ -1649,17 +1649,17 @@ eslint-visitor-keys@^4.2.0: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz" integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== -"eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^8.57.0 || ^9.0.0", eslint@^9.18.0, eslint@>=7.0.0: - version "9.18.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz" - integrity sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA== +"eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^8.57.0 || ^9.0.0", eslint@^9.19.0, eslint@>=7.0.0: + version "9.19.0" + resolved "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz" + integrity sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.12.1" "@eslint/config-array" "^0.19.0" "@eslint/core" "^0.10.0" "@eslint/eslintrc" "^3.2.0" - "@eslint/js" "9.18.0" + "@eslint/js" "9.19.0" "@eslint/plugin-kit" "^0.2.5" "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1"