diff --git a/.gitignore b/.gitignore index 66d3ae4..75d42a1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .env __pycache__/ .vercel +beamup.json \ No newline at end of file diff --git a/Dockerfiles/Dockerfile-auto-update b/Dockerfiles/Dockerfile-auto-update index 9566eb4..b60881b 100644 --- a/Dockerfiles/Dockerfile-auto-update +++ b/Dockerfiles/Dockerfile-auto-update @@ -1,23 +1,15 @@ -##Use an official Python runtime as a parent image FROM python:3.11-slim-bullseye -# Set the working directory in the container to /app WORKDIR /app -# Install git RUN apt-get update && apt-get install -y git -# Clone the repository -RUN git clone https://github.com/vitouchiha/MammaMia.git . +RUN git clone https://github.com/UrloMythus/MammaMia.git . -# Copy the local config.json file to the container COPY config.json /app/config.json -# Install any needed packages specified in requirements.txt RUN pip install --no-cache-dir -r requirements.txt -# Expose the port, for now default is 8080 cause it's the only one really allowed by HuggingFace EXPOSE 8080 -# Run run.py when the container launches -ENTRYPOINT ["python", "run.py"] +ENTRYPOINT ["python", "run.py"] \ No newline at end of file diff --git a/Dockerfiles/Dockerfile-auto-update-no-config b/Dockerfiles/Dockerfile-auto-update-no-config index bcbb4c9..44d074a 100644 --- a/Dockerfiles/Dockerfile-auto-update-no-config +++ b/Dockerfiles/Dockerfile-auto-update-no-config @@ -1,21 +1,14 @@ -#Use an official Python runtime as a parent image FROM python:3.11-slim-bullseye -# Set the working directory in the container to /app WORKDIR /app -# Install git RUN apt-get update && apt-get install -y git -# Clone the repository -RUN git clone https://github.com/vitouchiha/MammaMia.git . +RUN git clone https://github.com/UrloMythus/MammaMia.git . -# Install any needed packages specified in requirements.txt RUN pip install --no-cache-dir -r requirements.txt -# Expose the port, for now default is 8080 cause it's the only one really allowed by HuggingFace EXPOSE 8080 -# Run run.py when the container launches -ENTRYPOINT ["python", "run.py"] +ENTRYPOINT ["python", "run.py"] \ No newline at end of file diff --git a/Src/API/cb01.py b/Src/API/cb01.py index d7770ef..f1a1c86 100644 --- a/Src/API/cb01.py +++ b/Src/API/cb01.py @@ -6,6 +6,8 @@ from fake_headers import Headers import Src.Utilities.config as config from Src.Utilities.loadenv import load_env from Src.API.extractors.mixdrop import mixdrop +from Src.API.extractors.maxstream import maxstream +from Src.API.extractors.uprot import bypass_uprot import logging from Src.Utilities.config import setup_logging level = config.LEVEL @@ -13,6 +15,8 @@ logger = setup_logging(level) CB_DOMAIN = config.CB_DOMAIN CB_PROXY = config.CB_PROXY MX_PROXY = config.MX_PROXY +Icon = config.Icon +Name = config.Name proxies = {} proxies2 = {} env_vars = load_env() @@ -70,7 +74,21 @@ async def get_stayonline(link,client): real_url = response.json()['data']['value'] return real_url +async def get_maxstream(link,streams,client): + if 'stayonline' in link: + uprot_link = await get_stayonline(link,client) + else: + uprot_link = link + maxstream_link = await bypass_uprot(client,uprot_link) + if maxstream_link: + streams = await maxstream(maxstream_link,client,streams,'CB01','',proxies2,ForwardProxy) + else: + if maxstream_link == False: + return streams + else: + streams['streams'].append({'name': f"{Name}",'title': f'{Icon}CB01\n▶️ Please do the captcha at /uprot in order to be able to play this content! \n Remember to refresh the sources!\nIf you recently did the captcha then dont worry, just refresh the sources', 'url': 'https://github.com/UrloMythus/MammaMia', 'behaviorHints': { 'bingeGroup': 'cb01'}}) + return streams async def search_movie(showname,date,client): try: showname = showname.replace(" ","+").replace("ò","o").replace("è","e").replace("à","a").replace("ù","u").replace("ì","i") @@ -94,7 +112,7 @@ async def search_movie(showname,date,client): match = year_pattern.search(date_text) if match: year = match.group(0) - if year == date : # Check if the year is 2011 + if year == date : return href except Exception as e: logger.warning(f'MammaMia: Error in search_series cb01: {e}') @@ -116,7 +134,6 @@ async def search_series(showname,date,client): # Find the link inside the current card link_tag = card.find('h3', class_='card-title').find('a') href = link_tag['href'] - # Find the date span and extract possible years date_span = card.find('span', style=re.compile('color')) if date_span: @@ -125,7 +142,7 @@ async def search_series(showname,date,client): match = year_pattern.search(date_text) if match: year = match.group(0) - if year == date : # Check if the year is 2011 + if (int(year) - int(date)) == 0 or (int(year)-int(date)) == 1 or (int(year)-int(date)) == -1 : # Check if the year is 2011 return href except Exception as e: logger.warning(f'MammaMia: Error in search_series cb01: {e}') @@ -136,35 +153,54 @@ async def movie_redirect_url(link,client,MFP,MFP_CREDENTIALS,streams): # Extract the redirect URL from the HTML soup = BeautifulSoup(response.text, "lxml",parse_only=SoupStrainer('div')) redirect_url = soup.find("div", id="iframen2").get("data-src") + redirect_url_2 = soup.find("div", id="iframen1").get("data-src") if "stayonline" in redirect_url: mixdrop_real_link = await get_stayonline(redirect_url,client) - streams = await mixdrop(mixdrop_real_link,client,MFP,MFP_CREDENTIALS,streams,"CB01",proxies,ForwardProxy,"") - + streams,status = await mixdrop(mixdrop_real_link,client,MFP,MFP_CREDENTIALS,streams,"CB01",proxies,ForwardProxy,"") + if status == False: + streams = await get_maxstream(redirect_url_2,streams,client) return streams + +async def series_search_streams(text,search_text,response_text,headers,season,episode,client,MFP,MFP_CREDENTIALS,streams): + if "A" in text: + captcha = re.search(rf'{search_text}.*?href="([^"]+)',response_text,re.DOTALL) + if captcha: + response = await client.get(ForwardProxy + captcha.group(1), headers = headers, allow_redirects = True, proxies = proxies) + season = season.zfill(2) + match = re.search(rf"(S{season}E{episode}|{season}x{episode}).+?href='([^']+)",response.text) + print(match.group(2)) + if match: + streams = await get_maxstream(match.group(2),streams,client) + else: + match = re.search(rf'{season}×{episode}\s*–\s*]*href="[^"]*"[^>]*>[^<]*\s– ]*href="[^"]*',response_text) + if match: + links = match.group(0) + soup = BeautifulSoup(links,'lxml',parse_only=SoupStrainer('a')) + host_links = soup.find_all('a') + mixdrop_real_link = await get_stayonline(host_links[1]['href'],client) + status = False + #streams,status = await mixdrop(mixdrop_real_link,client,MFP,MFP_CREDENTIALS,streams,"CB01",proxies,ForwardProxy,"") + if status == False: + streams = await get_maxstream(host_links[0]['href'],streams,client) + return streams async def series_redirect_url(link,season,episode,client,MFP,MFP_CREDENTIALS,streams): - if len(episode) == 1: - episode = f'0{episode}' + episode = episode.zfill(2) headers = fake_headers.generate() response = await client.get(ForwardProxy + link, headers=headers, allow_redirects=True, timeout=10, proxies = proxies) - soup = BeautifulSoup(response.text, "lxml") + soup = BeautifulSoup(response.text, "lxml") seasons_text = soup.find_all('div', class_='sp-head') for season_text in seasons_text: text = season_text.text + search_text = season_text.text if f'STAGIONE' in text and f'{season}' in text: text = text.replace("STAGIONE","").replace("ITA", "") - if "A" in text: - return streams - else: - episode = episode.zfill(2) - match = re.search(rf'{season}×{episode}\s*–\s*]*href="[^"]*"[^>]*>[^<]*\s– ]*href="[^"]*',response.text) - if match: - links = match.group(0) - soup = BeautifulSoup(links,'lxml',parse_only=SoupStrainer('a')) - mixdrop_a = soup.find_all('a')[1] - mixdrop_link = mixdrop_a['href'] - mixdrop_real_link = await get_stayonline(mixdrop_link,client) - streams = await mixdrop(mixdrop_real_link,client,MFP,MFP_CREDENTIALS,streams,"CB01",proxies,ForwardProxy,"") - return streams + streams = await series_search_streams(text,search_text,response.text,headers,season,episode,client,MFP,MFP_CREDENTIALS,streams) + elif f'STAGIONE' in text and 'A' in text.replace("STAGIONE","").replace("ITA", ""): + parts = text.split('STAGIONE ')[1].split(' A ') + num1 = int(parts[0]) + num2 = int(parts[1][0]) + if int(season) in range(num1,num2): + streams = await series_search_streams(text,search_text,response.text,headers,season,episode,client,MFP,MFP_CREDENTIALS,streams) return streams @@ -219,8 +255,7 @@ async def cb01(streams,id,MFP,MFP_CREDENTIALS,client): async def test_animeworld(): from curl_cffi.requests import AsyncSession async with AsyncSession() as client: - # Replace with actual id, for example 'anime_id:episode' format - test_id = "tt32360916:1:1" # This is an example ID format + test_id = "tt0158552:1:2" # This is an example ID format MFP = "0" results = await cb01({'streams': []},test_id,MFP,['test','test'],client) print(results) diff --git a/Src/API/cookie.txt b/Src/API/cookie.txt index 0435bbe..0cccc34 100644 --- a/Src/API/cookie.txt +++ b/Src/API/cookie.txt @@ -1 +1 @@ -{'PHPSESSID': 'aq7rf8gu6nd9fuk0r711899blp', 'captch4': 'bc3c5526ddc7d0a3ad827e7848f5678f'} \ No newline at end of file +{'PHPSESSID': '351o0p0f00aaa7m0rughtn63og', 'captch5': 'e6cf235e0bcfee6044841d9dc4a7ea82'} \ No newline at end of file diff --git a/Src/API/eurostreaming.py b/Src/API/eurostreaming.py index e87e59e..38bc3c3 100644 --- a/Src/API/eurostreaming.py +++ b/Src/API/eurostreaming.py @@ -5,6 +5,8 @@ from urllib.parse import quote from Src.Utilities.loadenv import load_env from Src.API.extractors.mixdrop import mixdrop from Src.API.extractors.deltabit import deltabit +from Src.API.extractors.maxstream import maxstream +from Src.API.extractors.uprot import bypass_uprot import re import logging from Src.Utilities.config import setup_logging @@ -49,6 +51,18 @@ else: ForwardProxy = "" +async def get_maxstream(uprot_link,streams,language,client): + maxstream_link = await bypass_uprot(client,uprot_link) + if maxstream_link: + streams = await maxstream(maxstream_link,client,streams,'Eurostreaming',language,proxies,ForwardProxy) + else: + if maxstream_link == False: + return streams + else: + streams['streams'].append({'name': f"{Name}",'title': f'{Icon}Eurostreaming\n▶️ Please do the captcha at /uprot in order to be able to play this content! \n Remember to refresh the sources!\nIf you recently did the captcha then dont worry, just refresh the sources', 'url': 'https://github.com/UrloMythus/MammaMia', 'behaviorHints': { 'bingeGroup': 'cb01'}}) + + return streams + def convert_numbers(base64_data): image_data = base64.b64decode(base64_data) @@ -117,13 +131,13 @@ async def scraping_links(atag,MFP,MFP_CREDENTIALS,client,streams,language): except Exception as e: pattern = r']*rel="noopener"[^>]*>MixDrop' href = await get_host_link(pattern,atag,client) - streams = await mixdrop(href,client,MFP,MFP_CREDENTIALS,streams,"Eurostreaming",proxies,ForwardProxy,language) + streams,status = await mixdrop(href,client,MFP,MFP_CREDENTIALS,streams,"Eurostreaming",proxies,ForwardProxy,language) return streams if "MixDrop" in atag and "DeltaBit" not in atag: try: pattern = r']*rel="noopener"[^>]*>MixDrop' href = await get_host_link(pattern,atag,client) - streams = await mixdrop(href,client,MFP,MFP_CREDENTIALS,streams,"Eurostreaming",proxies,ForwardProxy,language) + streams,status = await mixdrop(href,client,MFP,MFP_CREDENTIALS,streams,"Eurostreaming",proxies,ForwardProxy,language) return streams except Exception as e: return streams @@ -135,14 +149,24 @@ async def scraping_links(atag,MFP,MFP_CREDENTIALS,client,streams,language): return streams except Exception as e: return streams - if 'DeltaBit' not in atag and 'MixDrop' not in atag: + if 'DeltaBit' not in atag and 'MixDrop' not in atag and 'MaxStream' in atag: + try: + pattern = r']*rel="noopener"[^>]*>MaxStream' + match = re.search(pattern, atag) + if match: + href_value = match.group(1) + streams = await get_maxstream(href_value,streams,language,client) + return streams + except Exception as e: + return streams + if 'DeltaBit' not in atag and 'MixDrop' not in atag and 'MaxStream' not in atag: logger.info("Just give up") return streams async def episodes_find(description,season,episode,MFP,MFP_CREDENTIALS,client,streams): t = 0 episode = episode.zfill(2) - pattern = rf'{season}×{episode}\s*(.*?)(?=)' + pattern = rf'\b{season}×{episode}\s*(.*?)(?=)' match = re.findall(pattern, description) if match: for episode_details in match: @@ -220,7 +244,7 @@ async def eurostreaming(streams,id,client,MFP,MFP_CREDENTIALS): async def test_euro(): from curl_cffi.requests import AsyncSession async with AsyncSession() as client: - results = await eurostreaming({'streams': []},"tt6156584:4:1",client,"0",['test','test']) + results = await eurostreaming({'streams': []},"tt0460681:11:1",client,"0",['test','test']) print(results) diff --git a/Src/API/guardahd.py b/Src/API/guardahd.py index a575d9e..11e70b0 100644 --- a/Src/API/guardahd.py +++ b/Src/API/guardahd.py @@ -40,8 +40,10 @@ async def search(clean_id,client): if response.status_code != 200: logger.warning(f"GuardaHD Failed to fetch search results: {response.status_code}") soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('li')) - li_tag = soup.find('li') - href = "https:" + li_tag['data-link'] + li_tags = soup.find_all('li') + for tag in li_tags: + if 'supervideo' in tag['data-link']: + href = 'https:' + tag['data-link'] return href @@ -64,7 +66,7 @@ async def test_script(): from curl_cffi.requests import AsyncSession async with AsyncSession() as client: # Replace with actual id, for example 'anime_id:episode' format - test_id = "tt16426418" # This is an example ID format + test_id = "tt12300742" # This is an example ID format results = await guardahd({'streams': []},test_id, client) print(results) diff --git a/Src/API/guardaserie.py b/Src/API/guardaserie.py index d7bd5eb..299b4db 100644 --- a/Src/API/guardaserie.py +++ b/Src/API/guardaserie.py @@ -51,7 +51,7 @@ async def search_imdb(clean_id,client): except Exception as e: logger.warning(f'GS {e}') return None - +''' async def search(showname,date,client): try: headers = random_headers.generate() @@ -71,7 +71,7 @@ async def search(showname,date,client): except Exception as e: return None - +''' async def player_url(page_url, season, episode,client): diff --git a/Src/API/guardoserie.py b/Src/API/guardoserie.py index 6223b16..c5c287a 100644 --- a/Src/API/guardoserie.py +++ b/Src/API/guardoserie.py @@ -134,7 +134,7 @@ async def guardoserie(streams,id,client,MFP,MFP_CREDENTIALS): async def test_guardoserie(): from curl_cffi.requests import AsyncSession async with AsyncSession() as client: - results = await guardoserie({'streams': []},"tt10919420:1:1",client,"1",['test','test']) + results = await guardoserie({'streams': []},"tt9165438:3:1",client,"1",['test','test']) print(results) diff --git a/Src/API/legacy/streamingcommunity_legacy.py b/Src/API/legacy/streamingcommunity_legacy.py index e69de29..cf985ad 100644 --- a/Src/API/legacy/streamingcommunity_legacy.py +++ b/Src/API/legacy/streamingcommunity_legacy.py @@ -0,0 +1,341 @@ +from bs4 import BeautifulSoup,SoupStrainer +from Src.Utilities.convert import get_TMDb_id_from_IMDb_id +from Src.Utilities.info import get_info_tmdb, is_movie, get_info_imdb +import Src.Utilities.config as config +import json +import random +import re +from urllib.parse import urlparse, parse_qs +from fake_headers import Headers +from Src.Utilities.loadenv import load_env +from Src.API.extractors.vixcloud import vixcloud +import urllib.parse +User_Agent= "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" + +env_vars = load_env() +SC_PROXY = config.SC_PROXY +VX_PROXY = config.VX_PROXY +proxies = {} +proxies2 = {} +if VX_PROXY == "1": + PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS') + proxy_list = json.loads(PROXY_CREDENTIALS) + proxy = random.choice(proxy_list) + if proxy == "": + proxies2 = {} + else: + proxies2 = { + "http": proxy, + "https": proxy + } +if SC_PROXY == "1": + PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS') + proxy_list = json.loads(PROXY_CREDENTIALS) + proxy = random.choice(proxy_list) + if proxy == "": + proxies = {} + else: + proxies = { + "http": proxy, + "https": proxy + } + if VX_PROXY == "1": + proxies2 = proxies + +SC_ForwardProxy = config.SC_ForwardProxy +VX_ForwardProxy = config.VX_ForwardProxy +if SC_ForwardProxy == "1": + ForwardProxy = env_vars.get('ForwardProxy') +elif VX_ForwardProxy == "1": + ForwardProxy = env_vars.get('ForwardProxy') +else: + ForwardProxy = "" +#Get domain +SC_DOMAIN = config.SC_DOMAIN +Public_Instance = config.Public_Instance +Alternative_Link = env_vars.get('ALTERNATIVE_LINK') +headers = Headers() +#GET VERSION OF STREAMING COMMUNITY: +async def get_version(client): + #Extract the version from the main page of the site + #You can extract it from any page of the site but I chose one of the lightiest + + try: + random_headers = headers.generate() + random_headers['Referer'] = f"{SC_DOMAIN}/" + random_headers['Origin'] = f"{SC_DOMAIN}" + base_url = f'{SC_DOMAIN}/richiedi-un-titolo' + response = await client.get(ForwardProxy + base_url, headers=random_headers, allow_redirects = True, impersonate="chrome124", proxies = proxies) + #Soup the response + soup = BeautifulSoup(response.text, "lxml") + + # Extract version + version = json.loads(soup.find("div", {"id": "app"}).get("data-page"))['version'] + return version + except Exception as e: + print("Couldn't find the version",e) + version = "65e52dcf34d64173542cd2dc6b8bb75b" + return version + +async def search(query,date,ismovie, client,SC_FAST_SEARCH,movie_id): + ''' + This function is used to search for a movie or a show in the Streaming Community website using the API + After it checks if the imdb id given is the same as the one in the website + We need to convert imdb id to tmdb id because often imdb ids are missing + ''' + random_headers = headers.generate() + random_headers['Referer'] = f"{SC_DOMAIN}/" + random_headers['Origin'] = f"{SC_DOMAIN}" + random_headers['Accept'] = 'application/json' # Assuming the API returns JSON + random_headers['Content-Type'] = 'application/json' + #Do a request to get the ID of serie/move and it's slug in the URL + response = await client.get(ForwardProxy + query, headers = random_headers, allow_redirects=True, impersonate = "chrome124", proxies = proxies) + print(response) + response = response.json() + for item in response['data']: + tid = item['id'] + slug = item['slug'] + type = item['type'] + if type == "tv": + type = 0 + elif type == "movie": + type = 1 + if type == ismovie: + #Added a Check to see if the result is what it is supposed to be + if SC_FAST_SEARCH == "0": + random_headers = headers.generate() + random_headers['Referer'] = f"{SC_DOMAIN}/" + random_headers['Origin'] = f"{SC_DOMAIN}" + response = await client.get ( ForwardProxy + f'{SC_DOMAIN}/it/titles/{tid}-{slug}', headers = random_headers, allow_redirects=True,impersonate = "chrome124", proxies = proxies) + soup = BeautifulSoup(response.text, "lxml") + data = json.loads(soup.find("div", {"id": "app"}).get("data-page")) + version = data['version'] + if "tt" in movie_id: + movie_id = str(await get_TMDb_id_from_IMDb_id(movie_id,client)) + print(movie_id) + #Here we need to convert because the IMDB ID is often bugged + tmdb_id = str(data['props']['title']['tmdb_id']) + if tmdb_id == movie_id: + return tid,slug,version + elif SC_FAST_SEARCH == "1": + version = await get_version(client) + return tid,slug,version + else: + print("Couldn't find anything") + + +async def get_film(tid,version,client,MFP): + '''' + This function is used to get the link of the m3u8 from the Streaming Community player,vixcloud + ''' + random_headers = headers.generate() + random_headers['Referer'] = f"{SC_DOMAIN}/" + random_headers['Origin'] = f"{SC_DOMAIN}" + random_headers['x-inertia'] = "true" + random_headers['x-inertia-version'] = version + random_headers['User-Agent'] = User_Agent + random_headers['user-agent'] = User_Agent + #Access the iframe + url = f'{SC_DOMAIN}/it/iframe/{tid}' + if MFP == "1": + url = f'{SC_DOMAIN}/it/iframe/{tid}' + quality = "Unknown" + return url,quality + response = await client.get(ForwardProxy + url, headers=random_headers, allow_redirects=True,impersonate = "chrome124", proxies = proxies) + iframe = BeautifulSoup(response.text, 'lxml') + #Get the link of iframe + iframe = iframe.find('iframe').get("src") + #Get the ID containted in the src of iframe + vixid = iframe.split("/embed/")[1].split("?")[0] + parsed_url = urlparse(iframe) + query_params = parse_qs(parsed_url.query) + random_headers = headers.generate() + random_headers['Referer'] = f"{SC_DOMAIN}/" + random_headers['Origin'] = f"{SC_DOMAIN}" + random_headers['x-inertia'] = "true" + random_headers['x-inertia-version'] = version + random_headers['User-Agent'] = User_Agent + random_headers['user-agent'] = User_Agent + #Get real token and expires by looking at the page in the iframe, vixcloud/embed + resp = await client.get(ForwardProxy + iframe, headers = random_headers, allow_redirects=True,impersonate= "chrome124", proxies = proxies2) + soup= BeautifulSoup(resp.text, "lxml") + script = soup.find("body").find("script").text + token = re.search(r"'token':\s*'(\w+)'", script).group(1) + expires = re.search(r"'expires':\s*'(\d+)'", script).group(1) + quality = re.search(r'"quality":(\d+)', script).group(1) + base_url = re.search(r"url:\s*'(https?://[^']+)'", script).group(1) + #Example url https://vixcloud.co/playlist/231315?b=1&token=bce060eec3dc9d1965a5d258dc78c964&expires=1728995040&rendition=1080p + url = f'https://vixcloud.co/playlist/{vixid}.m3u8?token={token}&expires={expires}' + if 'canPlayFHD' in query_params: + canPlayFHD = 'h=1' + url += "&h=1" + if 'b=1' in base_url: + url += "&b=1" + ''' + if 'b' in query_params: + b = 'b=1' + url += "&b=1" + ''' + ''' + if quality == "1080": + if "&h" in url: + url = url + elif "&b" in url and quality == "1080": + url = url.replace("&b=1","&h=1") + elif quality == "1080" and "&b" and "&h" not in url: + url = url + "&h=1" + else: + url = url + f"&token={token}" + ''' + return url,quality + +async def get_season_episode_id(tid,slug,season,episode,version,client): + ''' + This function is used to get the ID of the episode in the Streaming Community website + ''' + random_headers = headers.generate() + random_headers['Referer'] = f"{SC_DOMAIN}/" + random_headers['Origin'] = f"{SC_DOMAIN}" + random_headers['x-inertia'] = "true" + random_headers['x-inertia-version'] = version + random_headers['accept'] = 'text/html, application/xhtml+xml' + random_headers['accept-language'] = 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7' + + #Set some basic headers for the request + #Get episode ID + response = await client.get(ForwardProxy + f'{SC_DOMAIN}/it/titles/{tid}-{slug}/season-{season}', headers=random_headers, allow_redirects=True, impersonate = "chrome124", proxies = proxies) + # Print the json got + json_response = response.json().get('props', {}).get('loadedSeason', {}).get('episodes', []) + for dict_episode in json_response: + if dict_episode['number'] == episode: + return dict_episode['id'] + + + + + +async def get_episode_link(episode_id,tid,version,client,MFP): + '''' + This function is used to get the link of the m3u8 from the Streaming Community player,vixcloud + ''' + #The parameters for the request + random_headers = headers.generate() + random_headers['Referer'] = f"{SC_DOMAIN}/" + random_headers['Origin'] = f"{SC_DOMAIN}" + random_headers['User-Agent'] = User_Agent + random_headers['user-agent'] = User_Agent + params = { + 'episode_id': episode_id, + 'next_episode': '1' + } + #Let's try to get the link from iframe source + # Make a request to get iframe source + if MFP == "1": + url = f'{SC_DOMAIN}/it/iframe/{tid}?episode_id={episode_id}&next_episode=1' + quality = "Unknown" + return url,quality + response = await client.get(ForwardProxy + f"{SC_DOMAIN}/it/iframe/{tid}", params=params, headers = random_headers, allow_redirects=True, impersonate = "chrome124", proxies = proxies) + + # Parse response with BeautifulSoup to get iframe source + soup = BeautifulSoup(response.text, "lxml") + iframe = soup.find("iframe").get("src") + vixid = iframe.split("/embed/")[1].split("?")[0] + random_headers = headers.generate() + random_headers['Referer'] = f"{SC_DOMAIN}/" + random_headers['Origin'] = f"{SC_DOMAIN}" + random_headers['x-inertia'] = "true" + random_headers['x-inertia-version'] = version + random_headers['User-Agent'] = User_Agent + random_headers['user-agent'] = User_Agent + parsed_url = urlparse(iframe) + query_params = parse_qs(parsed_url.query) + #Get real token and expires by looking at the page in the iframe, vixcloud/embed + resp = await client.get(ForwardProxy + iframe, headers = random_headers, allow_redirects=True, impersonate = "chrome124", proxies = proxies2) + soup= BeautifulSoup(resp.text, "lxml") + script = soup.find("body").find("script").text + token = re.search(r"'token':\s*'(\w+)'", script).group(1) + expires = re.search(r"'expires':\s*'(\d+)'", script).group(1) + quality = re.search(r'"quality":(\d+)', script).group(1) + base_url = re.search(r"url:\s*'(https?://[^']+)'", script).group(1) + + #Example url https://vixcloud.co/playlist/231315?b=1&token=bce060eec3dc9d1965a5d258dc78c964&expires=1728995040&rendition=1080p + url = f'https://vixcloud.co/playlist/{vixid}.m3u8?token={token}&expires={expires}' + if 'canPlayFHD' in query_params: + canPlayFHD = 'h=1' + url += "&h=1" + if 'b=1' in base_url: + b = 'b=1' + url += "&b=1" + ''' + if quality == "1080": + if "&h" in url: + url = url + elif "&b" in url and quality == "1080": + url = url.replace("&b=1","&h=1") + elif quality == "1080" and "&b" and "&h" not in url: + url = url + "&h=1" + else: + url = url + f"&token={token}" + ''' + return url,quality + + +async def streamingcommunity_site(imdb,client,SC_FAST_SEARCH,MFP): + general = await is_movie(imdb) + ismovie = general[0] + imdb_id = general[1] + if ismovie == 0 : + season = int(general[2]) + episode = int(general[3]) + #Check if fast search is enabled or disabled + if SC_FAST_SEARCH == "1": + type = "StreamingCommunityFS" + if "tt" in imdb: + #Get showname + showname = await get_info_imdb(imdb_id,ismovie,type,client) + date = None + else: + #I just set n season to None to avoid bugs, but it is not needed if Fast search is enabled + date = None + #else just equals them + tmdba = imdb_id.replace("tmdb:","") + showname = get_info_tmdb(tmdba,ismovie,type) + elif SC_FAST_SEARCH == "0": + type = "StreamingCommunity" + if "tt" in imdb: + tmdba = await get_TMDb_id_from_IMDb_id(imdb_id,client) + showname,date = get_info_tmdb(tmdba,ismovie,type) + #HERE THE CASE IF IT IS A MOVIE + else: + if SC_FAST_SEARCH == "1": + type = "StreamingCommunityFS" + if "tt" in imdb: + #Get showname + date = None + showname = await get_info_imdb(imdb_id,ismovie,type,client) + else: + date = None + tmdba = imdb_id.replace("tmdb:","") + showname = get_info_tmdb(tmdba,ismovie,type) + elif SC_FAST_SEARCH == "0": + type = "StreamingCommunity" + if "tt" in imdb: + #Get showname + showname,date = await get_info_imdb(imdb_id,ismovie,type,client) + else: + tmdba = imdb_id.replace("tmdb:","") + showname,date = get_info_tmdb(tmdba,ismovie,type) + showname = showname.replace(" ", "+").replace("–", "+").replace("—","+") + showname = urllib.parse.quote_plus(showname) + query = f'{SC_DOMAIN}/api/search?q={showname}' + tid,slug,version = await search(query,date,ismovie,client,SC_FAST_SEARCH,imdb_id) + if ismovie == 1: + #TID means temporaly ID + url,quality = await get_film(tid,version,client,MFP) + print("MammaMia found results for StreamingCommunity") + return url,quality,slug + if ismovie == 0: + #Uid = URL ID + episode_id = await get_season_episode_id(tid,slug,season,episode,version,client) + url,quality = await get_episode_link(episode_id,tid,version,client,MFP) + return url,quality,slug \ No newline at end of file diff --git a/Src/API/streamingwatch.py b/Src/API/legacy/streamingwatch.py similarity index 100% rename from Src/API/streamingwatch.py rename to Src/API/legacy/streamingwatch.py diff --git a/Src/API/streamingcommunity.py b/Src/API/streamingcommunity.py index 0df48a2..c4fba8b 100644 --- a/Src/API/streamingcommunity.py +++ b/Src/API/streamingcommunity.py @@ -87,7 +87,7 @@ async def test_vixsrc(): async with AsyncSession() as client: # Replace with actual id, for example 'anime_id:episode' format test_id = "tt6468322:1:1" # This is an example ID format - results = await streaming_community(test_id, client,"0","0") + results = await streaming_community({'streams': []},test_id, client,"0",['test','welp']) print(results) if __name__ == "__main__": diff --git a/Src/API/toonitalia.py b/Src/API/toonitalia.py new file mode 100644 index 0000000..d2ac13a --- /dev/null +++ b/Src/API/toonitalia.py @@ -0,0 +1,121 @@ +from fake_headers import Headers + +random_headers = Headers() + +import Src.Utilities.config as config + +from Src.Utilities.info import get_info_imdb,get_info_tmdb +from urllib.parse import quote +from Src.Utilities.convert import get_IMDB_id_from_TMDb_id +from Src.Utilities.info import get_info_tmdb, is_movie, get_info_imdb +from Src.API.extractors.voe import voe +from Src.API.extractors.maxstream import maxstream +import logging +from Src.Utilities.config import setup_logging +level = config.LEVEL +import re + +import random +logger = setup_logging(level) +from Src.Utilities.loadenv import load_env +env_vars = load_env() +TI_DOMAIN = config.TI_DOMAIN + +TI_PROXY = config.TI_PROXY +proxies = {} +if TI_PROXY == "1": + PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS') + proxy_list = json.loads(PROXY_CREDENTIALS) + proxy = random.choice(proxy_list) + if proxy == "": + proxies = {} + else: + proxies = { + "http": proxy, + "https": proxy + } +TI_ForwardProxy = config.TI_ForwardProxy +if TI_ForwardProxy == "1": + ForwardProxy = env_vars.get('ForwardProxy') +else: + ForwardProxy = "" + + + + + +async def search(showname,date,season,episode,MFP,MFP_CREDENTIALS,ismovie,client,streams): + headers = random_headers.generate() + response = await client.get(ForwardProxy + f'{TI_DOMAIN}/wp-json/wp/v2/search?search={quote(showname)}',headers=headers, proxies = proxies) + data = response.json() + for item in data: + response = await client.get(ForwardProxy + item['_links']['self'][0]['href'],headers=headers, proxies = proxies) + info = response.json() + html = info['content']['rendered'] + if 'Stagione' in html and ismovie == 1: + continue + if 'Stagione' not in html and ismovie == 0: + continue + if ismovie == 0: + episode = episode.zfill(2) + pattern = rf'{season}×{episode}.*?]*href="([^"]*)' + if ismovie == 1: + pattern = r'Link.*href="([^"]*)(?=.*VOE)' + match = re.search(pattern,html) + if match: + url = match.group(1) + if 'maxstream' in url: + parts = url.split('.video/') + url = 'https://maxstream.video/emvvv/' + parts[1] + streams = await maxstream(url,client,streams,'ToonItalia','',proxies,ForwardProxy) + else: + streams = await voe(url,streams,'ToonItalia',MFP,MFP_CREDENTIALS,proxies,ForwardProxy,client) + return streams + + + + + + + + + + + + + + +async def toonitalia(streams,id,client,MFP,MFP_CREDENTIALS): + try: + general = await is_movie(id) + ismovie = general[0] + clean_id = general[1] + type = "Toonitalia" + if ismovie == 0 : + season = str(general[2]) + episode = str(general[3]) + elif ismovie == 1: + season = None + episode = None + if "tmdb" in id: + showname,date = get_info_tmdb(clean_id,ismovie,type) + else: + showname,date = await get_info_imdb(clean_id,ismovie,type,client) + streams = await search(showname,date, season,episode,MFP,MFP_CREDENTIALS,ismovie,client,streams) + return streams + except Exception as e: + print(e) + return streams + + + +async def test_toonitalia(): + from curl_cffi.requests import AsyncSession + async with AsyncSession() as client: + results = await toonitalia({'streams': []},"tt1466074:1:1",client,"0",['test','test']) + print(results) + + +if __name__ == "__main__": + import asyncio + asyncio.run(test_toonitalia()) \ No newline at end of file diff --git a/Src/Utilities/config.py b/Src/Utilities/config.py index 4255a78..7ddde7b 100644 --- a/Src/Utilities/config.py +++ b/Src/Utilities/config.py @@ -9,7 +9,6 @@ with open('config.json') as f: # Accessing SC_DOMAIN SITE = config["Siti"] SC_DOMAIN = SITE["StreamingCommunity"]['url'] -SW_DOMAIN = SITE["StreamingWatch"]['url'] AW_DOMAIN = SITE['AnimeWorld']['url'] CB_DOMAIN = SITE['CB01']['url'] GS_DOMAIN = SITE['Guardaserie']['url'] @@ -18,8 +17,8 @@ ES_DOMAIN = SITE['Eurostreaming']['url'] GF_DOMAIN = SITE['Guardaflix']['url'] GO_DOMAIN = SITE['Guardoserie']['url'] RT_DOMAIN = SITE['Realtime']['url'] +TI_DOMAIN = SITE['Toonitalia']['url'] SC = SITE['StreamingCommunity']['enabled'] -SW = SITE['StreamingWatch']['enabled'] AW = SITE['AnimeWorld']['enabled'] CB = SITE['CB01']['enabled'] GS = SITE['Guardaserie']['enabled'] @@ -28,6 +27,7 @@ ES= SITE['Eurostreaming']['enabled'] GF = SITE['Guardaflix']['enabled'] GO = SITE['Guardoserie']['enabled'] RT = SITE['Realtime']['enabled'] +TI = SITE['Toonitalia']['enabled'] SC_ForwardProxy = SITE['StreamingCommunity']["SC_ForwardProxy"] GS_ForwardProxy = SITE['Guardaserie']["GS_ForwardProxy"] GH_ForwardProxy = SITE['GuardaHD']["GH_ForwardProxy"] @@ -38,8 +38,9 @@ CB_ForwardProxy = SITE['CB01']["CB_ForwardProxy"] ES_ForwardProxy = SITE['Eurostreaming']['ES_ForwardProxy'] GF_ForwardProxy = SITE['Guardaflix']['GF_ForwardProxy'] GO_ForwardProxy = SITE['Guardoserie']['GO_ForwardProxy'] -SW_ForwardProxy = SITE['StreamingWatch']['SW_ForwardProxy'] RT_ForwardProxy = SITE['Realtime']['RT_ForwardProxy'] + +TI_ForwardProxy = SITE['Toonitalia']['TI_ForwardProxy'] GS_PROXY = SITE['Guardaserie']["GS_PROXY"] GH_PROXY = SITE['GuardaHD']["GH_PROXY"] CB_PROXY = SITE['CB01']["CB_PROXY"] @@ -50,8 +51,13 @@ MX_PROXY = SITE['CB01']["MX_PROXY"] ES_PROXY = SITE['Eurostreaming']['ES_PROXY'] GF_PROXY = SITE['Guardaflix']['GF_PROXY'] GO_PROXY = SITE['Guardoserie']['GO_PROXY'] -SW_PROXY = SITE['StreamingWatch']['SW_PROXY'] RT_PROXY = SITE['Realtime']['RT_PROXY'] +TI_PROXY = SITE['Toonitalia']['TI_PROXY'] +#Captcha +CAPTCHA = config['Captcha'] +UT_ForwardProxy = CAPTCHA['Uprot']['UT_ForwardProxy'] +UT_PROXY = CAPTCHA['Uprot']['UT_PROXY'] + #General GENERAL = config['General'] dotenv = GENERAL["load_env"] diff --git a/Src/Utilities/dictionaries.py b/Src/Utilities/dictionaries.py index cea4ed1..bfcacf3 100644 --- a/Src/Utilities/dictionaries.py +++ b/Src/Utilities/dictionaries.py @@ -445,7 +445,6 @@ provider_map = { 'SC': 'STREAMINGCOMMUNITY', 'SC_MFP': 'SC_MFP', 'LC': 'LORDCHANNEL', - 'SW': 'STREAMINGWATCH', 'TF_FS': 'TF_FAST_SEARCH', 'TF': 'TANTIFILM', # Assuming 'TF' should also be handled 'FT': 'FILMPERTUTTI', @@ -458,5 +457,6 @@ provider_map = { "ES": "EUROSTREAMING", "GO": "GUARDOSERIE", "RT": "REALTIME", + "TI": "TOONITALIA", "GF": "GUARDAFLIX" } \ No newline at end of file diff --git a/Src/Utilities/eval.py b/Src/Utilities/eval.py index 3a02af7..a2507b3 100644 --- a/Src/Utilities/eval.py +++ b/Src/Utilities/eval.py @@ -153,7 +153,7 @@ async def eval_solver(stream_link,proxies, ForwardProxy, client): for i in script_all: if detect(i.text): unpacked_code = unpack(i.text) - if "mixdrop" in stream_link: + if "xdrop" in stream_link: pattern = r'MDCore.wurl ?= ?"(.*?)"' else: diff --git a/Src/Utilities/info.py b/Src/Utilities/info.py index 5f4cb44..93ae2bf 100644 --- a/Src/Utilities/info.py +++ b/Src/Utilities/info.py @@ -64,6 +64,10 @@ def get_info_tmdb(tmbda,ismovie,type): elif type == 'Realtime': date = show.first_air_date return showname,date + elif type == 'Toonitalia': + date = show.first_air_date + date = date.split("-")[0] + return showname,date elif ismovie == 1: movie = Movie() @@ -115,6 +119,10 @@ def get_info_tmdb(tmbda,ismovie,type): elif type == 'Realtime': date = show.release_date return showname,date + elif type == "Toonitalia": + date = show.release_date + date = date.split("-")[0] + return showname,date async def get_info_imdb(imdb_id, ismovie, type,client): resp = await client.get(f'https://api.themoviedb.org/3/find/{imdb_id}?api_key={TMDB_KEY}&language=it&external_source=imdb_id') data = resp.json() @@ -164,6 +172,10 @@ async def get_info_imdb(imdb_id, ismovie, type,client): return showname,date elif type == 'Realtime': return showname,data['tv_results'][0]['first_air_date'] + elif type == "Toonitalia": + date = data['tv_results'][0]['first_air_date'] + date = date.split("-")[0] + return showname,date elif ismovie == 1: showname= data['movie_results'][0]['title'] @@ -206,6 +218,10 @@ async def get_info_imdb(imdb_id, ismovie, type,client): elif type == 'Realtime': date = data['movie_results'][0]['release_date'] return showname,date + elif type == 'Toonitalia': + date = data['movie_results'][0]['release_date'] + date = date.split("-")[0] + return showname,date diff --git a/beamup.json b/beamup.json index ea9e31f..4e895b2 100644 --- a/beamup.json +++ b/beamup.json @@ -1,4 +1,4 @@ { - "projectName": "MammaMia", - "lastCommit": "ca1df98" + "projectName": "mammamia", + "lastCommit": "58af5b8" } \ No newline at end of file diff --git a/config.json b/config.json index 7a90ab2..c93f3f9 100644 --- a/config.json +++ b/config.json @@ -8,14 +8,8 @@ "VX_PROXY": "0", "enabled": "1" }, - "StreamingWatch":{ - "url": "https://www.streamingwatch.org", - "SW_PROXY": "0", - "SW_ForwardProxy": "0", - "enabled":"1" - }, "CB01":{ - "url": "https://cb01net.cam", + "url": "https://cb01.uno", "CB_PROXY":"0", "CB_ForwardProxy":"0", "MX_ForwardProxy":"0", @@ -23,7 +17,7 @@ "enabled":"1" }, "Guardaserie":{ - "url": "https://guardaserietv.help", + "url": "https://guardaserietv.asia", "enabled":"1", "GS_ForwardProxy":"0", "GS_PROXY":"0" @@ -35,19 +29,19 @@ "GH_PROXY":"0" }, "Eurostreaming":{ - "url": "https://eurostreamings.vip/", + "url": "https://eurostreamings.life", "enabled": "1", "ES_ForwardProxy": "0", "ES_PROXY": "0" }, "Guardaflix":{ - "url": "https://guardaflix.wtf", + "url": "https://guardaplay.blog", "enabled": "1", "GF_ForwardProxy": "0", "GF_PROXY": "0" }, "Guardoserie":{ - "url": "https://guardoserie.wtf", + "url": "https://guardoserie.blog", "enabled": "1", "GO_ForwardProxy": "0", "GO_PROXY": "0" @@ -63,10 +57,22 @@ "enabled": "1", "RT_ForwardProxy": "0", "RT_PROXY": "0" + }, + "Toonitalia": { + "url": "https://toonitalia.xyz", + "enabled": "1", + "TI_ForwardProxy": "0", + "TI_PROXY": "0" } }, + "Captcha":{ + "Uprot": { + "UT_ForwardProxy": "0", + "UT_PROXY": "0" + } + }, "General":{ - "load_env": "0", + "load_env": "1", "HOST": "0.0.0.0", "PORT": 8080, "Name": "MammaMia", diff --git a/requirements.txt b/requirements.txt index f88049d..c63a41d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,4 +10,5 @@ slowapi curl_cffi fake-headers pycryptodome -rich \ No newline at end of file +rich +python-multipart \ No newline at end of file diff --git a/run.py b/run.py index 4cf6c77..1e82567 100644 --- a/run.py +++ b/run.py @@ -1,14 +1,12 @@ -from fastapi import FastAPI, HTTPException,Request +from fastapi import FastAPI, HTTPException,Request, Form,Cookie from fastapi.responses import JSONResponse,RedirectResponse,HTMLResponse from slowapi import Limiter from slowapi.util import get_remote_address from slowapi.middleware import SlowAPIMiddleware from static.static import HTML from static.configure import CONFIGURE - - +from fastapi.templating import Jinja2Templates from Src.API.streamingcommunity import streaming_community -from Src.API.streamingwatch import streamingwatch from Src.API.cb01 import cb01 from Src.API.guardaserie import guardaserie from Src.API.guardahd import guardahd @@ -16,12 +14,13 @@ from Src.API.animeworld import animeworld from Src.API.guardaflix import guardaflix from Src.API.guardoserie import guardoserie from Src.API.eurostreaming import eurostreaming +from Src.API.toonitalia import toonitalia from Src.API.realtime import search_catalog as realtime from Src.API.realtime import meta_catalog as meta_catalog_realtime from Src.API.realtime import realtime as streams_realtime from Src.Utilities.dictionaries import STREAM,extra_sources,provider_map from Src.API.epg import tivu, tivu_get,epg_guide,convert_bho_1,convert_bho_2,convert_bho_3 - +from Src.API.extractors.uprot import get_uprot_numbers,generate_uprot_txt import logging from urllib.parse import unquote from curl_cffi.requests import AsyncSession @@ -47,7 +46,6 @@ else: # Configure config SC = config.SC SC_DOMAIN = config.SC_DOMAIN -SW = config.SW AW = config.AW CB = config.CB GS = config.GS @@ -56,6 +54,7 @@ ES = config.ES GF = config.GF GO = config.GO RT = config.RT +TI = config.TI HOST = config.HOST PORT = int(config.PORT) if env_vars.get('PORT_ENV'): @@ -68,6 +67,9 @@ limiter = Limiter(key_func=get_remote_address) app.state.limiter = limiter app.add_middleware(SlowAPIMiddleware) User_Agent= "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" +#Tells Where to look for static files +static = Jinja2Templates(directory="static") + MANIFEST = { "id": "org.stremio.mammamia", "version": "2.0.0", @@ -145,7 +147,7 @@ def addon_manifest(config: str): @app.get('/manifest.json') def manifest(): - return RedirectResponse(url="/|SC|LC|SW|/manifest.json") + return RedirectResponse(url="/|SC|LC|/manifest.json") @app.get('/', response_class=HTMLResponse) def root(request: Request): @@ -301,8 +303,6 @@ async def addon_stream(request: Request,config, type, id,): else: SC_MFP = '0' streams = await streaming_community(streams,id,client,SC_MFP,MFP_CREDENTIALS) - if provider_maps['STREAMINGWATCH'] == "1" and SW == "1": - streams = await streamingwatch(streams,id,client) if provider_maps['CB01'] == "1" and CB == "1": streams = await cb01(streams,id,MFP,MFP_CREDENTIALS,client) if provider_maps['GUARDASERIE'] == "1" and GS == "1": @@ -317,12 +317,33 @@ async def addon_stream(request: Request,config, type, id,): streams = await guardoserie(streams,id,client,MFP,MFP_CREDENTIALS) if provider_maps['REALTIME'] == '1' and RT == '1': streams = await streams_realtime(streams,id,client) + if provider_maps['TOONITALIA'] == '1' and TI == '1': + streams = await toonitalia(streams,id,client,MFP,MFP_CREDENTIALS) return respond_with(streams) if not streams['streams']: raise HTTPException(status_code=404) return respond_with(streams) +@app.get('/uprot') +async def uprot(request: Request): + async with AsyncSession(proxies = proxies) as client: + image, cookies = await get_uprot_numbers(client) + response = static.TemplateResponse('uprot.html',{'request':request,"image_url": image}) + response.set_cookie(key='PHPSESSID', value=cookies['PHPSESSID'],httponly=True) + + return response +@app.post("/uprot") +async def execute_uprot(request: Request,user_input = Form(...),PHPSESSID: str = Cookie(None)): + async with AsyncSession(proxies = proxies) as client: + cookies = { + 'PHPSESSID': PHPSESSID + } + status = await generate_uprot_txt(user_input,cookies,client) + if status == True: + response = static.TemplateResponse('uprot.html',{'request':request,"image_url": 'https://tinyurl.com/doneokdone'}) + elif status == False: + return static.TemplateResponse('uprot.html',{'request':request,"image_url": 'https://tinyurl.com/tryagaindumb'}) if __name__ == '__main__': import uvicorn diff --git a/static/configure.py b/static/configure.py index 1bc9a96..8137f28 100644 --- a/static/configure.py +++ b/static/configure.py @@ -180,18 +180,13 @@ CONFIGURE = """ Mamma Mia - v2.0.2 + v2.1.0 This addon provides Movie, Series, Anime, and Live TV HTTPS Streams. https://github.com/UrloMythus/MammaMia/ 🕵️♂️ = Mediaflowproxy might be needed Select the box with this icon if you want to enable MFP for that source Select Providers: - - - StreamingWatch - - Guardoserie @@ -235,11 +230,17 @@ CONFIGURE = """ Eurostreaming 🕵️♂️ + + + Toonitalia + + Realtime + LiveTV @@ -276,7 +277,6 @@ CONFIGURE = """ let manifest = "|"; const providers = { "streamingcommunity": "SC", - "streamingwatch": "SW", "animeworld": "AW", "livetv": "LIVETV", "cb01": "CB", @@ -286,6 +286,7 @@ CONFIGURE = """ "guardaflix": "GF", "eurostreaming": "ES", "realtime": "RT", + "toonitalia": "TI", "streamingcommunity_mfp": "SC_MFP", "mediaflowproxy": "MFP" }; diff --git a/static/static.py b/static/static.py index 05a3726..75d0cc1 100644 --- a/static/static.py +++ b/static/static.py @@ -180,18 +180,13 @@ HTML = """ Mamma Mia - v2.0.2 + v2.1.0 This addon provides Movie, Series, Anime, and Live TV HTTPS Streams. https://github.com/UrloMythus/MammaMia/ 🕵️♂️ = Mediaflowproxy might be needed Select the box with this icon if you want to enable MFP for that source Select Providers: - - - StreamingWatch - - Guardoserie @@ -235,11 +230,17 @@ HTML = """ Eurostreaming 🕵️♂️ + + + Toonitalia + + Realtime + LiveTV @@ -276,7 +277,6 @@ HTML = """ let manifest = "|"; const providers = { "streamingcommunity": "SC", - "streamingwatch": "SW", "animeworld": "AW", "livetv": "LIVETV", "cb01": "CB", @@ -286,6 +286,7 @@ HTML = """ "guardaflix": "GF", "eurostreaming": "ES", "realtime": "RT", + "toonitalia": "TI", "streamingcommunity_mfp": "SC_MFP", "mediaflowproxy": "MFP" }; diff --git a/static/uprot.html b/static/uprot.html new file mode 100644 index 0000000..596bfbd --- /dev/null +++ b/static/uprot.html @@ -0,0 +1,128 @@ + + + + + + Mamma Mia + + Fast Search Example + + + + + + + + Uprot Captcha + Per abilitare MaxStream + + Inserire i numeri in foto per abilitare la fonte MaxStream per la durata di un giorno https://github.com/UrloMythus/MammaMia/ + + + + + + Submit + + + + + \ No newline at end of file
🕵️♂️ = Mediaflowproxy might be needed Select the box with this icon if you want to enable MFP for that source