This commit is contained in:
Aleksandr Statciuk 2022-02-12 05:55:50 +03:00
commit 26d5bf0436
27 changed files with 43517 additions and 0 deletions

12
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: iptv-org
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

19
.github/workflows/check.yml vendored Normal file
View File

@ -0,0 +1,19 @@
name: check
on:
workflow_dispatch:
pull_request:
types: [opened, synchronize, reopened, edited]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- id: files
uses: tj-actions/changed-files@v12.2
with:
files: \.csv$
- name: validate
if: steps.files.outputs.any_changed == 'true'
run: |
npm install
npm run db:validate -- ${{ steps.files.outputs.all_changed_files }}

29
.github/workflows/deploy.yml vendored Normal file
View File

@ -0,0 +1,29 @@
name: deploy
on:
workflow_dispatch:
push:
branches:
- master
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: npm install
- run: npm run db:export
- uses: tibdex/github-app-token@v1
if: ${{ !env.ACT }}
id: create-app-token
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: JamesIves/github-pages-deploy-action@4.1.1
if: ${{ !env.ACT }}
with:
branch: gh-pages
folder: .gh-pages
token: ${{ steps.create-app-token.outputs.token }}
git-config-name: iptv-bot[bot]
git-config-email: 84861620+iptv-bot[bot]@users.noreply.github.com
commit-message: '[Bot] Deploy to GitHub Pages'
clean: false

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/node_modules/
/.artifacts/

24
LICENSE Normal file
View File

@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>

29
data/categories.csv Normal file
View File

@ -0,0 +1,29 @@
id,name
auto,Auto
animation,Animation
business,Business
classic,Classic
comedy,Comedy
cooking,Cooking
culture,Culture
documentary,Documentary
education,Education
entertainment,Entertainment
family,Family
general,General
kids,Kids
legislative,Legislative
lifestyle,Lifestyle
movies,Movies
music,Music
news,News
outdoor,Outdoor
relax,Relax
religious,Religious
series,Series
science,Science
shop,Shop
sports,Sports
travel,Travel
weather,Weather
xxx,XXX
1 id name
2 auto Auto
3 animation Animation
4 business Business
5 classic Classic
6 comedy Comedy
7 cooking Cooking
8 culture Culture
9 documentary Documentary
10 education Education
11 entertainment Entertainment
12 family Family
13 general General
14 kids Kids
15 legislative Legislative
16 lifestyle Lifestyle
17 movies Movies
18 music Music
19 news News
20 outdoor Outdoor
21 relax Relax
22 religious Religious
23 series Series
24 science Science
25 shop Shop
26 sports Sports
27 travel Travel
28 weather Weather
29 xxx XXX

29797
data/channels.csv Normal file

File diff suppressed because it is too large Load Diff

251
data/countries.csv Normal file
View File

@ -0,0 +1,251 @@
name,code,lang,flag
Afghanistan,AF,pus,🇦🇫
Albania,AL,sqi,🇦🇱
Algeria,DZ,ara,🇩🇿
American Samoa,AS,eng,🇦🇸
Andorra,AD,cat,🇦🇩
Angola,AO,por,🇦🇴
Anguilla,AI,eng,🇦🇮
Antarctica,AQ,eng,🇦🇶
Antigua and Barbuda,AG,eng,🇦🇬
Argentina,AR,spa,🇦🇷
Armenia,AM,hye,🇦🇲
Aruba,AW,nld,🇦🇼
Australia,AU,eng,🇦🇺
Austria,AT,deu,🇦🇹
Azerbaijan,AZ,aze,🇦🇿
Bahamas,BS,eng,🇧🇸
Bahrain,BH,ara,🇧🇭
Bangladesh,BD,ben,🇧🇩
Barbados,BB,eng,🇧🇧
Belarus,BY,bel,🇧🇾
Belgium,BE,nld,🇧🇪
Belize,BZ,eng,🇧🇿
Benin,BJ,fra,🇧🇯
Bermuda,BM,eng,🇧🇲
Bhutan,BT,dzo,🇧🇹
Bolivia,BO,spa,🇧🇴
Bonaire,BQ,nld,🇧🇶
Bosnia and Herzegovina,BA,bos,🇧🇦
Botswana,BW,eng,🇧🇼
Bouvet Island,BV,nor,🇧🇻
Brazil,BR,por,🇧🇷
British Indian Ocean Territory,IO,eng,🇮🇴
British Virgin Islands,VG,eng,🇻🇬
Brunei,BN,msa,🇧🇳
Bulgaria,BG,bul,🇧🇬
Burkina Faso,BF,fra,🇧🇫
Burundi,BI,fra,🇧🇮
Cambodia,KH,khm,🇰🇭
Cameroon,CM,eng,🇨🇲
Canada,CA,eng,🇨🇦
Cape Verde,CV,por,🇨🇻
Cayman Islands,KY,eng,🇰🇾
Central African Republic,CF,fra,🇨🇫
Chad,TD,fra,🇹🇩
Chile,CL,spa,🇨🇱
China,CN,zho,🇨🇳
Christmas Island,CX,eng,🇨🇽
Cocos (Keeling) Islands,CC,eng,🇨🇨
Colombia,CO,spa,🇨🇴
Comoros,KM,ara,🇰🇲
Cook Islands,CK,eng,🇨🇰
Costa Rica,CR,spa,🇨🇷
Croatia,HR,hrv,🇭🇷
Cuba,CU,spa,🇨🇺
Curacao,CW,nld,🇨🇼
Cyprus,CY,ell,🇨🇾
Czech Republic,CZ,ces,🇨🇿
Democratic Republic of the Congo,CD,fra,🇨🇩
Denmark,DK,dan,🇩🇰
Djibouti,DJ,fra,🇩🇯
Dominica,DM,eng,🇩🇲
Dominican Republic,DO,spa,🇩🇴
East Timor,TL,por,🇹🇱
Ecuador,EC,spa,🇪🇨
Egypt,EG,ara,🇪🇬
El Salvador,SV,spa,🇸🇻
Equatorial Guinea,GQ,spa,🇬🇶
Eritrea,ER,tir,🇪🇷
Estonia,EE,est,🇪🇪
Ethiopia,ET,amh,🇪🇹
Falkland Islands,FK,eng,🇫🇰
Faroe Islands,FO,fao,🇫🇴
Fiji,FJ,eng,🇫🇯
Finland,FI,fin,🇫🇮
France,FR,fra,🇫🇷
French Guiana,GF,fra,🇬🇫
French Polynesia,PF,fra,🇵🇫
French Southern Territories,TF,fra,🇹🇫
Gabon,GA,fra,🇬🇦
Gambia,GM,eng,🇬🇲
Georgia,GE,kat,🇬🇪
Germany,DE,deu,🇩🇪
Ghana,GH,eng,🇬🇭
Gibraltar,GI,eng,🇬🇮
Greece,GR,ell,🇬🇷
Greenland,GL,kal,🇬🇱
Grenada,GD,eng,🇬🇩
Guadeloupe,GP,fra,🇬🇵
Guam,GU,eng,🇬🇺
Guatemala,GT,spa,🇬🇹
Guernsey,GG,eng,🇬🇬
Guinea,GN,fra,🇬🇳
Guinea-Bissau,GW,por,🇬🇼
Guyana,GY,eng,🇬🇾
Haiti,HT,fra,🇭🇹
Heard Island and McDonald Islands,HM,eng,🇭🇲
Honduras,HN,spa,🇭🇳
Hong Kong,HK,zho,🇭🇰
Hungary,HU,hun,🇭🇺
Iceland,IS,isl,🇮🇸
India,IN,hin,🇮🇳
Indonesia,ID,ind,🇮🇩
Iran,IR,fas,🇮🇷
Iraq,IQ,ara,🇮🇶
Ireland,IE,gle,🇮🇪
Isle of Man,IM,eng,🇮🇲
Israel,IL,heb,🇮🇱
Italy,IT,ita,🇮🇹
Ivory Coast,CI,fra,🇨🇮
Jamaica,JM,eng,🇯🇲
Japan,JP,jpn,🇯🇵
Jersey,JE,eng,🇯🇪
Jordan,JO,ara,🇯🇴
Kazakhstan,KZ,kaz,🇰🇿
Kenya,KE,eng,🇰🇪
Kiribati,KI,eng,🇰🇮
Kosovo,XK,sqi,🇽🇰
Kuwait,KW,ara,🇰🇼
Kyrgyzstan,KG,kir,🇰🇬
Laos,LA,lao,🇱🇦
Latvia,LV,lav,🇱🇻
Lebanon,LB,ara,🇱🇧
Lesotho,LS,eng,🇱🇸
Liberia,LR,eng,🇱🇷
Libya,LY,ara,🇱🇾
Liechtenstein,LI,deu,🇱🇮
Lithuania,LT,lit,🇱🇹
Luxembourg,LU,fra,🇱🇺
Macao,MO,zho,🇲🇴
Madagascar,MG,fra,🇲🇬
Malawi,MW,eng,🇲🇼
Malaysia,MY,msa,🇲🇾
Maldives,MV,div,🇲🇻
Mali,ML,fra,🇲🇱
Malta,MT,mlt,🇲🇹
Marshall Islands,MH,eng,🇲🇭
Martinique,MQ,fra,🇲🇶
Mauritania,MR,ara,🇲🇷
Mauritius,MU,eng,🇲🇺
Mayotte,YT,fra,🇾🇹
Mexico,MX,spa,🇲🇽
Micronesia,FM,eng,🇫🇲
Moldova,MD,ron,🇲🇩
Monaco,MC,fra,🇲🇨
Mongolia,MN,mon,🇲🇳
Montenegro,ME,srp,🇲🇪
Montserrat,MS,eng,🇲🇸
Morocco,MA,ara,🇲🇦
Mozambique,MZ,por,🇲🇿
Myanmar (Burma),MM,mya,🇲🇲
Namibia,NA,eng,🇳🇦
Nauru,NR,eng,🇳🇷
Nepal,NP,nep,🇳🇵
Netherlands,NL,nld,🇳🇱
New Caledonia,NC,fra,🇳🇨
New Zealand,NZ,eng,🇳🇿
Nicaragua,NI,spa,🇳🇮
Niger,NE,fra,🇳🇪
Nigeria,NG,eng,🇳🇬
Niue,NU,eng,🇳🇺
Norfolk Island,NF,eng,🇳🇫
North Korea,KP,kor,🇰🇵
North Macedonia,MK,mkd,🇲🇰
Northern Mariana Islands,MP,eng,🇲🇵
Norway,NO,nor,🇳🇴
Oman,OM,ara,🇴🇲
Pakistan,PK,eng,🇵🇰
Palau,PW,eng,🇵🇼
Palestine,PS,ara,🇵🇸
Panama,PA,spa,🇵🇦
Papua New Guinea,PG,eng,🇵🇬
Paraguay,PY,spa,🇵🇾
Peru,PE,spa,🇵🇪
Philippines,PH,eng,🇵🇭
Pitcairn Islands,PN,eng,🇵🇳
Poland,PL,pol,🇵🇱
Portugal,PT,por,🇵🇹
Puerto Rico,PR,spa,🇵🇷
Qatar,QA,ara,🇶🇦
Republic of the Congo,CG,fra,🇨🇬
Romania,RO,ron,🇷🇴
Russia,RU,rus,🇷🇺
Rwanda,RW,kin,🇷🇼
Réunion,RE,fra,🇷🇪
Saint Barthélemy,BL,fra,🇧🇱
Saint Helena,SH,eng,🇸🇭
Saint Kitts and Nevis,KN,eng,🇰🇳
Saint Lucia,LC,eng,🇱🇨
Saint Martin,MF,eng,🇲🇫
Saint Pierre and Miquelon,PM,fra,🇵🇲
Saint Vincent and the Grenadines,VC,eng,🇻🇨
Samoa,WS,smo,🇼🇸
San Marino,SM,ita,🇸🇲
Saudi Arabia,SA,ara,🇸🇦
Senegal,SN,fra,🇸🇳
Serbia,RS,srp,🇷🇸
Seychelles,SC,fra,🇸🇨
Sierra Leone,SL,eng,🇸🇱
Singapore,SG,eng,🇸🇬
Sint Maarten,SX,nld,🇸🇽
Slovakia,SK,slk,🇸🇰
Slovenia,SI,slv,🇸🇮
Solomon Islands,SB,eng,🇸🇧
Somalia,SO,som,🇸🇴
South Africa,ZA,afr,🇿🇦
South Georgia and the South Sandwich Islands,GS,eng,🇬🇸
South Korea,KR,kor,🇰🇷
South Sudan,SS,eng,🇸🇸
Spain,ES,spa,🇪🇸
Sri Lanka,LK,sin,🇱🇰
Sudan,SD,ara,🇸🇩
Suriname,SR,nld,🇸🇷
Svalbard and Jan Mayen,SJ,nor,🇸🇯
Swaziland,SZ,eng,🇸🇿
Sweden,SE,swe,🇸🇪
Switzerland,CH,deu,🇨🇭
Syria,SY,ara,🇸🇾
São Tomé and Príncipe,ST,por,🇸🇹
Taiwan,TW,zho,🇹🇼
Tajikistan,TJ,tgk,🇹🇯
Tanzania,TZ,swa,🇹🇿
Thailand,TH,tha,🇹🇭
Togo,TG,fra,🇹🇬
Tokelau,TK,eng,🇹🇰
Tonga,TO,eng,🇹🇴
Trinidad and Tobago,TT,eng,🇹🇹
Tunisia,TN,ara,🇹🇳
Turkey,TR,tur,🇹🇷
Turkmenistan,TM,tuk,🇹🇲
Turks and Caicos Islands,TC,eng,🇹🇨
Tuvalu,TV,eng,🇹🇻
U.S. Minor Outlying Islands,UM,eng,🇺🇲
U.S. Virgin Islands,VI,eng,🇻🇮
Uganda,UG,eng,🇺🇬
Ukraine,UA,ukr,🇺🇦
United Arab Emirates,AE,ara,🇦🇪
United Kingdom,UK,eng,🇬🇧
United States,US,eng,🇺🇸
Uruguay,UY,spa,🇺🇾
Uzbekistan,UZ,uzb,🇺🇿
Vanuatu,VU,bis,🇻🇺
Vatican City,VA,ita,🇻🇦
Venezuela,VE,spa,🇻🇪
Vietnam,VN,vie,🇻🇳
Wallis and Futuna,WF,fra,🇼🇫
Western Sahara,EH,spa,🇪🇭
Yemen,YE,ara,🇾🇪
Zambia,ZM,eng,🇿🇲
Zimbabwe,ZW,eng,🇿🇼
Åland,AX,swe,🇦🇽
1 name code lang flag
2 Afghanistan AF pus 🇦🇫
3 Albania AL sqi 🇦🇱
4 Algeria DZ ara 🇩🇿
5 American Samoa AS eng 🇦🇸
6 Andorra AD cat 🇦🇩
7 Angola AO por 🇦🇴
8 Anguilla AI eng 🇦🇮
9 Antarctica AQ eng 🇦🇶
10 Antigua and Barbuda AG eng 🇦🇬
11 Argentina AR spa 🇦🇷
12 Armenia AM hye 🇦🇲
13 Aruba AW nld 🇦🇼
14 Australia AU eng 🇦🇺
15 Austria AT deu 🇦🇹
16 Azerbaijan AZ aze 🇦🇿
17 Bahamas BS eng 🇧🇸
18 Bahrain BH ara 🇧🇭
19 Bangladesh BD ben 🇧🇩
20 Barbados BB eng 🇧🇧
21 Belarus BY bel 🇧🇾
22 Belgium BE nld 🇧🇪
23 Belize BZ eng 🇧🇿
24 Benin BJ fra 🇧🇯
25 Bermuda BM eng 🇧🇲
26 Bhutan BT dzo 🇧🇹
27 Bolivia BO spa 🇧🇴
28 Bonaire BQ nld 🇧🇶
29 Bosnia and Herzegovina BA bos 🇧🇦
30 Botswana BW eng 🇧🇼
31 Bouvet Island BV nor 🇧🇻
32 Brazil BR por 🇧🇷
33 British Indian Ocean Territory IO eng 🇮🇴
34 British Virgin Islands VG eng 🇻🇬
35 Brunei BN msa 🇧🇳
36 Bulgaria BG bul 🇧🇬
37 Burkina Faso BF fra 🇧🇫
38 Burundi BI fra 🇧🇮
39 Cambodia KH khm 🇰🇭
40 Cameroon CM eng 🇨🇲
41 Canada CA eng 🇨🇦
42 Cape Verde CV por 🇨🇻
43 Cayman Islands KY eng 🇰🇾
44 Central African Republic CF fra 🇨🇫
45 Chad TD fra 🇹🇩
46 Chile CL spa 🇨🇱
47 China CN zho 🇨🇳
48 Christmas Island CX eng 🇨🇽
49 Cocos (Keeling) Islands CC eng 🇨🇨
50 Colombia CO spa 🇨🇴
51 Comoros KM ara 🇰🇲
52 Cook Islands CK eng 🇨🇰
53 Costa Rica CR spa 🇨🇷
54 Croatia HR hrv 🇭🇷
55 Cuba CU spa 🇨🇺
56 Curacao CW nld 🇨🇼
57 Cyprus CY ell 🇨🇾
58 Czech Republic CZ ces 🇨🇿
59 Democratic Republic of the Congo CD fra 🇨🇩
60 Denmark DK dan 🇩🇰
61 Djibouti DJ fra 🇩🇯
62 Dominica DM eng 🇩🇲
63 Dominican Republic DO spa 🇩🇴
64 East Timor TL por 🇹🇱
65 Ecuador EC spa 🇪🇨
66 Egypt EG ara 🇪🇬
67 El Salvador SV spa 🇸🇻
68 Equatorial Guinea GQ spa 🇬🇶
69 Eritrea ER tir 🇪🇷
70 Estonia EE est 🇪🇪
71 Ethiopia ET amh 🇪🇹
72 Falkland Islands FK eng 🇫🇰
73 Faroe Islands FO fao 🇫🇴
74 Fiji FJ eng 🇫🇯
75 Finland FI fin 🇫🇮
76 France FR fra 🇫🇷
77 French Guiana GF fra 🇬🇫
78 French Polynesia PF fra 🇵🇫
79 French Southern Territories TF fra 🇹🇫
80 Gabon GA fra 🇬🇦
81 Gambia GM eng 🇬🇲
82 Georgia GE kat 🇬🇪
83 Germany DE deu 🇩🇪
84 Ghana GH eng 🇬🇭
85 Gibraltar GI eng 🇬🇮
86 Greece GR ell 🇬🇷
87 Greenland GL kal 🇬🇱
88 Grenada GD eng 🇬🇩
89 Guadeloupe GP fra 🇬🇵
90 Guam GU eng 🇬🇺
91 Guatemala GT spa 🇬🇹
92 Guernsey GG eng 🇬🇬
93 Guinea GN fra 🇬🇳
94 Guinea-Bissau GW por 🇬🇼
95 Guyana GY eng 🇬🇾
96 Haiti HT fra 🇭🇹
97 Heard Island and McDonald Islands HM eng 🇭🇲
98 Honduras HN spa 🇭🇳
99 Hong Kong HK zho 🇭🇰
100 Hungary HU hun 🇭🇺
101 Iceland IS isl 🇮🇸
102 India IN hin 🇮🇳
103 Indonesia ID ind 🇮🇩
104 Iran IR fas 🇮🇷
105 Iraq IQ ara 🇮🇶
106 Ireland IE gle 🇮🇪
107 Isle of Man IM eng 🇮🇲
108 Israel IL heb 🇮🇱
109 Italy IT ita 🇮🇹
110 Ivory Coast CI fra 🇨🇮
111 Jamaica JM eng 🇯🇲
112 Japan JP jpn 🇯🇵
113 Jersey JE eng 🇯🇪
114 Jordan JO ara 🇯🇴
115 Kazakhstan KZ kaz 🇰🇿
116 Kenya KE eng 🇰🇪
117 Kiribati KI eng 🇰🇮
118 Kosovo XK sqi 🇽🇰
119 Kuwait KW ara 🇰🇼
120 Kyrgyzstan KG kir 🇰🇬
121 Laos LA lao 🇱🇦
122 Latvia LV lav 🇱🇻
123 Lebanon LB ara 🇱🇧
124 Lesotho LS eng 🇱🇸
125 Liberia LR eng 🇱🇷
126 Libya LY ara 🇱🇾
127 Liechtenstein LI deu 🇱🇮
128 Lithuania LT lit 🇱🇹
129 Luxembourg LU fra 🇱🇺
130 Macao MO zho 🇲🇴
131 Madagascar MG fra 🇲🇬
132 Malawi MW eng 🇲🇼
133 Malaysia MY msa 🇲🇾
134 Maldives MV div 🇲🇻
135 Mali ML fra 🇲🇱
136 Malta MT mlt 🇲🇹
137 Marshall Islands MH eng 🇲🇭
138 Martinique MQ fra 🇲🇶
139 Mauritania MR ara 🇲🇷
140 Mauritius MU eng 🇲🇺
141 Mayotte YT fra 🇾🇹
142 Mexico MX spa 🇲🇽
143 Micronesia FM eng 🇫🇲
144 Moldova MD ron 🇲🇩
145 Monaco MC fra 🇲🇨
146 Mongolia MN mon 🇲🇳
147 Montenegro ME srp 🇲🇪
148 Montserrat MS eng 🇲🇸
149 Morocco MA ara 🇲🇦
150 Mozambique MZ por 🇲🇿
151 Myanmar (Burma) MM mya 🇲🇲
152 Namibia NA eng 🇳🇦
153 Nauru NR eng 🇳🇷
154 Nepal NP nep 🇳🇵
155 Netherlands NL nld 🇳🇱
156 New Caledonia NC fra 🇳🇨
157 New Zealand NZ eng 🇳🇿
158 Nicaragua NI spa 🇳🇮
159 Niger NE fra 🇳🇪
160 Nigeria NG eng 🇳🇬
161 Niue NU eng 🇳🇺
162 Norfolk Island NF eng 🇳🇫
163 North Korea KP kor 🇰🇵
164 North Macedonia MK mkd 🇲🇰
165 Northern Mariana Islands MP eng 🇲🇵
166 Norway NO nor 🇳🇴
167 Oman OM ara 🇴🇲
168 Pakistan PK eng 🇵🇰
169 Palau PW eng 🇵🇼
170 Palestine PS ara 🇵🇸
171 Panama PA spa 🇵🇦
172 Papua New Guinea PG eng 🇵🇬
173 Paraguay PY spa 🇵🇾
174 Peru PE spa 🇵🇪
175 Philippines PH eng 🇵🇭
176 Pitcairn Islands PN eng 🇵🇳
177 Poland PL pol 🇵🇱
178 Portugal PT por 🇵🇹
179 Puerto Rico PR spa 🇵🇷
180 Qatar QA ara 🇶🇦
181 Republic of the Congo CG fra 🇨🇬
182 Romania RO ron 🇷🇴
183 Russia RU rus 🇷🇺
184 Rwanda RW kin 🇷🇼
185 Réunion RE fra 🇷🇪
186 Saint Barthélemy BL fra 🇧🇱
187 Saint Helena SH eng 🇸🇭
188 Saint Kitts and Nevis KN eng 🇰🇳
189 Saint Lucia LC eng 🇱🇨
190 Saint Martin MF eng 🇲🇫
191 Saint Pierre and Miquelon PM fra 🇵🇲
192 Saint Vincent and the Grenadines VC eng 🇻🇨
193 Samoa WS smo 🇼🇸
194 San Marino SM ita 🇸🇲
195 Saudi Arabia SA ara 🇸🇦
196 Senegal SN fra 🇸🇳
197 Serbia RS srp 🇷🇸
198 Seychelles SC fra 🇸🇨
199 Sierra Leone SL eng 🇸🇱
200 Singapore SG eng 🇸🇬
201 Sint Maarten SX nld 🇸🇽
202 Slovakia SK slk 🇸🇰
203 Slovenia SI slv 🇸🇮
204 Solomon Islands SB eng 🇸🇧
205 Somalia SO som 🇸🇴
206 South Africa ZA afr 🇿🇦
207 South Georgia and the South Sandwich Islands GS eng 🇬🇸
208 South Korea KR kor 🇰🇷
209 South Sudan SS eng 🇸🇸
210 Spain ES spa 🇪🇸
211 Sri Lanka LK sin 🇱🇰
212 Sudan SD ara 🇸🇩
213 Suriname SR nld 🇸🇷
214 Svalbard and Jan Mayen SJ nor 🇸🇯
215 Swaziland SZ eng 🇸🇿
216 Sweden SE swe 🇸🇪
217 Switzerland CH deu 🇨🇭
218 Syria SY ara 🇸🇾
219 São Tomé and Príncipe ST por 🇸🇹
220 Taiwan TW zho 🇹🇼
221 Tajikistan TJ tgk 🇹🇯
222 Tanzania TZ swa 🇹🇿
223 Thailand TH tha 🇹🇭
224 Togo TG fra 🇹🇬
225 Tokelau TK eng 🇹🇰
226 Tonga TO eng 🇹🇴
227 Trinidad and Tobago TT eng 🇹🇹
228 Tunisia TN ara 🇹🇳
229 Turkey TR tur 🇹🇷
230 Turkmenistan TM tuk 🇹🇲
231 Turks and Caicos Islands TC eng 🇹🇨
232 Tuvalu TV eng 🇹🇻
233 U.S. Minor Outlying Islands UM eng 🇺🇲
234 U.S. Virgin Islands VI eng 🇻🇮
235 Uganda UG eng 🇺🇬
236 Ukraine UA ukr 🇺🇦
237 United Arab Emirates AE ara 🇦🇪
238 United Kingdom UK eng 🇬🇧
239 United States US eng 🇺🇸
240 Uruguay UY spa 🇺🇾
241 Uzbekistan UZ uzb 🇺🇿
242 Vanuatu VU bis 🇻🇺
243 Vatican City VA ita 🇻🇦
244 Venezuela VE spa 🇻🇪
245 Vietnam VN vie 🇻🇳
246 Wallis and Futuna WF fra 🇼🇫
247 Western Sahara EH spa 🇪🇭
248 Yemen YE ara 🇾🇪
249 Zambia ZM eng 🇿🇲
250 Zimbabwe ZW eng 🇿🇼
251 Åland AX swe 🇦🇽

7894
data/languages.csv Normal file

File diff suppressed because it is too large Load Diff

25
data/regions.csv Normal file
View File

@ -0,0 +1,25 @@
name,code,countries
Africa,AFR,AO;BF;BI;BJ;BW;CD;CF;CG;CI;CM;CV;DJ;DZ;EG;EH;ER;ET;GA;GH;GM;GN;GQ;GW;KE;KM;LR;LS;LY;MA;MG;ML;MR;MU;MW;MZ;NA;NE;NG;RE;RW;SC;SD;SH;SL;SN;SO;SS;ST;SZ;TD;TF;TG;TN;TZ;UG;YT;ZA;ZM;ZW
Americas,AMER,AG;AI;AR;AW;BB;BL;BM;BO;BR;BS;BV;BZ;CA;CL;CO;CR;CU;CW;DM;DO;EC;FK;GD;GF;GL;GP;GS;GT;GY;HN;HT;JM;KN;KY;LC;MF;MQ;MS;MX;NI;PA;PE;PM;PR;PY;SR;SV;SX;TC;TT;US;UY;VC;VE;VG;VI
Arab world,ARAB,AE;BH;DJ;DZ;EG;IQ;JO;KM;KW;LB;LY;MA;MR;OM;PS;QA;SA;SD;SO;SY;TN;YE
Asia,ASIA,AE;AF;AM;AZ;BD;BH;BN;BT;CN;CY;GE;ID;IL;IN;IQ;IR;JO;JP;KG;KH;KP;KR;KW;KZ;LA;LB;LK;MM;MN;MV;MY;NP;OM;PH;PK;PS;QA;RU;SA;SG;SY;TH;TJ;TL;TM;TR;TW;UZ;VN;YE
Asia-Pacific,APAC,AF;AS;AU;BD;BN;BT;CK;CN;FJ;FM;GU;ID;IN;JP;KH;KI;KP;KR;LA;LK;MH;MM;MN;MP;MV;MY;NC;NF;NP;NR;NU;NZ;PF;PG;PH;PK;PN;PW;SB;SG;TH;TK;TL;TO;TV;TW;VN;VU;WF;WS
Caribbean,CARIB,AG;AI;AW;BB;BL;BS;CU;CW;DM;DO;GD;GP;HT;JM;KN;KY;LC;MF;MQ;MS;PR;SX;TC;TT;VC;VG;VI
Central Asia,CAS,KG;KZ;TJ;TM;UZ
Commonwealth of Independent States,CIS,AM;AZ;BY;KG;KZ;MD;RU;TJ;UZ
Europe,EUR,AD;AL;AM;AT;AZ;BA;BE;BG;BY;CH;CY;CZ;DE;DK;EE;ES;FI;FR;GE;GR;HR;HU;IE;IS;IT;KZ;LI;LT;LU;LV;MC;MD;ME;MK;MT;NL;NO;PL;PT;RO;RS;RU;SE;SI;SK;SM;TR;UA;UK;VA
"Europe, the Middle East and Africa",EMEA,AD;AE;AL;AM;AO;AT;AZ;BA;BE;BF;BG;BH;BI;BJ;BW;BY;CD;CF;CG;CH;CI;CM;CV;CY;CZ;DE;DJ;DK;DZ;EE;EG;EH;ER;ES;ET;FI;FR;GA;GE;GH;GM;GN;GQ;GR;GW;HR;HU;IE;IQ;IR;IS;IT;JO;KE;KM;KW;KZ;LB;LI;LR;LS;LT;LU;LV;LY;MA;MC;MD;ME;MG;MK;ML;MR;MT;MU;MW;MZ;NA;NE;NG;NL;NO;OM;PL;PS;PT;QA;RE;RO;RS;RU;RW;SA;SC;SD;SE;SH;SI;SK;SL;SM;SN;SO;SS;ST;SY;SZ;TD;TF;TG;TN;TR;TZ;UA;UG;UK;VA;YE;YT;ZA;ZM;ZW
Hispanic America,HISPAM,AR;BO;CL;CO;CR;CU;DO;EC;GT;HN;MX;NI;PA;PE;PR;PY;SV;UY;VE
Latin America,LATAM,AR;BL;BO;BR;CL;CO;CR;CU;DO;EC;GF;GP;GT;HN;HT;MF;MQ;MX;NI;PA;PE;PR;PY;SV;UY;VE
Latin America and the Caribbean,LAC,AG;AI;AR;AW;BB;BL;BO;BR;BS;CL;CO;CR;CU;CW;DM;DO;EC;GD;GF;GP;GT;HN;HT;JM;KN;KY;LC;MF;MQ;MS;MX;NI;PA;PE;PR;PY;SV;SX;TC;TT;UY;VC;VE;VG;VI
Maghreb,MAGHREB,DZ;LY;MA;MR;TN
Middle East,MIDEAST,AE;BH;CY;EG;IL;IQ;IR;JO;KW;LB;OM;PS;QA;SA;SY;TR;YE
Middle East and North Africa,MENA,AE;BH;CY;DJ;DZ;EG;EH;IL;IQ;IR;JO;KW;LB;LY;MA;OM;PS;QA;SA;SD;SY;TN;TR;YE
Nordics,NORD,AX;DK;FO;FI;IS;NO;SE
North America,NORAM,AG;AI;AW;BB;BL;BM;BS;BZ;CA;CR;CU;CW;DM;DO;GD;GL;GP;GT;HN;HT;JM;KN;KY;LC;MF;MQ;MS;MX;NI;PA;PM;PR;SV;SX;TC;TT;US;VC;VG;VI
Northern America,NAM,BM;CA;GL;PM;US
Oceania,OCE,AS;AU;CK;FJ;FM;GU;KI;MH;MP;NC;NF;NR;NU;NZ;PF;PG;PN;PW;SB;TK;TO;TV;VU;WF;WS
South Asia,SAS,AF;BD;BT;IN;LK;MV;NP;PK
Sub-Saharan Africa,SSA,AO;BF;BI;BJ;BW;CD;CF;CG;CI;CM;CV;DJ;ER;ET;GA;GH;GM;GN;GQ;GW;KE;KM;LR;LS;MG;ML;MR;MU;MW;MZ;NA;NE;NG;RW;SC;SD;SL;SN;SO;SS;ST;SZ;TD;TG;TZ;UG;ZA;ZM;ZW
West Africa,WAFR,BF;BJ;CI;CV;GH;GM;GN;GW;LR;ML;MR;NE;NG;SH;SL;SN;TG
Worldwide,INT,AD;AE;AF;AG;AI;AL;AM;AO;AQ;AR;AS;AT;AU;AW;AX;AZ;BA;BB;BD;BE;BF;BG;BH;BI;BJ;BL;BM;BN;BO;BQ;BR;BS;BT;BV;BW;BY;BZ;CA;CC;CD;CF;CG;CH;CI;CK;CL;CM;CN;CO;CR;CU;CV;CW;CX;CY;CZ;DE;DJ;DK;DM;DO;DZ;EC;EE;EG;EH;ER;ES;ET;FI;FJ;FK;FM;FO;FR;GA;UK;GD;GE;GF;GG;GH;GI;GL;GM;GN;GP;GQ;GR;GS;GT;GU;GW;GY;HK;HM;HN;HR;HT;HU;ID;IE;IL;IM;IN;IO;IQ;IR;IS;IT;JE;JM;JO;JP;KE;KG;KH;KI;KM;KN;KP;KR;KW;KY;KZ;LA;LB;LC;LI;LK;LR;LS;LT;LU;LV;LY;MA;MC;MD;ME;MF;MG;MH;MK;ML;MM;MN;MO;MP;MQ;MR;MS;MT;MU;MV;MW;MX;MY;MZ;NA;NC;NE;NF;NG;NI;NL;NO;NP;NR;NU;NZ;OM;PA;PE;PF;PG;PH;PK;PL;PM;PN;PR;PS;PT;PW;PY;QA;RE;RO;RS;RU;RW;SA;SB;SC;SD;SE;SG;SH;SI;SJ;SK;SL;SM;SN;SO;SR;SS;ST;SV;SX;SY;SZ;TC;TD;TF;TG;TH;TJ;TK;TL;TM;TN;TO;TR;TT;TV;TW;TZ;UA;UG;UM;US;UY;UZ;VA;VC;VE;VG;VI;VN;VU;WF;WS;XK;YE;YT;ZA;ZM;ZW
1 name code countries
2 Africa AFR AO;BF;BI;BJ;BW;CD;CF;CG;CI;CM;CV;DJ;DZ;EG;EH;ER;ET;GA;GH;GM;GN;GQ;GW;KE;KM;LR;LS;LY;MA;MG;ML;MR;MU;MW;MZ;NA;NE;NG;RE;RW;SC;SD;SH;SL;SN;SO;SS;ST;SZ;TD;TF;TG;TN;TZ;UG;YT;ZA;ZM;ZW
3 Americas AMER AG;AI;AR;AW;BB;BL;BM;BO;BR;BS;BV;BZ;CA;CL;CO;CR;CU;CW;DM;DO;EC;FK;GD;GF;GL;GP;GS;GT;GY;HN;HT;JM;KN;KY;LC;MF;MQ;MS;MX;NI;PA;PE;PM;PR;PY;SR;SV;SX;TC;TT;US;UY;VC;VE;VG;VI
4 Arab world ARAB AE;BH;DJ;DZ;EG;IQ;JO;KM;KW;LB;LY;MA;MR;OM;PS;QA;SA;SD;SO;SY;TN;YE
5 Asia ASIA AE;AF;AM;AZ;BD;BH;BN;BT;CN;CY;GE;ID;IL;IN;IQ;IR;JO;JP;KG;KH;KP;KR;KW;KZ;LA;LB;LK;MM;MN;MV;MY;NP;OM;PH;PK;PS;QA;RU;SA;SG;SY;TH;TJ;TL;TM;TR;TW;UZ;VN;YE
6 Asia-Pacific APAC AF;AS;AU;BD;BN;BT;CK;CN;FJ;FM;GU;ID;IN;JP;KH;KI;KP;KR;LA;LK;MH;MM;MN;MP;MV;MY;NC;NF;NP;NR;NU;NZ;PF;PG;PH;PK;PN;PW;SB;SG;TH;TK;TL;TO;TV;TW;VN;VU;WF;WS
7 Caribbean CARIB AG;AI;AW;BB;BL;BS;CU;CW;DM;DO;GD;GP;HT;JM;KN;KY;LC;MF;MQ;MS;PR;SX;TC;TT;VC;VG;VI
8 Central Asia CAS KG;KZ;TJ;TM;UZ
9 Commonwealth of Independent States CIS AM;AZ;BY;KG;KZ;MD;RU;TJ;UZ
10 Europe EUR AD;AL;AM;AT;AZ;BA;BE;BG;BY;CH;CY;CZ;DE;DK;EE;ES;FI;FR;GE;GR;HR;HU;IE;IS;IT;KZ;LI;LT;LU;LV;MC;MD;ME;MK;MT;NL;NO;PL;PT;RO;RS;RU;SE;SI;SK;SM;TR;UA;UK;VA
11 Europe, the Middle East and Africa EMEA AD;AE;AL;AM;AO;AT;AZ;BA;BE;BF;BG;BH;BI;BJ;BW;BY;CD;CF;CG;CH;CI;CM;CV;CY;CZ;DE;DJ;DK;DZ;EE;EG;EH;ER;ES;ET;FI;FR;GA;GE;GH;GM;GN;GQ;GR;GW;HR;HU;IE;IQ;IR;IS;IT;JO;KE;KM;KW;KZ;LB;LI;LR;LS;LT;LU;LV;LY;MA;MC;MD;ME;MG;MK;ML;MR;MT;MU;MW;MZ;NA;NE;NG;NL;NO;OM;PL;PS;PT;QA;RE;RO;RS;RU;RW;SA;SC;SD;SE;SH;SI;SK;SL;SM;SN;SO;SS;ST;SY;SZ;TD;TF;TG;TN;TR;TZ;UA;UG;UK;VA;YE;YT;ZA;ZM;ZW
12 Hispanic America HISPAM AR;BO;CL;CO;CR;CU;DO;EC;GT;HN;MX;NI;PA;PE;PR;PY;SV;UY;VE
13 Latin America LATAM AR;BL;BO;BR;CL;CO;CR;CU;DO;EC;GF;GP;GT;HN;HT;MF;MQ;MX;NI;PA;PE;PR;PY;SV;UY;VE
14 Latin America and the Caribbean LAC AG;AI;AR;AW;BB;BL;BO;BR;BS;CL;CO;CR;CU;CW;DM;DO;EC;GD;GF;GP;GT;HN;HT;JM;KN;KY;LC;MF;MQ;MS;MX;NI;PA;PE;PR;PY;SV;SX;TC;TT;UY;VC;VE;VG;VI
15 Maghreb MAGHREB DZ;LY;MA;MR;TN
16 Middle East MIDEAST AE;BH;CY;EG;IL;IQ;IR;JO;KW;LB;OM;PS;QA;SA;SY;TR;YE
17 Middle East and North Africa MENA AE;BH;CY;DJ;DZ;EG;EH;IL;IQ;IR;JO;KW;LB;LY;MA;OM;PS;QA;SA;SD;SY;TN;TR;YE
18 Nordics NORD AX;DK;FO;FI;IS;NO;SE
19 North America NORAM AG;AI;AW;BB;BL;BM;BS;BZ;CA;CR;CU;CW;DM;DO;GD;GL;GP;GT;HN;HT;JM;KN;KY;LC;MF;MQ;MS;MX;NI;PA;PM;PR;SV;SX;TC;TT;US;VC;VG;VI
20 Northern America NAM BM;CA;GL;PM;US
21 Oceania OCE AS;AU;CK;FJ;FM;GU;KI;MH;MP;NC;NF;NR;NU;NZ;PF;PG;PN;PW;SB;TK;TO;TV;VU;WF;WS
22 South Asia SAS AF;BD;BT;IN;LK;MV;NP;PK
23 Sub-Saharan Africa SSA AO;BF;BI;BJ;BW;CD;CF;CG;CI;CM;CV;DJ;ER;ET;GA;GH;GM;GN;GQ;GW;KE;KM;LR;LS;MG;ML;MR;MU;MW;MZ;NA;NE;NG;RW;SC;SD;SL;SN;SO;SS;ST;SZ;TD;TG;TZ;UG;ZA;ZM;ZW
24 West Africa WAFR BF;BJ;CI;CV;GH;GM;GN;GW;LR;ML;MR;NE;NG;SH;SL;SN;TG
25 Worldwide INT AD;AE;AF;AG;AI;AL;AM;AO;AQ;AR;AS;AT;AU;AW;AX;AZ;BA;BB;BD;BE;BF;BG;BH;BI;BJ;BL;BM;BN;BO;BQ;BR;BS;BT;BV;BW;BY;BZ;CA;CC;CD;CF;CG;CH;CI;CK;CL;CM;CN;CO;CR;CU;CV;CW;CX;CY;CZ;DE;DJ;DK;DM;DO;DZ;EC;EE;EG;EH;ER;ES;ET;FI;FJ;FK;FM;FO;FR;GA;UK;GD;GE;GF;GG;GH;GI;GL;GM;GN;GP;GQ;GR;GS;GT;GU;GW;GY;HK;HM;HN;HR;HT;HU;ID;IE;IL;IM;IN;IO;IQ;IR;IS;IT;JE;JM;JO;JP;KE;KG;KH;KI;KM;KN;KP;KR;KW;KY;KZ;LA;LB;LC;LI;LK;LR;LS;LT;LU;LV;LY;MA;MC;MD;ME;MF;MG;MH;MK;ML;MM;MN;MO;MP;MQ;MR;MS;MT;MU;MV;MW;MX;MY;MZ;NA;NC;NE;NF;NG;NI;NL;NO;NP;NR;NU;NZ;OM;PA;PE;PF;PG;PH;PK;PL;PM;PN;PR;PS;PT;PW;PY;QA;RE;RO;RS;RU;RW;SA;SB;SC;SD;SE;SG;SH;SI;SJ;SK;SL;SM;SN;SO;SR;SS;ST;SV;SX;SY;SZ;TC;TD;TF;TG;TH;TJ;TK;TL;TM;TN;TO;TR;TT;TV;TW;TZ;UA;UG;UM;US;UY;UZ;VA;VC;VE;VG;VI;VN;VU;WF;WS;XK;YE;YT;ZA;ZM;ZW

3433
data/subdivisions.csv Executable file

File diff suppressed because it is too large Load Diff

1620
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

26
package.json Normal file
View File

@ -0,0 +1,26 @@
{
"name": "@iptv-org/database",
"scripts": {
"act:check": "act pull_request -W .github/workflows/check.yml",
"act:deploy": "act push -W .github/workflows/deploy.yml",
"db:validate": "node scripts/db/validate.js",
"db:export": "node scripts/db/export.js"
},
"private": true,
"author": "Arhey",
"dependencies": {
"axios": "^0.25.0",
"chalk": "^4.1.2",
"cheerio": "^1.0.0-rc.10",
"commander": "^9.0.0",
"csvtojson": "^2.0.10",
"glob": "^7.2.0",
"joi": "^17.6.0",
"json2csv": "^6.0.0-alpha.0",
"mz": "^2.7.0",
"node-cleanup": "^2.1.2",
"signale": "^1.4.0",
"slugify": "^1.6.5",
"transliteration": "^2.2.0"
}
}

1
scripts/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/bot.js

71
scripts/core/csv.js Normal file
View File

@ -0,0 +1,71 @@
const csv2json = require('csvtojson')
const fs = require('mz/fs')
const {
Parser,
transforms: { flatten },
formatters: { stringQuoteOnlyIfNecessary }
} = require('json2csv')
const csv2jsonOptions = {
checkColumn: true,
trim: true,
colParser: {
countries: listParser,
languages: listParser,
categories: listParser,
broadcast_area: listParser,
is_nsfw: boolParser,
logo: nullable,
subdivision: nullable,
city: nullable,
network: nullable
}
}
const json2csv = new Parser({
transforms: [flattenArray],
formatters: {
string: stringQuoteOnlyIfNecessary()
}
})
const csv = {}
csv.load = async function (filepath) {
return csv2json(csv2jsonOptions).fromFile(filepath)
}
csv.save = async function (filepath, data) {
const string = json2csv.parse(data)
return fs.writeFile(filepath, string)
}
csv.saveSync = function (filepath, data) {
const string = json2csv.parse(data)
return fs.writeFileSync(filepath, string)
}
module.exports = csv
function flattenArray(item) {
for (let prop in item) {
const value = item[prop]
item[prop] = Array.isArray(value) ? value.join(';') : value
}
return item
}
function listParser(value) {
return value.split(';').filter(i => i)
}
function boolParser(value) {
return value === 'true'
}
function nullable(value) {
return value === '' ? null : value
}

68
scripts/core/file.js Normal file
View File

@ -0,0 +1,68 @@
const path = require('path')
const glob = require('glob')
const fs = require('mz/fs')
const file = {}
file.list = function (pattern) {
return new Promise(resolve => {
glob(pattern, function (err, files) {
resolve(files)
})
})
}
file.getFilename = function (filepath) {
return path.parse(filepath).name
}
file.createDir = async function (dir) {
if (await file.exists(dir)) return
return fs.mkdir(dir, { recursive: true }).catch(console.error)
}
file.exists = function (filepath) {
return fs.exists(path.resolve(filepath))
}
file.read = function (filepath) {
return fs.readFile(path.resolve(filepath), { encoding: 'utf8' }).catch(console.error)
}
file.append = function (filepath, data) {
return fs.appendFile(path.resolve(filepath), data).catch(console.error)
}
file.create = function (filepath, data = '') {
filepath = path.resolve(filepath)
const dir = path.dirname(filepath)
return file
.createDir(dir)
.then(() => file.write(filepath, data))
.catch(console.error)
}
file.write = function (filepath, data = '') {
return fs.writeFile(path.resolve(filepath), data, { encoding: 'utf8' }).catch(console.error)
}
file.clear = async function (filepath) {
if (await file.exists(filepath)) return file.write(filepath, '')
return true
}
file.resolve = function (filepath) {
return path.resolve(filepath)
}
file.dirname = function (filepath) {
return path.dirname(filepath)
}
file.basename = function (filepath) {
return path.basename(filepath)
}
module.exports = file

3
scripts/core/index.js Normal file
View File

@ -0,0 +1,3 @@
exports.csv = require('./csv')
exports.file = require('./file')
exports.logger = require('./logger')

13
scripts/core/logger.js Normal file
View File

@ -0,0 +1,13 @@
const { Signale } = require('signale')
const options = {}
const logger = new Signale(options)
logger.config({
displayLabel: false,
displayScope: false,
displayBadge: false
})
module.exports = logger

23
scripts/db/export.js Normal file
View File

@ -0,0 +1,23 @@
const { csv } = require('../core')
const path = require('path')
const glob = require('glob')
const fs = require('fs')
const DATA_DIR = process.env.DATA_DIR || './data'
const OUTPUT_DIR = process.env.OUTPUT_DIR || './.gh-pages'
fs.exists(OUTPUT_DIR, function (exists) {
if (!exists) {
fs.mkdirSync(OUTPUT_DIR)
}
})
glob(`${DATA_DIR}/*.csv`, async function (err, files) {
for (const inputFile of files) {
const inputFilename = path.parse(inputFile).name
const outputFile = `${OUTPUT_DIR}/${inputFilename}.json`
const json = await csv.load(inputFile)
fs.writeFileSync(path.resolve(outputFile), JSON.stringify(json))
}
})

View File

@ -0,0 +1,10 @@
const Joi = require('joi')
module.exports = {
id: Joi.string()
.regex(/^[a-z]+$/)
.required(),
name: Joi.string()
.regex(/^[A-Z]+$/i)
.required()
}

View File

@ -0,0 +1,27 @@
const Joi = require('joi')
module.exports = {
id: Joi.string()
.regex(/^[A-Za-z0-9]+\.[a-z]{2}$/)
.required(),
name: Joi.string()
.regex(/^[\sa-zA-Z\u00C0-\u00FF0-9-!:&.+'/»#%°$@?()]+$/)
.required(),
network: Joi.string().allow(null),
country: Joi.string()
.regex(/^[A-Z]{2}$/)
.required(),
subdivision: Joi.string()
.regex(/^[A-Z]{2}-[A-Z0-9]{1,3}$/)
.allow(null),
city: Joi.string().allow(null),
broadcast_area: Joi.array().items(
Joi.string().regex(/^(s\/[A-Z]{2}-[A-Z0-9]{1,3}|c\/[A-Z]{2}|r\/[A-Z0-9]{3,7})$/)
),
languages: Joi.array()
.items(Joi.string().regex(/^[a-z]{3}$/))
.allow(''),
categories: Joi.array().items(Joi.string().regex(/^[a-z]+$/)),
is_nsfw: Joi.boolean().required(),
logo: Joi.string().uri().allow(null)
}

View File

@ -0,0 +1,16 @@
const Joi = require('joi')
module.exports = {
name: Joi.string()
.regex(/^[\sA-Z\u00C0-\u00FF().-]+$/i)
.required(),
code: Joi.string()
.regex(/^[A-Z]{2}$/)
.required(),
lang: Joi.string()
.regex(/^[a-z]{3}$/)
.required(),
flag: Joi.string()
.regex(/^[\uD83C][\uDDE6-\uDDFF][\uD83C][\uDDE6-\uDDFF]$/)
.required()
}

View File

@ -0,0 +1,6 @@
exports.channels = require('./channels')
exports.categories = require('./categories')
exports.countries = require('./countries')
exports.languages = require('./languages')
exports.regions = require('./regions')
exports.subdivisions = require('./subdivisions')

View File

@ -0,0 +1,8 @@
const Joi = require('joi')
module.exports = {
code: Joi.string()
.regex(/^[a-z]{3}$/)
.required(),
name: Joi.string().required()
}

View File

@ -0,0 +1,15 @@
const Joi = require('joi')
module.exports = {
name: Joi.string()
.regex(/^[\sA-Z\u00C0-\u00FF().,-]+$/i)
.required(),
code: Joi.string()
.regex(/^[A-Z]{3,7}$/)
.required(),
countries: Joi.array().items(
Joi.string()
.regex(/^[A-Z]{2}$/)
.allow('')
)
}

View File

@ -0,0 +1,11 @@
const Joi = require('joi')
module.exports = {
country: Joi.string()
.regex(/^[A-Z]{2}$/)
.required(),
name: Joi.string().required(),
code: Joi.string()
.regex(/^[A-Z]{2}-[A-Z0-9]{1,3}$/)
.required()
}

84
scripts/db/validate.js Normal file
View File

@ -0,0 +1,84 @@
const { logger, file, csv } = require('../core')
const { program } = require('commander')
const schemes = require('./schemes')
const chalk = require('chalk')
const Joi = require('joi')
program.argument('[filepath]', 'Path to file to validate').parse(process.argv)
async function main() {
let errors = []
const files = program.args.length
? program.args
: [
'data/categories.csv',
'data/channels.csv',
'data/countries.csv',
'data/languages.csv',
'data/regions.csv',
'data/subdivisions.csv'
]
for (const filepath of files) {
if (!filepath.endsWith('.csv')) continue
const data = await csv.load(filepath)
const filename = file.getFilename(filepath)
if (!schemes[filename]) {
logger.error(chalk.red(`\nERR: "${filename}" scheme is missing`))
process.exit(1)
}
let fileErrors = []
if (filename === 'channels') {
fileErrors = fileErrors.concat(findDuplicatesById(data))
}
const schema = Joi.object(schemes[filename])
data.forEach((row, i) => {
const { error } = schema.validate(row, { abortEarly: false })
if (error) {
error.details.forEach(detail => {
fileErrors.push({ line: i + 2, message: detail.message })
})
}
})
if (fileErrors.length) {
logger.info(`\n${chalk.underline(filepath)}`)
fileErrors.forEach(err => {
const position = err.line.toString().padEnd(6, ' ')
logger.error(` ${chalk.gray(position)} ${err.message}`)
})
errors = errors.concat(fileErrors)
}
}
if (errors.length) {
logger.error(chalk.red(`\n${errors.length} error(s)`))
process.exit(1)
}
}
main()
function findDuplicatesById(data) {
data = data.map(i => {
i.id = i.id.toLowerCase()
return i
})
const errors = []
const schema = Joi.array().unique((a, b) => a.id === b.id)
const { error } = schema.validate(data, { abortEarly: false })
if (error) {
error.details.forEach(detail => {
errors.push({
line: detail.context.pos + 2,
message: `Entry with the id "${detail.context.value.id}" already exists`
})
})
}
return errors
}