├── .github ├── FUNDING.yml └── workflows │ └── grab.yml ├── .gitignore ├── .vscode ├── .ropeproject │ └── config.py └── settings.json ├── build.sh ├── configs ├── ar_arab.xml ├── ar_bein.xml ├── ar_el_cinema.xml ├── ar_osn.xml ├── ar_osn2.xml ├── ar_osn3.xml ├── ar_osn4.xml ├── ar_osn5.xml ├── fr_canal.xml ├── fr_canal3.xml ├── fr_telerama.xml ├── others.xml ├── programme_tv.xml ├── programme_tv2.xml ├── programme_tv3.xml ├── programme_tv4.xml └── test.xml ├── docker ├── dockerfile ├── merge.sh └── readme.md ├── merge.xml.gz ├── merge.zip ├── out ├── epg.csv ├── epg_stats.csv ├── missed_channels.md └── test.xml ├── readme.md └── scripts ├── check.py ├── check_channels.sh ├── check_channels_programs.sh ├── grab_from_url.sh ├── missed_channels.sh ├── readme.md ├── readme.sh ├── stats_epg.py └── utils.sh /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: Fazzani 4 | buy_me_a_coffee: Fazzani 5 | -------------------------------------------------------------------------------- /.github/workflows/grab.yml: -------------------------------------------------------------------------------- 1 | name: grab 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | logLevel: 6 | description: 'Log level' 7 | required: true 8 | default: 'warning' 9 | schedule: 10 | - cron: '0 3 * * *' 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | with: 19 | persist-credentials: false 20 | 21 | - uses: actions/setup-python@v2 22 | with: 23 | python-version: '3.12' 24 | 25 | - name: Download & merge xmltv files 26 | env: 27 | EPG_URLS: ${{ secrets.EPG_URLS }} 28 | run: | 29 | chmod +x ./build.sh 30 | 31 | echo -e "--------------- downloading xmltv files\n" 32 | epg_urls=(${EPG_URLS//;/ }) 33 | ./build.sh --download "${epg_urls[@]}" 34 | 35 | echo -e "--------------- merging xmltv files\n" 36 | ./build.sh --merge 37 | 38 | - name: Update md files 39 | run: | 40 | echo -e "--------------- epg stats\n" 41 | 42 | ls -lah 43 | 44 | pip install pandas jinja2 45 | python ./scripts/check.py . 46 | ./build.sh --stats 47 | 48 | echo -e "--------------- generating md files\n" 49 | 50 | chmod +x ./scripts/readme.sh && ./scripts/readme.sh 51 | chmod +x ./scripts/missed_channels.sh && ./scripts/missed_channels.sh 52 | 53 | - name: Commit & Push changes 54 | uses: actions-js/push@master 55 | with: 56 | github_token: ${{ secrets.API_TOKEN }} 57 | author_email: "heni.fazzani@gmail.com" 58 | author_name: "Heni Fazzani" 59 | branch: "master" 60 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/tmp 2 | merge.xml 3 | merge.xmltv -------------------------------------------------------------------------------- /.vscode/.ropeproject/config.py: -------------------------------------------------------------------------------- 1 | # The default ``config.py`` 2 | # flake8: noqa 3 | 4 | 5 | def set_prefs(prefs): 6 | """This function is called before opening the project""" 7 | 8 | # Specify which files and folders to ignore in the project. 9 | # Changes to ignored resources are not added to the history and 10 | # VCSs. Also they are not returned in `Project.get_files()`. 11 | # Note that ``?`` and ``*`` match all characters but slashes. 12 | # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' 13 | # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' 14 | # '.svn': matches 'pkg/.svn' and all of its children 15 | # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' 16 | # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' 17 | prefs["ignored_resources"] = [ 18 | "*.pyc", 19 | "*~", 20 | ".ropeproject", 21 | ".hg", 22 | ".svn", 23 | "_svn", 24 | ".git", 25 | ".tox", 26 | ] 27 | 28 | # Specifies which files should be considered python files. It is 29 | # useful when you have scripts inside your project. Only files 30 | # ending with ``.py`` are considered to be python files by 31 | # default. 32 | # prefs['python_files'] = ['*.py'] 33 | 34 | # Custom source folders: By default rope searches the project 35 | # for finding source folders (folders that should be searched 36 | # for finding modules). You can add paths to that list. Note 37 | # that rope guesses project source folders correctly most of the 38 | # time; use this if you have any problems. 39 | # The folders should be relative to project root and use '/' for 40 | # separating folders regardless of the platform rope is running on. 41 | # 'src/my_source_folder' for instance. 42 | # prefs.add('source_folders', 'src') 43 | 44 | # You can extend python path for looking up modules 45 | # prefs.add('python_path', '~/python/') 46 | 47 | # Should rope save object information or not. 48 | prefs["save_objectdb"] = True 49 | prefs["compress_objectdb"] = False 50 | 51 | # If `True`, rope analyzes each module when it is being saved. 52 | prefs["automatic_soa"] = True 53 | # The depth of calls to follow in static object analysis 54 | prefs["soa_followed_calls"] = 0 55 | 56 | # If `False` when running modules or unit tests "dynamic object 57 | # analysis" is turned off. This makes them much faster. 58 | prefs["perform_doa"] = True 59 | 60 | # Rope can check the validity of its object DB when running. 61 | prefs["validate_objectdb"] = True 62 | 63 | # How many undos to hold? 64 | prefs["max_history_items"] = 32 65 | 66 | # Shows whether to save history across sessions. 67 | prefs["save_history"] = True 68 | prefs["compress_history"] = False 69 | 70 | # Set the number spaces used for indenting. According to 71 | # :PEP:`8`, it is best to use 4 spaces. Since most of rope's 72 | # unit-tests use 4 spaces it is more reliable, too. 73 | prefs["indent_size"] = 4 74 | 75 | # Builtin and c-extension modules that are allowed to be imported 76 | # and inspected by rope. 77 | prefs["extension_modules"] = [] 78 | 79 | # Add all standard c-extensions to extension_modules list. 80 | prefs["import_dynload_stdmods"] = True 81 | 82 | # If `True` modules with syntax errors are considered to be empty. 83 | # The default value is `False`; When `False` syntax errors raise 84 | # `rope.base.exceptions.ModuleSyntaxError` exception. 85 | prefs["ignore_syntax_errors"] = False 86 | 87 | # If `True`, rope ignores unresolvable imports. Otherwise, they 88 | # appear in the importing namespace. 89 | prefs["ignore_bad_imports"] = False 90 | 91 | # If `True`, rope will insert new module imports as 92 | # `from import ` by default. 93 | prefs["prefer_module_from_imports"] = False 94 | 95 | # If `True`, rope will transform a comma list of imports into 96 | # multiple separate import statements when organizing 97 | # imports. 98 | prefs["split_imports"] = False 99 | 100 | # If `True`, rope will remove all top-level import statements and 101 | # reinsert them at the top of the module when making changes. 102 | prefs["pull_imports_to_top"] = True 103 | 104 | # If `True`, rope will sort imports alphabetically by module name instead 105 | # of alphabetically by import statement, with from imports after normal 106 | # imports. 107 | prefs["sort_imports_alphabetically"] = False 108 | 109 | # Location of implementation of 110 | # rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general 111 | # case, you don't have to change this value, unless you're an rope expert. 112 | # Change this value to inject you own implementations of interfaces 113 | # listed in module rope.base.oi.type_hinting.providers.interfaces 114 | # For example, you can add you own providers for Django Models, or disable 115 | # the search type-hinting in a class hierarchy, etc. 116 | prefs[ 117 | "type_hinting_factory" 118 | ] = "rope.base.oi.type_hinting.factory.default_type_hinting_factory" 119 | 120 | 121 | def project_opened(project): 122 | """This function is called after opening the project""" 123 | # Do whatever you like here! 124 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.pythonPath": "/home/ansible/miniconda3/envs/check-channels/bin/python" 3 | } -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | OLDIFS=$IFS 4 | 5 | function build { 6 | git clone --depth 1 https://${GIT_TOKEN}@github.com/fazzani/grab.git > /dev/null 2>&1 && \ 7 | cd grab && \ 8 | docker run -it --rm -v "${PWD}/${WEBGRAB_FILENAME}:/config/WebGrab++.config.xml" --hostname test --mac-address="12:34:de:b0:6b:61" -v "${PWD}:/data" synker/webgraboneshot:latest 9 | git add --all && (git commit -m "Webgrab ${WEBGRAB_FILENAME}" || echo "No changes to commit" && exit 0) 10 | git config --global http.postBuffer 524288000 11 | 12 | local counter=0 13 | until [ $counter -gt 5 ]; do 14 | { { git pull &> /dev/null && git push -f; } && break; } || ((counter++)) 15 | echo Transfer disrupted, retrying in 10 seconds... 16 | sleep 10 17 | done 18 | } 19 | 20 | function merge { 21 | sudo apt-get install -yqq --no-install-recommends \ 22 | xmltv-util \ 23 | dos2unix \ 24 | zip 25 | 26 | dos2unix docker/merge.sh && \ 27 | chmod +x docker/merge.sh && \ 28 | docker/merge.sh ./tmp 29 | } 30 | 31 | function stats { 32 | local month_ago_date=$(date --date="-${1:-7} day" +%F) 33 | local data_file_path="/tmp/tmp_epg.csv" 34 | local merge_file_path="/tmp/epg_merge.csv" 35 | 36 | echo "Filtering git commits from $month_ago_date" 37 | [[ -f $merge_file_path ]] && rm $merge_file_path 38 | 39 | for commit in $(git log --after="$month_ago_date" --format=%h -- out/epg.csv) 40 | do 41 | git show $commit:out/epg.csv > $data_file_path 42 | python3 scripts/stats_epg.py -p $data_file_path 43 | [[ -f $data_file_path ]] && rm $data_file_path 44 | done 45 | python3 scripts/stats_epg.py -s 46 | } 47 | 48 | BUILD=false 49 | MERGE=false 50 | for arg in "$@" 51 | do 52 | case "$arg" in 53 | "--build") 54 | BUILD=true 55 | ;; 56 | "--download") 57 | shift 58 | chmod +x ./scripts/grab_from_url.sh && ./scripts/grab_from_url.sh $@ 59 | ;; 60 | "--merge") 61 | MERGE=true 62 | ;; 63 | "--check") 64 | shift 65 | pip install pandas --break-system-packages 66 | python3 ./scripts/check.py . 67 | ;; 68 | "--stats") 69 | shift 70 | pip install pandas --break-system-packages 71 | python3 ./scripts/stats_epg.py -s -f out/epg.csv 72 | exit 0 73 | ;; 74 | esac 75 | shift 76 | done 77 | 78 | [[ $BUILD = true ]] && build 79 | [[ $MERGE = true ]] && merge 80 | 81 | exit 0 -------------------------------------------------------------------------------- /configs/ar_arab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/ar_arab.xmltv 4 | m 5 | mdb 6 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 7 | on 8 | 1 9 | 12 10 | 1 11 | 12 | i 13 | 14 | MBC 3 15 | MBC 16 | MBC MAX 17 | MBC Action 18 | MBC 2 19 | MBC 4 20 | MBC Bollywood 21 | MBC Drama + 22 | MBC MASR 2 23 | MBC Drama 24 | MBC Egypt 25 | MBC Iraq 26 | Saudiya TV 27 | Emirates 28 | Hawass 29 | Dubai TV 30 | Dubai One 31 | Future TV 32 | LBC Europe 33 | Alsumaria 34 | LBCI 35 | CBC sofra 36 | Cima 37 | ART Cinema 38 | ART Aflam 1 39 | ART Aflam 2 40 | Rotana Drama 41 | Rotana Khalijiah 42 | Al Saeedah 43 | Al Nahar Drama 44 | Abu Dhabi Drama 45 | Alhayat Series 46 | 47 | 48 | -------------------------------------------------------------------------------- /configs/ar_bein.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/ar_bein.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36 Edg/79.0.309.71 8 | on 9 | 1 10 | 12,5 11 | 1 12 | 13 | i 14 | 15 | Watania 1 16 | Watania 2 17 | 18 | BS1 19 | BS2 20 | BS3 21 | SportsGlobalHD English 22 | News_ar English 23 | beIN sports 1 24 | beIN sports Z 25 | beIN sports 3 26 | beIN sports 4 27 | beIN sports 5 28 | beIN sports 6 29 | beIN sports 7 30 | beIN sports 8 31 | beIN sports 9 32 | beIN sports 10 33 | beIN sports 11 34 | beIN sports 12 35 | beIN sports 13 36 | beIN sports 14 37 | beIN sports 15 38 | beIN sports 16 39 | beIN sports 17 40 | beIN sports 4K 41 | BS NBA English 42 | beIN Movies 1 43 | beIN Movies 2 44 | beIN Movies 3 45 | beIN Movies 4 46 | beIN BoxOffice 1 47 | beIN Series 1 48 | beIN Series 2 49 | beIN Drama 1 50 | beIN gourmet 51 | beJUNIOR 52 | beIN Jeem 53 | beIN Baraem 54 | CartoonNetworkHD English 55 | CartoonNetworkAR English 56 | CartoonNetworkHindi English 57 | beIN Baby TV 58 | beIN CBeebies 59 | beIN DreamWorks 60 | beIN JimJam 61 | FOXFamilyMovies English 62 | FOXActionMovies English 63 | Star_World_HD English 64 | beIN TCM 65 | beIN amc 66 | Star Movies English 67 | beIN FOX 68 | beIN Outdoor Channel 69 | beIN V 70 | beIN Travel Channel 71 | beIN Extreme 72 | fatafeat 73 | FoodNetwork 74 | beIN HGTV 75 | CBSreality English 76 | beIN FX 77 | beIN DMAX 78 | beIN NatGeoWild 79 | beIN NatGeoPeople 80 | beIN NatGeo 81 | beIN BBCEarth 82 | beIN AnimalPlanet 83 | Aljazeera Documentary 84 | beIN TRT World 85 | beIN Euronews 86 | beIN CNN 87 | beIN Bloomberg 88 | beIN HLN 89 | beIN DTX 90 | beIN DLife 91 | beIN FineLiving 92 | 93 | -------------------------------------------------------------------------------- /configs/ar_el_cinema.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/ar_el_cinema.xmltv 4 | m 5 | mdb 6 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 7 | on 8 | 1 9 | 12 10 | 1 11 | 12 | i 13 | 14 | almanar 15 | Sada El Balad 16 | ON E 17 | Amman 18 | MTV 19 | Al Nahar TV 20 | Al Jadeed TV 21 | Al Kahera Wal Nas TV 22 | Al sharqya 23 | Zee alwan 24 | Fujairah 25 | Roya 26 | Mehwar 27 | Alhayat TV 28 | Sharjah TV 29 | Lana 30 | Sada El Balad Drama 31 | ON Drama 32 | iFILM TV 33 | DMC DRAMA 34 | Alhayat Series 35 | TeN TV 36 | Fan 37 | Oman 38 | Al Aoula Morocco 39 | Aflam TV 7 Maroc 40 | CBC Drama 41 | Nile Drama 42 | Series 43 | SBC 44 | Thikrayat Tv 45 | 46 | 47 | -------------------------------------------------------------------------------- /configs/ar_osn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/ar_osn.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | on 9 | 1 10 | 12,5 11 | 1 12 | 13 | i 14 | 15 | OSN Movies First 16 | OSN Movies First+2 17 | OSN Action 18 | OSN Movies 19 | OSN Popup 20 | OSN Enigma 21 | OSN Kids 22 | OSN Movies Disney 23 | 24 | 25 | -------------------------------------------------------------------------------- /configs/ar_osn2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/ar_osn2.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | on 9 | 1 10 | 12,5 11 | 2 12 | i 13 | 14 | Paramount 15 | Star Movies HD 16 | B4U Plus 17 | Imagine Movies 18 | OSN Ya Hala Al Oula 19 | OSN Ya Hala 20 | OSN Yahala Cinema 21 | Series Channel 22 | Al Yawm 23 | Al Safwa 24 | Fann 25 | ABS-CBN Regional Channel 26 | Aksyon TV 27 | Cine Mo 28 | Lifestyle Network 29 | GMA Pinoy TV 30 | GMA Life TV 31 | GMA News TV 32 | NET 25 33 | 34 | 35 | -------------------------------------------------------------------------------- /configs/ar_osn3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/ar_osn3.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | on 9 | 1 10 | 12,5 11 | 1 12 | i 13 | Cinema 1 14 | Cinema 2 15 | Music Now 16 | Hekayat 17 | Hekayat 2 18 | ART Aflam 1 19 | ART Aflam 2 20 | ART Cinema 21 | Ellay.com 22 | Al Aan TV 23 | Beity TV 24 | KTV1 HD 25 | KTV2 HD 26 | KTV Ethraa HD 27 | KTV Arabe HD 28 | KTV Majlis HD 29 | Al Qurain HD 30 | Sharjah TV 31 | Sharqiya from Kalba 32 | Crime \\u0026 Investigation Network 33 | History HD 34 | H2 HD 35 | Nat Geo HD 36 | Nat Geo Wild HD 37 | Nat Geo People HD 38 | Dubai Racing 1 HD 39 | Dubai Racing 3 40 | Sharjah Sport HD 41 | KTV Sport HD 42 | KTV Sport Plus HD 43 | TFC 44 | ABS-CBN Sports+Action 45 | Cinema One Global 46 | ANC 47 | DZMM Teleradyo 48 | DWRR 101.9 49 | Viva TV 50 | Myx 51 | 52 | -------------------------------------------------------------------------------- /configs/ar_osn4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/ar_osn4.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | on 9 | 1 10 | 12,5 11 | 1 12 | i 13 | 14 | Al Wosta from Al Dhaid 15 | Al Dafrah TV 16 | Bahrain TV 17 | Aghani Aghani 18 | Al Roya TV 19 | OSN Series First 20 | OSN Binge 21 | OSN Comedy 22 | Comedy Central 23 | Star World HD 24 | TLC HD 25 | E! Entertainment HD 26 | OSN Mezze 27 | OSN Living 28 | CGTN 29 | France 24 English 30 | NHK World TV 31 | Madani TV 32 | Sky News Arabia HD 33 | Sky News Arabia 34 | AlMamlaka TV 35 | Rusiya Al Yawm 36 | AL Hurra HD 37 | AL Hurra Iraq HD 38 | BBC Arabic 39 | France 24 40 | CGTN Arabic 41 | CNBC Arabia 42 | Discovery HD 43 | Discovery Science HD 44 | Discovery ID 45 | 46 | 47 | -------------------------------------------------------------------------------- /configs/ar_osn5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/ar_osn5.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | on 9 | 1 10 | 12,5 11 | 1 12 | i 13 | 14 | Fashion TV HD 15 | B4U Aflam 16 | MTV Live HD 17 | VH1 18 | Disney HD 19 | Disney XD 20 | Disney Junior 21 | Nickelodeon HD 22 | Nick Jr 23 | OSN Kid Zone TV 24 | NickToons HD 25 | Baby TV Europe 26 | OSN News 27 | Sky News HD 28 | BBC World 29 | CNBC 30 | Bloomberg 31 | 32 | 33 | -------------------------------------------------------------------------------- /configs/fr_canal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/fr_canal.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | on 9 | 1 10 | 12,1 11 | 12 | 2 13 | i 14 | 15 | CHERIE 25 16 | VICELAND 17 | MTV 18 | MCM 19 | GAME ONE 20 | MANGAS 21 | CSTAR HITS FRANCE 22 | M6 MUSIC 23 | NRJ HITS 24 | TRACE URBAN 25 | MCM TOP 26 | RFM TV 27 | MELODY 28 | MEZZO 29 | MEZZO LIVE 30 | BRAVA 31 | DJAZZ 32 | TRACE AFRICA 33 | FRANCE O 34 | 6TER 35 | NUMERO 23 36 | TV5 MONDE 37 | QVC 38 | ASTROCENTER TV 39 | MUSEUM 40 | LA CHAINE METEO 41 | MY ZEN TV 42 | RMC DECOUVERTE 43 | M6 BOUTIQUE 44 | PLANETE+ 45 | PLANETE+ CI 46 | PLANETE+ A&E 47 | NATIONAL GEO 48 | NAT GEO WILD 49 | VOYAGE 50 | USHUAIA TV 51 | HISTOIRE 52 | SCIENCE ET VIE TV 53 | ANIMAUX 54 | TREK 55 | SEASONS 56 | CHASSE ET PECHE 57 | CNEWS 58 | BFM TV 59 | LCI 60 | FRANCEINFO: 61 | FRANCE 24 62 | LCP 63 | BFM BUSINESS 64 | CNN INT. 65 | BBC WORLD NEWS 66 | EURONEWS 67 | INFOSPORT+ 68 | EUROSPORT 1 69 | EUROSPORT 2 70 | OL TV 71 | ONZEO 72 | GIRONDINS TV 73 | AB MOTEURS 74 | EQUIDIA 75 | BEIN SPORTS 1 76 | BEIN SPORTS 2 77 | BEIN SPORTS 3 78 | GOLF+ 79 | EXTREME SPORTS 80 | L'EQUIPE 81 | RMC SPORT 1 82 | RMC SPORT 2 83 | RMC SPORT 3 84 | RMC SPORT 4 85 | RMC SPORT NEWS 86 | FOOT+ 24/24 87 | BEIN SPORTS MAX 4 88 | BEIN SPORTS MAX 5 89 | BEIN SPORTS MAX 6 90 | BEIN SPORTS MAX 7 91 | BEIN SPORTS MAX 8 92 | BEIN SPORTS MAX 9 93 | BEIN SPORTS MAX 10 94 | 95 | -------------------------------------------------------------------------------- /configs/fr_canal3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/fr_canal3.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | on 9 | 1 10 | 12,1 11 | 2 12 | 13 | i 14 | 15 | DISNEY JUNIOR 16 | PIWI+ 17 | NICKELODEON JUNIOR 18 | TIJI 19 | BOOMERANG 20 | CARTOON NETWORK 21 | NICKELODEON 22 | TELETOON+ 23 | DISNEY XD 24 | CANAL J 25 | BOING 26 | TOONAMI 27 | NICKELODEON TEEN 28 | DISNEY CHANNEL 29 | GULLI 30 | MTV HITS 31 | COMEDIE+ 32 | POLAR+ 33 | WARNER TV 34 | SERIE CLUB 35 | ELLE GIRL 36 | NON STOP PEOPLE 37 | NOVELAS TV 38 | J-ONE 39 | AB1 40 | TV BREIZH 41 | TEVA 42 | PARIS PREMIERE 43 | RTL9 44 | BET 45 | C8 46 | W9 47 | TMC 48 | TFX 49 | NRJ 12 50 | FRANCE 4 51 | CSTAR 52 | 53 | 54 | -------------------------------------------------------------------------------- /configs/fr_telerama.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/fr_telerama.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | on 9 | 0 10 | 11 | 12 12 | 1 13 | i 14 | 15 | MTV Rocks 16 | MTV Base 17 | NRJ Hits 18 | AB 3 19 | E! (fr) 20 | Chasse et pêche 21 | Discovery Channel fr 22 | Discovery Science fr 23 | Science et Vie TV 24 | Extreme Sports Channel 25 | Motorsport TV 26 | OMTV 27 | Al Jazeera English 28 | BBC World News 29 | BE 1 30 | Be Ciné 31 | Be Séries 32 | La Deux 33 | La Trois 34 | La Une 35 | VOOsport World 1 36 | VOOsport World 2 37 | Real Madrid TV 38 | 39 | 40 | -------------------------------------------------------------------------------- /configs/others.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/others.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | on 9 | 1 10 | 12,1 11 | 1 12 | i 13 | 14 | Arena Sport 1.hr 15 | Arena Sport 2.hr 16 | Arena Sport 3.hr 17 | Arena Sport 4.hr 18 | Arena Sport 5.hr 19 | Arena Sport 1 20 | Arena Sport 2 21 | Arena Sport 3 22 | Arena Sport 4 23 | Arena Sport 5 24 | Arena Sport 1 BiH 25 | 26 | 27 | -------------------------------------------------------------------------------- /configs/programme_tv.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/programme-tv.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | on 9 | 1 10 | 12,1 11 | 12 | 2 13 | i 14 | TF1 15 | France 2 16 | France 3 17 | Canal+ 18 | France 5 19 | M6 20 | Arte 21 | C8 22 | W9 23 | TMC 24 | TFX 25 | NRJ 12 26 | La Chaîne parlementaire 27 | France 4 28 | BFMTV 29 | CNEWS 30 | CSTAR 31 | Gulli 32 | France Ô 33 | TF1 Séries Films 34 | L'Equipe 35 | 6ter 36 | RMC Story 37 | RMC Découverte 38 | Chérie 25 39 | LCI - La Chaîne Info 40 | Franceinfo 41 | Paris Première 42 | Canal+ Sport 43 | Canal+ Cinéma 44 | Planète+ 45 | Canal+ Séries 46 | Canal+ Family 47 | Canal+ Décalé 48 | Ciné+ Premier 49 | Ciné+ Frisson 50 | Ciné+ Emotion 51 | Ciné+ Famiz 52 | Ciné+ Club 53 | Ciné+ Classic 54 | OCS Max 55 | OCS City 56 | OCS Choc 57 | OCS Géants 58 | Disney Cinema 59 | TCM Cinéma 60 | Paramount Channel 61 | Action 62 | Sundance TV 63 | Comédie+ 64 | Polar+ 65 | Warner TV 66 | serieclub 67 | MTV 68 | ElleGirl 69 | Non Stop People HD 70 | Novelas TV 71 | MCM 72 | Game One 73 | J-One 74 | Mangas 75 | AB 1 76 | TvBreizh 77 | Téva 78 | RTL 9 79 | BET 80 | TV5MONDE 81 | MyZen.tv 82 | QVC 83 | 84 | 85 | -------------------------------------------------------------------------------- /configs/programme_tv2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/programme-tv2.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | 9 | on 10 | 1 11 | 12,1 12 | 2 13 | i 14 | M6 Boutique 15 | Planète+ Crime Investigation 16 | Planète+ Aventure Expérience 17 | National Geographic 18 | Nat Geo Wild 19 | Voyage 20 | Ushuaïa TV 21 | Histoire 22 | Science & Vie TV 23 | Animaux 24 | Trek 25 | Seasons 26 | Chasse et pêche 27 | La Chaîne Météo 28 | Euronews 29 | France 24 30 | BFM Business 31 | CNN 32 | I24news 33 | KTO 34 | Infosport+ 35 | Eurosport 1 36 | Eurosport 2 37 | beIN SPORTS 1 38 | beIN SPORTS 2 39 | beIN SPORTS 3 40 | RMC Sport 1 41 | RMC Sport 2 42 | RMC Sport 3 43 | RMC Sport 4 44 | RMC Sport News 45 | Onzéo 46 | OLTV 47 | Automoto 48 | Equidia 49 | Golf+ 50 | 51 | 52 | -------------------------------------------------------------------------------- /configs/programme_tv3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/programme-tv3.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | on 9 | 1 10 | 11 | 12,1 12 | 2 13 | i 14 | beIN SPORTS MAX 5 15 | beIN SPORTS MAX 6 16 | beIN SPORTS MAX 7 17 | beIN SPORTS MAX 8 18 | beIN SPORTS MAX 9 19 | beIN SPORTS MAX 10 20 | RMC Sport Live 5 21 | RMC Sport Live 6 22 | RMC Sport Live 7 23 | RMC Sport Live 8 24 | RMC Sport Live 9 25 | RMC Sport Live 10 26 | RMC Sport Live 11 27 | RMC Sport Live 12 28 | RMC Sport Live 13 29 | RMC Sport Live 14 30 | RMC Sport Live 15 31 | RMC Sport Live 16 32 | France 3 Corse Via Stella 33 | 2M Monde 34 | Al Jazeera English 35 | RTPI 36 | TVE 37 | RTL Télévision 38 | ARD 39 | RMC Sport 1 UHD 40 | Altice Studio 41 | BFM Paris 42 | Discovery Channel 43 | Discovery Science 44 | Discovery Family 45 | My Cuisine 46 | 13eme RUE 47 | Syfy 48 | E ! 49 | Vivolta 50 | RMC Sport Access 1 51 | RMC Sport Access 2 52 | RMC Sport Access 3 53 | Golf Channel 54 | TRACE Sport Stars 55 | Eurochannel 56 | Fashion TV 57 | Baby TV 58 | Gong 59 | Gong Max 60 | Ginx 61 | MTV Hits 62 | Trace Tropical 63 | BBlack 64 | VH1 65 | VH1 Classic 66 | MTV Rocks 67 | Stingray i-Concerts 68 | Rai Uno 69 | BBC Entertainment 70 | SWR 71 | ZDF 72 | RTS Un 73 | RTS Deux 74 | B.One 75 | Gospel Music TV 76 | La Une 77 | La Deux 78 | La Trois 79 | RTL TVI 80 | Club RTL 81 | Plug RTL 82 | Arte Belgique 83 | AB 3 84 | Be Séries 85 | Be Ciné 86 | Ciné+ Premier Belgique 87 | Ciné+ Frisson Belgique 88 | Ciné+ Classic Belgique 89 | VOOsport World 2 90 | VOOsport World 3 91 | Eleven Sports 1 92 | Eleven Sports 2 93 | Nautical Channel 94 | RTC Télé Liège 95 | Télé Sambre 96 | TV COM 97 | TV Lux 98 | Vedia 99 | NoTélé 100 | Canal C 101 | Télé MB 102 | MAtélé 103 | Canal Zoom 104 | BX1 105 | Nickelodéon Wallonia 106 | Disney Channel Wallonia 107 | Stingray Festival 4K 108 | ABXPLORE 109 | Canal Z 110 | één 111 | Canvas 112 | Vier 113 | Vijf 114 | Vitaya 115 | VTM 116 | Q2 117 | NPO1 118 | NPO2 119 | NPO3 120 | BBC 1 121 | BBC 2 122 | BE 1 123 | VOOsport World 1 124 | Crime District 125 | Demain TV 126 | LCP 100% 127 | Acht 128 | Ketnet 129 | 130 | -------------------------------------------------------------------------------- /configs/programme_tv4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/programme-tv4.xmltv 4 | m 5 | mdb 6 | automatic 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | 9 | on 10 | 1 11 | 12,1 12 | 2 13 | i 14 | Extreme Sports Channel 15 | Disney Junior 16 | Piwi+ 17 | Nickelodeon Junior 18 | TIJI 19 | Boomerang 20 | Cartoon Network 21 | Nickelodéon 22 | TéléToon+ 23 | Disney XD 24 | Canal J 25 | Boing 26 | Toonami 27 | Nickelodéon Teen 28 | Disney Channel 29 | MTV Hits (France) 30 | M6 Music 31 | NRJ Hits 32 | Trace Urban 33 | MCM Top 34 | RFM TV 35 | Melody 36 | Mezzo 37 | Mezzo Live HD 38 | Stingray Brava 39 | Nollywood TV 40 | A+ International France 41 | Trace Africa 42 | XXL 43 | Pink TV 44 | beIN SPORTS MAX 4 45 | 46 | 47 | -------------------------------------------------------------------------------- /configs/test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | /data/test.xmltv 4 | d 5 | mdb 6 | 212.237.52.79:3333 7 | Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; yie9) 8 | on 9 | 1 10 | 12 11 | 0 12 | i 13 | MBC 2 14 | 15 | -------------------------------------------------------------------------------- /docker/dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian 2 | ENV GITHUB_API_TOKEN xxxx 3 | ENV VERBOSE false 4 | LABEL maintainer="fazzani.heni@outlook.com" \ 5 | description="debian image with préinstalled xmltv_util package" \ 6 | system.dist="linux" \ 7 | multi.name="xmltv_util" 8 | 9 | WORKDIR /work 10 | 11 | RUN set -ex 12 | RUN apt-get update -yqq \ 13 | && apt-get upgrade -yqq \ 14 | && apt-get install -yqq --no-install-recommends \ 15 | xmltv-util \ 16 | dos2unix zip \ 17 | && apt-get autoremove -yqq --purge \ 18 | && apt-get clean \ 19 | && rm -rf \ 20 | /var/lib/apt/lists/* \ 21 | /tmp/* \ 22 | /var/tmp/* \ 23 | /usr/share/man \ 24 | /usr/share/doc \ 25 | /usr/share/doc-base 26 | 27 | CMD [ "/bin/bash" ] -------------------------------------------------------------------------------- /docker/merge.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | command -v tv_merge >/dev/null 2>&1 || { echo >&2 "I require tv_merge but it's not installed. Please install xmltv-util package. Aborting."; exit 1; } 6 | command -v gzip >/dev/null 2>&1 || { echo >&2 "I require gzip but it's not installed. Aborting."; exit 1; } 7 | command -v zip >/dev/null 2>&1 || { echo >&2 "I require zip but it's not installed. Aborting."; exit 1; } 8 | 9 | echo "Processing..................." 10 | /usr/bin/tv_cat --utf8 "$1"/*.xml | /usr/bin/tv_grep --on-after now > ./merge.xml 11 | 12 | echo "Cleaning up.................." 13 | [[ -f "./merge.zip" ]] && rm "./merge.zip" 14 | [[ -f "./merge.xml.gz" ]] && rm "./merge.xml.gz" 15 | 16 | echo "Archiving...................." 17 | zip -r merge.zip merge.xml 18 | gzip -fkq merge.xml 19 | 20 | exit 0 -------------------------------------------------------------------------------- /docker/readme.md: -------------------------------------------------------------------------------- 1 | # Merge xmltv 2 | 3 | ENV GITHUB_API_TOKEN required 4 | 5 | ```bash 6 | sudo docker run -it -v "${PWD}:/work" -e GITHUB_API_TOKEN=${GITHUB_API_TOKEN} synker/xmltv_merge:0.0.5 dos2unix docker/merge.sh && docker/merge.sh *.xmltv 7 | # creating and pushing docker image 8 | docker build -t synker/xmltv_merge:latest -t synker/xmltv_merge:0.0.5 . 9 | docker push 10 | ``` 11 | 12 | Elasticsearch missing channel mapping index 13 | 14 | ```json 15 | PUT missingepgchannels 16 | { 17 | "mappings": { 18 | "_doc": { 19 | "properties": { 20 | "report": { 21 | "type": "nested", 22 | "properties": { 23 | "_id": { 24 | "type": "text" 25 | }, 26 | "update_date": { 27 | "type": "date", 28 | "format": "yyyy/MM/dd HH:mm:ss" 29 | }, 30 | "sources": { 31 | "type": "nested", 32 | "properties": { 33 | "filename": { 34 | "type": "text" 35 | }, 36 | "total": { 37 | "type": "long" 38 | }, 39 | "missed": { 40 | "type": "long" 41 | }, 42 | "missedlist": { 43 | "type": "text" 44 | } 45 | } 46 | } 47 | } 48 | } 49 | } 50 | } 51 | } 52 | } 53 | ``` -------------------------------------------------------------------------------- /merge.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fazzani/grab/aedc58ca005f82ab9f6da829eb1c954cee29ad56/merge.xml.gz -------------------------------------------------------------------------------- /merge.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fazzani/grab/aedc58ca005f82ab9f6da829eb1c954cee29ad56/merge.zip -------------------------------------------------------------------------------- /out/missed_channels.md: -------------------------------------------------------------------------------- 1 | 2 | # Missed Channels 3 | 4 | ![Channel count](https://img.shields.io/static/v1?style=for-the-badge&label=channel%20count&message=872&color=red&cacheSeconds=3600) 5 | 6 | 7 | |Icon|Channel|Country|Site| 8 | |:---|:-----:|:-----:|:--:| 9 | ||DisneyXD.uk|uk|| 10 | ||Historia.es|es|| 11 | ||Russia24.ru|ru|| 12 | ||HGTV.pl|pl|| 13 | ||TVPSport.pl|pl|| 14 | ||CrimeInvestigation.uk|uk|| 15 | ||NatGeoWild.pl|pl|| 16 | ||CazaPesca.es|es|| 17 | ||CreateCraft.uk|uk|| 18 | ||Eurosport2.uk|uk|| 19 | ||Hollywood.es|es|| 20 | ||IdealWorld.uk|uk|| 21 | ||4funTV.pl|pl|| 22 | ||NatGeoPeople.pl|pl|| 23 | ||63.espn|espn|| 24 | ||TVNTurbo.pl|pl|| 25 | ||ITVWales.uk|uk|| 26 | ||TVP1.pl|pl|| 27 | ||TVPPolonia.pl|pl|| 28 | ||BeinSports3.fr|fr|| 29 | ||TVPKultura.pl|pl|| 30 | ||Now90s.uk|uk|| 31 | ||BeinSports2.fr|fr|| 32 | ||BeinSports1.fr|fr|| 33 | ||DisneyChannel.ru|ru|| 34 | ||Vamos.es|es|| 35 | ||Bein9Max.fr|fr|| 36 | ||CBSReality.uk|uk|| 37 | ||CRTV.cm|cm|| 38 | ||ExtremeSports.pl|pl|| 39 | ||SkyCinemaFamily.uk|uk|| 40 | ||TVOne.pk|pk|| 41 | ||DawnNews.pk|pk|| 42 | ||109.espn|espn|| 43 | ||Urdu1.pk|pk|| 44 | ||106.espn|espn|| 45 | ||10.espn|espn|| 46 | ||PTVHome.pk|pk|| 47 | ||Eurosport1.uk|uk|| 48 | ||12.espn|espn|| 49 | ||POPMax.uk|uk|| 50 | ||30.espn|espn|| 51 | ||11.espn|espn|| 52 | ||C105.api.telerama.fr|fr|| 53 | ||TVPSeriale.pl|pl|| 54 | ||1.espn|espn|| 55 | ||HorrorChannel.uk|uk|| 56 | ||103.espn|espn|| 57 | ||100.espn|espn|| 58 | ||13.espn|espn|| 59 | ||ARYNews.pk|pk|| 60 | ||CraftExtra.uk|uk|| 61 | ||MovistarGolf.es|es|| 62 | ||HumNews.pk|pk|| 63 | ||SkySportsArena.uk|uk|| 64 | ||HumTV.pk|pk|| 65 | ||Russia1.ru|ru|| 66 | ||CanalPlusFamily.fr|fr|| 67 | ||4FunDance.pl|pl|| 68 | ||0.espn|espn|| 69 | ||ElevenSport2.pl|pl|| 70 | ||ElevenSport3.pl|pl|| 71 | ||Bein4Max.fr|fr|| 72 | ||ElevenSport4.pl|pl|| 73 | ||FilmboxExtra.pl|pl|| 74 | ||FilmboxFamily.pl|pl|| 75 | ||Adventure.pl|pl|| 76 | ||PrimaMax.cz|cz|| 77 | ||FilmboxPremium.pl|pl|| 78 | ||KuchniaPlus.pl|pl|| 79 | ||ActiveFamily.pl|pl|| 80 | ||KinoPolskaMuzyka.pl|pl|| 81 | ||PrimaZoom.cz|cz|| 82 | ||KinoPolska.pl|pl|| 83 | ||MovistarDrama.es|es|| 84 | ||StarsTV.pl|pl|| 85 | ||BarrandovKrimi.cz|cz|| 86 | ||TTV.pl|pl|| 87 | ||AXN.pl|pl|| 88 | ||AXNBlack.pl|pl|| 89 | ||AXNSpin.pl|pl|| 90 | ||Tinypop.uk|uk|| 91 | ||HighStreet5.uk|uk|| 92 | ||Bein7Max.fr|fr|| 93 | ||AXNWhite.pl|pl|| 94 | ||Superstacja.pl|pl|| 95 | ||HighStreet4.uk|uk|| 96 | ||FoxComedy.pl|pl|| 97 | ||FilmBoxAction.pl|pl|| 98 | ||EpicDrama.pl|pl|| 99 | ||Drama.uk|uk|| 100 | ||TVPInfo.pl|pl|| 101 | ||BBCPersian.uk|uk|| 102 | ||TVNŻycieJakBajce.pl|pl|| 103 | ||TVPHistoria.pl|pl|| 104 | ||HBO3.pl|pl|| 105 | ||MovistarDeportes3.es|es|| 106 | ||FOX.pl|pl|| 107 | ||CITV.uk|uk|| 108 | ||Bein8Max.fr|fr|| 109 | ||TVP2.pl|pl|| 110 | ||BritAsiaTV.uk|uk|| 111 | ||TVP3.pl|pl|| 112 | ||TVPRozrywka.pl|pl|| 113 | ||CT4Sport.cz|cz|| 114 | ||MovistarDeportes2.es|es|| 115 | ||CBSDrama.uk|uk|| 116 | ||CT24.cz|cz|| 117 | ||CT2.cz|cz|| 118 | ||BTSport1.uk|uk|| 119 | ||TVNStyle.pl|pl|| 120 | ||CT1.cz|cz|| 121 | ||Bein6Max.fr|fr|| 122 | ||RealityXtra.uk|uk|| 123 | ||Bein5Max.fr|fr|| 124 | ||C444.api.telerama.fr|fr|| 125 | ||C445.api.telerama.fr|fr|| 126 | ||FilmBoxArtHouse.pl|pl|| 127 | ||SportKlub.pl|pl|| 128 | ||ElevenSport1.pl|pl|| 129 | ||MovistarAccion.es|es|| 130 | ||65.espn|espn|| 131 | ||38.espn|espn|| 132 | ||79.espn|espn|| 133 | ||39.espn|espn|| 134 | ||ANT1.gr|gr|| 135 | ||69.espn|espn|| 136 | ||73.espn|espn|| 137 | ||56.espn|espn|| 138 | ||55.espn|espn|| 139 | ||HallmarkDrama.us|us|| 140 | ||54.espn|espn|| 141 | ||53.espn|espn|| 142 | ||74.espn|espn|| 143 | ||75.espn|espn|| 144 | ||15.espn|espn|| 145 | ||51.espn|espn|| 146 | ||CHRGD.ca|ca|| 147 | ||Euronews.us|us|| 148 | ||76.espn|espn|| 149 | ||50.espn|espn|| 150 | ||87.espn|espn|| 151 | ||5.espn|espn|| 152 | ||8.espn|espn|| 153 | ||ATTSportsNetPittsburgh.us|us|| 154 | ||ATTSportsNetHouston.us|us|| 155 | ||OpenTV.gr|gr|| 156 | ||88.espn|espn|| 157 | ||ATTSNRM.us|us|| 158 | ||77.espn|espn|| 159 | ||52.espn|espn|| 160 | ||Arenasport7.hr|hr|| 161 | ||97.espn|espn|| 162 | ||SportKlub6.hr|hr|| 163 | ||96.espn|espn|| 164 | ||Arenasport9.hr|hr|| 165 | ||Omrop.nl|nl|| 166 | ||95.espn|espn|| 167 | ||94.espn|espn|| 168 | ||Arenasport8.hr|hr|| 169 | ||SportKlub1.hr|hr|| 170 | ||ZiggoSportSelect.nl|nl|| 171 | ||92.espn|espn|| 172 | ||66.espn|espn|| 173 | ||SportKlub2.hr|hr|| 174 | ||64.espn|espn|| 175 | ||Alaraby.eg|eg|| 176 | ||SportKlub4.hr|hr|| 177 | ||33.espn|espn|| 178 | ||FOXSports.us|us|| 179 | ||OprahWinfreyNetwork.ca|ca|| 180 | ||34.espn|espn|| 181 | ||OneSoccer.ca|ca|| 182 | ||ArenaSport6.hr|hr|| 183 | ||Arenasport10.hr|hr|| 184 | ||SportKlub5.hr|hr|| 185 | ||86.espn|espn|| 186 | ||31.espn|espn|| 187 | ||62.espn|espn|| 188 | ||61.espn|espn|| 189 | ||StartTV.gr|gr|| 190 | ||SportKlub3.hr|hr|| 191 | ||102.espn|espn|| 192 | ||18.espn|espn|| 193 | ||19.espn|espn|| 194 | ||29.espn|espn|| 195 | ||Yoopa.ca|ca|| 196 | ||108.espn|espn|| 197 | ||2.espn|espn|| 198 | ||104.espn|espn|| 199 | ||20.espn|espn|| 200 | ||21.espn|espn|| 201 | ||22.espn|espn|| 202 | ||28.espn|espn|| 203 | ||27.espn|espn|| 204 | ||EpixHits.us|us|| 205 | ||78.espn|espn|| 206 | ||25.espn|espn|| 207 | ||EpixDriveIn.us|us|| 208 | ||Epix.us|us|| 209 | ||26.espn|espn|| 210 | ||SkyCinemaThriller.uk|uk|| 211 | ||SkyCinemaSciFiHorror.uk|uk|| 212 | ||VRAK.ca|ca|| 213 | ||AMC.uk|uk|| 214 | ||SkyCinemaPremiere.uk|uk|| 215 | ||3.espn|espn|| 216 | ||SkySportSelect.nz|nz|| 217 | ||105.espn|espn|| 218 | ||107.espn|espn|| 219 | ||FootPlus24.fr|fr|| 220 | ||24.espn|espn|| 221 | ||vsportpremierleague1.no|no|| 222 | ||vsportpremierleague2.no|no|| 223 | ||vsportpremierleague3.no|no|| 224 | ||vsportpremierleague4.no|no|| 225 | ||72.espn|espn|| 226 | ||49.espn|espn|| 227 | ||71.espn|espn|| 228 | ||44.espn|espn|| 229 | ||7.espn|espn|| 230 | ||82.espn|espn|| 231 | ||4.espn|espn|| 232 | ||40.espn|espn|| 233 | ||41.espn|espn|| 234 | ||89.espn|espn|| 235 | ||17.espn|espn|| 236 | ||45.espn|espn|| 237 | ||9.espn|espn|| 238 | ||46.espn|espn|| 239 | ||47.espn|espn|| 240 | ||81.espn|espn|| 241 | ||57.espn|espn|| 242 | ||48.espn|espn|| 243 | ||70.espn|espn|| 244 | ||80.espn|espn|| 245 | ||42.espn|espn|| 246 | ||6.espn|espn|| 247 | ||23.espn|espn|| 248 | ||14.espn|espn|| 249 | ||101.espn|espn|| 250 | ||16.espn|espn|| 251 | ||43.espn|espn|| 252 | ||beINSports5.tr|tr|| 253 | ||CanalAndalucia.es|es|| 254 | ||DiscoveryScience.tr|tr|| 255 | ||InvestigationDiscovery.pl|pl|| 256 | ||beINMoviesPremiere2.tr|tr|| 257 | ||FoxLife.ru|ru|| 258 | ||TVGalicia.es|es|| 259 | ||TVRepublika.pl|pl|| 260 | ||24Kitchen.tr|tr|| 261 | ||BBC.pl|pl|| 262 | ||Fox.tr|tr|| 263 | ||SkyCinemaThriller.de|de|| 264 | ||SkyCinemaSpecial.de|de|| 265 | ||SkyCinemaPremierenPlus24.de|de|| 266 | ||TLC.pl|pl|| 267 | ||SkyCinemaPremieren.de|de|| 268 | ||beINBoxOffice2.tr|tr|| 269 | ||HannibalTV.tn|tn|| 270 | ||ElhiwarEttounsi.tn|tn|| 271 | ||TunisnaTV.tn|tn|| 272 | ||Tunisia2.tn|tn|| 273 | ||SkyCinemaBestOf.de|de|| 274 | ||SyriaDramaAR.sy|sy|| 275 | ||Planete.pl|pl|| 276 | ||beINSports4K.qa|qa|| 277 | ||TeenNick.de|de|| 278 | ||PoloTV.pl|pl|| 279 | ||DaznLaLiga.es|es|| 280 | ||Polonia1.pl|pl|| 281 | ||BBCCbeebies.pl|pl|| 282 | ||Cinemax.pl|pl|| 283 | ||beINSports1.tr|tr|| 284 | ||PolsatNews2.pl|pl|| 285 | ||BabyFirstTV.pl|pl|| 286 | ||beINSeriesVice.tr|tr|| 287 | ||beINSeriesSciFi.tr|tr|| 288 | ||BFMParis.fr|fr|| 289 | ||FoxCrime.tr|tr|| 290 | ||PolsatMusic.pl|pl|| 291 | ||beINSeriesDrama.tr|tr|| 292 | ||beINSeriesComedy.tr|tr|| 293 | ||NutaTV.pl|pl|| 294 | ||PolsatGames.pl|pl|| 295 | ||C98.api.telerama.fr|fr|| 296 | ||beINMoviesFamily.tr|tr|| 297 | ||beINSportsHaber.tr|tr|| 298 | ||DiscoveryIDXtra.tr|tr|| 299 | ||JimJam.pl|pl|| 300 | ||ComedyCentral.pl|pl|| 301 | ||beINMoviesAction2.tr|tr|| 302 | ||PowerTV.pl|pl|| 303 | ||beINBoxOffice3.tr|tr|| 304 | ||Nickelodeon.pl|pl|| 305 | ||beINMoviesPremier.tr|tr|| 306 | ||Powerturk.tr|tr|| 307 | ||beINSports3.tr|tr|| 308 | ||BBCBrit.pl|pl|| 309 | ||TVS.pl|pl|| 310 | ||beINBoxOffice1.tr|tr|| 311 | ||13TV.es|es|| 312 | ||DAZNLigue1.fr|fr|| 313 | ||PanoramaDrama.eg|eg|| 314 | ||NileComedy.eg|eg|| 315 | ||C8.fr|fr|| 316 | ||NileCinema.eg|eg|| 317 | ||DiscoveryChannel.pt|pt|| 318 | ||discoveryplusextra3.se|se|| 319 | ||atglive.se|se|| 320 | ||bbcearth.se|se|| 321 | ||JimJam.pt|pt|| 322 | ||FashionTV.pt|pt|| 323 | ||discoveryplusextra1.se|se|| 324 | ||discoveryplusextra2.se|se|| 325 | ||discoveryplusextra4.se|se|| 326 | ||AMC.pl|pl|| 327 | ||discoveryplusextra5.se|se|| 328 | ||discoveryplusextra6.se|se|| 329 | ||discoveryplusextra7.se|se|| 330 | ||viasatultra.dk|dk|| 331 | ||discoveryplusextra8.se|se|| 332 | ||tv4motor.se|se|| 333 | ||C732.api.telerama.fr|fr|| 334 | ||SamiraTV.dz|dz|| 335 | ||PanoramaDrama2.eg|eg|| 336 | ||C730.api.telerama.fr|fr|| 337 | ||NileTV.eg|eg|| 338 | ||History.se|se|| 339 | ||MBCEgyptAr.eg|eg|| 340 | ||AlNaharOne.eg|eg|| 341 | ||C734.api.telerama.fr|fr|| 342 | ||BBCEarth.pl|pl|| 343 | ||FoxMovies.pt|pt|| 344 | ||IqraaTV.sa|sa|| 345 | ||Wau.sk|sk|| 346 | ||MLaLiga.es|es|| 347 | ||MovistarSeries1.es|es|| 348 | ||DiscoveryChannel.es|es|| 349 | ||HistoryChannel.pt|pt|| 350 | ||CrimeInvestigation.pt|pt|| 351 | ||viasatsportultra.se|se|| 352 | ||CanalplusSeries.fr|fr|| 353 | ||EEntertainment.sa|sa|| 354 | ||Saudi1.sa|sa|| 355 | ||FoxCrime.pt|pt|| 356 | ||NileFamily.eg|eg|| 357 | ||SaudiQuran.sa|sa|| 358 | ||SundanceTV.es|es|| 359 | ||AMCCrime.es|es|| 360 | ||AlYawm.sa|sa|| 361 | ||AlMajdQuran.sa|sa|| 362 | ||AlSunnahAlNabawiyahEn.sa|sa|| 363 | ||EVENEMENTALACARTE.fr|fr|| 364 | ||nicktoons.se|se|| 365 | ||Dark.es|es|| 366 | ||EnquetesCriminelles2424.fr|fr|| 367 | ||cmorehits.dk|dk|| 368 | ||NileSport.eg|eg|| 369 | ||PFC.pt|pt|| 370 | ||NileNews.eg|eg|| 371 | ||Eurosport2.pt|pt|| 372 | ||DKISS.es|es|| 373 | ||MovistarComedia.es|es|| 374 | ||VT1.cz|cz|| 375 | ||TVN24.pl|pl|| 376 | ||Boomerang.cz|cz|| 377 | ||MovistarCineEspanol.es|es|| 378 | ||GOLD.uk|uk|| 379 | ||ParamountChannel.es|es|| 380 | ||FoodNetwork.ru|ru|| 381 | ||Movies4Men.uk|uk|| 382 | ||UPNetwork.cz|cz|| 383 | ||AnimalPlanet.pl|pl|| 384 | ||VT2.cz|cz|| 385 | ||MTVLive.ru|ru|| 386 | ||HBO.pl|pl|| 387 | ||History.pl|pl|| 388 | ||Toros.es|es|| 389 | ||VT24.cz|cz|| 390 | ||DiscoPoloMusic.pl|pl|| 391 | ||TVN.pl|pl|| 392 | ||MovistarCine.es|es|| 393 | ||C104.api.telerama.fr|fr|| 394 | ||C106.api.telerama.fr|fr|| 395 | ||DisneyChannel.pl|pl|| 396 | ||C103.api.telerama.fr|fr|| 397 | ||DisneyChannel.uk|uk|| 398 | ||ViaplaySports1.uk|uk|| 399 | ||ViaplaySports2.uk|uk|| 400 | ||DAZN.de|de|| 401 | ||AutoMotorSport.de|de|| 402 | ||TV3Catalunya.es|es|| 403 | ||SuperPolsat.pl|pl|| 404 | ||NovaInternational.cz|cz|| 405 | ||TNT.pl|pl|| 406 | ||Syfy.uk|uk|| 407 | ||FoodNetwork.pl|pl|| 408 | ||MovistarDeportes1.es|es|| 409 | ||Boomerang.pl|pl|| 410 | ||EskaTVextra.pl|pl|| 411 | ||NovaTV.cz|cz|| 412 | ||wPolsce.pl|pl|| 413 | ||NatGeo.cz|cz|| 414 | ||JMLDirect.uk|uk|| 415 | ||DAZN1.uk|uk|| 416 | ||SonyChannel.uk|uk|| 417 | ||MotowizjaTV.pl|pl|| 418 | ||NickJr.cz|cz|| 419 | ||FishingHunting.cz|cz|| 420 | ||TNTSport1.uk|uk|| 421 | ||Domo.pl|pl|| 422 | ||TCM.uk|uk|| 423 | ||FilmboxExtra.cz|cz|| 424 | ||DisneyJunior.pl|pl|| 425 | ||EEntertainment.uk|uk|| 426 | ||TVN24BiznesSwiat.pl|pl|| 427 | ||Dave.uk|uk|| 428 | ||TVN7.pl|pl|| 429 | ||TVNFabula.pl|pl|| 430 | ||Yesterday.uk|uk|| 431 | ||NatGeoWild.cz|cz|| 432 | ||Sport5.cz|cz|| 433 | ||TV4.pl|pl|| 434 | ||RedCarpet.pl|pl|| 435 | ||C18.api.telerama.fr|fr|| 436 | ||beINSports8En.qa|qa|| 437 | ||beINSports4.tr|tr|| 438 | ||ParamountChannel.pl|pl|| 439 | ||WaidwerkTV.de|de|| 440 | ||EEntertainment.de|de|| 441 | ||VOXMusicTV.pl|pl|| 442 | ||TravelChannel.pl|pl|| 443 | ||PolsatSportPremium6.pl|pl|| 444 | ||CBSReality.pl|pl|| 445 | ||PolsatSportPremium5.pl|pl|| 446 | ||PolsatSportPremium4.pl|pl|| 447 | ||Polsat.pl|pl|| 448 | ||ViaplayXtra.uk|uk|| 449 | ||CartoonNetwork.pl|pl|| 450 | ||Teletoon.pl|pl|| 451 | ||PolsatSportPremium3.pl|pl|| 452 | ||А1.ru|ru|| 453 | ||BBCLifestyle.pl|pl|| 454 | ||InsightTV.de|de|| 455 | ||TVR.pl|pl|| 456 | ||ViasatHistoryNature.tr|tr|| 457 | ||beINSports4En.qa|qa|| 458 | ||TVTrwam.pl|pl|| 459 | ||AnimalPlanet.tr|tr|| 460 | ||DiscoveryChannel.ru|ru|| 461 | ||Kinomix.ru|ru|| 462 | ||Cinemax2.pl|pl|| 463 | ||MLaLiga2.es|es|| 464 | ||C102.api.telerama.fr|fr|| 465 | ||MTVLive.pl|pl|| 466 | ||FightKlub.pl|pl|| 467 | ||C101.api.telerama.fr|fr|| 468 | ||MTVPolska.pl|pl|| 469 | ||DiscoveryScience.pl|pl|| 470 | ||AhlulbaytTV.uk|uk|| 471 | ||Eden.uk|uk|| 472 | ||Discovery.pl|pl|| 473 | ||MovistarClasicos.es|es|| 474 | ||MatchIgra.ru|ru|| 475 | ||W.uk|uk|| 476 | ||Alibi.uk|uk|| 477 | ||AleKino.pl|pl|| 478 | ||beINSports2.tr|tr|| 479 | ||DiscoveryHistoria.pl|pl|| 480 | ||TVPuls.pl|pl|| 481 | ||Metro.pl|pl|| 482 | ||TNTSport4.uk|uk|| 483 | ||Minimini.pl|pl|| 484 | ||DiscoveryLife.pl|pl|| 485 | ||TVPuls2.pl|pl|| 486 | ||HBO2.pl|pl|| 487 | ||TNTSport3.uk|uk|| 488 | ||TNTSport2.uk|uk|| 489 | ||CTS.tw|tw|| 490 | ||Trinity.tt|tt|| 491 | ||Beyblade2424.fr|fr|| 492 | ||Motorvision TV.de|de|| 493 | ||beINMoviesAction.tr|tr|| 494 | ||DisneyJunior.uk|uk|| 495 | ||KlanKosova.al|al|| 496 | ||T7.al|al|| 497 | ||Doku1.al|al|| 498 | ||NatGeo.al|al|| 499 | ||RTV21.al|al|| 500 | ||OraNews.al|al|| 501 | ||FoxLife.al|al|| 502 | ||SportKlub3.rs|rs|| 503 | ||Primafila9.it|it|| 504 | ||ParamountChannel.it|it|| 505 | ||SportKlub2.rs|rs|| 506 | ||Primafila13.it|it|| 507 | ||NatGeoWild.ro|ro|| 508 | ||Primafila8.it|it|| 509 | ||SportKlub1.rs|rs|| 510 | ||Primafila7.it|it|| 511 | ||TVPaprika.ro|ro|| 512 | ||SportKlub.rs|rs|| 513 | ||JMovie.in|in|| 514 | ||TravelxpTamil.in|in|| 515 | ||sanskartv.in|in|| 516 | ||ZoneInterdite2424.fr|fr|| 517 | ||MadisonSquareGardenPlus.us|us|| 518 | ||SportKlub10.rs|rs|| 519 | ||I24News.fr|fr|| 520 | ||CartoonNetwork.in|in|| 521 | ||LEquipeLive3.fr|fr|| 522 | ||LEquipeLive4.fr|fr|| 523 | ||LEquipeLive5.fr|fr|| 524 | ||IBCTamil.in|in|| 525 | ||Nick.in|in|| 526 | ||VTVNews.in|in|| 527 | ||News18Kannada.in|in|| 528 | ||IBCBakthi.in|in|| 529 | ||Pink2.rs|rs|| 530 | ||CBSReality.rs|rs|| 531 | ||PremiumAction.it|it|| 532 | ||Kino2.al|al|| 533 | ||Arihant.in|in|| 534 | ||TVDukagjini.al|al|| 535 | ||FilmAksion.al|al|| 536 | ||FilmDrame.al|al|| 537 | ||FilmKomedi.al|al|| 538 | ||FilmThriller.al|al|| 539 | ||RTSH1.al|al|| 540 | ||RTSHSport.al|al|| 541 | ||Sofia.al|al|| 542 | ||JuniorTV.al|al|| 543 | ||KTV.al|al|| 544 | ||Kino1.al|al|| 545 | ||Tgcom24.it|it|| 546 | ||SkySportCollection.it|it|| 547 | ||SkySportNBA.it|it|| 548 | ||Techno24.ru|ru|| 549 | ||SkySportFootball.it|it|| 550 | ||MTV.it|it|| 551 | ||ZagorodnayaJizn.ru|ru|| 552 | ||FilmBox.ro|ro|| 553 | ||PrimeVideoLigue1.fr|fr|| 554 | ||IndiaNews.in|in|| 555 | ||NatGeo.ro|ro|| 556 | ||Primafila15.it|it|| 557 | ||Primafila16.it|it|| 558 | ||Tiji.fr|fr|| 559 | ||Primafila17.it|it|| 560 | ||Boing.it|it|| 561 | ||SpikeTV.it|it|| 562 | ||TravelAndAdventure.ru|ru|| 563 | ||ClassHorseTV.it|it|| 564 | ||MilanTV.it|it|| 565 | ||Sport1.il|il|| 566 | ||TravelChannel.ru|ru|| 567 | ||Sport2.il|il|| 568 | ||Primafila1.it|it|| 569 | ||CheddarBusiness.us|us|| 570 | ||Primafila14.it|it|| 571 | ||sonysabhd.in|in|| 572 | ||SportKlub4.rs|rs|| 573 | ||SportKlub9.rs|rs|| 574 | ||ptcpunjabi.in|in|| 575 | ||SportKlub8.rs|rs|| 576 | ||Blaze.it|it|| 577 | ||SportKlub7.rs|rs|| 578 | ||RaiItalia.it|it|| 579 | ||SF2424.fr|fr|| 580 | ||RMCSportLive6.fr|fr|| 581 | ||IndiaNewsRaj.in|in|| 582 | ||GolfChannel.fr|fr|| 583 | ||DDGyanDarshan.in|in|| 584 | ||ViasatExplore.ru|ru|| 585 | ||SportKlub5.rs|rs|| 586 | ||VH1.it|it|| 587 | ||travelxphd.in|in|| 588 | ||Sahana.in|in|| 589 | ||BabyTV.it|it|| 590 | ||SportKlub6.rs|rs|| 591 | ||DD Podhigai.in|in|| 592 | ||timesnowhd.in|in|| 593 | ||Primafila10.it|it|| 594 | ||Primafila11.it|it|| 595 | ||TVXXI.ru|ru|| 596 | ||NatGeoWild.in|in|| 597 | ||IndiaNewsUPUK.in|in|| 598 | ||MBCDrama.ae|ae|| 599 | ||MBC3.ae|ae|| 600 | ||ktvhd.in|in|| 601 | ||Nashville2424.fr|fr|| 602 | ||OCSMax.fr|fr|| 603 | ||24Ghante.in|in|| 604 | ||zeecinema.in|in|| 605 | ||etvhd.in|in|| 606 | ||DiscoveryScience.ro|ro|| 607 | ||NRJ12.fr|fr|| 608 | ||OCSGeants.fr|fr|| 609 | ||TravelChannel.ro|ro|| 610 | ||indianewsupuk.in|in|| 611 | ||OCSCity.fr|fr|| 612 | ||OCSChoc.fr|fr|| 613 | ||EmmanuelTV.za|za|| 614 | ||FOXLife.in|in|| 615 | ||DubaiRacing.ae|ae|| 616 | ||DubaiSports2.ae|ae|| 617 | ||b4umovies.in|in|| 618 | ||DubaiSports1.ae|ae|| 619 | ||Turbo2424.fr|fr|| 620 | ||VuzuAMP.za|za|| 621 | ||WeTV.in|in|| 622 | ||B4UPlus.ae|ae|| 623 | ||ABC Kids||| 624 | ||ETVTelengana.in|in|| 625 | ||EPIC.in|in|| 626 | ||uk.ZEE TV|ZEE TV|| 627 | ||DivaUniversal.ro|ro|| 628 | ||MBCMax.ae|ae|| 629 | ||SharjahSportEn.ae|ae|| 630 | ||SharjahSport.ae|ae|| 631 | ||CNBCArabiya.ae|ae|| 632 | ||NationalGeographicAbuDhabi.ae|ae|| 633 | ||TheFilipinoChannelEn.ae|ae|| 634 | ||colorshd.in|in|| 635 | ||BloombergEn.ae|ae|| 636 | ||colorscineplexhd.in|in|| 637 | ||OSNMezze.ae|ae|| 638 | ||colorsbanglahd.in|in|| 639 | ||colorskannadahd.in|in|| 640 | ||Mathrubhumi News.in|in|| 641 | ||OSNMoviesKids.ae|ae|| 642 | ||OSNNews.ae|ae|| 643 | ||OSNSeriesPrime.ae|ae|| 644 | ||colorsmarathihd.in|in|| 645 | ||DiscoveryKids.in|in|| 646 | ||OSNYaHalaAlOula.ae|ae|| 647 | ||colorsrishtey.in|in|| 648 | ||AnimalPlanet.in|in|| 649 | ||siminnsport3.is|is|| 650 | ||RMCSportLive13.fr|fr|| 651 | ||Sony.in|in|| 652 | ||RMCSportLive12.fr|fr|| 653 | ||news18india.in|in|| 654 | ||stod2fjolskylda.is|is|| 655 | ||stod2sport3.is|is|| 656 | ||TataSkyBollywoodPremiere.in|in|| 657 | ||ParasTV.in|in|| 658 | ||pitaara.in|in|| 659 | ||InfoTV.af|af|| 660 | ||RMCSportLive11.fr|fr|| 661 | ||zeecinemaindiahd.in|in|| 662 | ||Primafila5.it|it|| 663 | ||satsang.in|in|| 664 | ||RMCSportLive10.fr|fr|| 665 | ||Primafila18.it|it|| 666 | ||FOX.rs|rs|| 667 | ||Primafila6.it|it|| 668 | ||LesReinesDuShopping2424.fr|fr|| 669 | ||Primafila2.it|it|| 670 | ||RMCSportLive5.fr|fr|| 671 | ||Primafila3.it|it|| 672 | ||Primafila4.it|it|| 673 | ||CNNNews18.in|in|| 674 | ||siminnsport5.is|is|| 675 | ||DDUttarPradesh.in|in|| 676 | ||zing.in|in|| 677 | ||NDTVIndia.in|in|| 678 | ||ZeeHindustan.in|in|| 679 | ||GinxeSports.za|za|| 680 | ||jayamax.in|in|| 681 | ||TeleLocaleProvence.fr|fr|| 682 | ||DiscoveryTamil.in|in|| 683 | ||colorsgujarati.in|in|| 684 | ||DighvijayNews.in|in|| 685 | ||MediaOne.in|in|| 686 | ||Miniplex.in|in|| 687 | ||LEquipeLive7.fr|fr|| 688 | ||abpnews.in|in|| 689 | ||aastha.in|in|| 690 | ||Tbc1.af|af|| 691 | ||aajtakhd.in|in|| 692 | ||AlIraqiyaTV.iq|iq|| 693 | ||Woman.rs|rs|| 694 | ||MAATV.in|in|| 695 | ||ndtv24x7.in|in|| 696 | ||CartoonNetwork.rs|rs|| 697 | ||DiscoveryScience.rs|rs|| 698 | ||PressTV.ir|ir|| 699 | ||VarzeshFarsi.ir|ir|| 700 | ||LesMarseillais2424.fr|fr|| 701 | ||FashionTV.ru|ru|| 702 | ||NASATV.us|us|| 703 | ||BoxOffice.qa|qa|| 704 | ||FoxSports4.nl|nl|| 705 | ||NBCSportsChicago.us|us|| 706 | ||ICIRadioCanadaMontreal.ca|ca|| 707 | ||Fox.nl|nl|| 708 | ||DetskijMir.ru|ru|| 709 | ||Karusel.ru|ru|| 710 | ||CBSReality.hu|hu|| 711 | ||beINSports9En.qa|qa|| 712 | ||MuzTV.ru|ru|| 713 | ||bTV.bg|bg|| 714 | ||CartoonNetwork.ru|ru|| 715 | ||beINSports6En.qa|qa|| 716 | ||Psychologiya21.ru|ru|| 717 | ||UniversalKids.us|us|| 718 | ||Spike.nl|nl|| 719 | ||beINSports3En.qa|qa|| 720 | ||Bonumtv.hu|hu|| 721 | ||BeinSportsExtra3.qa|qa|| 722 | ||BeinSportsExtra2.qa|qa|| 723 | ||NBCSportsWashington.us|us|| 724 | ||NauticalChannel.ru|ru|| 725 | ||Boomerang.hu|hu|| 726 | ||NationalGeographic.ru|ru|| 727 | ||PervyyKanal.ru|ru|| 728 | ||NovaSport.bg|bg|| 729 | ||Kanal3.bg|bg|| 730 | ||ViasatNature.bg|bg|| 731 | ||EKids.bg|bg|| 732 | ||ViasatHistory.bg|bg|| 733 | ||ViasatExplore.bg|bg|| 734 | ||TVPlus.bg|bg|| 735 | ||CityTV.bg|bg|| 736 | ||MAXSport1.bg|bg|| 737 | ||MAXSport2.bg|bg|| 738 | ||bTVAction.bg|bg|| 739 | ||MAXSport3.bg|bg|| 740 | ||bTVLady.bg|bg|| 741 | ||FoxSports1.nl|nl|| 742 | ||Cinemax2.bg|bg|| 743 | ||Cinemax.bg|bg|| 744 | ||KinoNova.bg|bg|| 745 | ||bTVCinema.bg|bg|| 746 | ||MAXSport4.bg|bg|| 747 | ||NatGeoWild.bg|bg|| 748 | ||RTPRedNacional.bo|bo|| 749 | ||RTVi.ru|ru|| 750 | ||TVGazeta.br|br|| 751 | ||RusskijExtreme.ru|ru|| 752 | ||JovemPanNews.br|br|| 753 | ||FOXMoviesAction.qa|qa|| 754 | ||SBS9.nl|nl|| 755 | ||bTVComedy.bg|bg|| 756 | ||ZiggoSportGolf.nl|nl|| 757 | ||cmorestars.fi|fi|| 758 | ||beINSports5En.qa|qa|| 759 | ||AlJazeeraMubasher.qa|qa|| 760 | ||DiscoveryScience.ru|ru|| 761 | ||60.espn|espn|| 762 | ||36.espn|espn|| 763 | ||90.espn|espn|| 764 | ||91.espn|espn|| 765 | ||67.espn|espn|| 766 | ||MAXSport2.hr|hr|| 767 | ||SportKlub9.hr|hr|| 768 | ||NatGeoWild.ru|ru|| 769 | ||59.espn|espn|| 770 | ||MTVMusic24.nl|nl|| 771 | ||58.espn|espn|| 772 | ||37.espn|espn|| 773 | ||85.espn|espn|| 774 | ||99.espn|espn|| 775 | ||35.espn|espn|| 776 | ||83.espn|espn|| 777 | ||93.espn|espn|| 778 | ||32.espn|espn|| 779 | ||84.espn|espn|| 780 | ||KreatorTv.hr|hr|| 781 | ||ParamountNetwork.ca|ca|| 782 | ||68.espn|espn|| 783 | ||beINSports7En.qa|qa|| 784 | ||M4Sport.hu|hu|| 785 | ||ComedyCentralExtra.nl|nl|| 786 | ||ComedyCentralFamily.hu|hu|| 787 | ||DigiAnimalWorld.hu|hu|| 788 | ||NTV.ru|ru|| 789 | ||JimJam.ru|ru|| 790 | ||CBSReality.ru|ru|| 791 | ||DigiWorld.hu|hu|| 792 | ||MTVLive.nl|nl|| 793 | ||AlKassOne.qa|qa|| 794 | ||DiscoveryTurboXtra.hu|hu|| 795 | ||Multimaniya.ru|ru|| 796 | ||ZiggoSportRacing.nl|nl|| 797 | ||Eurosport2.ru|ru|| 798 | ||AlKassSportsChannel.qa|qa|| 799 | ||MatchStrana.ru|ru|| 800 | ||MatchFutbol3.ru|ru|| 801 | ||CanalPlusKids.fr|fr|| 802 | ||MatchFutbol2.ru|ru|| 803 | ||ZiggoSportTennis.nl|nl|| 804 | ||Fem3.hu|hu|| 805 | ||MatchFutbol1.ru|ru|| 806 | ||MatchBoec.ru|ru|| 807 | ||MTVHits.nl|nl|| 808 | ||cmorehits.fi|fi|| 809 | ||ZiggoSportVoetbal.nl|nl|| 810 | ||EnglishClub.ru|ru|| 811 | ||Zvezda.ru|ru|| 812 | ||TeleAntilles.fr|fr|| 813 | ||Mir24.ru|ru|| 814 | ||Mir.ru|ru|| 815 | ||AlMayadeen.lb|lb|| 816 | ||GoodLife.il|il|| 817 | ||13emeRue.mu|mu|| 818 | ||beINSportsGlobal.qa|qa|| 819 | ||LazioStyleChannel.it|it|| 820 | ||MTVIndia.mu|mu|| 821 | ||GalaTV9Nacional.mx|mx|| 822 | ||LDC.lb|lb|| 823 | ||OTVLebanon.lb|lb|| 824 | ||Decades.us|us|| 825 | ||ImagenTV.mx|mx|| 826 | ||Telemundo.mx|mx|| 827 | ||TelehitHD.mx|mx|| 828 | ||SkySport24.it|it|| 829 | ||NatGeoWild.il|il|| 830 | ||RoyalHD.mn|mn|| 831 | ||MTVLebanon.lb|lb|| 832 | ||TM.mn|mn|| 833 | ||А2.ru|ru|| 834 | ||LanaTV.lb|lb|| 835 | ||RMCSportLive8.fr|fr|| 836 | ||DiscoveryScience.il|il|| 837 | ||AlJadeed.lb|lb|| 838 | ||TV1000ActionEast.ru|ru|| 839 | ||TLC.ru|ru|| 840 | ||Arryadia.ma|ma|| 841 | ||TV1000RusskoeKino.ru|ru|| 842 | ||TV3.ru|ru|| 843 | ||EuroSport1.il|il|| 844 | ||RMCSportLive7.fr|fr|| 845 | ||BeinSportsExtra1.qa|qa|| 846 | ||TV1000East.ru|ru|| 847 | ||ViasatNature.ru|ru|| 848 | ||NBN.lb|lb|| 849 | ||HBO3.bg|bg|| 850 | ||FoxSports3.nl|nl|| 851 | ||SonyTV.ru|ru|| 852 | ||BallySPortsSoCal.us|us|| 853 | ||FoxSports2.nl|nl|| 854 | ||DiemaSport.bg|bg|| 855 | ||Eurosport1.bg|bg|| 856 | ||Sport4.il|il|| 857 | ||Diema.bg|bg|| 858 | ||BallySportsNewOrleans.us|us|| 859 | ||DiemaFamily.bg|bg|| 860 | ||FilmBox.bg|bg|| 861 | ||TV1.bg|bg|| 862 | ||HBO2.bg|bg|| 863 | ||Eurosport2.bg|bg|| 864 | ||HBO.bg|bg|| 865 | ||AlMaghribia.ma|ma|| 866 | ||BulgariaONAIR.bg|bg|| 867 | ||ShoppingChannel.il|il|| 868 | ||EuroSport2.il|il|| 869 | ||FoodNetwork.bg|bg|| 870 | ||BallySportsWisconsin.us|us|| 871 | ||Primafila12.it|it|| 872 | ||BallySportsWest.us|us|| 873 | ||BallySportsSun.us|us|| 874 | ||RMCSportLive9.fr|fr|| 875 | ||BoberTV.ru|ru|| 876 | ||Sport3.il|il|| 877 | ||98.espn|espn|| 878 | ||TVSud.fr|fr|| 879 | ||BallySportsSouthwestPlus.us|us|| 880 | ||Sport5.il|il|| 881 | -------------------------------------------------------------------------------- /scripts/check.py: -------------------------------------------------------------------------------- 1 | # type: ignore 2 | import datetime 3 | import glob 4 | import logging 5 | import os 6 | import sys 7 | import xml.etree.ElementTree as ET 8 | from typing import List, Tuple 9 | 10 | import pandas as pd 11 | 12 | LOGLEVEL = os.environ.get("LOGLEVEL", "INFO").upper() 13 | logging.basicConfig(level=LOGLEVEL) 14 | 15 | 16 | def check(file_path: str) -> Tuple[List[any], List[str]]: 17 | tree = ET.parse(file_path) 18 | root = tree.getroot() 19 | 20 | df_cols: List[str] = ["start", "channel", "title"] 21 | df: pd.DataFrame = pd.DataFrame(columns=df_cols) 22 | 23 | all_channels: List[any] = list( 24 | map( 25 | lambda c: { 26 | "id": c.get("id"), 27 | "icon": c.find("icon").get("src").split("|")[0] if c.find("icon") is not None else "", 28 | "site": c.find("url").text if c.find("url") else "", 29 | "country": c.get("id").split(".")[-1] if c.get("id") is not None and "." in c.get("id") else "", 30 | }, 31 | root.findall("channel"), 32 | ) 33 | ) 34 | 35 | logging.info("grab all programs...") 36 | 37 | progs = list( 38 | map( 39 | lambda i: { 40 | "start": i.get("start"), 41 | "channel": i.get("channel"), 42 | "title": i.find("./title").text, 43 | }, 44 | root.findall("programme"), 45 | ) 46 | ) 47 | df = pd.concat( 48 | [df, pd.DataFrame(progs)], 49 | ignore_index=True, 50 | ) 51 | 52 | df.set_index("start", inplace=True) 53 | df = df.set_index(pd.to_datetime(df.index)) 54 | df.index = pd.to_datetime(df.index, utc=True) 55 | res: pd.DataFrame = df[df.index.to_pydatetime() > (datetime.datetime.now(datetime.timezone.utc) - pd.Timedelta(days=1))] 56 | count = res.groupby(["channel"], as_index=False).count() 57 | logging.debug(f"count: {count}") 58 | 59 | unique_all_channels = pd.DataFrame(all_channels).drop_duplicates(subset="id", keep="first").to_dict("records") 60 | 61 | channels_with_no_prog = [x for x in set(map(lambda c: c["id"], unique_all_channels)) if x not in set(res["channel"].unique().tolist())] 62 | 63 | return (unique_all_channels, channels_with_no_prog) 64 | 65 | 66 | if __name__ == "__main__": 67 | all: List[dict] = [] 68 | missed: List[str] = [] 69 | logging.debug(f"{datetime.datetime.today()}") 70 | try: 71 | for file_path in glob.glob(sys.argv[1] + "/*.xml"): 72 | logging.info(f"processing file {file_path}") 73 | all_ch, missed_ch = check(file_path) 74 | all = [*all, *all_ch] 75 | missed = [*missed, *missed_ch] 76 | 77 | df: pd.DataFrame = pd.DataFrame(all, columns=["id", "icon", "site", "country"]) 78 | # duplicated_ignore_case_df = df.groupby(df.id.str.lower()).filter(lambda x: (len(x) > 1)) 79 | # logging.info(duplicated_ignore_case_df.head(10)) 80 | 81 | df["date"] = datetime.datetime.today() 82 | df.set_index("date", inplace=True) 83 | df["missed"] = df["id"].apply(lambda row: row in missed) 84 | 85 | logging.debug(df.head(10)) 86 | logging.debug(f"all: {all}") 87 | logging.debug(f"with no progs: {missed}") 88 | logging.info(f"Total count: {len(all)} missed count: {len(missed)}") 89 | logging.info(f"Completeness {100-(len(missed)/len(all)*100):3.2f}%") 90 | 91 | df.sort_values("country").to_csv( 92 | os.path.join(sys.argv[1], "out", "epg.csv"), 93 | encoding="utf-8", 94 | date_format="%Y%m%d", 95 | ) 96 | 97 | except Exception as ex: 98 | logging.error("Unexpected error:", ex) 99 | sys.exit(1) 100 | -------------------------------------------------------------------------------- /scripts/check_channels.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #______________________________________________________________________________ 3 | # 4 | # Check si une chaine dans le xmltv généré n'aurait pas des programmes 5 | # si oui on envoie un mail 6 | # on met à jour le fichier utilisé par l'application web qui contient la liste de références des chaines ayant des EPG 7 | #______________________________________________________________________________ 8 | 9 | source $(dirname $0)/utils.sh 10 | OLDIFS=$IFS 11 | 12 | # Check if command installed 13 | command -v xmllint >/dev/null 2>&1 || { echoError "libxml2-utils required but it's not installed. Aborting." >&2; exit 1; } 14 | command -v xml2json >/dev/null 2>&1 || { echoError "The package npm xml2json-cli required but it's not installed. Aborting." >&2; exit 1; } 15 | command -v xmlstarlet >/dev/null 2>&1 || { echoError "The package xmlstarlet required but it's not installed. Aborting." >&2; exit 1; } 16 | 17 | # arg0: input file 18 | # arg1: output file 19 | # arg2: output file json 20 | # arg3: output file missing programs 21 | function checkChannels { 22 | echoInfo "${NC}" 23 | 24 | if [ ! -z "$1" ]; then 25 | fileInput="$1" 26 | else 27 | echoError "input file arg required!" 28 | fileInput="guide.xmltv" 29 | fi 30 | 31 | echo "Extract all channels from Xmltv file: $fileInput" 32 | tmp="tmp" 33 | echo "" > $tmp 34 | xmllint --encode utf8 --xpath '//channel' $fileInput >> $tmp 35 | echo "" >> $tmp 36 | country=${fileInput#*_} 37 | country=${country%.xmltv} 38 | xmlstarlet ed -i "//channel" -t attr -n "country" -v "$country" "$tmp" > "$tmp.xml" 39 | xmllint --encode utf8 --xpath '//channel' "$tmp.xml" >> "$2" 40 | rm tmp* 41 | 42 | # check missing programs 43 | 44 | grep -Ei " tempfile # liste des chaines 45 | grep -Ei "channel=\"(.*)\"" $fileInput | grep -oEi "channel=\"(.*)\"" | grep -oEi "\"(.*)\"" | uniq | sort > tempfile2 #liste des programmes 46 | 47 | listChannels=$(comm -3 tempfile tempfile2) # diff des 2 files 48 | echo $listChannels 49 | total=`echo $(cat tempfile | wc -l)` 50 | not_missed=`echo $(cat tempfile2 | wc -l)` 51 | countErrors=`echo $((comm -3 tempfile tempfile2) | wc -l )` 52 | 53 | echoInfo "Channels total count : $total" 54 | echoInfo "Channels with programs count : $not_missed" 55 | 56 | if [ $countErrors -ne 0 ];then 57 | echoError "Channels without programs count : $countErrors" 58 | echo 59 | declare -a listchannelsWithUrl=() 60 | 61 | # save and change IFS 62 | IFS=$'\n' 63 | 64 | for mp in $listChannels; 65 | do 66 | url=$(xmlstarlet sel -t -v "//channel[@id=${mp}]/url" $fileInput) 67 | listchannelsWithUrl+=($(echo "{\"name\":$mp, \"url\":\"$url\"},")) 68 | done 69 | 70 | # restore it 71 | IFS=$OLDIFS 72 | listchannelsWithUrl=$(echo "${listchannelsWithUrl[@]}" | sed -e '$s/,$//') 73 | echo ${listchannelsWithUrl} 74 | 75 | echo "{\"filename\":\"$fileInput\",\"total\":$total,\"missed\":$countErrors,\"missedlist\":" >> $4 76 | res=$(echo "[${listchannelsWithUrl}]},") 77 | echo $res | column 78 | echo "${res}" >> $4 79 | # mes="

Cheacking file $fileInput


$countErrors channels without programmes was detected :
" 80 | # echoInfo "Pushing notification" 81 | # push_message "Error webgrab" "$mes$res" 82 | fi 83 | 84 | rm tempfile 85 | rm tempfile2 86 | 87 | echoInfo "${NC}" 88 | } 89 | 90 | function push_to_git { 91 | git remote add origin2 https://${GITHUB_API_TOKEN}@github.com/fazzani/grab.git > /dev/null 2>&1 92 | git add $@ && \ 93 | git commit -m "check channels" && \ 94 | git pull origin2 HEAD:master && \ 95 | git push origin2 HEAD:master 96 | } 97 | 98 | #__________________________ main __________________________ 99 | # echo "____ : $1 arg count ____ $# : ____" 100 | if [ -z "$1" ];then 101 | echoInfo "You must pass a list of epg files!!" 102 | exit -1 103 | fi 104 | now=$(date +"%Y/%m/%d %H:%M:%S") 105 | echo $now 106 | 107 | outputfile="out/check_channels.xml" 108 | outputfile_json="out/check_channels.json" 109 | outputfile_missing_prog="out/check_missing_programs.json" 110 | 111 | #vider les fichiers output 112 | echo "" > $outputfile > $outputfile_json 113 | echo "{\"created_date\":\"$now\",\"id\":\"1\",\"sources\":[" > $outputfile_missing_prog 114 | #convert encoding to utf-8 115 | echo -ne '\xEF\xBB\xBF' > $outputfile 116 | #file -i $outputfile 117 | echo '' >> $outputfile 118 | 119 | for i in "$@"; 120 | do 121 | checkChannels $i $outputfile $outputfile_json $outputfile_missing_prog & 122 | wait 123 | done 124 | 125 | echo '' >> $outputfile 126 | 127 | # formatting channels without programs file 128 | content_missing=$(cat $outputfile_missing_prog) 129 | echo ${content_missing%,}"]}" > $outputfile_missing_prog 130 | # Generate json version 131 | 132 | xml2json $outputfile $outputfile_json 133 | 134 | # Generate readme.md 135 | 136 | echo -e "# Daily EPG" > readme.md 137 | echo -e "[![Build Status](https://travis-ci.org/Fazzani/grab.svg?branch=master)](https://travis-ci.org/Fazzani/grab)" >> readme.md 138 | echo -e "## channels list" >> readme.md 139 | echo -e "[All channels link](https://github.com/Fazzani/grab/blob/master/merge.tar.gz?raw=true)\n\r" >> readme.md 140 | echo -e "\r\n" >> readme.md 141 | cat $outputfile_json | jq -r '.tv.channel[] | [ .id, .url, .icon.src ] | @csv' | tr -d \" | \ 142 | awk -v FS="," 'BEGIN{printf "|Icon|Channel|Site|\n";printf "|:----|:---:|:---:|\n"}{printf "|![icon](%s)|%s|%s|\n",$3,$1,$2}' >> readme.md 143 | 144 | # curl \ 145 | # -H "Accept: application/json" \ 146 | # -H "Content-Type:application/json" \ 147 | # -X POST --data @<( cat $outputfile_json ) https://api.myjson.com/bins 148 | 149 | #Push to Git 150 | push_to_git $outputfile $outputfile_json $outputfile_missing_prog readme.md 151 | 152 | echo -e "The End.${NC}" 153 | exit 0 154 | 155 | -------------------------------------------------------------------------------- /scripts/check_channels_programs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #______________________________________________________________________________ 3 | # 4 | # Check si un une chaine dans le xmltv généré n'aurait pas des programmes collectés 5 | # si oui, on push une notification 6 | #______________________________________________________________________________ 7 | 8 | source $(dirname $0)/utils 9 | 10 | function check_missing_epg { 11 | echoInfo "${NC}" 12 | echoInfo -e "$__________ Checking epg file => $1 _________" 13 | echo 14 | 15 | if [ ! -z "$1" ];then 16 | fileInput="$1" 17 | else 18 | echoError "no input file was detected ${NC}" 19 | fileInput="guide.xmltv" 20 | fi 21 | 22 | grep -Ei " tempfile && # liste des chaines 23 | grep -Ei "channel=\"(.*)\"" $fileInput | grep -oEi "channel=\"(.*)\"" | grep -oEi "\"(.*)\"" | uniq | sort> tempfile2 #liste des programmes 24 | # comm -3 tmpfile tmpfile2 25 | listChannels=$(comm -3 tempfile tempfile2) # diff des 2 files 26 | echoInfo "Channels total count : "`echo $(cat tempfile | wc -l)` 27 | echoInfo "Channels with programmes count : "`echo $(cat tempfile2 | wc -l)` 28 | countErrors=`echo "$listChannels" | wc -l` 29 | 30 | if [ $countErrors -ne 0 ];then 31 | echo -e "${RED}Channels without programmes count : " $(echo "$listChannels"|wc -l) 32 | echo 33 | res=$(echo -e "${listChannels}" | sed -e 's/\"//g') 34 | echo $res | column 35 | fi 36 | 37 | mes="

Cheacking file $fileInput


$countErrors channels without programmes was detected :
" 38 | echoInfo "Pushing notification" 39 | push_message "Error webgrab" "$mes$res" 40 | 41 | rm tempfile 42 | rm tempfile2 43 | } 44 | 45 | #__________________________ main __________________________ 46 | 47 | # echo "____ : $1 arg count ____ $# : ____" 48 | if [ -z "$1" ];then 49 | echo "List of epg files is required" 50 | exit -1 51 | fi 52 | 53 | outputfile="check_missing_programs.xml" 54 | touch $outputfile 55 | truncate -s 0 $outputfile #vider le fichier output 56 | 57 | for i in "$@"; do 58 | check_missing_epg $i $outputfile 59 | done 60 | 61 | exit 0 -------------------------------------------------------------------------------- /scripts/grab_from_url.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source $(dirname $0)/utils.sh 4 | 5 | # tmpDir="$(dirname $0)/tmp" 6 | # echoInfo "$(dirname $tmpDir)" 7 | tmpDir="./tmp" 8 | mkdir -p "$tmpDir" 9 | 10 | for url in "$@" 11 | do 12 | filename=$(basename $url) 13 | localzipName=`echo $filename | awk -F '?' '{print $1}'` 14 | fileDestTmp=$(hash $url) 15 | fileDest="${filename%.*}" 16 | extension="${localzipName##*.}" 17 | 18 | echoInfo "___localzipName: ${localzipName} _________" 19 | echoInfo "_____extension : ${extension} _________" 20 | echoInfo "_____ fileDest : ${fileDest} _________" 21 | echoInfo "___fileDestTmp : ${fileDestTmp} _________" 22 | echoInfo "___________tmp : ${tmpDir} _________" 23 | 24 | wget -q -O $tmpDir/$localzipName $url \ 25 | --header="User-Agent: Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11" \ 26 | --no-check-certificate 27 | 28 | if [ $extension = "zip" ]; then 29 | command -v unzip >/dev/null 2>&1 || { echoError "unzip required but its'nt installed. Aborting." >&2; exit 1; } 30 | echoInfo "Unzip file..." 31 | unzip -q -o $tmpDir/$localzipName -d $tmpDir/ 32 | fileDest=$localzipName 33 | elif [ $extension = "gz" ]; then 34 | command -v gunzip >/dev/null 2>&1 || { echoError "gunzip required but its'nt installed. Aborting." >&2; exit 1; } 35 | echoInfo "Extrat gz file..." 36 | gunzip -f $tmpDir/$localzipName > "$tmpDir/$fileDestTmp.xml" 37 | fileDest="$fileDestTmp" 38 | else 39 | sudo mv $tmpDir/$localzipName $tmpDir/$fileDestTmp.xml 40 | fileDest="$fileDestTmp" 41 | fi 42 | 43 | # sudo mv $tmpDir/$fileDest.xml $fileDest.xmltv && 44 | echoInfo "${fileDest} grab finished successfully" 45 | echo 46 | # if [ -z $localzipName ]; then 47 | # echoInfo "Deleting $tmpDir/$localzipName ..." 48 | # sudo rm $tmpDir/$localzipName 49 | # fi 50 | done 51 | 52 | exit 0 53 | -------------------------------------------------------------------------------- /scripts/missed_channels.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from jinja2 import Template 4 | import csv 5 | import os 6 | 7 | data: str = ''' 8 | # Missed Channels 9 | 10 | ![Channel count](https://img.shields.io/static/v1?style=for-the-badge&label=channel%20count&message={{channel_count}}&color=red&cacheSeconds=3600) 11 | 12 | 13 | |Icon|Channel|Country|Site| 14 | |:---|:-----:|:-----:|:--:| 15 | {% for ch in channels -%} 16 | ||{{ ch.id }}|{{ ch.country }}|{{ ch.site }}| 17 | {% endfor %} 18 | ''' 19 | 20 | tpl = Template(data) 21 | with open(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "out", "epg_stats.csv")), encoding="utf8") as f: 22 | channels = list(csv.DictReader(f)) 23 | missed_channels = list(filter(lambda x: x['missed_percent'] == '100.0', channels)) 24 | # completeness = "{0:3.2f}%".format(100 - (missed_count / len(channels) * 100)) 25 | output = tpl.render(channels=missed_channels, 26 | channel_count=len(missed_channels)) 27 | with open(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "out", 'missed_channels.md')), 'w', encoding="utf8") as stream: 28 | stream.write(output) 29 | -------------------------------------------------------------------------------- /scripts/readme.md: -------------------------------------------------------------------------------- 1 | # missing channels programs 2 | 3 | ```json 4 | // epg index mapping 5 | 6 | PUT epg 7 | { 8 | "mappings": { 9 | "channels": { 10 | "properties": { 11 | "tv": { 12 | "type": "nested", 13 | "properties": { 14 | "channel": { 15 | "type": "nested", 16 | "properties": { 17 | "active": { 18 | "type": "boolean" 19 | }, 20 | "country": { 21 | "type": "text", 22 | "fields": { 23 | "keyword": { 24 | "type": "keyword", 25 | "ignore_above": 256 26 | } 27 | } 28 | }, 29 | "display-name": { 30 | "type": "nested", 31 | "properties": { 32 | "$t": { 33 | "type": "text", 34 | "fields": { 35 | "keyword": { 36 | "type": "keyword", 37 | "ignore_above": 256 38 | } 39 | } 40 | }, 41 | "lang": { 42 | "type": "text", 43 | "fields": { 44 | "keyword": { 45 | "type": "keyword", 46 | "ignore_above": 256 47 | } 48 | } 49 | } 50 | } 51 | }, 52 | "icon": { 53 | "properties": { 54 | "src": { 55 | "type": "text", 56 | "fields": { 57 | "keyword": { 58 | "type": "keyword", 59 | "ignore_above": 256 60 | } 61 | } 62 | } 63 | } 64 | }, 65 | "id": { 66 | "type": "text", 67 | "fields": { 68 | "keyword": { 69 | "type": "keyword", 70 | "ignore_above": 256 71 | } 72 | } 73 | }, 74 | "url": { 75 | "type": "text", 76 | "fields": { 77 | "keyword": { 78 | "type": "keyword", 79 | "ignore_above": 256 80 | } 81 | } 82 | } 83 | } 84 | }, 85 | "generator-info-name": { 86 | "type": "text", 87 | "fields": { 88 | "keyword": { 89 | "type": "keyword", 90 | "ignore_above": 256 91 | } 92 | } 93 | }, 94 | "generator-info-url": { 95 | "type": "text", 96 | "fields": { 97 | "keyword": { 98 | "type": "keyword", 99 | "ignore_above": 256 100 | } 101 | } 102 | } 103 | } 104 | } 105 | } 106 | } 107 | } 108 | } 109 | 110 | 111 | ``` 112 | 113 | ## Active EPG Channels Query 114 | 115 | ```json 116 | GET epg/_search 117 | { 118 | "query": { 119 | "nested": { 120 | "path": "tv.channel", 121 | "query": { 122 | "bool": { 123 | "must": [ 124 | { 125 | "match": { 126 | "tv.channel.active": true 127 | } 128 | } 129 | ] 130 | } 131 | }, 132 | "inner_hits": { 133 | "highlight": { 134 | "fields": { 135 | "tv.channel": {} 136 | } 137 | } 138 | } 139 | } 140 | } 141 | } 142 | ``` -------------------------------------------------------------------------------- /scripts/readme.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from jinja2 import Template 4 | import csv 5 | import os 6 | 7 | data: str = ''' 8 | # Daily EPG (Electronic Program Guide) 9 | 10 | [![grab](https://github.com/Fazzani/grab/actions/workflows/grab.yml/badge.svg)](https://github.com/Fazzani/grab/actions/workflows/grab.yml) 11 | 12 | ![Channel count](https://img.shields.io/static/v1?style=for-the-badge&label=channel%20count&message={{channel_count}}&color=9cf&cacheSeconds=3600) 13 | ![Completeness](https://img.shields.io/static/v1?style=for-the-badge&label=Completeness&message={{completeness}}&color=yellow&cacheSeconds=3600) 14 | 15 | ## Available epg 16 | 17 | - [EPG (gz archive)](https://github.com/Fazzani/grab/blob/master/merge.xml.gz?raw=true) 18 | - [EPG (zip archive)](https://github.com/Fazzani/grab/blob/master/merge.zip?raw=true) 19 | 20 | ## Channels list 21 | 22 | - [Missed channels list](out/missed_channels.md) 23 | 24 | |Icon|Channel|Country|Site| 25 | |:---|:-----:|:-----:|:--:| 26 | {% for ch in channels -%} 27 | {% if ch.missed == 'True' -%} 28 | ||~~{{ ch.id }}~~|{{ ch.country }}|{{ ch.site }}| 29 | {% else -%} 30 | ||{{ ch.id }}|{{ ch.country }}|{{ ch.site }}| 31 | {% endif -%} 32 | {% endfor %} 33 | ''' 34 | 35 | tpl = Template(data) 36 | with open(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "out", "epg.csv")), encoding="utf8") as f: 37 | channels = list(csv.DictReader(f)) 38 | missed_count = len(list(filter(lambda x: x['missed'] == 'True', channels))) 39 | completeness = "{0:3.2f}%".format(100 - (missed_count / len(channels) * 100)) 40 | output = tpl.render(channels=channels, 41 | completeness=completeness, channel_count=len(channels)) 42 | with open(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", 'readme.md')), 'w', encoding="utf8") as readme: 43 | readme.write(output) 44 | -------------------------------------------------------------------------------- /scripts/stats_epg.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import sys 3 | from os import path 4 | from shutil import copyfile 5 | 6 | import pandas as pd 7 | 8 | # pd.set_option('display.max_columns', None) 9 | # pd.set_option('display.max_rows', None) 10 | merge_path: str = "/tmp/epg_merge.csv" 11 | parser = argparse.ArgumentParser(description="Flip a switch by setting a flag") 12 | parser.add_argument("--file_path", "-f", help="csv epg file path", action="store", dest="file_path") 13 | parser.add_argument( 14 | "--stats", 15 | "-s", 16 | help="Calculate statistics", 17 | action="store_true", 18 | default=False, 19 | dest="is_stats", 20 | ) 21 | 22 | 23 | def fill_from_git_history(file_path: str) -> None: 24 | if path.exists(merge_path): 25 | df_merge = pd.read_csv(merge_path) 26 | else: 27 | copyfile(file_path, merge_path) 28 | sys.exit(0) 29 | df = pd.read_csv(file_path) 30 | df_res = pd.concat([df_merge, df], ignore_index=True) 31 | df_res.set_index(["date"], inplace=True) 32 | df_res.to_csv(merge_path) 33 | print(df_res.shape) 34 | print(df.head()) 35 | 36 | 37 | def stats(file_path: str) -> None: 38 | 39 | df: pd.DataFrame = pd.read_csv(file_path) 40 | df.reset_index().set_index(["date"], inplace=True) 41 | df["total"] = df.groupby("id").date.transform("count") 42 | df["missed_count"] = df[df.missed == True].missed.groupby(df.id).transform("count") 43 | df["missed_count"] = df.missed_count.fillna(value=0) 44 | df["icon"] = df.icon.fillna(value="") 45 | df["missed_percent"] = (df.missed_count / df.total) * 100 46 | df.drop(["date"], axis=1, inplace=True) 47 | df.drop_duplicates(subset="id", keep="first", inplace=True) 48 | df.sort_values(by="missed_percent", ascending=False, inplace=True) 49 | df.reset_index(inplace=True) 50 | df.drop("index", axis=1, inplace=True) 51 | print(df.shape) 52 | # print(df[(df.missed_count > 0) & (df.missed_count < 9)].head(20)) 53 | print(df.head(50)) 54 | df.to_csv("out/epg_stats.csv") 55 | 56 | 57 | if __name__ == "__main__": 58 | args = parser.parse_args() 59 | if args.is_stats: 60 | stats(args.file_path) 61 | elif args.file_path: 62 | fill_from_git_history(args.file_path) 63 | 64 | sys.exit(0) 65 | -------------------------------------------------------------------------------- /scripts/utils.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RED='\033[0;31m' 4 | YELLOW='\033[0;33m' 5 | GREEN='\033[0;32m' 6 | NC='\033[0m' # No Color 7 | 8 | function echoInfo { 9 | echo -e "${GREEN}$1${NC}" 10 | } 11 | 12 | function echoError { 13 | echo -e "${RED}$1${NC}" 14 | } 15 | 16 | function hash { 17 | echo `/bin/echo $1 | /usr/bin/md5sum | cut -f1 -d" "` 18 | } 19 | --------------------------------------------------------------------------------