LoremPizza commited on
Commit
312bdb8
·
verified ·
1 Parent(s): 5c449e7

Upload 20 files

Browse files
Files changed (20) hide show
  1. Dockerfile +15 -0
  2. LICENSE +21 -0
  3. animeworld.py +148 -0
  4. config.json +40 -0
  5. config.py +31 -0
  6. convert.py +17 -0
  7. convert_date.py +39 -0
  8. cool.py +145 -0
  9. dictionaries.py +835 -0
  10. filmpertutti.py +136 -0
  11. info.py +145 -0
  12. loadenv.py +22 -0
  13. lordchannel.py +104 -0
  14. okru.py +19 -0
  15. requirements.txt +9 -0
  16. run.py +228 -0
  17. streamingcommunity.py +219 -0
  18. streamingwatch.py +103 -0
  19. tantifilm.py +267 -0
  20. webru.py +38 -0
Dockerfile ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use an official Python runtime as a parent image
2
+ FROM python:3.10-slim-buster
3
+ # Set the working directory in the container to /app
4
+ WORKDIR /app
5
+
6
+ # Copy the current directory contents into the container at /app
7
+ # (including run.py, filmpertutti.py, and requirements.txt)
8
+ ADD . /app
9
+ # Install any needed packages specified in requirements.txt
10
+ RUN pip install --no-cache-dir -r requirements.txt
11
+ #EXPOSE the port, for now default is 8080 cause it's the only one really allowed by HuggingFace
12
+ EXPOSE 8080
13
+
14
+ # Run run.py when the container launches
15
+ CMD ["python", "run.py"]
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Urlo30
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
animeworld.py ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import httpx
2
+ import asyncio
3
+
4
+ from bs4 import BeautifulSoup
5
+ import datetime
6
+ import json
7
+ from info import get_info_kitsu
8
+ import config
9
+ import re
10
+ months = {
11
+ "Gennaio": "January", "Febbraio": "February", "Marzo": "March",
12
+ "Aprile": "April", "Maggio": "May", "Giugno": "June",
13
+ "Luglio": "July", "Agosto": "August", "Settembre": "September",
14
+ "Ottobre": "October", "Novembre": "November", "Dicembre": "December"
15
+ }
16
+ showname_replace = {
17
+ "Attack on Titan": "L'attacco dei Giganti"
18
+ }
19
+
20
+ AW_DOMAIN = config.AW_DOMAIN
21
+ async def get_mp4(anime_url,ismovie,episode,client):
22
+ response = await client.get(anime_url,follow_redirects=True)
23
+ soup = BeautifulSoup(response.text,'lxml')
24
+ episode_page = soup.find('a', {'data-episode-num':episode })
25
+ if episode_page is None:
26
+ return None
27
+ episode_page = f'https://animeworld.{AW_DOMAIN}{episode_page["href"]}'
28
+ response = await client.get(episode_page,follow_redirects=True)
29
+ soup = BeautifulSoup(response.text,'lxml')
30
+ a_tag = soup.find('a', {'id': 'alternativeDownloadLink', 'class': 'm-1 btn btn-sm btn-primary'})
31
+ url = a_tag['href']
32
+ response = await client.head(url)
33
+ if response.status_code == 404:
34
+ url = None
35
+ return url
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+ async def old_search(showname,date,ismovie,episode,client):
44
+ cookies = {
45
+ 'sessionId': 's%3AtGSRfYcsIoaeV0nqFJgN69Zxixb_-uJU.fcNz%2FsJBiiP8v8TwthMN9%2FmynWFciI5gezZuz8CltyQ',
46
+ }
47
+
48
+ headers = {
49
+ 'authority': f'www.animeworld.{AW_DOMAIN}',
50
+ 'accept': 'application/json, text/javascript, */*; q=0.01',
51
+ 'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7',
52
+ # 'content-length': '0',
53
+ # 'cookie': 'sessionId=s%3AtGSRfYcsIoaeV0nqFJgN69Zxixb_-uJU.fcNz%2FsJBiiP8v8TwthMN9%2FmynWFciI5gezZuz8CltyQ',
54
+ 'csrf-token': 'oKFK43s4-BzfqPX27RlAORUd-iyiAfXyfDAo',
55
+ 'origin': f'https://www.animeworld.{AW_DOMAIN}',
56
+ 'referer': f'https://www.animeworld.{AW_DOMAIN}/',
57
+ 'sec-ch-ua': '"Not-A.Brand";v="99", "Chromium";v="124"',
58
+ 'sec-ch-ua-mobile': '?0',
59
+ 'sec-ch-ua-platform': '"Android"',
60
+ 'sec-fetch-dest': 'empty',
61
+ 'sec-fetch-mode': 'cors',
62
+ 'sec-fetch-site': 'same-origin',
63
+ 'user-agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
64
+ 'x-requested-with': 'XMLHttpRequest',
65
+ }
66
+
67
+ params = {
68
+ 'keyword': showname,
69
+ }
70
+
71
+ response = await client.post(f'https://www.animeworld.{AW_DOMAIN}/api/search/v2', params=params, cookies=cookies, headers=headers,follow_redirects=True)
72
+
73
+ data = json.loads(response.text)
74
+ final_urls = []
75
+ for anime in data["animes"]:
76
+ release_date = anime["release"]
77
+ for ita, eng in months.items():
78
+ release_date = release_date.replace(ita, eng)
79
+ release_date = datetime.datetime.strptime(release_date, "%d %B %Y")
80
+ release_date = release_date.strftime("%Y-%m-%d")
81
+ if release_date == date:
82
+ identifier = anime["identifier"]
83
+ link = anime["link"]
84
+ anime_url = f'https://animeworld.{AW_DOMAIN}/play/{link}.{identifier}'
85
+ final_url = await get_mp4(anime_url,ismovie,episode,client)
86
+ final_urls.append(final_url)
87
+ break
88
+ showname = showname + " (ITA)"
89
+ params = {
90
+ 'keyword': showname,
91
+ }
92
+ response = await client.post(f'https://www.animeworld.{AW_DOMAIN}/api/search/v2', params=params, cookies=cookies, headers=headers, follow_redirects=True)
93
+ data = json.loads(response.text)
94
+ for anime in data["animes"]:
95
+ release_date = anime["release"]
96
+ for ita, eng in months.items():
97
+ release_date = release_date.replace(ita, eng)
98
+ release_date = datetime.datetime.strptime(release_date, "%d %B %Y")
99
+ release_date = release_date.strftime("%Y-%m-%d")
100
+ if release_date == date:
101
+ identifier = anime["identifier"]
102
+ link = anime["link"]
103
+ anime_url = f'https://animeworld.{AW_DOMAIN}/play/{link}.{identifier}'
104
+ final_url = await get_mp4(anime_url,ismovie,episode,client)
105
+ final_urls.append(final_url)
106
+ break
107
+ return final_urls
108
+
109
+ async def search(showname,date,ismovie,episode,client):
110
+ search_year = date[:4]
111
+ response = await client.get(f'https://www.animeworld.so/filter?year={search_year}&sort=2&keyword={showname}',follow_redirects=True)
112
+ soup = BeautifulSoup(response.text,'lxml')
113
+ anime_list = soup.find_all('a', class_=['poster', 'tooltipstered'])
114
+ final_urls = []
115
+ for anime in anime_list:
116
+ anime_info_url = f'https://www.animeworld.{AW_DOMAIN}/{anime["data-tip"]}'
117
+ response = await client.get(anime_info_url,follow_redirects=True)
118
+ pattern = r'<label>Data di uscita:</label>\s*<span>\s*(.*?)\s*</span>'
119
+ match = re.search(pattern, response.text, re.S)
120
+ release_date = match.group(1).strip()
121
+ for ita, eng in months.items():
122
+ release_date = release_date.replace(ita, eng)
123
+ release_date = datetime.datetime.strptime(release_date, "%d %B %Y")
124
+ release_date = release_date.strftime("%Y-%m-%d")
125
+ print(release_date)
126
+ if release_date == date:
127
+ anime_url = f'https://www.animeworld.{AW_DOMAIN}{anime["href"]}'
128
+ final_url = await get_mp4(anime_url,ismovie,episode,client)
129
+ if final_url:
130
+ final_urls.append(final_url)
131
+
132
+ return final_urls
133
+
134
+ async def animeworld(id,client):
135
+ try:
136
+ print(id)
137
+ kitsu_id = id.split(":")[1]
138
+ episode = id.split(":")[2]
139
+ ismovie = 1 if len(id.split(":")) == 2 else 0
140
+ showname,date = await get_info_kitsu(kitsu_id,client)
141
+ if showname in showname_replace:
142
+ showname = showname_replace[showname]
143
+ final_urls = await search(showname,date,ismovie,episode,client)
144
+ return final_urls
145
+ except:
146
+ print("Animeworld failed")
147
+ return None
148
+
config.json ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "Siti": {
3
+ "StreamingCommunity": {
4
+ "enabled": "1",
5
+ "domain": "buzz",
6
+ "fast_search": "0"
7
+ },
8
+ "Filmpertutti": {
9
+ "enabled": "0",
10
+ "domain": "diy"
11
+ },
12
+ "Tuttifilm":{
13
+ "enabled": "0",
14
+ "domain": "bond",
15
+ "fast_search": "0"
16
+ },
17
+ "Mysterius":{
18
+ "enabled": "0"
19
+ },
20
+ "LordChannel":{
21
+ "enabled":"1",
22
+ "domain":"com"
23
+ },
24
+ "StreamingWatch":{
25
+ "enabled":"1",
26
+ "domain":"org"
27
+ },
28
+ "AnimeWorld":{
29
+ "enabled":"1",
30
+ "domain":"so"
31
+ }
32
+ },
33
+ "General":{
34
+ "load_env": "1",
35
+ "HOST": "0.0.0.0",
36
+ "PORT": "8080",
37
+ "HF": "0"
38
+ }
39
+ }
40
+
config.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #LOAD THE CONFIG
2
+ import json
3
+
4
+ # Open the configuration file
5
+ with open('config.json') as f:
6
+ # Load JSON data from file
7
+ config = json.load(f)
8
+
9
+ # Accessing SC_DOMAIN
10
+ SITE = config["Siti"]
11
+ FT_DOMAIN = SITE["Filmpertutti"]['domain']
12
+ SC_DOMAIN = SITE["StreamingCommunity"]['domain']
13
+ TF_DOMAIN = SITE["Tuttifilm"]['domain']
14
+ LC_DOMAIN = SITE["LordChannel"]['domain']
15
+ SW_DOMAIN = SITE["StreamingWatch"]['domain']
16
+ AW_DOMAIN = SITE['AnimeWorld']['domain']
17
+ FILMPERTUTTI = SITE["Filmpertutti"]['enabled']
18
+ STREAMINGCOMMUNITY = SITE["StreamingCommunity"]['enabled']
19
+ MYSTERIUS = SITE["Mysterius"]['enabled']
20
+ TUTTIFILM = SITE["Tuttifilm"]['enabled']
21
+ LORDCHANNEL = SITE["LordChannel"]['enabled']
22
+ STREAMINGWATCH = SITE["StreamingWatch"]['enabled']
23
+ ANIMEWORLD = SITE['AnimeWorld']['enabled']
24
+ SC_FAST_SEARCH = SITE["StreamingCommunity"]['fast_search']
25
+ TF_FAST_SEARCH = SITE["Tuttifilm"]['fast_search']
26
+ #General
27
+ GENERAL = config['General']
28
+ dotenv = GENERAL["load_env"]
29
+ HOST = GENERAL["HOST"]
30
+ PORT = GENERAL["PORT"]
31
+ HF = GENERAL["HF"]
convert.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ from tmdbv3api import TMDb, Movie, TV
3
+ from loadenv import load_env
4
+ import config
5
+ env_vars = load_env()
6
+
7
+ TMDB_KEY = env_vars.get('TMDB_KEY')
8
+ async def get_TMDb_id_from_IMDb_id(imdb_id,client):
9
+ response = await client.get(f'https://api.themoviedb.org/3/find/{imdb_id}',
10
+ params={'external_source': 'imdb_id', 'api_key': f'{TMDB_KEY}'})
11
+ tmbda = response.json()
12
+ if tmbda['movie_results']:
13
+ return tmbda['movie_results'][0]['id']
14
+ elif tmbda['tv_results']:
15
+ return tmbda['tv_results'][0]['id']
16
+ else:
17
+ return None
convert_date.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ def convert_US_date(date):
3
+ us_data = next((country_data for country_data in date['results'] if country_data["iso_3166_1"] == "US"), None)
4
+ if us_data:
5
+ us_release_dates_type_3 = [rd for rd in us_data['release_dates'] if rd['type'] == 3]
6
+ # Sort the list of release dates and get the latest
7
+ us_release_dates_type_3.sort(key = lambda x: x['release_date'], reverse=True)
8
+ if len(us_release_dates_type_3) > 0:
9
+ latest_release_date = us_release_dates_type_3[0]['release_date']
10
+ date = latest_release_date.split('T')[0]
11
+ print('Latest US theatrical release date:', date)
12
+ return date
13
+ else:
14
+ us_release_dates_type_4 = [rd for rd in us_data['release_dates'] if rd['type'] == 4]
15
+ us_release_dates_type_4.sort(key = lambda x: x['release_date'], reverse=True)
16
+ if len(us_release_dates_type_4) > 0:
17
+ latest_release_date = us_release_dates_type_4[0]['release_date']
18
+ date = latest_release_date.split('T')[0]
19
+ print('Latest US theatrical release date (type 4):', date)
20
+ return date
21
+ def convert_IT_date(date):
22
+ it_data = next((country_data for country_data in date['results'] if country_data["iso_3166_1"] == "IT"), None)
23
+ if it_data:
24
+ it_release_dates_type_3 = [rd for rd in it_data['release_dates'] if rd['type'] == 3]
25
+ # Sort the list of release dates and get the latest
26
+ it_release_dates_type_3.sort(key = lambda x: x['release_date'], reverse=True)
27
+ if len(it_release_dates_type_3) > 0:
28
+ latest_release_date = it_release_dates_type_3[0]['release_date']
29
+ date = latest_release_date.split('T')[0]
30
+ print('Latest IT theatrical release date:', date)
31
+ return date
32
+ else:
33
+ it_release_dates_type_4 = [rd for rd in it_data['release_dates'] if rd['type'] == 4]
34
+ it_release_dates_type_4.sort(key = lambda x: x['release_date'], reverse=True)
35
+ if len(it_release_dates_type_4) > 0:
36
+ latest_release_date = it_release_dates_type_4[0]['release_date']
37
+ date = latest_release_date.split('T')[0]
38
+ print('Latest IT theatrical release date (type 4):', date)
39
+ return date
cool.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import json
3
+ from info import get_info_tmdb,is_movie
4
+ from convert import get_TMDb_id_from_IMDb_id
5
+ from loadenv import load_env
6
+ env_vars = load_env()
7
+ MYSTERIUS_KEY = env_vars.get('MYSTERIUS_KEY')
8
+ async def get_links(slug,season,episode,ismovie,client):
9
+ try:
10
+ headers = {
11
+ "x-api-key": MYSTERIUS_KEY
12
+ }
13
+ response = await client.get("https://mammamia-urlo-ulala12431.hf.space/api/cookie", headers=headers)
14
+ Auths = response.json()
15
+ Bearer = Auths.get('cookie')
16
+ ap_session = Auths.get('auth')
17
+
18
+ cookies = {'ap_session': ap_session}
19
+
20
+ headers = {
21
+ 'accept': 'application/json, text/plain, */*',
22
+ 'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7',
23
+ 'authorization': f'Bearer {Bearer}',
24
+ 'referer': f'https://altadefinizione-originale.com/play/{slug}',
25
+ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 OPR/111.0.0.0',
26
+ 'x-requested-with': 'XMLHttpRequest',
27
+ }
28
+ if ismovie == 1:
29
+
30
+ response = await client.get(f'https://altadefinizione-originale.com/api/post/urls/stream/{slug}',cookies=cookies,headers=headers)
31
+ elif ismovie == 0:
32
+ print("HERE SEASON",season)
33
+ print("HERE EPISODE",episode)
34
+ request_url =f'https://altadefinizione-originale.com/api/post/urls/stream/{slug}/{season}/{episode}'
35
+ print(request_url)
36
+ response = await client.get(request_url,cookies=cookies,headers=headers)
37
+ try:
38
+ video_data = response.json() # Assuming this is the JSON response containing video streams
39
+ if 'streams' not in video_data:
40
+ print("Invalid JSON format: 'streams' key not found or incorrect structure")
41
+ return None
42
+
43
+ streams = video_data['streams']
44
+
45
+ resolutions = {}
46
+
47
+ for stream in streams:
48
+ resolution_name = stream['resolution']['name'].lower() # Convert resolution name to lowercase
49
+ url = stream['url']
50
+
51
+ # Remove everything after '.mp4' in the URL
52
+ mp4_index = url.find('.mp4')
53
+ if mp4_index != -1:
54
+ url = url[:mp4_index + 4] # +4 to include '.mp4' in the substring
55
+
56
+ resolutions[resolution_name] = url
57
+
58
+ return resolutions
59
+
60
+ except KeyError as e:
61
+ print(f"KeyError: {e}")
62
+ return None
63
+ except json.JSONDecodeError as e:
64
+ print(f"JSONDecodeError: {e}")
65
+ return None
66
+
67
+ except requests.RequestException as e:
68
+ print(f"Request error: {e}")
69
+ return None
70
+
71
+
72
+ # Example usage: Fetch video links
73
+
74
+
75
+ # Print the dictionary
76
+
77
+
78
+
79
+
80
+
81
+ async def search_imdb(showname,tmdba,client):
82
+ tmdba = str(tmdba)
83
+ query = f'https://altadefinizione-originale.com/api/search?search={showname}&page=1'
84
+ response = await client.get(query,follow_redirects=True)
85
+ if response.status_code == 200:
86
+ data = response.json()
87
+ if 'data' in data:
88
+ for item in data['data']:
89
+ if item.get('tmdb_id') == tmdba:
90
+ slug = item.get('slug')
91
+ print(slug)
92
+ return slug
93
+
94
+
95
+
96
+ def parse_links(resolution_links):
97
+ results = {}
98
+ if resolution_links:
99
+ print("Video links:")
100
+ for resolution, link in resolution_links.items():
101
+ if "cdn.altadefinizione-originale.com" in link:
102
+ link = link.replace("cdn.altadefinizione-originale.com","protectlinknt.b-cdn.net")
103
+ print(f"{resolution}: {link}")
104
+ results[resolution] = link
105
+ return results
106
+ else:
107
+ print("Failed to fetch video links")
108
+
109
+
110
+ async def cool(imdb,client):
111
+ try:
112
+ type = "Cool"
113
+ general = is_movie(imdb)
114
+ ismovie = general[0]
115
+ imdb_id = general[1]
116
+ if ismovie == 0 :
117
+ season = int(general[2])
118
+ episode = int(general[3])
119
+
120
+ if "tt" in imdb:
121
+ #Get showname
122
+ tmdba = await get_TMDb_id_from_IMDb_id(imdb_id,client)
123
+ else:
124
+ tmdba = imdb_id.replace("tmdb:","")
125
+
126
+ showname = get_info_tmdb(tmdba,ismovie,type)
127
+
128
+
129
+ slug = await search_imdb(showname,tmdba,client)
130
+ print(ismovie)
131
+ if ismovie == 1:
132
+ season = None
133
+ episode = None
134
+ resolution_links = await get_links(slug,episode,season,ismovie,client)
135
+ results = parse_links(resolution_links)
136
+ return results
137
+ elif ismovie == 0:
138
+ season = season -1
139
+ episode = episode - 1
140
+ resolution_links = get_links(slug,season,episode,ismovie)
141
+ results = parse_links(resolution_links)
142
+ return results
143
+ except Exception as e:
144
+ print("Cool Error",e)
145
+ return None
dictionaries.py ADDED
@@ -0,0 +1,835 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ okru = {
2
+ "rai-1": "https://ok.ru/videoembed/7703488765552?nochat=1",
3
+ "rai-2": "https://ok.ru/videoembed/7805618364016?nochat=1",
4
+ "canale-5": "https://ok.ru/videoembed/7789978328688?nochat=1",
5
+ "italia-1": "https://ok.ru/videoembed/7393558339184?nochat=1",
6
+ "rai-premium": "https://ok.ru/videoembed/7363152715376?nochat=1",
7
+ "rai-movie": "https://ok.ru/videoembed/7384012693104?nochat=1",
8
+ "tv8": "https://ok.ru/videoembed/7681651777136?nochat=1",
9
+ "rsi-la-2": "https://ok.ru/videoembed/7681648107120?nochat=1"
10
+ }
11
+
12
+ STREAM = {
13
+ "channels": [
14
+ {
15
+ "id": "la7",
16
+ "title": "LA7",
17
+ "name": "HD/FHD",
18
+ "genres": ["La7"],
19
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/LA7_-_Logo_2011.svg/1280px-LA7_-_Logo_2011.svg.png",
20
+ "url": "https://d3749synfikwkv.cloudfront.net/v1/master/3722c60a815c199d9c0ef36c5b73da68a62b09d1/cc-74ylxpgd78bpb/Live.m3u8"
21
+ },
22
+ {
23
+ "id": "rai-1",
24
+ "title": "Rai 1",
25
+ "name": "Full HD",
26
+ "genres": ["Rai"],
27
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Rai_1_-_Logo_2016.svg/1280px-Rai_1_-_Logo_2016.svg.png",
28
+ "url": "http://173.208.52.200/rai1/index.m3u8"
29
+ },
30
+ {
31
+ "id": "rai-2",
32
+ "title": "Rai 2",
33
+ "name": "Full HD",
34
+ "genres": ["Rai"],
35
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/99/Rai_2_-_Logo_2016.svg/1280px-Rai_2_-_Logo_2016.svg.png",
36
+ "url": "http://173.208.52.200/rai2/index.m3u8"
37
+ },
38
+ {
39
+ "id": "rai-3",
40
+ "title": "Rai 3",
41
+ "name": "Full HD",
42
+ "genres": ["Rai"],
43
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Rai_3_-_Logo_2016.svg/1280px-Rai_3_-_Logo_2016.svg.png",
44
+ "url": "http://173.208.52.200/rai3/index.m3u8"
45
+ },
46
+ {
47
+ "id": "rai-4",
48
+ "title": "Rai 4",
49
+ "name": "Full HD",
50
+ "genres": ["Rai"],
51
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Rai_3_-_Logo_2016.svg/1280px-Rai_3_-_Logo_2016.svg.png",
52
+ "url": "http://173.208.52.200/rai4/index.m3u8"
53
+ },
54
+ {
55
+ "id": "rai-premium",
56
+ "title": "Rai Premium",
57
+ "name": "Full HD",
58
+ "genres": ["Rai"],
59
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/ad/Rai_Premium_-_Logo_2017.svg/1920px-Rai_Premium_-_Logo_2017.svg.png",
60
+ "url": "https://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=746992"
61
+ },
62
+ {
63
+ "id": "rai-4k",
64
+ "title": "Rai 4K",
65
+ "name": "4K",
66
+ "genres": ["Rai"],
67
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/ad/Rai_4K_-_Logo_2016.svg/1920px-Rai_4K_-_Logo_2016.svg.png",
68
+ "url": "https://raievent10-elem-live.akamaized.net/hls/live/619189/raievent10/raievent10/playlist.m3u8"
69
+
70
+ },
71
+ {
72
+ "id": "rai-news",
73
+ "title": "Rai News",
74
+ "name": "Unknown",
75
+ "genres": ["Rai"],
76
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a1/Rai_News_24_logo_%282022%29.svg/1920px-Rai_News_24_logo_%282022%29.svg.png",
77
+ "url": "https://streamcdnb4-8e7439fdb1694c8da3a0fd63e4dda518.msvdn.net/rainews1/hls/playlist_mo.m3u8"
78
+ },
79
+ {
80
+ "id": "rai-movie",
81
+ "title": "Rai Movie",
82
+ "name": "Unknown",
83
+ "genres": ["Rai"],
84
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/61/Rai_Movie_-_Logo_2017.svg/1920px-Rai_Movie_-_Logo_2017.svg.png",
85
+ "url": "https://m3u.iranvids.com/rai-movie/output.m3u8"
86
+ },
87
+ {
88
+ "id": "rai-sport",
89
+ "title": "Rai Sport",
90
+ "name": "Unknown",
91
+ "genres": ["Rai"],
92
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/Rai_Sport_-_Logo_2022.svg/1920px-Rai_Sport_-_Logo_2022.svg.png",
93
+ "url": "https://m3u.iranvids.com/rai-sport01/output.m3u8"
94
+ },
95
+ {
96
+ "id": "rete-4",
97
+ "title": "Rete 4",
98
+ "name": "Full HD",
99
+ "genres": ["Mediaset"],
100
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/Rete_4_2018.svg/1024px-Rete_4_2018.svg.png",
101
+ "url": "http://173.208.52.200/rete4/index.m3u8"
102
+ },
103
+ {
104
+ "id": "euronews",
105
+ "title": "Euronews",
106
+ "name": "720p",
107
+ "genres": ["Euronews"],
108
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/Euronews_2022.svg/1920px-Euronews_2022.svg.png",
109
+ "url": "https://rakuten-euronews-3-it.samsung.wurl.tv/manifest/playlist.m3u8"
110
+ },
111
+ {
112
+ "id": "canale-5",
113
+ "title": "Canale 5",
114
+ "name": "Full HD",
115
+ "genres": ["Mediaset"],
116
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Canale_5_-_2018_logo.svg/1024px-Canale_5_-_2018_logo.svg.png",
117
+ "url": "http://173.208.52.200/canale5/index.m3u8"
118
+ },
119
+ {
120
+ "id": "italia-1",
121
+ "title": "Italia 1",
122
+ "name": "Full HD",
123
+ "genres": ["Mediaset"],
124
+ "poster": "https://upload.wikimedia.org/wikipedia/en/thumb/e/e2/Italia_1.svg/1024px-Italia_1.svg.png",
125
+ "url": "http://173.208.52.200/italia1/index.m3u8"
126
+ },
127
+ {
128
+ "id": "topcrime",
129
+ "title": "Top Crime",
130
+ "name": "HD/FHD",
131
+ "genres": ["Mediaset"],
132
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e3/Top_Crime_-_Logo_2013.svg/260px-Top_Crime_-_Logo_2013.svg.png",
133
+ "url": "https://live02-seg.msf.cdn.mediaset.net/live/ch-lt/lt-clr.isml/index.m3u8"
134
+ },
135
+ {
136
+ "id": "mediaset-extra",
137
+ "title": "Mediaset Extra",
138
+ "name": "HD/FHD",
139
+ "genres": ["Mediaset"],
140
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e3/Mediaset_Extra_logo.svg/1920px-Mediaset_Extra_logo.svg.png",
141
+ "url": "https://live02-seg.msf.cdn.mediaset.net/live/ch-kq/kq-clr.isml/index.m3u8"
142
+ },
143
+ {
144
+ "id": "focus",
145
+ "title": "Focus",
146
+ "name": "HD/FHD",
147
+ "genres": ["Mediaset"],
148
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/d/d0/Focus_channel.png",
149
+ "url": "https://live02-seg.msf.cdn.mediaset.net/live/ch-fu/fu-clr.isml/index.m3u8"
150
+ },
151
+ {
152
+ "id": "boing",
153
+ "title": "Boing",
154
+ "name": "HD/FHD",
155
+ "genres": ["Mediaset"],
156
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/8/8c/Logo_Boing.png",
157
+ "url": "https://live02-seg.msf.cdn.mediaset.net/live/ch-kb/kb-clr.isml/index.m3u8"
158
+ },
159
+ {
160
+ "id": "cartoonito",
161
+ "title": "Cartoonito",
162
+ "name": "HD/FHD",
163
+ "genres": ["Mediaset"],
164
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/Cartoonito_-_Logo_2021.svg/1920px-Cartoonito_-_Logo_2021.svg.png",
165
+ "url": "https://live02-seg.msf.cdn.mediaset.net/live/ch-la/la-clr.isml/index.m3u8"
166
+ },
167
+ {
168
+ "id": "history",
169
+ "title": "History",
170
+ "name": "",
171
+ "genres": ["A+E"],
172
+ "poster": "https://houseofgeekery.com/wp-content/uploads/2022/06/hiscvr.jpg"
173
+ },
174
+ {
175
+ "id": "comedy-central",
176
+ "title": "Comedy Central",
177
+ "name": "",
178
+ "genres": ["Paramount"],
179
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/aa/Comedy_Central_2018.svg/1920px-Comedy_Central_2018.svg.png"
180
+ },
181
+ {
182
+ "id": "skytg24",
183
+ "title": "Sky TG24",
184
+ "name": "Unknown",
185
+ "genres": ["Sky"],
186
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Sky_TG24_-_Logo_2021.svg/1920px-Sky_TG24_-_Logo_2021.svg.png",
187
+ "url": "https://hlslive-web-gcdn-skycdn-it.akamaized.net/TACT/12221/web/master.m3u8?hdnts=st=1701861650~exp=1765449000~acl=/*~hmac=84c9f3f71e57b13c3a67afa8b29a8591ea9ed84bf786524399545d94be1ec04d"
188
+ },
189
+ {
190
+ "id": "tv8",
191
+ "title": "TV8",
192
+ "name": "SD",
193
+ "genres": ["Sky"],
194
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/9/9a/TV8_logo.png",
195
+ "url": "https://hlslive-web-gcdn-skycdn-it.akamaized.net/TACT/11223/tv8web/master.m3u8?hdnea=st=1701861650~exp=1765449000~acl=/*~hmac=84c9f3f71e57b13c3a67afa8b29a8591ea9ed84bf786524399545d94be1ec04d"
196
+ },
197
+ {
198
+ "id": "cielo",
199
+ "title": "Cielo",
200
+ "name": "SD",
201
+ "genres": ["Sky"],
202
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/Cielo_TV_logo_2013.svg/1920px-Cielo_TV_logo_2013.svg.png",
203
+ "url": "https://hlslive-web-gcdn-skycdn-it.akamaized.net/TACT/11219/cieloweb/master.m3u8?hdnea=st=1701861650~exp=1765449000~acl=/*~hmac=84c9f3f71e57b13c3a67afa8b29a8591ea9ed84bf786524399545d94be1ec04d"
204
+ },
205
+ {
206
+ "id": "sky-cinema-action",
207
+ "title": "Sky Cinema Action",
208
+ "name": "",
209
+ "genres": ["Sky"],
210
+ "poster": "https://static.wikia.nocookie.net/logopedia/images/4/4b/Sky_Cinema_Action_HD_(alternative).svg"
211
+ },
212
+ {
213
+ "id": "sky-arte",
214
+ "title": "Sky Arte",
215
+ "name": "",
216
+ "genres": ["Sky"],
217
+ "poster": "https://upload.wikimedia.org/wikipedia/en/9/9c/Sky_Arts_2020.png"
218
+ },
219
+ {
220
+ "id": "sky-atlantic",
221
+ "title": "Sky Atlantic",
222
+ "name": "",
223
+ "genres": ["Sky"],
224
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/Sky_Atlantic_-_Logo_2020.svg/1920px-Sky_Atlantic_-_Logo_2020.svg.png"
225
+ },
226
+ {
227
+ "id": "sky-cinema-collection",
228
+ "title": "Sky Cinema Collection",
229
+ "name": "",
230
+ "genres": ["Sky"],
231
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/2/20/Sky_Cinema_Collection_-_Logo_2021.svg"
232
+ },
233
+ {
234
+ "id": "sky-cinema-comedy",
235
+ "title": "Sky Cinema Comedy",
236
+ "name": "",
237
+ "genres": ["Sky"],
238
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/e/e7/Sky_Cinema_Comedy_-_Logo_2021.svg"
239
+ },
240
+ {
241
+ "id": "sky-cinema-drama",
242
+ "title": "Sky Cinema Drama",
243
+ "name": "",
244
+ "genres": ["Sky"],
245
+ "poster":"https://upload.wikimedia.org/wikipedia/commons/3/33/Sky_Cinema_Drama_-_Logo_2021.svg"
246
+ },
247
+ {
248
+ "id": "sky-cinema-due",
249
+ "title": "Sky Cinema Due",
250
+ "name": "",
251
+ "genres": ["Sky"],
252
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Sky_Cinema_Due_-_Logo_2021.svg/1920px-Sky_Cinema_Due_-_Logo_2021.svg.png"
253
+ },
254
+ {
255
+ "id": "sky-cinema-family",
256
+ "title": "Sky Cinema Family",
257
+ "name": "",
258
+ "genres": ["Sky"],
259
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/2/2b/Sky_Cinema_Family_-_Logo_2021.svg"
260
+ },
261
+ {
262
+ "id": "sky-cinema-romance",
263
+ "title": "Sky Cinema Romance",
264
+ "name": "",
265
+ "genres": ["Sky"],
266
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/6/6b/Sky_Cinema_Romance_-_Logo_2021.svg"
267
+ },
268
+ {
269
+ "id": "sky-cinema-suspence",
270
+ "title": "Sky Cinema Suspence",
271
+ "name": "",
272
+ "genres": ["Sky"],
273
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/24/Sky_Cinema_Suspense_HD_-_Logo_2021.svg/1920px-Sky_Cinema_Suspense_HD_-_Logo_2021.svg.png"
274
+ },
275
+ {
276
+ "id": "sky-cinema-uno",
277
+ "title": "Sky Cinema Uno",
278
+ "name": "",
279
+ "genres": ["Sky"],
280
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/69/Sky_Cinema_Uno_%2B24_-_Logo_2021.svg/1920px-Sky_Cinema_Uno_%2B24_-_Logo_2021.svg.png"
281
+ },
282
+ {
283
+ "id": "sky-crime",
284
+ "title": "Sky Crime",
285
+ "name": "",
286
+ "genres": ["Sky"],
287
+ "poster": "https://upload.wikimedia.org/wikipedia/en/thumb/a/ad/Sky_Crime_logo_2020.svg/1920px-Sky_Crime_logo_2020.svg.png"
288
+ },
289
+ {
290
+ "id": "sky-documentaries",
291
+ "title": "Sky Documentaries",
292
+ "name": "",
293
+ "genres": ["Sky"],
294
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Sky_Documentaries.svg/1920px-Sky_Documentaries.svg.png"
295
+ },
296
+ {
297
+ "id": "sky-investigation",
298
+ "title": "Sky Investigation",
299
+ "name": "",
300
+ "genres": ["Sky"],
301
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/Sky_Investigation.svg/1920px-Sky_Investigation.svg.png"
302
+ },
303
+ {
304
+ "id": "sky-nature",
305
+ "title": "Sky Nature",
306
+ "name": "",
307
+ "genres": ["Sky"],
308
+ "poster":"https://static.wikia.nocookie.net/logopedia/images/f/f1/Sky_Nature_2020.svg"
309
+ },
310
+ {
311
+ "id": "sky-serie",
312
+ "title": "Sky Serie",
313
+ "name": "",
314
+ "genres": ["Sky"],
315
+ "poster": "https://static.wikia.nocookie.net/logopedia/images/5/54/Sky_Serie.svg"
316
+ },
317
+ {
318
+ "id": "sky-uno",
319
+ "title": "Sky Uno",
320
+ "name": "",
321
+ "genres": ["Sky"],
322
+ "poster": "https://static.wikia.nocookie.net/logopedia/images/6/66/Sky_Uno_-_Logo_2018.svg"
323
+ },
324
+ {
325
+ "id": "sky-sport-24",
326
+ "title": "Sky Sport 24",
327
+ "name": "",
328
+ "genres": ["Sky"],
329
+ "poster": "https://static.wikia.nocookie.net/logopedia/images/5/5d/Sky_Sport_24_2020.svg"
330
+
331
+ },
332
+ {
333
+ "id": "sky-sport-golf",
334
+ "title": "Sky Sport Golf",
335
+ "name": "",
336
+ "genres": ["Sky"],
337
+ "poster": "https://static.wikia.nocookie.net/logopedia/images/d/d2/Sky_Sports_Golf_HD.png"
338
+ },
339
+ {
340
+ "id": "sky-sport-251",
341
+ "title": "Sky Sport 251",
342
+ "name": "",
343
+ "genres": ["Sky"],
344
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Sky_Sport_-_Logo_2020.svg/1920px-Sky_Sport_-_Logo_2020.svg.png"
345
+ },
346
+ {
347
+ "id": "sky-sport-252",
348
+ "title": "Sky Sport 252",
349
+ "name": "",
350
+ "genres": ["Sky"],
351
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Sky_Sport_-_Logo_2020.svg/1920px-Sky_Sport_-_Logo_2020.svg.png"
352
+ },
353
+ {
354
+ "id": "sky-sport-253",
355
+ "title": "Sky Sport 253",
356
+ "name": "",
357
+ "genres": ["Sky"],
358
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Sky_Sport_-_Logo_2020.svg/1920px-Sky_Sport_-_Logo_2020.svg.png"
359
+ },
360
+ {
361
+ "id": "sky-sport-254",
362
+ "title": "Sky Sport 254",
363
+ "name": "",
364
+ "genres": ["Sky"],
365
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Sky_Sport_-_Logo_2020.svg/1920px-Sky_Sport_-_Logo_2020.svg.png"
366
+ },
367
+ {
368
+ "id": "sky-sport-255",
369
+ "title": "Sky Sport 255",
370
+ "name": "",
371
+ "genres": ["Sky"],
372
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Sky_Sport_-_Logo_2020.svg/1920px-Sky_Sport_-_Logo_2020.svg.png"
373
+ },
374
+ {
375
+ "id": "sky-sport-256",
376
+ "title": "Sky Sport 256",
377
+ "name": "",
378
+ "genres": ["Sky"],
379
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Sky_Sport_-_Logo_2020.svg/1920px-Sky_Sport_-_Logo_2020.svg.png"
380
+ },
381
+ {
382
+ "id": "sky-sport-257",
383
+ "title": "Sky Sport 257",
384
+ "name": "",
385
+ "genres": ["Sky"],
386
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Sky_Sport_-_Logo_2020.svg/1920px-Sky_Sport_-_Logo_2020.svg.png"
387
+ },
388
+ {
389
+ "id": "sky-sport-258",
390
+ "title": "Sky Sport 258",
391
+ "name": "",
392
+ "genres": ["Sky"],
393
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Sky_Sport_-_Logo_2020.svg/1920px-Sky_Sport_-_Logo_2020.svg.png"
394
+ },
395
+ {
396
+ "id": "sky-sport-259",
397
+ "title": "Sky Sport 259",
398
+ "name": "",
399
+ "genres": ["Sky"],
400
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Sky_Sport_-_Logo_2020.svg/1920px-Sky_Sport_-_Logo_2020.svg.png"
401
+ },
402
+ {
403
+ "id": "sky-sport-260",
404
+ "title": "Sky Sport 260",
405
+ "name": "",
406
+ "genres": ["Sky"],
407
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Sky_Sport_-_Logo_2020.svg/1920px-Sky_Sport_-_Logo_2020.svg.png"
408
+ },
409
+ {
410
+ "id": "sky-sport-261",
411
+ "title": "Sky Sport 261",
412
+ "name": "",
413
+ "genres": ["Sky"],
414
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Sky_Sport_-_Logo_2020.svg/1920px-Sky_Sport_-_Logo_2020.svg.png"
415
+ },
416
+ {
417
+ "id": "sky-sport-max",
418
+ "title": "Sky Sport Max",
419
+ "name": "",
420
+ "genres": ["Sky"],
421
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/9/95/Sky_Max_2021.svg"
422
+ },
423
+ {
424
+ "id": "sky-sport-uno",
425
+ "title": "Sky Sport Uno",
426
+ "name": "",
427
+ "genres": ["Sky"],
428
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/af/Sky_Sport_Uno_-_Logo_2020.svg/1920px-Sky_Sport_Uno_-_Logo_2020.svg.png"
429
+ },
430
+ {
431
+ "id": "sky-sport-f1",
432
+ "title": "Sky Sport F1",
433
+ "name": "",
434
+ "genres": ["Sky"],
435
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/eb/Sky_Sport_F1_-_Logo_2020.svg/1920px-Sky_Sport_F1_-_Logo_2020.svg.png"
436
+ },
437
+ {
438
+ "id": "sky-sport-motogp",
439
+ "title": "Sky Sport MotoGP",
440
+ "name": "",
441
+ "genres": ["Sky"],
442
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Sky_Sport_MotoGP_-_Logo_2020.svg/1920px-Sky_Sport_MotoGP_-_Logo_2020.svg.png"
443
+ },
444
+ {
445
+ "id": "sky-sport-calcio",
446
+ "title": "Sky Sport Calcio",
447
+ "name": "",
448
+ "genres": ["Sky"],
449
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/Sky_Sport_Calcio.svg/1920px-Sky_Sport_Calcio.svg.png"
450
+ },
451
+ {
452
+ "id": "sky-sport-arena",
453
+ "title": "Sky Sport Arena",
454
+ "name": "",
455
+ "genres": ["Sky"],
456
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Sky_Sport_Arena_-_Logo_2020.svg/1920px-Sky_Sport_Arena_-_Logo_2020.svg.png"
457
+ },
458
+ {
459
+ "id": "sky-sport-tennis",
460
+ "title": "Sky Sport Tennis",
461
+ "name": "",
462
+ "genres": ["Sky"],
463
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Sky_Sport_Tennis.svg/1920px-Sky_Sport_Tennis.svg.png"
464
+ },
465
+ {
466
+ "id": "sky-sport-nba",
467
+ "title": "Sky Sport NBA",
468
+ "name": "",
469
+ "genres": ["Sky"],
470
+ "poster": "https://static.wikia.nocookie.net/logopedia/images/f/f4/Sky_Sport_NBA_2020.svg"
471
+ },
472
+ {
473
+ "id": "dazn-zona-a",
474
+ "title": "DAZN Zona A",
475
+ "name": "",
476
+ "genres": ["DAZN"],
477
+ "poster": "https://search.bus-hit.me/image_proxy?url=https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2F0%2F03%2FLogo_del_canale_televisivo_Zona_DAZN.svg&h=01f2a96f0856050456cedc029bc289986d577fce54d4d691826822405ed1ff20"
478
+ },
479
+ {
480
+ "id": "eurosport-1",
481
+ "title": "Eurosport 1",
482
+ "name": "",
483
+ "genres": ["Warner Bros"],
484
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/Eurosport_1_Logo_2015.svg/1920px-Eurosport_1_Logo_2015.svg.png"
485
+ },
486
+ {
487
+ "id": "eurosport-2",
488
+ "title": "Eurosport 2",
489
+ "name": "",
490
+ "genres": ["Warner Bros"],
491
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d8/Eurosport_2_Logo_2015.svg/1920px-Eurosport_2_Logo_2015.svg.png"
492
+ },
493
+ {
494
+ "id": "dmax",
495
+ "title": "DMAX",
496
+ "name": "Unknown",
497
+ "genres": ["Warner Bros"],
498
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/98/DMAX_BLACK.svg/1920px-DMAX_BLACK.svg.png",
499
+ "url": "https://amg16146-wbdi-amg16146c8-samsung-it-1841.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-dmax-samsungit/playlist.m3u8"
500
+ },
501
+ {
502
+ "id": "foodnetwork",
503
+ "title": "Food Network",
504
+ "name": "Unknown",
505
+ "genres": ["Warner Bros"],
506
+ "poster":"https://upload.wikimedia.org/wikipedia/commons/thumb/0/06/Food_Network_logo.svg/1024px-Food_Network_logo.svg.png",
507
+ "url": "https://amg16146-wbdi-amg16146c3-samsung-it-1836.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-foodnetwork-samsungit/playlist.m3u8"
508
+ },
509
+ {
510
+ "id": "frisbee",
511
+ "title": "Frisbee",
512
+ "name": "Unknown",
513
+ "genres": ["Warner Bros"],
514
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/FRISBEE_LOGO_2015.png/1280px-FRISBEE_LOGO_2015.png",
515
+ "url": "https://amg16146-wbdi-amg16146c7-samsung-it-1840.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-frisbee-samsungit/playlist.m3u8"
516
+ },
517
+ {
518
+ "id": "giallo",
519
+ "title": "Giallo",
520
+ "name": "Unknown",
521
+ "genres": ["Warner Bros"],
522
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8e/Giallo_-_Logo_2014.svg/200px-Giallo_-_Logo_2014.svg.png",
523
+ "url": "https://amg16146-wbdi-amg16146c5-samsung-it-1838.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-giallo-samsungit/playlist.m3u8"
524
+ },
525
+ {
526
+ "id": "hgtv",
527
+ "title": "HGTV",
528
+ "name": "Unknown",
529
+ "genres": ["Warner Bros"],
530
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/HGTV_2010.svg/1920px-HGTV_2010.svg.png",
531
+ "url": "https://amg16146-wbdi-amg16146c9-samsung-it-1842.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-hgtv-samsungit/playlist.m3u8"
532
+ },
533
+ {
534
+ "id": "k2",
535
+ "title": "K2",
536
+ "name": "Unknown",
537
+ "genres": ["Warner Bros"],
538
+ "poster": "https://upload.wikimedia.org/wikipedia/it/thumb/7/70/K2_logo_%282013%29.svg/800px-K2_logo_%282013%29.svg.png",
539
+ "url": "https://amg16146-wbdi-amg16146c6-samsung-it-1839.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-k2-samsungit/playlist.m3u8"
540
+ },
541
+ {
542
+ "id": "nove",
543
+ "title": "Nove",
544
+ "name": "Unknown",
545
+ "genres": ["Warner Bros"],
546
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2d/Nove_-_Logo_2017.svg/220px-Nove_-_Logo_2017.svg.png",
547
+ "url": "https://amg16146-wbdi-amg16146c1-samsung-it-1831.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-nove-samsungit/playlist.m3u8"
548
+ },
549
+
550
+ {
551
+ "id": "realtime",
552
+ "title": "Real Time",
553
+ "name": "Unknown",
554
+ "genres": ["Warner Bros"],
555
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Real_Time_logo.svg/1920px-Real_Time_logo.svg.png",
556
+ "url": "https://amg16146-wbdi-amg16146c2-samsung-it-1835.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-realtime-samsungit/playlist.m3u8"
557
+ },
558
+ {
559
+ "id": "supertennis",
560
+ "title": "Super Tennis",
561
+ "name": "Unknown",
562
+ "genres": ["FIT"],
563
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/0/02/SUPERTENNIS_HD.png",
564
+ "url": "https://live-embed.supertennix.hiway.media/restreamer/supertennix_client/gpu-a-c0-16/restreamer/rtmp/hls/h24_supertennix/manifest.m3u8"
565
+ },
566
+ {
567
+ "id": "solocalcio",
568
+ "title": "Solo Calcio",
569
+ "name": "Unknown",
570
+ "genres": ["Sportitalia"],
571
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/SI_Live_24_logo_%282019%29.svg/1280px-SI_Live_24_logo_%282019%29.svg.png",
572
+ "url": "https://di-kzbhv8pw.vo.lswcdn.net/sportitalia/sisolocalcio/playlist.m3u8"
573
+ },
574
+ {
575
+ "id": "sportitalia",
576
+ "title": ["Sportitalia"],
577
+ "name": "Unknown",
578
+ "genres": ["Sportitalia"],
579
+ "poster": "https://upload.wikimedia.org/wikipedia/en/5/55/Sportitalia.jpg",
580
+ "url": "https://di-kzbhv8pw.vo.lswcdn.net/sportitalia/sihd/playlist.m3u8"
581
+ },
582
+ {
583
+ "id": "sportitalia24",
584
+ "title": "Sportitalia 24",
585
+ "name": "Unknown",
586
+ "genres": ["Sportitalia"],
587
+ "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/SI_Live_24_logo_%282019%29.svg/1280px-SI_Live_24_logo_%282019%29.svg.png",
588
+ "url": "https://di-kzbhv8pw.vo.lswcdn.net/sportitalia/sihd/playlist.m3u8"
589
+ },
590
+ {
591
+ "id": "rsi-la-2",
592
+ "title": "RSI LA 2",
593
+ "name": "Unknown",
594
+ "genres": ["RSI"],
595
+ "poster": "https://livehere.one/img/rsi.png"
596
+ },
597
+ {
598
+ "id": "baby-shark-tv",
599
+ "title": "Baby Shark TV",
600
+ "name": "Unknown",
601
+ "genres": ["Rakuten"],
602
+ "poster": "https://flxt.tmsimg.com/assets/p19459897_b_v13_aa.jpg",
603
+ "url": "https://c0c65b821b3542c3a4dca92702f59944.mediatailor.us-east-1.amazonaws.com/v1/master/04fd913bb278d8775298c26fdca9d9841f37601f/RakutenTV-eu_BabySharkTV/playlist.m3u8?ads.content_classification=6&ads.device_lmt=1&ads.device_make=&ads.device_model=&ads.device_type=web&ads.device_year=&ads.env=prod&ads.gdpr_consent=&ads.market=it&ads.player_height=&ads.player_width=&ads.pod_type=playerpage_midroll&ads.ppid=&ads.rtv_content_id=3623&ads.rtv_content_language=eng&ads.rtvid=271861&ads.streaming_id=17ded124-30eb-47bc-ab57-ddfce3a16599&ads.user_type=visitor&ads.wurl_channel=696"
604
+ },
605
+ {
606
+ "id": "adrenaline-movies",
607
+ "title": "Rakuten Adrenaline Movies",
608
+ "name": "Unknown",
609
+ "genres": ["Rakuten"],
610
+ "poster": "https://tvpnlogopeu.samsungcloud.tv/platform/image/sourcelogo/vc/00/02/34/ITBC11000050E_20231213T033148SQUARE.png_20231213033148.png",
611
+ "url": "https://minerva-fullmoon-1-eu.plex.wurl.tv/4300.m3u8"
612
+ },
613
+ {
614
+ "id": "bizzarro-movies",
615
+ "title": "Bizzarro Movies",
616
+ "name": "Unknown",
617
+ "genres": ["Rakuten"],
618
+ "poster": "https://tvpnlogopeu.samsungcloud.tv/platform/image/sourcelogo/vc/00/02/34/ITBA3300024IU_20240214T034959SQUARE.png_20240214034959.png",
619
+ "url": "https://minerva-bizzarromovies-1-eu.plex.wurl.tv/4300.m3u8"
620
+ },
621
+ {
622
+ "id": "cinema-italiano",
623
+ "title": "Cinema Italiano",
624
+ "name": "Unknown",
625
+ "genres": ["Rakuten"],
626
+ "poster": "https://tvpnlogopeu.samsungcloud.tv/platform/image/sourcelogo/vc/00/02/34/ITBA33000238E_20240313T074122SQUARE.png",
627
+ "url": "https://minerva-cinemasegreto-1-eu.plex.wurl.tv/4300.m3u8"
628
+ },
629
+ {
630
+ "id": "le-vite-degli-altri",
631
+ "title": "Le Vite Degli Altri",
632
+ "name": "Unknown",
633
+ "genres": ["Rakuten"],
634
+ "poster": "https://tvpnlogopeu.samsungcloud.tv/platform/image/sourcelogo/vc/00/02/34/ITBD3200002DU_20230913T031625SQUARE.png_20230913031625.png",
635
+ "url": "https://amg02512-nexodigital-amg02512c2-wedotv-eu-869.playouts.now.amagi.tv/playlist/amg02512-nexodigital-levitedeglialtri-wedotveu/playlist.m3u8"
636
+ },
637
+ {
638
+ "id": "dark-matter",
639
+ "title": "Dark Matter",
640
+ "name": "Unknown",
641
+ "genres": ["Rakuten"],
642
+ "poster": "https://tvpnlogopeu.samsungcloud.tv/platform/image/sourcelogo/vc/00/02/34/ITBC400001LX_20220404T005859SQUARE.png_20220404005901.png",
643
+ "url": "https://d39g1vxj2ef6in.cloudfront.net/v1/master/3fec3e5cac39a52b2132f9c66c83dae043dc17d4/prod-rakuten-stitched/master.m3u8?ads.xumo_channelId=88883020&ads.xumo_contentId=3480"
644
+ },
645
+ {
646
+ "id": "cine-western",
647
+ "title": "Cine Western",
648
+ "name": "Unknown",
649
+ "genres": ["Rakuten"],
650
+ "poster": "https://tvpnlogopeu.samsungcloud.tv/platform/image/sourcelogo/vc/00/02/34/ITBB20000072M_20240214T035001SQUARE.png_20240214035002.png",
651
+ "url": "https://minerva-wp-1-eu.plex.wurl.tv/4300.m3u8"
652
+ },
653
+ {
654
+ "id": "serie-crime",
655
+ "title": "Serie Crime",
656
+ "name": "Unknown",
657
+ "genres": ["Rakuten"],
658
+ "poster": "https://images-2.rakuten.tv/storage/global-live-channel/translation/artwork-negative/0e0a6638-7c4c-4065-82d7-a34d818388ee-width500.png",
659
+ "url": "https://rakuten-seriecrime-6-it.xiaomi.wurl.tv/4300.m3u8"
660
+ },
661
+ {
662
+ "id": "filmrise-sci-fi",
663
+ "title": "Filmrise Sci-Fi",
664
+ "name": "Unknown",
665
+ "genres": ["Rakuten"],
666
+ "poster": "https://images-3.rakuten.tv/storage/global-live-channel/translation/artwork_negative/ba0fa0a9-7e17-497e-abcc-9405dbb3a7f5-filmrise-sci-fi-1643623368-quality100.png",
667
+ "url": "https://d39g1vxj2ef6in.cloudfront.net/v1/master/3fec3e5cac39a52b2132f9c66c83dae043dc17d4/prod-rakuten-stitched/master.m3u8?ads.xumo_channelId=9991764"
668
+ },
669
+ {
670
+ "id": "doctor-who",
671
+ "title": "Doctor Who",
672
+ "name": "Unknown",
673
+ "genres": ["Rakuten"],
674
+ "poster": "https://images.pluto.tv/channels/62e7f8db27ce19000732d1aa/colorLogoPNG.png",
675
+ "url": "https://bbceu-doctorwho-1-it.rakuten.wurl.tv/3000.m3u8"
676
+ },
677
+ {
678
+ "id": "bbc-drama",
679
+ "title": "BBC Drama",
680
+ "name": "Unknown",
681
+ "genres": ["Rakuten"],
682
+ "poster": "https://images.pluto.tv/channels/62e7fa5ab5062e0007dcf97d/colorLogoPNG.png",
683
+ "url": "https://bbceu-bbcdrama-2-it.rakuten.wurl.tv/3000.m3u8"
684
+ },
685
+ {
686
+ "id": "documentari",
687
+ "title": "Documentari (Grandi Documentari)",
688
+ "name": "Unknown",
689
+ "genres": ["Rakuten"],
690
+ "poster": "https://tvpnlogopeu.samsungcloud.tv/platform/image/sourcelogo/vc/00/02/34/ITBC35000016T_20230208T013151SQUARE.png_20230208013152.png",
691
+ "url": "https://videosolutions-wedobigstories-rakuten.amagi.tv/playlist1080p.m3u8"
692
+ },
693
+ {
694
+ "id": "house-of-docs",
695
+ "title": "House of Docs",
696
+ "name": "Unknown",
697
+ "genres": ["Rakuten"],
698
+ "poster": "https://tvpnlogopeu.samsungcloud.tv/platform/image/sourcelogo/vc/00/02/34/ITBD1100001B7_20230412T042554SQUARE.png_20230412042554.png",
699
+ "url": "https://amg02512-nexodigital-amg02512c1-wedotv-eu-871.playouts.now.amagi.tv/playlist/amg02512-nexodigital-houseofdocs-wedotveu/playlist.m3u8"
700
+ },
701
+ {
702
+ "id": "pluto-matrimoni",
703
+ "title": "Pluto TV Matrimoni",
704
+ "name": "Unknown",
705
+ "genres": ["Pluto"],
706
+ "poster": "https://images.pluto.tv/channels/661f8f2506839f0008b864e9/colorLogoPNG.png",
707
+ "url": "http://stitcher.pluto.tv/v1/stitch/embed/hls/channel/661f8f2506839f0008b864e9/master.m3u8?deviceId=0&deviceModel=samsung&deviceVersion=0&appVersion=0&deviceType=samsung&deviceMake=samsung&deviceDNT=true"
708
+ },
709
+ {
710
+ "id": "the-asylum",
711
+ "title": "The Asylum",
712
+ "name": "Unknown",
713
+ "genres": ["Pluto"],
714
+ "poster": "https://images.pluto.tv/channels/62e8d5369e48940007fc1dc1/colorLogoPNG.png",
715
+ "url": "http://stitcher.pluto.tv/v1/stitch/embed/hls/channel/62e8d5369e48940007fc1dc1/master.m3u8?deviceType=samsung-tvplus&deviceMake=samsung&deviceModel=samsung&deviceVersion=unknown&appVersion=unknown&deviceLat=0&deviceLon=0&deviceDNT=%7BTARGETOPT%7D&deviceId=%7BPSID%7D&advertisingId=%7BPSID%7D&us_privacy=1YNY&samsung_app_domain=%7BAPP_DOMAIN%7D&samsung_app_name=%7BAPP_NAME%7D&profileLimit=&profileFloor=&embedPartner=samsung-tvplus"
716
+ },
717
+ {
718
+ "id": "western",
719
+ "title": "Western",
720
+ "name": "Unknown",
721
+ "genres": ["Pluto"],
722
+ "poster": "https://images.pluto.tv/channels/62e7fb67478a5b0007e6c50c/colorLogoPNG.png",
723
+ "url": "http://stitcher.pluto.tv/v1/stitch/embed/hls/channel/62e7fb67478a5b0007e6c50c/master.m3u8?deviceType=samsung-tvplus&deviceMake=samsung&deviceModel=samsung&deviceVersion=unknown&appVersion=unknown&deviceLat=0&deviceLon=0&deviceDNT=%7BTARGETOPT%7D&deviceId=%7BPSID%7D&advertisingId=%7BPSID%7D&us_privacy=1YNY&samsung_app_domain=%7BAPP_DOMAIN%7D&samsung_app_name=%7BAPP_NAME%7D&profileLimit=&profileFloor=&embedPartner=samsung-tvplus"
724
+ },
725
+ {
726
+ "id": "consulenze-illegali",
727
+ "title": "Consulenze Illegali",
728
+ "name": "Unknown",
729
+ "genres": ["Pluto"],
730
+ "poster": "https://images.pluto.tv/channels/60b9dc99521a1400079bdfba/colorLogoPNG.png",
731
+ "url": "http://stitcher.pluto.tv/v1/stitch/embed/hls/channel/60b9dc99521a1400079bdfba/master.m3u8?deviceType=samsung-tvplus&deviceMake=samsung&deviceModel=samsung&deviceVersion=unknown&appVersion=unknown&deviceLat=0&deviceLon=0&deviceDNT=%7BTARGETOPT%7D&deviceId=%7BPSID%7D&advertisingId=%7BPSID%7D&us_privacy=1YNY&samsung_app_domain=%7BAPP_DOMAIN%7D&samsung_app_name=%7BAPP_NAME%7D&profileLimit=&profileFloor=&embedPartner=samsung-tvplus"
732
+ }
733
+ ]
734
+ }
735
+
736
+
737
+
738
+
739
+ webru_vary = {
740
+ "sky-cinema-action": "https://webuit.mizhls.ru/lb/calcioXac/index.m3u8",
741
+ "comedy-central": "https://webuit.mizhls.ru/lb/calcioXcomedycentral/index.m3u8",
742
+ "history": "https://webuit.mizhls.ru/lb/calcioXhistory/index.m3u8",
743
+ "sky-arte": "https://webuit.mizhls.ru/lb/calcioXskyarte/index.m3u8",
744
+ "sky-atlantic": "https://webuit.mizhls.ru/lb/calcioXskyatlantic/index.m3u8",
745
+ "sky-cinema-collection": "https://webuit.mizhls.ru/lb/calcioXskycinemacollection/index.m3u8",
746
+ "sky-cinema-comedy": "https://webuit.mizhls.ru/lb/calcioXskycinemacomedy/index.m3u8",
747
+ "sky-cinema-drama": "https://webuit.mizhls.ru/lb/calcioXskycinemadrama/index.m3u8",
748
+ "sky-cinema-due": "https://webuit.mizhls.ru/lb/calcioXskycinemadue/index.m3u8",
749
+ "sky-cinema-family": "https://webuit.mizhls.ru/lb/calcioXskycinemafamily/index.m3u8",
750
+ "sky-cinema-romance": "https://webuit.mizhls.ru/lb/calcioXskycinemaromance/index.m3u8",
751
+ "sky-cinema-suspence": "https://webuit.mizhls.ru/lb/calcioXskycinemasuspence/index.m3u8",
752
+ "sky-cinema-uno": "https://webuit.mizhls.ru/lb/calcioXskycinemauno/index.m3u8",
753
+ "sky-crime": "https://webuit.mizhls.ru/lb/calcioXskycrime/index.m3u8",
754
+ "sky-documentaries": "https://webuit.mizhls.ru/lb/calcioXskydocumentaries/index.m3u8",
755
+ "sky-investigation": "https://webuit.mizhls.ru/lb/calcioXskyinvestigation/index.m3u8",
756
+ "sky-nature": "https://webuit.mizhls.ru/lb/calcioXskynature/index.m3u8",
757
+ "sky-serie": "https://webuit.mizhls.ru/lb/calcioXskyserie/index.m3u8",
758
+ "sky-uno": "https://webuit.mizhls.ru/lb/calcioXskyuno/index.m3u8",
759
+ "sky-sport-24": "https://webuit.mizhls.ru/lb/calcioXskysport24/index.m3u8",
760
+ "sky-sport-golf": "https://webuit.mizhls.ru/lb/calcioXskysportgolf/index.m3u8",
761
+ "sky-sport-251": "https://webuit.mizhls.ru/lb/calcioXskysport251/index.m3u8",
762
+ "sky-sport-253": "https://webuit.mizhls.ru/lb/calcioXskysport253/index.m3u8",
763
+ "sky-sport-max": "https://webuit.mizhls.ru/lb/calcioXskysportmax/index.m3u8",
764
+ "sky-sport-255": "https://webuit.mizhls.ru/lb/calcioXskysport255/index.m3u8",
765
+ "sky-sport-259": "https://webuit.mizhls.ru/lb/calcioXsky259/index.m3u8",
766
+ "sky-sport-252": "https://webuit.mizhls.ru/lb/calcioXskysport252/index.m3u8",
767
+ "sky-sport-254": "https://webuit.mizhls.ru/lb/calcioXskysport254/index.m3u8",
768
+ "sky-sport-256": "https://webuit.mizhls.ru/lb/calcioXskysport256/index.m3u8",
769
+ "sky-sport-257": "https://webuit.mizhls.ru/lb/calcioXskysport257/index.m3u8",
770
+ "sky-sport-258": "https://webuit.mizhls.ru/lb/calcioXsky258/index.m3u8",
771
+ "sky-sport-259": "https://webuit.mizhls.ru/lb/calcioXsky259/index.m3u8",
772
+ "sky-sport-260": "https://webuit.mizhls.ru/lb/calcioXsky260/index.m3u8",
773
+ "sky-sport-261": "https://webuit.mizhls.ru/lb/calcioXsky261/index.m3u8",
774
+ "eurosport-1": "https://webuit.mizhls.ru/lb/calcioXeurosport1/index.m3u8",
775
+ "eurosport-2": "https://webuit.mizhls.ru/lb/calcioXeurosport2/index.m3u8",
776
+ "sky-sport-uno": "https://webuit.mizhls.ru/lb/calcioXskysportuno/index.m3u8",
777
+ "sky-sport-f1": "https://webuit.mizhls.ru/lb/calcioXskysportf1/index.m3u8",
778
+ "sky-sport-motogp": "https://webuit.mizhls.ru/lb/calcioXskysportmotogp/index.m3u8",
779
+ "sky-sport-calcio": "https://webuit.mizhls.ru/lb/calcioXskysportcalcio/index.m3u8",
780
+ "sky-sport-arena": "https://webuit.mizhls.ru/lb/calcioXskysportarena/index.m3u8",
781
+ "sky-sport-tennis": "https://webuit.mizhls.ru/lb/calcioXskysporttennis/index.m3u8",
782
+ "sky-sport-nba": "https://webuit.mizhls.ru/lb/calcioXskysportnba/index.m3u8",
783
+ "dazn-zona-a": "https://webuit.mizhls.ru/lb/calcioXzona/index.m3u8"
784
+ }
785
+
786
+
787
+ webru_dlhd = {
788
+ "sky-sport-tennis": "https://webhdrunns.mizhls.ru/lb/premium576/index.m3u8",
789
+ "sky-sport-uno": "https://webhdrunns.mizhls.ru/lb/premium461/index.m3u8",
790
+ "sky-cinema-collection": "https://webhdrunns.mizhls.ru/lb/premium859/index.m3u8",
791
+ "sky-cinema-romance": "https://webhdrunns.mizhls.ru/lb/premium864/index.m3u8",
792
+ "sky-sport-24": "https://webhdrunns.mizhls.ru/lb/premium869/index.m3u8",
793
+ "sky-sport-254": "https://webhdrunns.mizhls.ru/lb/premium874/index.m3u8",
794
+ "sky-sport-f1": "https://webhdrunns.mizhls.ru/lb/premium577/index.m3u8",
795
+ "sky-sport-arena": "https://webhdrunns.mizhls.ru/lb/premium462/index.m3u8",
796
+ "sky-cinema-uno": "https://webhdrunns.mizhls.ru/lb/premium860/index.m3u8",
797
+ "sky-cinema-family": "https://webhdrunns.mizhls.ru/lb/premium865/index.m3u8",
798
+ "sky-sport-calcio": "https://webhdrunns.mizhls.ru/lb/premium870/index.m3u8",
799
+ "sky-sport-255": "https://webhdrunns.mizhls.ru/lb/premium875/index.m3u8",
800
+ "sky-cinema-action": "https://webhdrunns.mizhls.ru/lb/premium861/index.m3u8",
801
+ "sky-cinema-due": "https://webhdrunns.mizhls.ru/lb/premium866/index.m3u8",
802
+ "sky-sport-251": "https://webhdrunns.mizhls.ru/lb/premium871/index.m3u8",
803
+ "sky-sport-256": "https://webhdrunns.mizhls.ru/lb/premium876/index.m3u8",
804
+ "sky-sport-golf": "https://webhdrunns.mizhls.ru/lb/premium574/index.m3u8",
805
+ "sky-uno": "https://webhdrunns.mizhls.ru/lb/premium881/index.m3u8",
806
+ "sky-cinema-comedy": "https://webhdrunns.mizhls.ru/lb/premium862/index.m3u8",
807
+ "sky-cinema-drama": "https://webhdrunns.mizhls.ru/lb/premium867/index.m3u8",
808
+ "sky-sport-252": "https://webhdrunns.mizhls.ru/lb/premium872/index.m3u8",
809
+ "sky-sport-257": "https://webhdrunns.mizhls.ru/lb/premium877/index.m3u8",
810
+ "sky-sport-motogp": "https://webhdrunns.mizhls.ru/lb/premium575/index.m3u8",
811
+ "sky-sport-football": "https://webhdrunns.mizhls.ru/lb/premium460/index.m3u8",
812
+ "sky-cinema-uno-24": "https://webhdrunns.mizhls.ru/lb/premium863/index.m3u8",
813
+ "sky-cinema-suspence": "https://webhdrunns.mizhls.ru/lb/premium868/index.m3u8",
814
+ "sky-sport-253": "https://webhdrunns.mizhls.ru/lb/premium873/index.m3u8",
815
+ "sky-serie": "https://webhdrunns.mizhls.ru/lb/premium880/index.m3u8"
816
+ }
817
+ extra_sources = {
818
+ "rai-1": ["https://m3u.iranvids.com/rai01/output.m3u8"],
819
+ "rai-2": ["https://m3u.iranvids.com/rai02/output.m3u8"],
820
+ "rai-3": ["https://dash2.antik.sk/live/test_rai_tre_tizen/playlist.m3u8","https://wzstreaming.rai.it/TVlive/liveStream/playlist.m3u8","https://list.iptvcat.com/my_list/s/1f22856f68f2fba4a993c47f47c78a64.m3u8","https://list.iptvcat.com/my_list/s/a372048a4fb440e752aec141aa02885f.m3u8","https://list.iptvcat.com/my_list/s/c7efe17aa0dc8096561967bfb828d4f3.m3u8","https://list.iptvcat.com/my_list/s/2d1f14bbb3370d263d8d3f0d9f5128e0.m3u8"],
821
+ "rete-4":["http://tvit.leicaflorianrobert.dev/mediaset/rete-4/stream.m3u8","https://live02-seg.msf.cdn.mediaset.net/live/ch-r4/r4-clr.isml/index.m3u8"],
822
+ "canale-5":["https://live02-seg.msf.cdn.mediaset.net/live/ch-c5/c5-clr.isml/index.m3u8","http://tvit.leicaflorianrobert.dev/mediaset/canale-5/stream.m3u8"],
823
+ "italia-1":["https://tvit.leicaflorianrobert.dev/mediaset/italia-1/stream.m3u8","https://live02-seg.msf.cdn.mediaset.net/live/ch-i1/i1-clr.isml/index.m3u8"],
824
+ "rai-4k": ["https://list.iptvcat.com/my_list/s/fbf04fbd9694eee71b5af9f12e49538d.m3u8"],
825
+ "rai-news":["https://8e7439fdb1694c8da3a0fd63e4dda518.msvdn.net/rainews1/hls/playlist_mo.m3u8"],
826
+ "topcrime": ["https://tvit.leicaflorianrobert.dev/mediaset/top-crime/stream.m3u8"],
827
+ "mediaset-extra": ["https://tvit.leicaflorianrobert.dev/mediaset/mediaset-extra/stream.m3u8"],
828
+ "focus": ["https://tvit.leicaflorianrobert.dev/mediaset/focus/stream.m3u8"],
829
+ "boing": ["https://tvit.leicaflorianrobert.dev/mediaset/boing/stream.m3u8"],
830
+ "cartoonito": ["https://tvit.leicaflorianrobert.dev/mediaset/cartoonito/stream.m3u8"],
831
+ "tv8": ["https://tvit.leicaflorianrobert.dev/sky/tv8/stream.m3u8"],
832
+ "cielo": ["https://tvit.leicaflorianrobert.dev/sky/cielo/stream.m3u8"],
833
+ "dmax": ["https://tvit.leicaflorianrobert.dev/discovery/dmax/stream.m3u8"],
834
+ "nove": ["https://tvit.leicaflorianrobert.dev/discovery/nove/stream.m3u8"]
835
+ }
filmpertutti.py ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from tmdbv3api import TMDb, Movie, TV
3
+ import requests
4
+ from bs4 import BeautifulSoup,SoupStrainer
5
+ import string
6
+ import re
7
+ from datetime import datetime
8
+ import dateparser
9
+ from convert import get_TMDb_id_from_IMDb_id
10
+ from info import get_info_tmdb, is_movie, get_info_imdb
11
+ from convert_date import convert_US_date
12
+ import logging
13
+ import config
14
+
15
+ FT_DOMAIN = config.FT_DOMAIN
16
+
17
+ #Some basic headers
18
+ headers = {
19
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.10; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
20
+ 'Accept-Language': 'en-US,en;q=0.5'
21
+ }
22
+ #Map months to check if date = date
23
+ month_mapping = {
24
+ 'Jan': 'Gennaio', 'Feb': 'Febbraio', 'Mar': 'Marzo', 'Apr': 'Aprile',
25
+ 'May': 'Maggio', 'Jun': 'Giugno', 'Jul': 'Luglio', 'Aug': 'Agosto',
26
+ 'Sep': 'Settembre', 'Oct': 'Ottobre', 'Nov': 'Novembre', 'Dec': 'Dicembre'
27
+ }
28
+
29
+ async def search(query,date,client):
30
+ response = await client.get(query).json()
31
+ #Get link tid of every item and then open the link to see if the date = date
32
+ for json in response:
33
+ link = json['link']
34
+ tid = json['id']
35
+ series_response = await client.get(link, headers=headers, follow_redirects=True)
36
+ series_soup = BeautifulSoup(series_response.text, 'lxml')
37
+ release_span = series_soup.find('span', class_='released')
38
+ if release_span:
39
+ if release_span.text != "Data di uscita: N/A":
40
+ date_string = release_span.text.split(': ')[-1] # Get the date part
41
+ for eng, ita in month_mapping.items():
42
+ date_string = re.sub(rf'\b{eng}\b', ita, date_string)
43
+
44
+ # Swap to YY-MM-DD formatting using dateparser
45
+ release_date = dateparser.parse(date_string, languages=['it']).strftime("%Y-%m-%d")
46
+ if release_date == date:
47
+ url = link
48
+ tid = tid
49
+ return url, tid
50
+ else:
51
+ print("Date are not equals")
52
+
53
+ def get_episode_link(season,episode,tid,url):
54
+ #Get the link from where we have to obtain mixdrop link
55
+ tlink = f'{url}?show_video=true&post_id={tid}&season_id={season-1}&episode_id={episode-1}'
56
+ return tlink
57
+
58
+
59
+ def get_film(url):
60
+ #Get the link from where we have to obtain mixdrop link
61
+ tlink = url + "?show_video=true"
62
+ return tlink
63
+
64
+ async def get_real_link(tlink,client):
65
+ #Some basic code to get the mixdrop link
66
+ page = await client.get(tlink, headers=headers, follow_redirects=True)
67
+ soup = BeautifulSoup(page.content(), features="lxml",parse_only=SoupStrainer('iframe'))
68
+ iframe_src = soup.find('iframe')['src']
69
+
70
+ iframe_page = await client.get(iframe_src, headers=headers, follow_redirects=True)
71
+ iframe_soup = BeautifulSoup(iframe_page.content(), features="lxml")
72
+
73
+ mega_button = iframe_soup.find('div', attrs={'class': 'megaButton', 'rel': 'nofollow'}, string='MIXDROP')
74
+ if mega_button:
75
+ real_link = mega_button.get('meta-link')
76
+ return real_link
77
+
78
+ async def get_true_link(real_link,client):
79
+ response = await client.get(real_link, headers=headers, follow_redirects=True)
80
+ [s1, s2] = re.search(r"\}\('(.+)',.+,'(.+)'\.split", response.text).group(1, 2)
81
+ schema = s1.split(";")[2][5:-1]
82
+ terms = s2.split("|")
83
+ charset = string.digits + string.ascii_letters
84
+ d = dict()
85
+ for i in range(len(terms)):
86
+ d[charset[i]] = terms[i] or charset[i]
87
+ s = 'https:'
88
+ for c in schema:
89
+ s += d[c] if c in d else c
90
+ return s
91
+
92
+ async def filmpertutti(imdb,client):
93
+ general = is_movie(imdb)
94
+ ismovie = general[0]
95
+ imdb_id = general[1]
96
+ type = "Filmpertutti"
97
+ if ismovie == 0 :
98
+ season = int(general[2])
99
+ episode = int(general[3])
100
+ if "tt" in imdb:
101
+ if ismovie == 0:
102
+ #Get showname and date
103
+ showname,date = await get_info_imdb(imdb_id,ismovie,type,client)
104
+ else:
105
+ #THIS IS needed cause the only way to get all releases dates is by giving a tmdb ID not a IMDB
106
+ tmdba = await get_TMDb_id_from_IMDb_id(imdb_id,client)
107
+ showname,date = get_info_tmdb(tmdba,ismovie,type)
108
+
109
+ elif "tmdb" in imdb:
110
+ #Get showname and date
111
+ tmdba = imdb_id.replace("tmdb:","")
112
+ showname,date = get_info_tmdb(tmdba,ismovie,type)
113
+ showname = showname.replace(" ", "+").replace("–", "+").replace("—","+")
114
+ #Build the query
115
+ query = f'https://filmpertutti.{FT_DOMAIN}/wp-json/wp/v2/posts?search={showname}&page=1&_fields=link,id'
116
+ try:
117
+ url,tid = await search(query,date,client)
118
+ except:
119
+ print("No results found")
120
+ return None
121
+ if ismovie == 0:
122
+ episode_link = get_episode_link(season,episode,tid,url)
123
+ #Let's get mixdrop link
124
+ real_link = await get_real_link(episode_link,client)
125
+ #let's get delivery link, streaming link
126
+ streaming_link = await get_true_link(real_link,client)
127
+ print(streaming_link)
128
+ return streaming_link
129
+ elif ismovie == 1:
130
+ film_link = get_film(url)
131
+ #Let's get mixdrop link
132
+ real_link = await get_real_link(film_link,client)
133
+ #let's get delivery link, streaming link
134
+ streaming_link = await get_true_link(real_link,client)
135
+ print(streaming_link)
136
+ return streaming_link
info.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from loadenv import load_env
2
+ from tmdbv3api import TMDb, Movie, TV
3
+ from convert_date import convert_US_date, convert_IT_date
4
+ import requests
5
+ import config
6
+ import json
7
+ SC_FAST_SEARCH = config.SC_FAST_SEARCH
8
+ TF_FAST_SEARCH = config.TF_FAST_SEARCH
9
+ env_vars = load_env()
10
+ TMDB_KEY = env_vars.get('TMDB_KEY')
11
+
12
+
13
+ def get_info_tmdb(tmbda,ismovie,type):
14
+ tmdb = TMDb()
15
+ tmdb.api_key = f'{TMDB_KEY}'
16
+ tmdb.language = 'it'
17
+ if ismovie == 0:
18
+ tv = TV()
19
+ show= tv.details(tmbda)
20
+ showname = show.name
21
+ if type == "Filmpertutti":
22
+ date= show.first_air_date
23
+ print("Real date",date)
24
+ return showname,date
25
+ elif type == "StreamingCommunity":
26
+ if SC_FAST_SEARCH == "0":
27
+ n_season = show.number_of_seasons
28
+ full_date = show.first_air_date
29
+ date = full_date.split("-")[0]
30
+ print(date)
31
+ return showname,date
32
+ else:
33
+ return showname
34
+ elif type == "Tuttifilm":
35
+ if TF_FAST_SEARCH == "0":
36
+ date = show.first_air_date
37
+ date = date.split("-")[0]
38
+ print("Real date",date)
39
+ return showname,date
40
+ else:
41
+ return showname
42
+ elif type == "Cool":
43
+ return showname
44
+ elif type == "LordChannel":
45
+ date = show.first_air_date
46
+ date = date.split("-")[0]
47
+ print("Real date",date)
48
+ return showname,date
49
+ elif type == "StreamingWatch":
50
+ date = show.first_air_date
51
+ date = date.split("-")[0]
52
+ print("Real date",date)
53
+ return showname,date
54
+
55
+ elif ismovie == 1:
56
+ movie = Movie()
57
+ show= movie.details(tmbda)
58
+ showname= show.title
59
+ #Get all release dates
60
+ if type == "Filmpertutti":
61
+ date = show.release_dates
62
+ #GET US RELEASE DATE because filmpertutti somewhy uses US release date
63
+ date = convert_US_date(date)
64
+ return showname,date
65
+ elif type == "StreamingCommunity":
66
+ return showname
67
+ elif type == "Tuttifilm":
68
+ if TF_FAST_SEARCH == "0":
69
+ date = show.release_date
70
+ date = date.split("-")[0]
71
+ print("Real date",date)
72
+ return showname,date
73
+ else:
74
+ return showname
75
+ elif type == "Cool":
76
+ return showname
77
+ elif type == "LordChannel":
78
+ date = show.release_date
79
+ date = date.split("-")[0]
80
+ print("Real date",date)
81
+ return showname,date
82
+ elif type == "StreamingWatch":
83
+ date = show.release_date
84
+ date = date.split("-")[0]
85
+ print("Real date",date)
86
+ return showname,date
87
+
88
+ async def get_info_imdb(imdb_id, ismovie, type,client):
89
+
90
+ resp = await client.get(f'https://api.themoviedb.org/3/find/{imdb_id}?api_key={TMDB_KEY}&language=it&external_source=imdb_id')
91
+ data = resp.json()
92
+ if ismovie == 0:
93
+ showname = data['tv_results'][0]['name']
94
+ if type == "Filmpertutti":
95
+ date= data['tv_results'][0]['first_air_date']
96
+ print("Real date",date)
97
+ return showname, date
98
+ elif type == "StreamingCommunity":
99
+ return showname
100
+ elif type == "Tuttifilm":
101
+ if TF_FAST_SEARCH == "0":
102
+ date = data['tv_results'][0]['first_air_date']
103
+ date = date.split("-")[0]
104
+ return showname,date
105
+ elif TF_FAST_SEARCH == "1":
106
+ return showname
107
+ elif type == "Cool":
108
+ return showname
109
+
110
+ elif ismovie == 1:
111
+ showname= data['movie_results'][0]['title']
112
+ if type == "Filmpertutti":
113
+ return
114
+ elif type == "StreamingCommunity":
115
+ return showname
116
+ elif type == "Tuttifilm":
117
+ date = data['movie_results'][0]['release_date']
118
+ date = date.split("-")[0]
119
+ return showname,date
120
+ elif type == "Cool":
121
+ return showname
122
+
123
+ async def get_info_kitsu(kitsu_id,client):
124
+ api_url = f'https://kitsu.io/api/edge/anime/{kitsu_id}'
125
+ response = await client.get(api_url)
126
+ data = json.loads(response.text)
127
+ showname = data['data']['attributes']['canonicalTitle']
128
+ date = data['data']['attributes']['startDate']
129
+ return showname,date
130
+
131
+
132
+
133
+
134
+ def is_movie(imdb_id):
135
+ if "tmdb:" in imdb_id:
136
+ imdb_id = imdb_id.replace("tmdb:","")
137
+ if ":" in imdb_id:
138
+ season = imdb_id.split(":")[1]
139
+ episode = imdb_id.split(":")[-1]
140
+ ismovie = 0
141
+ imdb_id = imdb_id.split(":")[0]
142
+ return ismovie,imdb_id,season,episode
143
+ else:
144
+ ismovie = 1
145
+ return ismovie,imdb_id
loadenv.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import config
3
+ import config
4
+ MYSTERIUS = config.MYSTERIUS
5
+ dotenv = config.dotenv
6
+ TUTTIFILM = config.TUTTIFILM
7
+ HF = config.HF
8
+ #You need to keep dotenv disabled on remote servers
9
+ if dotenv == "1":
10
+ from dotenv import load_dotenv
11
+ load_dotenv(".env")
12
+
13
+
14
+ def load_env():
15
+ env_vars = {}
16
+ env_vars['TMDB_KEY'] = os.getenv('TMDB_KEY')
17
+ if MYSTERIUS == "1":
18
+ env_vars['MYSTERIUS_KEY'] = os.getenv('MYSTERIUS_KEY')
19
+ if TUTTIFILM == "1":
20
+ if HF == "1":
21
+ env_vars['PROXY_CREDENTIALS'] = os.getenv('PROXY')
22
+ return env_vars
lordchannel.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from tmdbv3api import TMDb, Movie, TV
2
+ import requests
3
+ import logging
4
+ from bs4 import BeautifulSoup,SoupStrainer
5
+ from datetime import datetime
6
+ import dateparser
7
+ from convert import get_TMDb_id_from_IMDb_id
8
+ from info import get_info_tmdb, is_movie, get_info_imdb
9
+ import config
10
+ import re
11
+ import json
12
+ LC_DOMAIN = config.LC_DOMAIN
13
+ async def search(showname,date,season,episode,ismovie,client):
14
+ cookies = {
15
+ 'csrftoken': '7lvc502CZe8Zbx7iSX1xkZOBA1NbDxJZ',
16
+ }
17
+
18
+ headers = {
19
+ 'authority': f'lordchannel.{LC_DOMAIN}',
20
+ 'accept': '*/*',
21
+ 'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7',
22
+ # 'cookie': 'csrftoken=7lvc502CZe8Zbx7iSX1xkZOBA1NbDxJZ',
23
+ 'referer': f'https://lordchannel.{LC_DOMAIN}/anime/anime-ita/',
24
+ 'sec-ch-ua': '"Not-A.Brand";v="99", "Chromium";v="124"',
25
+ 'sec-ch-ua-mobile': '?0',
26
+ 'sec-ch-ua-platform': '"Android"',
27
+ 'sec-fetch-dest': 'empty',
28
+ 'sec-fetch-mode': 'cors',
29
+ 'sec-fetch-site': 'same-origin',
30
+ 'user-agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
31
+ 'x-requested-with': 'XMLHttpRequest',
32
+ }
33
+
34
+ params = {
35
+ 'media': showname,
36
+ '_': '1724421723999',
37
+ }
38
+
39
+ response = await client.get(f'https://lordchannel.{LC_DOMAIN}/live_search/', params=params, cookies=cookies, headers=headers, follow_redirects=True)
40
+ data = json.loads(response.text)
41
+ for entry in data['data']:
42
+ if entry is not None: # check if the a_tag exists
43
+ href = entry['url']
44
+ quality = entry['qualit\u00e0_video']
45
+ link = f'https://lordchannel.{LC_DOMAIN}{href}'
46
+ response = await client.get(link, follow_redirects=True)
47
+ soup2 = BeautifulSoup(response.text,'lxml')
48
+ li_tag = soup2.select_one("ul.card__meta li:nth-of-type(2)")
49
+ if li_tag is not None: # check if the li_tag exists
50
+ card_date = li_tag.text[-4:]
51
+ if card_date == date:
52
+ if ismovie == 1:
53
+ video_url = soup2.find('a', class_="btn-streaming streaming_btn")
54
+ video_url = video_url['href']
55
+ return video_url,quality
56
+ elif ismovie == 0:
57
+ div = soup2.find('div', id=f'collapse{season}')
58
+ episode = episode -1 #Index start from 0 so I need to subtract 1
59
+ episode = div.select('tr')[2] # index is 2 because we want the correct element
60
+ video_url = href = episode.find('a').get('href')
61
+ return video_url,quality
62
+ else:
63
+ print("Sadly date are not equals")
64
+ continue
65
+
66
+ async def get_m3u8(video_url,client):
67
+ response = await client.get(video_url, follow_redirects=True)
68
+ pattern = r'const videoData = \[(.*?)\];'
69
+ match = re.search(pattern, response.text)
70
+
71
+ if match:
72
+ video_data = match.group(1).strip().split(', ')
73
+ url = video_data[0]
74
+ return url
75
+
76
+ async def lordchannel(imdb,client):
77
+ try:
78
+ general = is_movie(imdb)
79
+ ismovie = general[0]
80
+ imdb_id = general[1]
81
+ type = "LordChannel"
82
+ if ismovie == 0:
83
+ season = int(general[2])
84
+ episode = int(general[3])
85
+ if "tt" in imdb:
86
+ tmdba = await get_TMDb_id_from_IMDb_id(imdb_id,client)
87
+ else:
88
+ tmdba = imdb_id
89
+ else:
90
+ season = None
91
+ episode = None
92
+ if "tt" in imdb:
93
+ tmdba = await get_TMDb_id_from_IMDb_id(imdb_id,client)
94
+ else:
95
+ tmdba = imdb_id
96
+ showname,date = get_info_tmdb(tmdba,ismovie,type)
97
+ video_url,quality = await search(showname,date,season,episode,ismovie,client)
98
+ url = await get_m3u8(video_url,client)
99
+ url = url.replace('"','')
100
+ print(url)
101
+ return url,quality
102
+ except:
103
+ print("Lordchannel Failed")
104
+ return None,None
okru.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ from bs4 import BeautifulSoup
3
+ import json
4
+ from dictionaries import okru
5
+
6
+
7
+
8
+ async def okru_get_url(id,client):
9
+ embed_link = okru[id]
10
+ print(embed_link)
11
+ response = await client.get(embed_link, follow_redirects=True)
12
+ soup = BeautifulSoup(response.text, 'lxml')
13
+ div = soup.find('div', {'data-module': 'OKVideo'})
14
+ data_options = div.get('data-options')
15
+ data = json.loads(data_options)
16
+ metadata = json.loads(data['flashvars']['metadata'])
17
+ m3u8_link = metadata['hlsMasterPlaylistUrl']
18
+ print(m3u8_link)
19
+ return m3u8_link
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ bs4
2
+ tmdbv3api
3
+ dateparser
4
+ python-dotenv
5
+ fastapi
6
+ uvicorn
7
+ tzdata
8
+ lxml
9
+ httpx
run.py ADDED
@@ -0,0 +1,228 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException,Request,Query
2
+ from fastapi.responses import JSONResponse
3
+ from filmpertutti import filmpertutti
4
+ from streamingcommunity import streaming_community
5
+ from tantifilm import tantifilm
6
+ from lordchannel import lordchannel
7
+ from streamingwatch import streamingwatch
8
+ import json
9
+ import config
10
+ import logging
11
+ from okru import okru_get_url
12
+ from animeworld import animeworld
13
+ from dictionaries import okru,STREAM,extra_sources,webru_vary,webru_dlhd
14
+ from webru import webru
15
+ import httpx
16
+ # Configure logging
17
+ FILMPERTUTTI = config.FILMPERTUTTI
18
+ STREAMINGCOMMUNITY = config.STREAMINGCOMMUNITY
19
+ MYSTERIUS = config.MYSTERIUS
20
+ TUTTIFILM = config.TUTTIFILM
21
+ TF_DOMAIN = config.TF_DOMAIN
22
+ LORDCHANNEL = config.LORDCHANNEL
23
+ STREAMINGWATCH= config.STREAMINGWATCH
24
+ ANIMEWORLD = config.ANIMEWORLD
25
+ HOST = config.HOST
26
+ PORT = int(config.PORT)
27
+ HF = config.HF
28
+ if HF == "1":
29
+ HF = "🤗️"
30
+ #Cool code to set the hugging face if the service is hosted there.
31
+ else:
32
+ HF = ""
33
+ if MYSTERIUS == "1":
34
+ from cool import cool
35
+
36
+ app = FastAPI()
37
+ MANIFEST = {
38
+ "id": "org.stremio.mammamia",
39
+ "version": "1.0.5",
40
+ "catalogs": [
41
+ {
42
+ "type": "tv",
43
+ "id": "tv_channels",
44
+ "name": "TV Channels",
45
+ "extra": [
46
+ {
47
+ "name": "genre",
48
+ "isRequired": False,
49
+ "options": ["Rai", "Mediaset", "Sky", "Euronews", "La7", "Warner Bros", "FIT", "Sportitalia","RSI","DAZN", "Rakuten", "Pluto", "A+E", "Paramount", "Chill"]
50
+ }
51
+ ]
52
+ }
53
+ ],
54
+ "resources": ["stream", "catalog", "meta"],
55
+ "types": ["movie", "series", "tv"],
56
+ "name": "Mamma Mia",
57
+ "description": "Addon providing HTTPS Streams for Italian Movies, Series, and Live TV! Note that you need to have Kitsu Addon installed in order to watch Anime",
58
+ "logo": "https://creazilla-store.fra1.digitaloceanspaces.com/emojis/49647/pizza-emoji-clipart-md.png"
59
+ }
60
+
61
+
62
+
63
+ def respond_with(data):
64
+ resp = JSONResponse(data)
65
+ resp.headers['Access-Control-Allow-Origin'] = '*'
66
+ resp.headers['Access-Control-Allow-Headers'] = '*'
67
+ return resp
68
+
69
+ @app.get('/manifest.json')
70
+ def addon_manifest():
71
+ return respond_with(MANIFEST)
72
+
73
+ @app.get('/')
74
+ def root():
75
+ return "Hello, this is a Stremio Addon providing HTTPS Stream for Italian Movies/Series, to install it add /manifest.json to the url and then add it into the Stremio search bar"
76
+
77
+ def addon_catalog(type: str, id: str, genre: str = None):
78
+ print(f"Received genre parameter: {genre}")
79
+ if type != "tv":
80
+ raise HTTPException(status_code=404)
81
+
82
+ catalogs = {"metas": []}
83
+
84
+ for channel in STREAM["channels"]:
85
+ if genre and genre not in channel.get("genres", []):
86
+ continue # Skip channels that don't match the selected genre
87
+
88
+ catalogs["metas"].append({
89
+ "id": channel["id"],
90
+ "type": "tv",
91
+ "name": channel["title"],
92
+ "poster": channel["poster"], # Add poster URL if available
93
+ "description": f"Watch {channel['title']}",
94
+ "genres": channel.get("genres", [])
95
+ })
96
+
97
+ return catalogs
98
+ @app.get('/catalog/{type}/{id}.json')
99
+ def first_catalog(type: str, id: str, genre: str = None):
100
+ catalogs = addon_catalog(type, id,genre)
101
+ return respond_with(catalogs)
102
+
103
+ @app.get('/catalog/{type}/{id}/genre={genre}.json')
104
+ def first_catalog(type: str, id: str, genre: str = None):
105
+ catalogs = addon_catalog(type, id,genre)
106
+ return respond_with(catalogs)
107
+
108
+ @app.get('/meta/tv/{id}.json')
109
+ def addon_meta(id: str):
110
+ # Find the channel by ID
111
+ channel = next((ch for ch in STREAM['channels'] if ch['id'] == id), None)
112
+
113
+ if not channel:
114
+ raise HTTPException(status_code=404, detail="Channel not found")
115
+
116
+ meta = {
117
+ 'meta': {
118
+ 'id': channel['id'],
119
+ 'type': 'tv',
120
+ 'name': channel['name'],
121
+ 'poster': channel['poster'],
122
+ 'posterShape': 'landscape',
123
+ 'description': channel['title'],
124
+ # Additional fields can be added here
125
+ 'background': channel['poster'], # Example of using the same poster as background
126
+ 'logo': channel['poster'],
127
+ 'genres': channel.get('genres', []), # Example of using the same poster as logo
128
+ }
129
+ }
130
+ if 'url' in channel:
131
+ meta['meta']['url'] = channel['url'] # Using the stream URL as a website link
132
+ return respond_with(meta)
133
+
134
+
135
+ @app.get('/stream/{type}/{id}.json')
136
+ async def addon_stream(type, id):
137
+ if type not in MANIFEST['types']:
138
+ raise HTTPException(status_code=404)
139
+ streams = {'streams': []}
140
+ async with httpx.AsyncClient() as client:
141
+ if type == "tv":
142
+ for channel in STREAM["channels"]:
143
+ if channel["id"] == id:
144
+ i = 0
145
+ if 'url' in channel:
146
+ i = i+1
147
+ streams['streams'].append({
148
+ 'title': f"Server {i} " + f" "+ channel['name'] + " " + channel['title'] ,
149
+ 'url': channel['url']
150
+ })
151
+ if id in okru:
152
+ i = i+1
153
+ channel_url = await okru_get_url(id,client)
154
+ streams['streams'].append({
155
+ 'title': f"Server {i} " + channel['title'] + " OKRU",
156
+ 'url': channel_url
157
+ })
158
+ if id in extra_sources:
159
+ list_sources = extra_sources[id]
160
+ for item in list_sources:
161
+ i = i+1
162
+ streams['streams'].append({'title':f"Server {i} " + channel['title'],'url': item})
163
+ if id in webru_vary:
164
+ i = i+1
165
+ webru_url = await webru(id,"vary",client)
166
+ streams['streams'].append({'title': f"Server {i} " + channel['title'],'url': webru_url})
167
+ if not streams['streams']:
168
+ raise HTTPException(status_code=404)
169
+ return respond_with(streams)
170
+ else:
171
+ logging.debug(f"Handling movie or series: {id}")
172
+ if "kitsu" in id:
173
+ if ANIMEWORLD == "1":
174
+ animeworld_urls = await animeworld(id,client)
175
+ print(animeworld_urls)
176
+ if animeworld_urls:
177
+ i = 0
178
+ for url in animeworld_urls:
179
+ if url:
180
+ if i == 0:
181
+ title = "Original"
182
+ elif i == 1:
183
+ title = "Italian"
184
+ streams['streams'].append({'title': f'{HF}Animeworld {title}', 'url': url})
185
+ i+=1
186
+ else:
187
+ if MYSTERIUS == "1":
188
+ results = await cool(id,client)
189
+ if results:
190
+ for resolution, link in results.items():
191
+ streams['streams'].append({'title': f'{HF}Mysterious {resolution}', 'url': link})
192
+ if STREAMINGCOMMUNITY == "1":
193
+ url_streaming_community,url_720_streaming_community,quality_sc = await streaming_community(id,client)
194
+ if url_streaming_community is not None:
195
+ if quality_sc == "1080":
196
+ streams['streams'].append({'title': f'{HF}StreamingCommunity 1080p Max', 'url': url_streaming_community})
197
+ streams['streams'].append({'title': f'{HF}StreamingCommunity 720p Max', 'url': url_720_streaming_community})
198
+ else:
199
+ streams['streams'].append({'title': f'{HF}StreamingCommunity 720p Max', 'url': url_streaming_community})
200
+ if LORDCHANNEL == "1":
201
+ url_lordchannel,quality_lordchannel = await lordchannel(id,client)
202
+ if quality_lordchannel == "FULL HD" and url_lordchannel != None:
203
+ streams['streams'].append({'title': f'{HF}LordChannel 1080p', 'url': url_lordchannel})
204
+ elif url_lordchannel != None:
205
+ streams['streams'].append({'title': f'{HF}LordChannel 720p', 'url': url_lordchannel})
206
+ if FILMPERTUTTI == "1":
207
+ url_filmpertutti = await filmpertutti(id,client)
208
+ if url_filmpertutti is not None:
209
+ streams['streams'].append({'title': 'Filmpertutti', 'url': url_filmpertutti})
210
+ if TUTTIFILM == "1":
211
+ url_tuttifilm = await tantifilm(id,client)
212
+ if url_tuttifilm:
213
+ if not isinstance(url_tuttifilm, str):
214
+ for title, url in url_tuttifilm.items():
215
+ streams['streams'].append({'title': f'{HF}Tantifilm {title}', 'url': url, 'behaviorHints': {'proxyHeaders': {"request": {"Referer": "https://d000d.com/"}}, 'notWebReady': True}})
216
+ if STREAMINGWATCH == "1":
217
+ url_streamingwatch = await streamingwatch(id,client)
218
+ if url_streamingwatch:
219
+ streams['streams'].append({'title': f'{HF}StreamingWatch 720p', 'url': url_streamingwatch})
220
+ if not streams['streams']:
221
+ raise HTTPException(status_code=404)
222
+
223
+ return respond_with(streams)
224
+
225
+
226
+ if __name__ == '__main__':
227
+ import uvicorn
228
+ uvicorn.run("run:app", host=HOST, port=PORT, log_level="info")
streamingcommunity.py ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from tmdbv3api import TMDb, Movie, TV
2
+ import logging
3
+ from bs4 import BeautifulSoup,SoupStrainer
4
+ from datetime import datetime
5
+ import dateparser
6
+ from convert import get_TMDb_id_from_IMDb_id
7
+ from info import get_info_tmdb, is_movie, get_info_imdb
8
+ import config
9
+ import json
10
+ import re
11
+ from urllib.parse import urlparse, parse_qs
12
+
13
+ #Get domain
14
+ SC_DOMAIN= config.SC_DOMAIN
15
+ SC_FAST_SEARCH = config.SC_FAST_SEARCH
16
+
17
+ headers = {
18
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.10; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
19
+ 'Accept-Language': 'en-US,en;q=0.5'
20
+ }
21
+
22
+ #GET VERSION OF STREAMING COMMUNITY:
23
+ async def get_version(client):
24
+ #Extract the version from the main page of the site
25
+
26
+
27
+ try:
28
+ base_url = f'https://streamingcommunity.{SC_DOMAIN}/richiedi-un-titolo'
29
+ response = await client.get(base_url, headers=headers, follow_redirects=True)
30
+ #Soup the response
31
+ soup = BeautifulSoup(response.text, "lxml")
32
+
33
+ # Extract version
34
+ version = json.loads(soup.find("div", {"id": "app"}).get("data-page"))['version']
35
+ return version
36
+ except:
37
+ print("Couldn't find the version")
38
+ version = "65e52dcf34d64173542cd2dc6b8bb75b"
39
+ return version
40
+
41
+ async def search(query,date,ismovie, client):
42
+ #Do a request to get the ID of serie/move and it's slug in the URL
43
+ response = await client.get(query, follow_redirects=True)
44
+ response = response.json()
45
+
46
+ for item in response['data']:
47
+ tid = item['id']
48
+ slug = item['slug']
49
+ type = item['type']
50
+ if type == "tv":
51
+ type = 0
52
+ elif type == "movie":
53
+ type = 1
54
+ if type == ismovie:
55
+ #Added a Check to see if the result is what it is supposed to be
56
+ if SC_FAST_SEARCH == "0":
57
+ if ismovie == 0:
58
+ response = await client.get ( f'https://streamingcommunity.{SC_DOMAIN}/titles/{tid}-{slug}', follow_redirects=True)
59
+ pattern = r'<div[^>]*class="features"[^>]*>.*?<span[^>]*>(.*?)<\/span>'
60
+ match = re.search(pattern, response.text)
61
+ print(match.group(1).split("-")[0])
62
+ first_air_year = match.group(1).split("-")[0]
63
+ date = int(date)
64
+ first_air_year = int(first_air_year)
65
+ if first_air_year == date:
66
+ return tid,slug
67
+ elif ismovie == 1:
68
+ return tid,slug
69
+ elif SC_FAST_SEARCH == "1":
70
+ return tid,slug
71
+ else:
72
+ print("Couldn't find anything")
73
+
74
+
75
+ async def get_film(tid,version,client):
76
+ headers = {
77
+ 'user-agent': "Mozilla/5.0 (Windows NT 10.10; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537",
78
+ 'x-inertia': 'true',
79
+ #Version of streaming community
80
+ 'x-inertia-version': version
81
+ }
82
+ #Access the iframe
83
+ url = f'https://streamingcommunity.{SC_DOMAIN}/iframe/{tid}'
84
+ response = await client.get(url, headers=headers, follow_redirects=True)
85
+ iframe = BeautifulSoup(response.text, 'lxml')
86
+ #Get the link of iframe
87
+ iframe = iframe.find('iframe').get("src")
88
+ #Get the ID containted in the src of iframe
89
+ vixid = iframe.split("/embed/")[1].split("?")[0]
90
+ parsed_url = urlparse(iframe)
91
+ query_params = parse_qs(parsed_url.query)
92
+ #Get real token and expires by looking at the page in the iframe, vixcloud/embed
93
+ resp = await client.get(iframe, headers = headers, follow_redirects=True)
94
+ soup= BeautifulSoup(resp.text, "lxml")
95
+ script = soup.find("body").find("script").text
96
+ token = re.search(r"'token':\s*'(\w+)'", script).group(1)
97
+ expires = re.search(r"'expires':\s*'(\d+)'", script).group(1)
98
+ quality = re.search(r'"quality":(\d+)', script).group(1)
99
+ #Example url https://vixcloud.co/playlist/231315?b=1&token=bce060eec3dc9d1965a5d258dc78c964&expires=1728995040&rendition=1080p
100
+ url = f'https://vixcloud.co/playlist/{vixid}?token={token}&expires={expires}'
101
+ if 'canPlayFHD' in query_params:
102
+ canPlayFHD = 'h=1'
103
+ url += "&h=1"
104
+ if 'b' in query_params:
105
+ b = 'b=1'
106
+ url += "&b=1"
107
+ url720 = f'https://vixcloud.co/playlist/{vixid}'
108
+ return url,url720,quality,
109
+
110
+ async def get_season_episode_id(tid,slug,season,episode,version,client):
111
+ #Set some basic headers for the request
112
+ headers = {
113
+ 'user-agent': "Mozilla/5.0 (Windows NT 10.10; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
114
+ 'x-inertia': 'true',
115
+ #Version of streaming community
116
+ 'x-inertia-version': version
117
+ }
118
+ #Get episode ID
119
+ response = await client.get(f'https://streamingcommunity.{SC_DOMAIN}/titles/{tid}-{slug}/stagione-{season}', headers=headers, follow_redirects=True)
120
+ # Print the json got
121
+ json_response = response.json().get('props', {}).get('loadedSeason', {}).get('episodes', [])
122
+ for dict_episode in json_response:
123
+ if dict_episode['number'] == episode:
124
+ return dict_episode['id']
125
+
126
+ async def get_episode_link(episode_id,tid,version,client):
127
+ #The parameters for the request
128
+ params = {
129
+ 'episode_id': episode_id,
130
+ 'next_episode': '1'
131
+ }
132
+ #Let's try to get the link from iframe source
133
+ # Make a request to get iframe source
134
+ response = await client.get(f"https://streamingcommunity.{SC_DOMAIN}/iframe/{tid}", params=params, follow_redirects=True)
135
+
136
+ # Parse response with BeautifulSoup to get iframe source
137
+ soup = BeautifulSoup(response.text, "lxml")
138
+ iframe = soup.find("iframe").get("src")
139
+ vixid = iframe.split("/embed/")[1].split("?")[0]
140
+ headers = {
141
+ 'user-agent': "Mozilla/5.0 (Windows NT 10.10; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537",
142
+ 'x-inertia': 'true',
143
+ #Version of streaming community
144
+ 'x-inertia-version': version
145
+ }
146
+ parsed_url = urlparse(iframe)
147
+ query_params = parse_qs(parsed_url.query)
148
+ #Get real token and expires by looking at the page in the iframe, vixcloud/embed
149
+ resp = await client.get(iframe, headers = headers, follow_redirects=True)
150
+ soup= BeautifulSoup(resp.text, "lxml")
151
+ script = soup.find("body").find("script").text
152
+ token = re.search(r"'token':\s*'(\w+)'", script).group(1)
153
+ expires = re.search(r"'expires':\s*'(\d+)'", script).group(1)
154
+ quality = re.search(r'"quality":(\d+)', script).group(1)
155
+ #Example url https://vixcloud.co/playlist/231315?b=1&token=bce060eec3dc9d1965a5d258dc78c964&expires=1728995040&rendition=1080p
156
+ url = f'https://vixcloud.co/playlist/{vixid}?token={token}&expires={expires}'
157
+ if 'canPlayFHD' in query_params:
158
+ canPlayFHD = 'h=1'
159
+ url += "&h=1"
160
+ if 'b' in query_params:
161
+ b = 'b=1'
162
+ url += "&b=1"
163
+ url720 = f'https://vixcloud.co/playlist/{vixid}'
164
+ return url,url720,quality
165
+
166
+
167
+ async def streaming_community(imdb,client):
168
+ try:
169
+ general = is_movie(imdb)
170
+ ismovie = general[0]
171
+ imdb_id = general[1]
172
+ type = "StreamingCommunity"
173
+ if ismovie == 0 :
174
+ season = int(general[2])
175
+ episode = int(general[3])
176
+ #Check if fast search is enabled or disabled
177
+ if SC_FAST_SEARCH == "1":
178
+ if "tt" in imdb:
179
+ #Get showname
180
+ showname = await get_info_imdb(imdb_id,ismovie,type,client)
181
+ date = None
182
+ else:
183
+ #I just set n season to None to avoid bugs, but it is not needed if Fast search is enabled
184
+ date = None
185
+ #else just equals them
186
+ tmdba = imdb_id.replace("tmdb:","")
187
+ showname = get_info_tmdb(tmdba,ismovie,type)
188
+ elif SC_FAST_SEARCH == "0":
189
+ tmdba = await get_TMDb_id_from_IMDb_id(imdb_id,client)
190
+ showname,date = get_info_tmdb(tmdba,ismovie,type)
191
+ #HERE THE CASE IF IT IS A MOVIE
192
+ else:
193
+ if "tt" in imdb:
194
+ #Get showname
195
+ date = None
196
+ showname = await get_info_imdb(imdb_id,ismovie,type,client)
197
+ else:
198
+ date = None
199
+ tmdba = imdb_id.replace("tmdb:","")
200
+ showname = get_info_tmdb(tmdba,ismovie,type)
201
+
202
+ showname = showname.replace(" ", "+").replace("–", "+").replace("—","+")
203
+ query = f'https://streamingcommunity.{SC_DOMAIN}/api/search?q={showname}'
204
+ tid,slug = await search(query,date,ismovie,client)
205
+ version = await get_version(client)
206
+ if ismovie == 1:
207
+ #TID means temporaly ID
208
+ url,url720,quality = await get_film(tid,version,client)
209
+ print(url)
210
+ return url,url720,quality
211
+ if ismovie == 0:
212
+ #Uid = URL ID
213
+ episode_id = await get_season_episode_id(tid,slug,season,episode,version,client)
214
+ url,url720,quality = await get_episode_link(episode_id,tid,version,client)
215
+ print(url)
216
+ return url,url720,quality
217
+ except Exception as e:
218
+ print("StreamingCommunity failed")
219
+ return None,None,None
streamingwatch.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from tmdbv3api import TMDb, Movie, TV
2
+ import requests
3
+ import logging
4
+ from bs4 import BeautifulSoup,SoupStrainer
5
+ from datetime import datetime
6
+ import dateparser
7
+ from convert import get_TMDb_id_from_IMDb_id
8
+ from info import get_info_tmdb, is_movie, get_info_imdb
9
+ import config
10
+ import re
11
+ import json
12
+ SW_DOMAIN = config.SW_DOMAIN
13
+ async def search(showname,season,episode,date,ismovie,client):
14
+ if ismovie == 1:
15
+ query = f'https://www.streamingwatch.{SW_DOMAIN}/wp-admin/admin-ajax.php'
16
+ headers = {
17
+ 'authority': f'www.streamingwatch.{SW_DOMAIN}',
18
+ 'accept': '*/*',
19
+ 'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7',
20
+ 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
21
+ # 'cookie': 'wordpress_test_cookie=WP%20Cookie%20check',
22
+ 'origin': f'https://www.streamingwatch.{SW_DOMAIN}',
23
+ 'referer': f'https://www.streamingwatch.{SW_DOMAIN}',
24
+ 'sec-ch-ua': '"Not-A.Brand";v="99", "Chromium";v="124"',
25
+ 'sec-ch-ua-mobile': '?0',
26
+ 'sec-ch-ua-platform': '"Android"',
27
+ 'sec-fetch-dest': 'empty',
28
+ 'sec-fetch-mode': 'cors',
29
+ 'sec-fetch-site': 'same-origin',
30
+ 'user-agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
31
+ 'x-requested-with': 'XMLHttpRequest',
32
+ }
33
+ data = {
34
+ 'action': 'data_fetch',
35
+ 'keyword': showname,
36
+ '_wpnonce': '648328b831',
37
+ }
38
+ cookies = {
39
+ 'wordpress_test_cookie': 'WP%20Cookie%20check',
40
+ }
41
+ response = await client.post(query,cookies=cookies, headers=headers, data=data)
42
+ soup = BeautifulSoup(response.content,'lxml')
43
+ page_date = soup.find(id = 'search-cat-year').text.strip()
44
+ if page_date == date:
45
+ href = soup.find('a')['href']
46
+ response = await client.get(href, follow_redirects=True)
47
+ soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('iframe'))
48
+ iframe = soup.find('iframe')
49
+ hdplayer = iframe.get('data-lazy-src')
50
+
51
+ return hdplayer
52
+ elif ismovie == 0:
53
+ #Some series have the name in english so we first search with the categories option and then we use the obtained ID to get all the episodes
54
+ id_response = await client.get(f'https://streamingwatch.{SW_DOMAIN}/wp-json/wp/v2/categories?search={showname}&_fields=id', follow_redirects=True)
55
+ data = json.loads(id_response.text)
56
+ category_id = data[0]['id']
57
+ query = f'https://streamingwatch.{SW_DOMAIN}/wp-json/wp/v2/posts?categories={category_id}&per_page=100'
58
+ response = await client.get(query, follow_redirects=True)
59
+ data_json = response.text
60
+ data = json.loads(data_json)
61
+ for entry in data:
62
+ if f"stagione-{season}-episodio-{episode}" in entry["slug"]:
63
+ content = entry["content"]["rendered"]
64
+ #"content":{
65
+ # "rendered":"<p><!--baslik:PRO--><iframe loading=\"lazy\" src=\"https:\/\/hdplayer.gives\/embed\/YErLVq64uNTZRNz\" frameborder=\"0\" width=\"700\" height=\"400\" allowfullscreen><\/iframe><\/p>\n","protected":false}
66
+ start = content.find('src="') + len('src="') #start of url
67
+ end = content.find('"', start) #end of url
68
+ hdplayer = content[start:end]
69
+ return hdplayer
70
+ async def hls_url(hdplayer,client):
71
+ response = await client.get(hdplayer, follow_redirects=True)
72
+ match = re.search(r'sources:\s*\[\s*\{\s*file\s*:\s*"([^"]*)"', response.text)
73
+ url = match.group(1)
74
+ print(url)
75
+ return url
76
+ async def streamingwatch(imdb,client):
77
+ try:
78
+ general = is_movie(imdb)
79
+ ismovie = general[0]
80
+ imdb_id = general[1]
81
+ type = "StreamingWatch"
82
+ if ismovie == 0:
83
+ season = int(general[2])
84
+ episode = int(general[3])
85
+ if "tt" in imdb:
86
+ tmdba = await get_TMDb_id_from_IMDb_id(imdb_id,client)
87
+ else:
88
+ tmdba = imdb_id
89
+ else:
90
+ season = None
91
+ episode = None
92
+ if "tt" in imdb:
93
+ tmdba = await get_TMDb_id_from_IMDb_id(imdb_id,client)
94
+ else:
95
+ tmdba = imdb_id
96
+ showname,date = get_info_tmdb(tmdba,ismovie,type)
97
+ showname = showname.replace(" ", "+").replace("–", "+").replace("—","+")
98
+ hdplayer = await search(showname,season,episode,date,ismovie,client)
99
+ url = await hls_url(hdplayer,client)
100
+ return url
101
+ except:
102
+ print("StreamingWatch Failed")
103
+ return None
tantifilm.py ADDED
@@ -0,0 +1,267 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ from bs4 import BeautifulSoup,SoupStrainer
3
+ import re
4
+ import time
5
+ from info import is_movie,get_info_imdb,get_info_tmdb
6
+ import config
7
+ from loadenv import load_env
8
+ TF_FAST_SEARCH = config.TF_FAST_SEARCH
9
+ TF_DOMAIN = config.TF_DOMAIN
10
+ HF = config.HF
11
+ env_vars = load_env()
12
+ PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
13
+
14
+
15
+ async def search(showname,ismovie,date,client):
16
+ url = f'https://www.tanti.{TF_DOMAIN}/search/{showname}'
17
+ response = await client.get(url, follow_redirects=True)
18
+ soup = BeautifulSoup(response.text, "lxml")
19
+ if ismovie == 1:
20
+ all_link = soup.select('#movies .col .list-media')
21
+ for link in all_link:
22
+ url = link['href']
23
+ response = client.get(url, follow_redirects=True)
24
+ pattern = r'Data di rilascio\s*</div>\s*<div class="text">\s*(\d{4})\s*</div>'
25
+ found_date = re.search(pattern, response.text)
26
+ release_date = str(found_date.group(1))
27
+ if release_date == date:
28
+ tid= url.split('-')[-1]
29
+ #Return URL and even the soup so I can use it later
30
+ #I try to get doodstream link inside this function so I do not have to get again the response
31
+ return tid,url
32
+ elif ismovie == 0:
33
+ all_link = soup.select('#series .col .list-media')
34
+ for link in all_link:
35
+ base_url = link['href']
36
+ url = f'{base_url}-1-season-1-episode'
37
+ response = await client.get(url, follow_redirects=True)
38
+ pattern = r'Data di rilascio\s*</div>\s*<div class="text">\s*(\d{4})\s*</div>'
39
+ found_date = re.search(pattern, response.text)
40
+ release_date = str(found_date.group(1))
41
+ if release_date == date:
42
+ tid= url.split('-')[1]
43
+ soup = BeautifulSoup(response.text, 'lxml')
44
+ a_tag = soup.find('a', class_='dropdown-toggle btn-service selected')
45
+ embed_id = a_tag['data-embed']
46
+ #I try to get doodstream link inside this function so I do not have to get again the response
47
+ return url,embed_id
48
+
49
+ async def fast_search(showname,ismovie,client):
50
+ url = f'https://www.tanti.{TF_DOMAIN}/search/{showname}'
51
+ response = await client.get(url, follow_redirects=True)
52
+ soup = BeautifulSoup(response.text, "lxml")
53
+ if ismovie == 1:
54
+ first_link = soup.select_one('#movies .col .list-media')
55
+ url = first_link['href']
56
+ tid= url.split('-')[1]
57
+ return tid,url
58
+ elif ismovie == 0:
59
+ first_link = soup.select_one('#series .col .list-media')
60
+ base_url = first_link['href']
61
+ url = f'{base_url}-1-season-1-episode'
62
+ response = await client.get(url, follow_redirects=True)
63
+ soup = BeautifulSoup(response.text, 'lxml')
64
+ a_tag = soup.find('a', class_='dropdown-toggle btn-service selected')
65
+ embed_id = a_tag['data-embed']
66
+ return url,embed_id
67
+
68
+
69
+
70
+ async def get_protect_link(id,url,client):
71
+ #Get the link where the Iframe is located, which contains the doodstream url kind of.
72
+ response = await client.get(f"https://p.hdplayer.casa/myadmin/play.php?id={id}", follow_redirects=True)
73
+ soup = BeautifulSoup(response.text, "lxml", parse_only=SoupStrainer('iframe'))
74
+ protect_link = soup.iframe['src']
75
+ if "protect" in protect_link:
76
+ return protect_link
77
+ else:
78
+ #DO this in case the movie has a 3D version etc
79
+ response = await client.get(url, follow_redirects=True)
80
+ soup = BeautifulSoup(response.text, 'lxml')
81
+ a_tag = soup.find('a', class_='dropdown-toggle btn-service selected')
82
+ embed_id = a_tag['data-embed']
83
+ headers = {
84
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
85
+ 'Referer': url
86
+ }
87
+ #Parameters needed is the embed ID
88
+ data = {
89
+ 'id': embed_id
90
+ }
91
+ ajax_url = f"https://www.tanti.{TF_DOMAIN}/ajax/embed"
92
+ response = await client.post(ajax_url, headers=headers, data=data)
93
+ hdplayer = response.text[43:-27]
94
+ response = await client.get(hdplayer, follow_redirects=True)
95
+ soup = BeautifulSoup(response.text, 'lxml')
96
+ links_dict = {}
97
+ li_tags = soup.select('ul.nav.navbar-nav li.dropdown')
98
+ for li_tag in li_tags:
99
+ a_tag = li_tag.find('a')
100
+ if a_tag:
101
+ title = a_tag.text.strip()
102
+ #Since tantifilm player is broken I just skip it
103
+ if title == "1" or "Tantifilm" in title:
104
+ continue # Get the text of the <a> tag
105
+ href = a_tag['href']
106
+ response = await client.get(href, follow_redirects=True)
107
+ soup = BeautifulSoup(response.text, "lxml", parse_only=SoupStrainer('iframe'))
108
+ protect_link = soup.iframe['src']
109
+ if "protect" in protect_link:
110
+ url = true_url(protect_link)
111
+ links_dict[title] = url
112
+ return links_dict
113
+ # Get the value of the href attribute
114
+
115
+
116
+ async def get_nuovo_indirizzo_and_protect_link(url,embed_id,season,episode,client):
117
+ headers = {
118
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
119
+ 'Referer': url
120
+ }
121
+ #Parameters needed is the embed ID
122
+ data = {
123
+ 'id': embed_id
124
+ }
125
+ ajax_url = f"https://www.tanti.{TF_DOMAIN}/ajax/embed"
126
+ response = await client.post(ajax_url, headers=headers, data=data)
127
+ nuovo_indirizzo = response.text[43:-27]
128
+ response = await client.get(nuovo_indirizzo, follow_redirects=True)
129
+ soup = BeautifulSoup(response.text, 'lxml')
130
+ #Get season
131
+ season = season - 1
132
+ li_tags = soup.select('ul.nav.navbar-nav > li.dropdown')
133
+ if len(li_tags) != 1:
134
+ link = li_tags[season].find('a')['href']
135
+ response = await client.get(link, follow_redirects=True)
136
+ soup = BeautifulSoup(response.text, 'lxml')
137
+ option_tag = soup.select(f'select[name="ep_select"] > option:nth-of-type({episode})')[0]
138
+ link = option_tag['value']
139
+ #Let's find protect link now
140
+ response = await client.get(link, follow_redirects=True)
141
+ soup = BeautifulSoup(response.text, "lxml", parse_only=SoupStrainer('iframe'))
142
+ protect_link = soup.iframe['src']
143
+ return protect_link
144
+
145
+ else:
146
+ #If there is only one season than
147
+ option_tag = soup.select('select.dynamic_select > option')[episode]
148
+ link = option_tag['value']
149
+ #Let's find protect link now
150
+ response = await client.get(link, follow_redirects=True)
151
+ soup = BeautifulSoup(response.text, "lxml", parse_only=SoupStrainer('iframe'))
152
+ protect_link = soup.iframe['src']
153
+ return protect_link
154
+
155
+
156
+ async def true_url(protect_link,client):
157
+ print(protect_link)
158
+ # Define headers
159
+ headers = {
160
+ "Range": "bytes=0-",
161
+ "Referer": "https://d000d.com/",
162
+ }
163
+ if HF == "1":
164
+ proxy = PROXY_CREDENTIALS
165
+ proxies = {
166
+ "http": proxy,
167
+ "https": proxy
168
+ }
169
+ response = await client.get(protect_link, proxies=proxies, follow_redirects=True)
170
+ else:
171
+ response = await client.get(protect_link, follow_redirects=True)
172
+ link = response.url
173
+
174
+
175
+ if response.status_code == 200:
176
+ # Get unique timestamp for the request
177
+ real_time = str(int(time.time()))
178
+
179
+ # Regular Expression Pattern for the match
180
+ pattern = r"(\/pass_md5\/.*?)'.*(\?token=.*?expiry=)"
181
+
182
+ # Find the match
183
+ match = re.search(pattern, response.text, re.DOTALL)
184
+
185
+ # If a match was found
186
+ if match:
187
+ # Create real link (match[0] includes all matched elements)
188
+ url =f'https://d000d.com{match[1]}'
189
+ print("MD5: ", url)
190
+ rebobo = await client.get(url, headers=headers, follow_redirects=True)
191
+ real_url = f'{rebobo.text}123456789{match[2]}{real_time}'
192
+ print(real_url)
193
+ return real_url
194
+ else:
195
+ print("No match found in the text.")
196
+ return None
197
+
198
+ print("Error: Could not get the response.")
199
+ return None
200
+
201
+
202
+
203
+ #Get temporaly ID
204
+ async def tantifilm(imdb,client):
205
+ urls = None
206
+ try:
207
+ general = is_movie(imdb)
208
+ ismovie = general[0]
209
+ imdb_id = general[1]
210
+ type = "Tuttifilm"
211
+ if ismovie == 0 :
212
+ season = int(general[2])
213
+ episode = int(general[3])
214
+ if "tt" in imdb:
215
+ if TF_FAST_SEARCH == "0":
216
+ showname,date = await get_info_imdb(imdb_id,ismovie,type,client)
217
+ url,embed_id = await search(showname,ismovie,date,client)
218
+ elif TF_FAST_SEARCH == "1":
219
+ showname = await get_info_imdb(imdb_id,ismovie,type,client)
220
+ url,embed_id = await fast_search(showname,ismovie,client)
221
+ else:
222
+ #else just equals them
223
+ tmdba = imdb_id.replace("tmdb:","")
224
+ if TF_FAST_SEARCH == "0":
225
+ showname,date = get_info_tmdb(tmdba,ismovie,type)
226
+ url,embed_id = await search(showname,ismovie,date,client)
227
+ elif TF_FAST_SEARCH == "1":
228
+ showname= get_info_tmdb(tmdba,ismovie,type)
229
+ url,embed_id = await fast_search(showname,ismovie,client)
230
+ protect_link = await get_nuovo_indirizzo_and_protect_link(url,embed_id,season,episode,client)
231
+ url = await true_url(protect_link,client)
232
+ return url
233
+ elif ismovie == 1:
234
+ if "tt" in imdb:
235
+ #Get showname
236
+ if TF_FAST_SEARCH == "0":
237
+ showname,date = await get_info_imdb(imdb_id,ismovie,type,client)
238
+ tid,url = await search(showname,ismovie,date,client)
239
+ elif TF_FAST_SEARCH == "1":
240
+ showname = await get_info_imdb(imdb_id,ismovie,type,client)
241
+ date = None
242
+ tid,url = await fast_search(showname,ismovie,client)
243
+ else:
244
+
245
+ #else just equals themtantifilm("tt2096673")
246
+
247
+ if TF_FAST_SEARCH == "0":
248
+ showname,date = get_info_tmdb(imdb,ismovie,type)
249
+ tid,url = await search(showname,ismovie,date,client)
250
+ elif TF_FAST_SEARCH == "1":
251
+ showname = get_info_tmdb(imdb,ismovie,type)
252
+ tid,url = await fast_search(showname,ismovie,client)
253
+ protect_link = await get_protect_link(tid,url,client)
254
+ if not isinstance(protect_link, str):
255
+ urls = protect_link
256
+ if urls:
257
+ return urls
258
+ else:
259
+ print("Tantifilm Error v2")
260
+ else:
261
+ url = await true_url(protect_link,client)
262
+ if url:
263
+ return url
264
+
265
+ except Exception as e:
266
+ print("Tantifilm Error: ", e)
267
+ return None
webru.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import httpx
2
+ import random
3
+ from dictionaries import webru_vary,webru_dlhd
4
+ Referer = "https://ilovetoplay.xyz/"
5
+ Origin = "https://ilovetoplay.xyz"
6
+ headers = {
7
+ "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0",
8
+ "Accept": "*/*",
9
+ "Accept-Language": "en-US,en;q=0.5",
10
+ "Accept-Encoding": "gzip, deflate, br, zstd",
11
+ "Origin": Origin,
12
+ "DNT": "1",
13
+ "Sec-GPC": "1",
14
+ "Connection": "keep-alive",
15
+ "Referer": Referer,
16
+ "Sec-Fetch-Dest": "empty",
17
+ "Sec-Fetch-Mode": "cors",
18
+ "Sec-Fetch-Site": "cross-site",
19
+ "Pragma": "no-cache",
20
+ "Cache-Control": "no-cache",
21
+ }
22
+
23
+ async def get_stream_link(id,site,client):
24
+ if site == "dlhd":
25
+ m3u8_url = webru_dlhd[id]
26
+ elif site == "vary":
27
+ m3u8_url = webru_vary[id]
28
+ response = await client.get(m3u8_url, headers=headers, follow_redirects=False)
29
+ if response.status_code == 301:
30
+ stream_url = response.headers.get("Location", "")
31
+ return stream_url,Referer,Origin
32
+ async def webru(id,site,client):
33
+ stream_url, Referer,Origin = await get_stream_link(id,site,client)
34
+ mediaproxy = ["https://lorempizza-mediamammamia1.hf.space/","https://lorempizza-mediamammamia2.hf.space/", "https://lorempizza-mediamammamia3.hf.space/", "https://lorempizza-mediamammamia4.hf.space/", "https://lorempizza-mediamammamia5.hf.space/", "https://lorempizza-mediamammamia6.hf.space/", "https://lorempizza-mediamammamia7.hf.space/", "https://lorempizza-mediamammamia8.hf.space/", "https://lorempizza-mediamammamia9.hf.space/", "https://lorempizza-mediamammamia10.hf.space/"]
35
+ medialink = random.choice(mediaproxy)
36
+ new_stream_url = f'{medialink}proxy/hls?key_url=https%3A%2F%2Fkey.mizhls.ru%2F&api_password=MammaMia!09&d={stream_url}&h_Referer={Referer}&h_Origin={Origin}&h_User-Agent=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F58.0.3029.110%20Safari%2F537.3'
37
+ print(new_stream_url)
38
+ return new_stream_url