MammaMia version 2.0.0

This commit is contained in:
UrloMythus
2025-09-15 17:31:03 +02:00 Unverified
parent 87d5253580
commit 1ac0869350
47 changed files with 1513 additions and 1241 deletions
+2 -7
View File
@@ -1,14 +1,9 @@
# Use an official Python runtime as a parent image FROM python:3.11-slim-bullseye
FROM python:3.10-slim-buster
# Set the working directory in the container to /app
WORKDIR /app WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r 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 EXPOSE 8080
# Run run.py when the container launches # Run run.py when the container launches
CMD ["python", "run.py"] ENTRYPOINT ["python", "run.py"]
+1 -1
View File
@@ -20,4 +20,4 @@ RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 8080 EXPOSE 8080
# Run run.py when the container launches # Run run.py when the container launches
CMD ["python", "run.py"] ENTRYPOINT ["python", "run.py"]
+1 -1
View File
@@ -18,4 +18,4 @@ RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 8080 EXPOSE 8080
# Run run.py when the container launches # Run run.py when the container launches
CMD ["python", "run.py"] ENTRYPOINT ["python", "run.py"]
+1 -9
View File
@@ -1,26 +1,18 @@
# Use an official Python runtime as a parent image
FROM python:3.11-slim-bullseye FROM python:3.11-slim-bullseye
# Set the working directory in the container to /app
WORKDIR /app WORKDIR /app
# Install necessary packages including git and Tesseract OCR
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y git tesseract-ocr libtesseract-dev && \ apt-get install -y git tesseract-ocr libtesseract-dev && \
apt-get clean && \ apt-get clean && \
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/*
# Clone the repository
RUN git clone https://github.com/UrloMythus/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 RUN pip install --no-cache-dir -r requirements.txt
# Install pytesseract
RUN pip install --no-cache-dir pytesseract RUN pip install --no-cache-dir pytesseract
# Expose the port, for now default is 8080 cause it's the only one really allowed by HuggingFace
EXPOSE 8080 EXPOSE 8080
# Run run.py when the container launches ENTRYPOINT ["python", "run.py"]
CMD ["python", "run.py"]
+74 -53
View File
@@ -52,13 +52,28 @@ Movies, Series, Anime and Live TV are supported.
``pip install -r requirements.txt `` ``pip install -r requirements.txt ``
2. Create a .env file and fill it (look at example.env) 2. If you want to use Eurostreaming install those packages:
- Linux (Debian/Ubuntu):
``sudo apt install tesseract-ocr libtesseract-dev ``
- Windows: Install the following library from this [link](https://github.com/UB-Mannheim/tesseract/wiki)
- MacOS: ```brew install tesseract```
Then install the following Python package:
``pip install pytesseract ``
3. Create a .env file and fill it (look at example.env)
4. Modify the config.json as you wish
4. Then to start the Fast API app server just execute:
3. Then to start the Fast API app server just execute:
@@ -80,7 +95,7 @@ Movies, Series, Anime and Live TV are supported.
To host this project with Hugging Face, go to the [linked](https://huggingface.co/spaces/aiMAmmaM/DuplicateTheSpace) page and follow these steps: To host this project with Hugging Face you will need a Github Account, a Hugging Face account and a [TMDB KEY](https://www.educative.io/courses/movie-database-api-python/set-up-the-credentials).
@@ -90,38 +105,56 @@ To host this project with Hugging Face, go to the [linked](https://huggingface.c
1. Create an Hugging Face Account [here](https://huggingface.co/join) 1. Fork this project and give it a random name.
[!WARNING] The name must not be related to Mamma Mia or mediaflowproxy. Just use a random name
2. Go on the Github of the [Repo](https://github.com/UrloMythus/MammaMia/), click on Fork -> Create New Fork -> Create One.
3. Click on static directory and then click on static.py. Remove the whole content and put:
```
HTML = """
Whatever you want
"""
```
4. Change ```Whatever you want``` with a random phrase (the longer it is, the better it is). If you are too lazy go to this [link](https://www.thewordfinder.com/random-sentence-generator/) and generate it.
5. Click Commit Changes
[!WARNING] Since the main page doesn't exist anymore, you will need to configure MammaMia from /configure endpoint
6. Go to [linked](https://huggingface.co/login?next=%2Fnew-space) page and create a new Public Docker Space.
2. Go to [linked](https://huggingface.co/spaces/aiMAmmaM/DuplicateTheSpace) page and click on three dots on the top (right) part of the screen [!WARNING] The Space must be Public or else you won't be able to access it
3. Click Duplicate this Space
4. Insert TMDB Key and set visibility to Public
5. Duplicate the Project
6. Go on the Github of the [Repo](https://github.com/UrloMythus/MammaMia/), and after creating a Github Account click on Fork -> Create New Fork -> Create One.
7. After that go back to your HuggingFace Space and click on Files --> Click on Dockerfile ---> Click on edit ---> Where there is "YourUsername" put your Github username and where there is "YourRepoName" insert the name of the fork.
8. When you are done click Commit Changes to main
7. You are done! 7. Go to Settings and in ```Variables and secrets``` section click New Secret. As ```Name``` put TMDB_KEY and as ```Value`` put your TMDB Key
8. Go to Files and click Contribute -> Create a new file
9. In ```Name your file``` field put ```Dockerfile``` . Inside the text box put the content of the Dockerfile called ```Dockerfile-auto-update-no-config``` which you will find inside the /Dockerfiles directory of your Github Fork.
10. Where there is "YourUsername" put your Github username and where there is "YourRepoName" insert the name of the fork.
[!WARNING] Don't remove the final . or it won't work
11. When you are done click Commit Changes to main
12. Go to the README.md in the Files section of your HuggingFace's space and click on it. After that click on edit. After ```pinned: false``` insert this ```app_port: 8080```
13. When you are done click Commit Changes to main
14. You are done!
15. To install it on Stremio you will need the Direct URL. It can be found on three dots --> Embed This Space --> Direct URL
8. To install it on Stremio altought, you will need the Direct URL. It can be found on three dots --> Embed This Space --> Direct URL
If you do not find it it means your space is Private. To fix so go to Settings and click Set Visibility to Public. If you do not find it it means your space is Private. To fix so go to Settings and click Set Visibility to Public.
How do I handle Updates ? First of all you will need to go to your GitHub Repo and click Sync Changes. Then go into your HuggingFace Space ---> Settings ---> Factory Reset 16. How to handle updates: First of all you will need to go to your GitHub Repo and click Sync Changes (without discarding commits). Then go into your HuggingFace Space ---> Settings ---> Factory Reset
@@ -130,7 +163,7 @@ How do I handle Updates ? First of all you will need to go to your GitHub Repo a
## Render ## Render
[![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/UrloMythus/MammaMia)
@@ -168,7 +201,7 @@ To install this project on [Render](https://render.com/) follow these steps:
4. Among the other environment variables, put PORT = 8080. This is needed because Render needs the Port given as an environment variable. Remember to put TMDB_KEY as an enviroment variable. 4. Aside from usual enviroment variables you will need to put PORT = 8080.
@@ -190,8 +223,7 @@ To install this project on [Render](https://render.com/) follow these steps:
Remember, load_env and Public Instance needs to be disabled in the config.json and Remote_Instance needs to be set to 1 Remember, load_env needs to be disabled in the config.json
@@ -203,15 +235,6 @@ Remember, load_env and Public Instance needs to be disabled in the config.json a
# How to add to Stremio
Open your instance URL and configure MammaMia. Once you are done you can click on INSTALL Button. If it doesn't work click on Generate Manifest and copy it. Then paste it in Stremio Search Bar. If you are on Mac or on Web go to addons, click Add an Addon, and paste it there.
@@ -232,14 +255,12 @@ Open your instance URL and configure MammaMia. Once you are done you can click o
| Enviroment Variable | Value | | Enviroment Variable | Value |
|-------------------------|---| |-------------------------|---|
|TMDB_KEY|INSERT YOUR API KEY HERE| |TMDB_KEY|INSERT YOUR API KEY HERE|
|FORWARDPROXY| "YOURFORWARDPROXY/" For sites with Cloudfare Protections| |FORWARDPROXY| "YOURFORWARDPROXY/" |
|PROXY | ["PROXY1","PROXY2"] For sites with Cloudfare Protections, use as many as you wish| |PROXY | ["PROXY1","PROXY2"]|
Tutorial to get the TMDB Key: [Tutorial](https://www.themoviedb.org/settings/api)
Here is [linked](https://www.themoviedb.org/settings/api) a tutorial about how to get a TMDB KEY
@@ -264,27 +285,22 @@ Down here all explained:
| Config | Value | | Config | Value |
|-------------------------|---| |-------------------------|---|
| Domain | The domain of the site, must be a string | | Domain | The domain of the site, must be a string |
|enabled | If the site is enabled or not. This will override user-preference while configuration the add-on| |enabled | If the site is enabled or not. This will override user-preference in the configuration|
|**_ForwardProxy|If that site needs to use a ForwardProxy which needs to be given in the enviroment variables |**_ForwardProxy| Whether or not to use the ForwardProxy for the specific site.|
|**_Proxy| If that site needs to use Proxies which need to be given in the enviroment variables |**_Proxy| Whether or not to use the Proxies for the specific site.|
|Cookies| Cookies needed for a specific site to work. To get them you will need to log in the site and obtain cookies using Dev Tools.
|load_env|It needs to be enabled if you need to load a .env file. On remote hosting services, like Hugging Face or Render, it needs to be disabled. | |load_env|It needs to be enabled if you need to load a .env file. On remote hosting services, like Hugging Face or Render, it needs to be disabled. |
|HOST| The host for the Fast API APP| |HOST| The host for the Fast API APP|
|PORT| The port for the Fast API APP. Default: 8080 | |PORT| The port for the Fast API APP. Default: 8080
|level| The level for the logging module. Default: info
|Icon| The Icon for the Add-On.| |Icon| The Icon for the Add-On.|
|Public_Instance| If it's the main public instance. Most of users shouldn't care about this|
|Remote_Instance| Set to "1" if the server where the add-on is hosted has not the same IP of the one where Stremio Server is.|
|Global_Proxy| Whatever to enable a Global Proxy which will be valid for every request in the add-on. |Global_Proxy| Whatever to enable a Global Proxy which will be valid for every request in the add-on.
For now Mysterius must be kept disabled if you do not know what you are doing.
Check those links to get the new Domain for the providers. Check those links to get the new Domain for the providers.
[FILMPERTUTTI](https://filmpertuttiiii.nuovo.live/)
@@ -292,7 +308,6 @@ Check those links to get the new Domain for the providers.
[TANTIFILM](https://tantinuovo.com/tantifilm-nuovo-indirizzo/)
@@ -300,7 +315,6 @@ Check those links to get the new Domain for the providers.
[LORDCHANNEL](https://t.me/+5MQwrb3eqb81NGI0)
@@ -308,10 +322,17 @@ Check those links to get the new Domain for the providers.
[CB01](https://cb01.uno/) [CB01](https://cb01.uno/)
[GUARDAFLIX](https://guardoserie.it/)
[GUARDOSERIE](https://guardoserie.it/)
[EUROSTREAMING](https://eurostreaming-nuovo-indirizzo.online/)
## Mediaflow Proxy ## Mediaflow Proxy
This project uses Mediaflow-Proxy to bypass some protections. You can find instructions about how to install it [here](https://github.com/mhdzumair/mediaflow-proxy/). This project uses Mediaflow-Proxy to bypass some protections. You can find instructions about how to install it [here](https://github.com/mhdzumair/mediaflow-proxy/).
Not only some provider won't play without it, as said in the config, but also most of paid channels won't.
## Credits ## Credits
+30 -15
View File
@@ -1,11 +1,19 @@
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import datetime import datetime
import logging
import json import json
from Src.Utilities.info import get_info_kitsu from Src.Utilities.info import get_info_kitsu
import Src.Utilities.config as config import Src.Utilities.config as config
import re import re
from fake_headers import Headers from fake_headers import Headers
import Src.Utilities.config as config
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
Icon = config.Icon
Name = config.Name
random_headers = Headers() random_headers = Headers()
proxies = {} proxies = {}
from Src.Utilities.loadenv import load_env from Src.Utilities.loadenv import load_env
@@ -55,7 +63,7 @@ async def security_cookie (response):
f"SecurityAW-{unknown_chars}": Security_Cookie f"SecurityAW-{unknown_chars}": Security_Cookie
} }
return cookies return cookies
async def get_mp4(anime_url,ismovie,episode,client): async def get_mp4(anime_url,ismovie,episode,client,i,streams):
cookies = {} cookies = {}
if ForwardProxy != "": if ForwardProxy != "":
response = await client.get(ForwardProxy + anime_url,allow_redirects=True,impersonate = "chrome124",proxies=proxies) response = await client.get(ForwardProxy + anime_url,allow_redirects=True,impersonate = "chrome124",proxies=proxies)
@@ -82,12 +90,18 @@ async def get_mp4(anime_url,ismovie,episode,client):
response = await client.head(url) response = await client.head(url)
if response.status_code == 404: if response.status_code == 404:
url = None url = None
return url if url:
if i == 0:
language = "Original"
elif i == 1:
language = "Italian"
streams['streams'].append({'title': f'{Icon}Animeworld {language}', 'url': url,'behaviorHints': {'bingeGroup': 'animeworld'}})
return streams
async def search(showname,date,ismovie,episode,client): async def search(showname,date,ismovie,episode,client,streams):
search_year = date[:4] search_year = date[:4]
headers = random_headers.generate() headers = random_headers.generate()
link = f'{AW_DOMAIN}/filter?year={search_year}&sort=2&keyword={showname}' link = f'{AW_DOMAIN}/filter?year={search_year}&sort=2&keyword={showname}'
@@ -99,7 +113,7 @@ async def search(showname,date,ismovie,episode,client):
cookies = {} cookies = {}
soup = BeautifulSoup(response.text,'lxml') soup = BeautifulSoup(response.text,'lxml')
anime_list = soup.find_all('a', class_=['poster', 'tooltipstered']) anime_list = soup.find_all('a', class_=['poster', 'tooltipstered'])
final_urls = [] i = 0
for anime in anime_list: for anime in anime_list:
anime_info_url = f'{AW_DOMAIN}/{anime["data-tip"]}' anime_info_url = f'{AW_DOMAIN}/{anime["data-tip"]}'
response = await client.get(ForwardProxy + anime_info_url,allow_redirects=True, impersonate = "chrome124", cookies = cookies, proxies = proxies) response = await client.get(ForwardProxy + anime_info_url,allow_redirects=True, impersonate = "chrome124", cookies = cookies, proxies = proxies)
@@ -118,12 +132,13 @@ async def search(showname,date,ismovie,episode,client):
release_date == (datetime.datetime.strptime(date, "%Y-%m-%d") + datetime.timedelta(days=1)).strftime("%Y-%m-%d") or release_date == (datetime.datetime.strptime(date, "%Y-%m-%d") + datetime.timedelta(days=1)).strftime("%Y-%m-%d") or
release_date == (datetime.datetime.strptime(date, "%Y-%m-%d") - datetime.timedelta(days=1)).strftime("%Y-%m-%d")): release_date == (datetime.datetime.strptime(date, "%Y-%m-%d") - datetime.timedelta(days=1)).strftime("%Y-%m-%d")):
anime_url = f'{AW_DOMAIN}{anime["href"]}' anime_url = f'{AW_DOMAIN}{anime["href"]}'
final_url = await get_mp4(anime_url,ismovie,episode,client) streams = await get_mp4(anime_url,ismovie,episode,client,i,streams)
if final_url: i+=1
final_urls.append(final_url) logger.info(f"AnimeWorld Found Results for current ID")
return final_urls
async def animeworld(id,client): return streams
async def animeworld(streams,id,client):
try: try:
kitsu_id = id.split(":")[1] kitsu_id = id.split(":")[1]
ismovie = 1 if len(id.split(":")) == 2 else 0 ismovie = 1 if len(id.split(":")) == 2 else 0
@@ -142,11 +157,11 @@ async def animeworld(id,client):
showname = showname.split("’")[0] showname = showname.split("’")[0]
if ":" in showname: if ":" in showname:
showname = showname.split(":")[0] showname = showname.split(":")[0]
final_urls = await search(showname,date,ismovie,episode,client) streams = await search(showname,date,ismovie,episode,client,streams)
return final_urls return streams
except Exception as e: except Exception as e:
print("Animeworld failed",e) logger.warning(f"Animeworld failed {e}")
return None return streams
async def test_animeworld(): async def test_animeworld():
async with AsyncSession() as client: async with AsyncSession() as client:
@@ -200,7 +215,7 @@ async def old_search(showname,date,ismovie,episode,client):
'keyword': showname, 'keyword': showname,
} }
response = await client.post(f'https://www.animeworld.{AW_DOMAIN}/api/search/v2', params=params, cookies=cookies, headers=headers,allow_redirects=True, impersonate = "chrome124") response = await client.post(f'https://www.animeworld.{AW_DOMAIN}/api/search/v2', params=params, cookies=cookies, headers=headers,allow_redirects=True)
data = json.loads(response.text) data = json.loads(response.text)
final_urls = [] final_urls = []
@@ -221,7 +236,7 @@ async def old_search(showname,date,ismovie,episode,client):
params = { params = {
'keyword': showname, 'keyword': showname,
} }
response = await client.post(ForwardProxy + f'https://www.animeworld.{AW_DOMAIN}/api/search/v2', params=params, cookies=cookies, headers=headers, allow_redirects=True, impersonate = "chrome124", proxies = proxies) response = await client.post(ForwardProxy + f'https://www.animeworld.{AW_DOMAIN}/api/search/v2', params=params, cookies=cookies, headers=headers, allow_redirects=True, proxies = proxies)
data = json.loads(response.text) data = json.loads(response.text)
for anime in data["animes"]: for anime in data["animes"]:
release_date = anime["release"] release_date = anime["release"]
+39 -144
View File
@@ -5,6 +5,11 @@ from Src.Utilities.convert import get_TMDb_id_from_IMDb_id
from fake_headers import Headers from fake_headers import Headers
import Src.Utilities.config as config import Src.Utilities.config as config
from Src.Utilities.loadenv import load_env from Src.Utilities.loadenv import load_env
from Src.API.extractors.mixdrop import mixdrop
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
CB_DOMAIN = config.CB_DOMAIN CB_DOMAIN = config.CB_DOMAIN
CB_PROXY = config.CB_PROXY CB_PROXY = config.CB_PROXY
MX_PROXY = config.MX_PROXY MX_PROXY = config.MX_PROXY
@@ -13,6 +18,7 @@ proxies2 = {}
env_vars = load_env() env_vars = load_env()
import random import random
import json import json
from Src.Utilities.mfp import build_mfp
if MX_PROXY == "1": if MX_PROXY == "1":
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS') PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
proxy_list = json.loads(PROXY_CREDENTIALS) proxy_list = json.loads(PROXY_CREDENTIALS)
@@ -65,86 +71,15 @@ async def get_stayonline(link,client):
return real_url return real_url
async def get_uprot(link,client):
if "msf" in link:
link = link.replace("msf","mse")
headers = fake_headers.generate()
response = await client.get(ForwardProxy2 + link, headers=headers, allow_redirects=True, timeout=10, proxies=proxies2, impersonate = "chrome124")
soup = BeautifulSoup(response.text, "lxml")
maxstream_url = soup.find("a")
maxstream_url = maxstream_url.get("href")
return maxstream_url
async def get_true_link_mixdrop(real_link,client,MFP):
try:
import string
if "club" in real_link:
real_link = real_link.replace("club","ps").split('/2')[0]
if MFP == "1":
return real_link
headers = fake_headers.generate()
response = await client.get(real_link, headers=headers, allow_redirects=True,timeout = 30, impersonate = "chrome124")
[s1, s2] = re.search(r"\}\('(.+)',.+,'(.+)'\.split", response.text).group(1, 2)
schema = s1.split(";")[2][5:-1]
terms = s2.split("|")
charset = string.digits + string.ascii_letters
d = dict()
for i in range(len(terms)):
d[charset[i]] = terms[i] or charset[i]
s = 'https:'
for c in schema:
s += d[c] if c in d else c
print(s)
return s
except Exception as e:
print(e)
return None
async def get_true_link_maxstream(maxstream_url,client):
headers = fake_headers.generate()
# Send a GET request to the Maxstream URL)
response = await client.get(ForwardProxy2 + maxstream_url, headers=headers, allow_redirects=True, timeout=10,proxies = proxies2, impersonate = "chrome124")
[s1, s2] = re.search(r"\}\('(.+)',.+,'(.+)'\.split", response.text).group(1, 2)
terms = s2.split("|")
urlset_index = terms.index('urlset')
hls_index = terms.index('hls')
sources_index = terms.index('sources')
result = terms[urlset_index + 1 : hls_index]
reversed_elements = result[::-1]
first_part = terms[hls_index +1 : sources_index]
reversed_first_part = first_part[::-1]
first_url_part = ""
for first_part in reversed_first_part:
if "0" in first_part:
first_url_part += first_part
else:
first_url_part += first_part + "-"
base_url = f"https://{first_url_part}.host-cdn.net/hls/"
if len(reversed_elements) == 1:
final_url = base_url + "," + reversed_elements[0] + ".urlset/master.m3u8"
lenght = len(reversed_elements)
i = 1
for element in reversed_elements:
base_url += element + ","
if lenght == i:
base_url += ".urlset/master.m3u8"
else:
i += 1
final_url = base_url
return final_url
async def search_movie(showname,date,client): async def search_movie(showname,date,client):
try: try:
showname = showname.replace(" ","+").replace("ò","o").replace("è","e").replace("à","a").replace("ù","u").replace("ì","i") showname = showname.replace(" ","+").replace("ò","o").replace("è","e").replace("à","a").replace("ù","u").replace("ì","i")
headers = fake_headers.generate() headers = fake_headers.generate()
headers['Referer'] = f'{CB_DOMAIN}/' headers['Referer'] = f'{CB_DOMAIN}/'
query = f'{CB_DOMAIN}/?s={showname}' query = f'{CB_DOMAIN}/?s={showname}'
response = await client.get(ForwardProxy + query,headers=headers, impersonate = "chrome124", proxies = proxies) response = await client.get(ForwardProxy + query,headers=headers, proxies = proxies)
if response.status_code != 200: if response.status_code != 200:
print(f"CB01 Failed to fetch search results: {response.status_code}") logger.warning(f"CB01 Failed to fetch search results: {response.status_code}")
soup = BeautifulSoup(response.text, 'lxml',parse_only=SoupStrainer('div', class_='card-content')) soup = BeautifulSoup(response.text, 'lxml',parse_only=SoupStrainer('div', class_='card-content'))
cards = soup.find_all('div', class_='card-content') cards = soup.find_all('div', class_='card-content')
year_pattern = re.compile(r'(19|20)\d{2}') year_pattern = re.compile(r'(19|20)\d{2}')
@@ -162,7 +97,7 @@ async def search_movie(showname,date,client):
if year == date : # Check if the year is 2011 if year == date : # Check if the year is 2011
return href return href
except Exception as e: except Exception as e:
print(f'MammaMia: Error in search_series cb01: {e}') logger.warning(f'MammaMia: Error in search_series cb01: {e}')
async def search_series(showname,date,client): async def search_series(showname,date,client):
@@ -171,9 +106,9 @@ async def search_series(showname,date,client):
headers = fake_headers.generate() headers = fake_headers.generate()
headers['Referer'] = f'{CB_DOMAIN}/serietv/' headers['Referer'] = f'{CB_DOMAIN}/serietv/'
query = f'{CB_DOMAIN}/serietv/?s={showname}' query = f'{CB_DOMAIN}/serietv/?s={showname}'
response = await client.get(ForwardProxy + query,headers=headers,impersonate = "chrome124", proxies = proxies) response = await client.get(ForwardProxy + query,headers=headers, proxies = proxies)
if response.status_code != 200: if response.status_code != 200:
print(f"CB01 Failed to fetch search results: {response.status_code}") logger.warning(f"CB01 Failed to fetch search results: {response.status_code}")
soup = BeautifulSoup(response.text, 'lxml',parse_only=SoupStrainer('div', class_='card-content')) soup = BeautifulSoup(response.text, 'lxml',parse_only=SoupStrainer('div', class_='card-content'))
cards = soup.find_all('div', class_='card-content') cards = soup.find_all('div', class_='card-content')
year_pattern = re.compile(r'(19|20)\d{2}') year_pattern = re.compile(r'(19|20)\d{2}')
@@ -193,42 +128,24 @@ async def search_series(showname,date,client):
if year == date : # Check if the year is 2011 if year == date : # Check if the year is 2011
return href return href
except Exception as e: except Exception as e:
print(f'MammaMia: Error in search_series cb01: {e}') logger.warning(f'MammaMia: Error in search_series cb01: {e}')
async def movie_redirect_url(link,client,MFP): async def movie_redirect_url(link,client,MFP,MFP_CREDENTIALS,streams):
headers = fake_headers.generate() headers = fake_headers.generate()
response = await client.get(ForwardProxy + link, headers=headers, allow_redirects=True, timeout=10, impersonate = "chrome124", proxies = proxies) response = await client.get(ForwardProxy + link, headers=headers, allow_redirects=True, timeout=10, proxies = proxies)
# Extract the redirect URL from the HTML # Extract the redirect URL from the HTML
soup = BeautifulSoup(response.text, "lxml",parse_only=SoupStrainer('div')) soup = BeautifulSoup(response.text, "lxml",parse_only=SoupStrainer('div'))
redirect_url = soup.find("div", id="iframen2").get("data-src") redirect_url = soup.find("div", id="iframen2").get("data-src")
print(redirect_url)
if "stayonline" in redirect_url: if "stayonline" in redirect_url:
mixdrop_real_link = await get_stayonline(redirect_url,client) mixdrop_real_link = await get_stayonline(redirect_url,client)
final_url = await get_true_link_mixdrop(mixdrop_real_link,client,MFP) streams = await mixdrop(mixdrop_real_link,client,MFP,MFP_CREDENTIALS,streams,"CB01",proxies,ForwardProxy,"")
if final_url != None:
return final_url
else:
redirect_url = soup.find("div", id="iframen1").get("data-src")
if "stayonline" in redirect_url:
redirect_url =await get_stayonline(redirect_url,client)
maxstream_real_link = await get_uprot(redirect_url,client)
final_url = await get_true_link_maxstream(maxstream_real_link,client)
return(final_url)
else: return streams
redirect_url = soup.find("div", id="iframen1").get("data-src") async def series_redirect_url(link,season,episode,client,MFP,MFP_CREDENTIALS,streams):
if "stayonline" in redirect_url:
redirect_url =await get_stayonline(redirect_url,client)
maxstream_real_link = await get_uprot(redirect_url,client)
final_url = await get_true_link_maxstream(maxstream_real_link,client)
return(final_url)
return redirect_url
async def series_redirect_url(link,season,episode,client,MFP):
if len(episode) == 1: if len(episode) == 1:
episode = f'0{episode}' episode = f'0{episode}'
headers = fake_headers.generate() headers = fake_headers.generate()
response = await client.get(ForwardProxy + link, headers=headers, allow_redirects=True, timeout=10,impersonate = "chrome124", proxies = proxies) 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') seasons_text = soup.find_all('div', class_='sp-head')
for season_text in seasons_text: for season_text in seasons_text:
@@ -236,47 +153,25 @@ async def series_redirect_url(link,season,episode,client,MFP):
if f'STAGIONE' in text and f'{season}' in text: if f'STAGIONE' in text and f'{season}' in text:
text = text.replace("STAGIONE","").replace("ITA", "") text = text.replace("STAGIONE","").replace("ITA", "")
if "A" in text: if "A" in text:
if len(season) == 1: return streams
season = f'0{season}'
sp_body = season_text.find_next('div', class_='sp-body')
link_tag = sp_body.find('a')
uprot_long = link_tag.get('href')
response = await client.get(ForwardProxy + uprot_long, headers=headers, allow_redirects=True, timeout=10, impersonate = "chrome124", proxies = proxies)
season = "01"
episode = "04"
pattern1 = rf"(?i)\S*?\.{season}x{episode}\S*?\.mkv.*?href=['\"](.*?)['\"]"
pattern2 = rf"\S*\.S{season}E{episode}\S*?\.mkv|\.mp4|\.avi.*?href=['\"](.*?)['\"]"
match = re.search(pattern1, response.text)
if match:
maxstream_link = match.group(1)
else: else:
match = re.search(pattern2, response.text) episode = episode.zfill(2)
match = re.search(rf'{season}&#215;{episode}\s*&#8211;\s*<a[^>]*href="[^"]*"[^>]*>[^<]*</a>\s&#8211; <a[^>]*href="[^"]*',response.text)
if match: if match:
maxstream_link = match.group(1) links = match.group(0)
if "stayonline" in maxstream_link: soup = BeautifulSoup(links,'lxml',parse_only=SoupStrainer('a'))
maxstream_link =await get_stayonline(maxstream_link,client) mixdrop_a = soup.find_all('a')[1]
maxstream_real_link = await get_uprot(maxstream_link,client) mixdrop_link = mixdrop_a['href']
final_url = await get_true_link_maxstream(maxstream_real_link,client)
return final_url
else:
pattern = re.compile(r'4&#215;03\s*&#8211;.*?<a href="(.*?)".*?>Maxstream</a>\s*&#8211;.*?<a href="(.*?)".*?>Mixdrop</a>', re.DOTALL)
match = pattern.search(response.text)
maxstream_link = match.group(1)
mixdrop_link = match.group(2)
print(f"Maxstream: {maxstream_link}")
print(f"Mixdrop: {mixdrop_link}")
mixdrop_real_link = await get_stayonline(mixdrop_link,client) mixdrop_real_link = await get_stayonline(mixdrop_link,client)
final_url = await get_true_link_mixdrop(mixdrop_real_link,client,MFP) streams = await mixdrop(mixdrop_real_link,client,MFP,MFP_CREDENTIALS,streams,"CB01",proxies,ForwardProxy,"")
if final_url == None: return streams
if "stayonline" in maxstream_link:
maxstream_link =await get_stayonline(maxstream_link,client)
maxstream_real_link = await get_uprot(maxstream_link,client)
final_url = await get_true_link_maxstream(maxstream_real_link,client)
return final_url
async def cb01(id,client,MFP):
async def cb01(streams,id,MFP,MFP_CREDENTIALS,client):
try: try:
general = await is_movie(id) general = await is_movie(id)
ismovie = general[0] ismovie = general[0]
@@ -290,17 +185,17 @@ async def cb01(id,client,MFP):
season = general[2] season = general[2]
episode = general[3] episode = general[3]
link = await search_series(showname,date,client) link = await search_series(showname,date,client)
final_url = await series_redirect_url(link,season,episode,client,MFP) streams = await series_redirect_url(link,season,episode,client,MFP,MFP_CREDENTIALS,streams)
return final_url return streams
elif ismovie == 1: elif ismovie == 1:
season = None season = None
episode = None episode = None
link = await search_movie(showname,date,client) link = await search_movie(showname,date,client)
redirect_url = await movie_redirect_url(link,client,MFP) streams = await movie_redirect_url(link,client,MFP,MFP_CREDENTIALS,streams)
return redirect_url return streams
except Exception as e: except Exception as e:
print(f'MammaMia: Error in cb01: {e}') logger.warning(f'MammaMia: Error in cb01: {e}')
return None return streams
@@ -324,9 +219,9 @@ async def test_animeworld():
from curl_cffi.requests import AsyncSession from curl_cffi.requests import AsyncSession
async with AsyncSession() as client: async with AsyncSession() as client:
# Replace with actual id, for example 'anime_id:episode' format # Replace with actual id, for example 'anime_id:episode' format
test_id = "tt0045247" # This is an example ID format test_id = "tt32360916:1:1" # This is an example ID format
MFP = "0" MFP = "0"
results = await cb01(test_id, client,MFP) results = await cb01({'streams': []},test_id,MFP,['test','test'],client)
print(results) print(results)
if __name__ == "__main__": if __name__ == "__main__":
+8 -4
View File
@@ -1,5 +1,9 @@
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import Src.Utilities.config as config
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
tivu = { tivu = {
"dazn-zona-a": "801", "dazn-zona-a": "801",
} }
@@ -171,7 +175,7 @@ async def tivu_get(id,client):
description = hour_range + " " + program_name description = hour_range + " " + program_name
return description return description
except Exception as e: except Exception as e:
print(e) logger.warning(f"EPG {e}")
description = f'Watch {id}' description = f'Watch {id}'
return description return description
@@ -194,10 +198,10 @@ async def epg_guide(id,client):
data = response.json() data = response.json()
description = data['description'].replace("- EPG by epg-guide.com","").replace("No description","") description = data['description'].replace("- EPG by epg-guide.com","").replace("No description","")
title = data['title'] title = data['title']
print("MammaMia: EPG FOUND") logger.info("MammaMia: EPG FOUND")
return description,title return description,title
except Exception as e: except Exception as e:
print(e) logger.debug(e)
description = f'Watch {id}' description = f'Watch {id}'
title = "" title = ""
return description,title return description,title
+49 -110
View File
@@ -3,10 +3,15 @@ import Src.Utilities.config as config
from fake_headers import Headers from fake_headers import Headers
from urllib.parse import quote from urllib.parse import quote
from Src.Utilities.loadenv import load_env from Src.Utilities.loadenv import load_env
from Src.API.extractors.mixdrop import mixdrop
from Src.API.extractors.deltabit import deltabit
import re import re
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
from bs4 import BeautifulSoup,SoupStrainer from bs4 import BeautifulSoup,SoupStrainer
env_vars = load_env() env_vars = load_env()
from fake_headers import Headers
random_headers = Headers() random_headers = Headers()
try: try:
import pytesseract import pytesseract
@@ -17,11 +22,11 @@ except Exception as e:
import base64 import base64
from io import BytesIO from io import BytesIO
import time import time
from Src.Utilities.eval import eval_solver
import os import os
import json import json
import difflib import difflib
import random import random
from Src.Utilities.mfp import build_mfp
ES_DOMAIN = config.ES_DOMAIN ES_DOMAIN = config.ES_DOMAIN
ES_PROXY = config.ES_PROXY ES_PROXY = config.ES_PROXY
@@ -45,82 +50,6 @@ else:
'''
OK <a href="https://uprot.net/msf/fwbtgsssmt0q" target="_blank" rel="noopener">MaxStream</a> – <a href="https://clicka.cc/delta/6svqpze62r8z" target="_blank" rel="noopener">DeltaBit</a> – <a href="https://clicka.cc/tv/5eumjxxt" target="_blank" rel="noopener">Turbovid</a>
pattern = r'href="([^"]+)"'
match = re.search(pattern, text)
href_value = match.group(1)
'''
async def mixdrop(url,MFP,client):
"""Extract Mixdrop URL."""
if "club" in url:
url = url.replace("club", "cv").split("/2")[0]
if "cfd" in url:
url = url.replace("cfd", "cv").replace("emb","e").split("/2")[0]
if MFP == "1":
return url,""
headers = {"accept-language": "en-US,en;q=0.5"}
final_url = f"https:{await eval_solver(url, proxies , ForwardProxy, client)}"
return final_url,""
async def deltabit(page_url,client):
"""Extract Deltabit URL."""
i = 0
#Set up some headers
headers = random_headers.generate()
headers2 = random_headers.generate()
#Get the redirected link, so the actual deltabit link.
page_url_response = await client.get(ForwardProxy + page_url,headers={**headers, 'Range': 'bytes=0-0'}, proxies=proxies)
page_url = page_url_response.url
print("Page_URl is",page_url)
#Change the referer and user agent of the generated headers
headers2['referer'] = 'https://safego.cc/'
headers2['user-agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36'
#Request to the deltabit link
response = await client.get(ForwardProxy + page_url, headers = headers2, allow_redirects = True, proxies = proxies)
page_url = response.url
#Often deltabit redirects to another deltabit link. We need the redirected link to put it in the headers.
origin = page_url.split('/')[2]
headers['origin'] = f'https://{origin}'
headers['referer'] = page_url
headers['user-agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36'
#We check the page for the data such as hash and fname.
soup = BeautifulSoup(response.text, 'lxml', parse_only=SoupStrainer('input'))
data = {}
for input in soup:
name = input.get('name')
value = input.get('value')
data[name] = value
data['imhuman'] = ''
data['referer']= page_url
#We need to wait 2.5 seconds or the request will fail
time.sleep(2.5)
fname = data['fname']
#Request to the deltabit link
response = await client.post(ForwardProxy + page_url, data = data, headers = headers, proxies = proxies)
link = re.findall(r'sources:\s*\["([^"]+)"', response.text, re.DOTALL)
print(link)
if not link:
if not i >= 3:
link,fname = await deltabit(page_url,client)
i +=1
else:
link = link[0]
return link,fname
def convert_numbers(base64_data): def convert_numbers(base64_data):
image_data = base64.b64decode(base64_data) image_data = base64.b64decode(base64_data)
image = Image.open(BytesIO(image_data)) image = Image.open(BytesIO(image_data))
@@ -154,7 +83,7 @@ async def real_page(safego_url,client):
if len(soup)>= 1: if len(soup)>= 1:
return soup.a['href'] return soup.a['href']
else: else:
print("Getting numbers") logger.info("Getting numbers")
numbers,cookies = await get_numbers(safego_url,client) numbers,cookies = await get_numbers(safego_url,client)
numbers = convert_numbers(numbers) numbers = convert_numbers(numbers)
data = {'captch4': numbers} data = {'captch4': numbers}
@@ -166,7 +95,7 @@ async def real_page(safego_url,client):
soup = BeautifulSoup(response.text,'lxml', parse_only=SoupStrainer('a')) soup = BeautifulSoup(response.text,'lxml', parse_only=SoupStrainer('a'))
return soup.a['href'] return soup.a['href']
except Exception as e: except Exception as e:
print(e) logger.info(f"ES{e}")
async def get_host_link(pattern,atag,client): async def get_host_link(pattern,atag,client):
match = re.search(pattern, atag) match = re.search(pattern, atag)
headers = random_headers.generate() headers = random_headers.generate()
@@ -176,45 +105,54 @@ async def get_host_link(pattern,atag,client):
href_value = response.url href_value = response.url
href = await real_page(href_value,client) href = await real_page(href_value,client)
return href return href
async def scraping_links(atag,MFP,client): async def scraping_links(atag,MFP,MFP_CREDENTIALS,client,streams,language):
#Check which hosts are avaiable and extract the links from one of them. Turbovid uses Cloudflare therefore is not avaiable. Maxstream has a captcha. #Check which hosts are avaiable and extract the links from one of them. Turbovid uses Cloudflare therefore is not avaiable. Maxstream has a captcha.
if "MixDrop" and "DeltaBit" in atag: if "MixDrop" in atag and "DeltaBit" in atag:
pattern = r'<a\s+href="([^"]+)"[^>]*rel="noopener"[^>]*>DeltaBit</a>' pattern = r'<a\s+href="([^"]+)"[^>]*rel="noopener"[^>]*>DeltaBit</a>'
href = await get_host_link(pattern,atag,client) href = await get_host_link(pattern,atag,client)
try: try:
full_url,name = await deltabit(href,client) streams = await deltabit(href,client,streams,"Eurostreaming",proxies,ForwardProxy,language)
except Exception as e: except Exception as e:
pattern = r'<a\s+href="([^"]+)"[^>]*rel="noopener"[^>]*>MixDrop</a>' pattern = r'<a\s+href="([^"]+)"[^>]*rel="noopener"[^>]*>MixDrop</a>'
href = await get_host_link(pattern,atag,client) href = await get_host_link(pattern,atag,client)
full_url,name = await mixdrop(href,MFP,client) streams = await mixdrop(href,client,MFP,MFP_CREDENTIALS,streams,"Eurostreaming",proxies,ForwardProxy,language)
return full_url,name return streams
if "MixDrop" in atag and "DeltaBit" not in atag: if "MixDrop" in atag and "DeltaBit" not in atag:
try:
pattern = r'<a\s+href="([^"]+)"[^>]*rel="noopener"[^>]*>MixDrop</a>' pattern = r'<a\s+href="([^"]+)"[^>]*rel="noopener"[^>]*>MixDrop</a>'
href = await get_host_link(pattern,atag,client) href = await get_host_link(pattern,atag,client)
full_url,name = await mixdrop(href,MFP,client) streams = await mixdrop(href,client,MFP,MFP_CREDENTIALS,streams,"Eurostreaming",proxies,ForwardProxy,language)
return full_url,name return streams
except Exception as e:
return streams
if 'DeltaBit' in atag and "MixDrop" not in atag: if 'DeltaBit' in atag and "MixDrop" not in atag:
try:
pattern = r'<a\s+href="([^"]+)"[^>]*rel="noopener"[^>]*>DeltaBit</a>' pattern = r'<a\s+href="([^"]+)"[^>]*rel="noopener"[^>]*>DeltaBit</a>'
href = await get_host_link(pattern,atag,client) href = await get_host_link(pattern,atag,client)
full_url,name = await deltabit(href,client) streams = await deltabit(href,client,streams,"Eurostreaming",proxies,ForwardProxy,language)
return full_url,name 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:
print("Just give up") logger.info("Just give up")
return None,"" return streams
async def episodes_find(description,season,episode,MFP,client): async def episodes_find(description,season,episode,MFP,MFP_CREDENTIALS,client,streams):
t = 0
episode = episode.zfill(2) episode = episode.zfill(2)
pattern = rf'{season}&#215;{episode}\s*(.*?)(?=<br\s*/?>)' pattern = rf'{season}&#215;{episode}\s*(.*?)(?=<br\s*/?>)'
match = re.findall(pattern, description) match = re.findall(pattern, description)
urls= {}
if match: if match:
for episode_details in match: for episode_details in match:
if "href" in episode_details: if "href" in episode_details:
full_url,name = await scraping_links(episode_details.split(' – ', 1)[1],MFP,client) if t == 0:
if full_url: language = "\nITA"
urls[full_url] = name elif t == 1:
return urls language = "\nSUB-ITA"
async def search(showname,date,season,episode,MFP,client): t +=1
streams = await scraping_links(episode_details.split(' – ', 1)[1],MFP,MFP_CREDENTIALS,client,streams,language)
return streams
async def search(showname,date,season,episode,MFP,MFP_CREDENTIALS,client,streams):
headers = random_headers.generate() headers = random_headers.generate()
response = await client.get(ForwardProxy + f"{ES_DOMAIN}/wp-json/wp/v2/search?search={quote(showname)}&_fields=id", proxies = proxies, headers = headers) response = await client.get(ForwardProxy + f"{ES_DOMAIN}/wp-json/wp/v2/search?search={quote(showname)}&_fields=id", proxies = proxies, headers = headers)
@@ -228,8 +166,8 @@ async def search(showname,date,season,episode,MFP,client):
description = description['content']['rendered'] description = description['content']['rendered']
ratio = difflib.SequenceMatcher(None, title, showname).ratio() ratio = difflib.SequenceMatcher(None, title, showname).ratio()
if ratio >=0.96: if ratio >=0.96:
urls = await episodes_find(description,season,episode,MFP,client) streams = await episodes_find(description,season,episode,MFP,MFP_CREDENTIALS,client,streams)
return urls return streams
else: else:
year_pattern = re.compile(r'(?<!/)(19|20)\d{2}(?!/)') year_pattern = re.compile(r'(?<!/)(19|20)\d{2}(?!/)')
match = year_pattern.search(description) match = year_pattern.search(description)
@@ -246,13 +184,13 @@ async def search(showname,date,season,episode,MFP,client):
if match: if match:
year = match.group(0) year = match.group(0)
if abs(int(year) - int(date)) <=1: if abs(int(year) - int(date)) <=1:
urls = await episodes_find(description,season,episode,MFP,client) streams = await episodes_find(description,season,episode,MFP,MFP_CREDENTIALS,client,streams)
return urls return streams
return streams
async def eurostreaming(streams,id,client,MFP,MFP_CREDENTIALS):
async def eurostreaming(id,client,MFP):
try: try:
general = await is_movie(id) general = await is_movie(id)
ismovie = general[0] ismovie = general[0]
@@ -262,16 +200,17 @@ async def eurostreaming(id,client,MFP):
season = str(general[2]) season = str(general[2])
episode = str(general[3]) episode = str(general[3])
elif ismovie == 1: elif ismovie == 1:
return None return streams
if "tmdb" in id: if "tmdb" in id:
showname,date = get_info_tmdb(clean_id,ismovie,type) showname,date = get_info_tmdb(clean_id,ismovie,type)
else: else:
showname,date = await get_info_imdb(clean_id,ismovie,type,client) showname,date = await get_info_imdb(clean_id,ismovie,type,client)
print(showname) logger.info(f"ES {showname}")
urls = await search(showname,date, season,episode,MFP,client) streams = await search(showname,date, season,episode,MFP,MFP_CREDENTIALS,client,streams)
return urls return streams
except Exception as e: except Exception as e:
print(e) logger.warning(f"ES {e}")
return streams
@@ -279,7 +218,7 @@ async def eurostreaming(id,client,MFP):
async def test_euro(): async def test_euro():
from curl_cffi.requests import AsyncSession from curl_cffi.requests import AsyncSession
async with AsyncSession() as client: async with AsyncSession() as client:
results = await eurostreaming("tt2261391:6:1",client,0) results = await eurostreaming({'streams': []},"tt9253284:1:4",client,"0",['test','test'])
print(results) print(results)
async def test_deltabit(): async def test_deltabit():
+70
View File
@@ -0,0 +1,70 @@
from fake_headers import Headers
import Src.Utilities.config as config
from bs4 import BeautifulSoup,SoupStrainer
import re
import time
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
Icon = config.Icon
Name = config.Name
random_headers = Headers()
async def deltabit(page_url,client,streams,site_name,proxies,ForwardProxy,language):
"""Extract Deltabit URL."""
i = 0
#Set up some headers
headers = random_headers.generate()
headers2 = random_headers.generate()
#Get the redirected link, so the actual deltabit link.
page_url_response = await client.get(ForwardProxy + page_url,headers={**headers, 'Range': 'bytes=0-0'}, proxies=proxies)
page_url = page_url_response.url
logger.info(f"Page_URl is {page_url}")
#Change the referer and user agent of the generated headers
headers2['referer'] = 'https://safego.cc/'
headers2['user-agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36'
#Request to the deltabit link
response = await client.get(ForwardProxy + page_url, headers = headers2, allow_redirects = True, proxies = proxies)
page_url = response.url
#Often deltabit redirects to another deltabit link. We need the redirected link to put it in the headers.
origin = page_url.split('/')[2]
headers['origin'] = f'https://{origin}'
headers['referer'] = page_url
headers['user-agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36'
#We check the page for the data such as hash and fname.
soup = BeautifulSoup(response.text, 'lxml', parse_only=SoupStrainer('input'))
data = {}
for input in soup:
name = input.get('name')
value = input.get('value')
data[name] = value
data['imhuman'] = ''
data['referer']= page_url
#We need to wait 2.5 seconds or the request will fail
time.sleep(2.5)
fname = data['fname']
#Request to the deltabit link
response = await client.post(ForwardProxy + page_url, data = data, headers = headers, proxies = proxies)
link = re.findall(r'sources:\s*\["([^"]+)"', response.text, re.DOTALL)
if not link:
if not i >= 3:
page_url = 'https://deltabit.co/q4r8w4assff4'
link,fname = await deltabit(page_url,client)
i +=1
else:
link = link[0]
if link:
streams['streams'].append({'name': f"{Name}{language}",'title': f'{Icon}{site_name}\n▶️ Deltabit\n{fname}', 'url': link, 'behaviorHints': {'bingeGroup': f'{site_name.lower()}'}})
return streams
+18
View File
@@ -0,0 +1,18 @@
import Src.Utilities.config as config
from Src.Utilities.eval import eval_solver
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
Icon = config.Icon
Name = config.Name
async def dropload(player_link,client,streams,site_name, proxies, ForwardProxy):
url = await eval_solver(player_link, proxies,ForwardProxy, client)
if url:
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}{site_name}\n▶️ Dropload', 'url': url, 'behaviorHints': {'proxyHeaders': {"request": {"User-Agent": 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'}}, 'notWebReady': True, 'bingeGroup': f'{site_name.lower()}'}})
logger.info(f"{site_name} on Dropload found results for the current ID")
return streams
+41
View File
@@ -0,0 +1,41 @@
import Src.Utilities.config as config
Icon = config.Icon
Name = config.Name
import re
from fake_headers import Headers
random_headers = Headers()
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
async def hdplayer(hdplayer,client,streams,Referer,site_name,proxies,ForwardProxy):
headers = random_headers.generate()
response = await client.get(hdplayer, allow_redirects=True, headers = headers)
match = re.search(r'sources:\s*\[\s*\{\s*file\s*:\s*"([^"]*)"', response.text)
url = match.group(1)
if url:
#Fix for Exoplayer which needs .m3u8 in the url to play the file
url = url + ".m3u8"
streams['streams'].append({'name': f"{Name}\n720/1080p",'title': f'{Icon}{site_name}\n ▶️ HDPlayer', 'url': url, 'behaviorHints': {'proxyHeaders': {"request": {"Referer": Referer}}, 'notWebReady': True, 'bingeGroup': f'{site_name.lower()}'}})
logger.info(f"{site_name} on HDPlayer found results for the current ID")
return streams
#Testing
async def test_hdplayer():
from curl_cffi.requests import AsyncSession
async with AsyncSession() as client:
results = await hdplayer("https://hdplayer.gives/embed/udnjutxECQGuwsU",client,{'streams': []},'https://hdplayer.gives/', "StreamingWatch", {},'')
print(results)
if __name__ == "__main__":
import asyncio
asyncio.run(test_hdplayer())
+94
View File
@@ -0,0 +1,94 @@
import requests
from Crypto.Cipher import AES
import json
import re
from rich.prompt import Prompt
from rich.console import Console
from fake_headers import Headers
import Src.Utilities.config as config
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
Icon = config.Icon
Name = config.Name
'''
This script was done mostly by @Arrowar, creator of https://github.com/Arrowar/StreamingCommunity/
It was modified for the use in MammaMia
'''
random_headers = Headers()
KEY = b'kiemtienmua911ca' # 16 byte
IV = b'1234567890oiuytr' # 16 byte
async def fetch_response(client,referer,player_url,url,id, proxies, ForwardProxy):
headers = random_headers.generate()
headers['referer'] = player_url
data = {
'id': id,
'w': '2560',
'h': '1440',
'r': referer,
}
response = await client.get(ForwardProxy + url, headers=headers, params = data, proxies = proxies)
return response.text
def hex_to_bytes(hex_str):
hex_str = re.sub(r'[^0-9a-fA-F]', '', hex_str)
if len(hex_str) % 2 != 0:
hex_str = '0' + hex_str
return bytes(int(hex_str[i:i+2], 16) for i in range(0, len(hex_str), 2))
def decrypt_aes_cbc(ciphertext_bytes, key, iv):
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(ciphertext_bytes)
pad_len = decrypted[-1]
if 1 <= pad_len <= 16:
decrypted = decrypted[:-pad_len]
return decrypted
async def loadm(player_link,client,streams,referer,site_name,proxies,ForwardProxy):
parts = player_link.split('#')
id = parts[1]
player_url = parts[0]
api = player_url + 'api/v1/video'
#It downloads m (crypted informations) from the API"
response_hex = await fetch_response(client,referer,player_url,api,id, proxies, ForwardProxy)
#Convert Hex in Bytes
ciphertext_bytes = hex_to_bytes(response_hex)
#We decrypt AES-CBC encryption with Key,IV and the bytes
decrypted_bytes = decrypt_aes_cbc(ciphertext_bytes, KEY, IV)
decrypted_str = decrypted_bytes.decode('utf-8')
data = json.loads(decrypted_str)
#We get the hls
hls = data['cf']
title = data['title']
if hls:
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}{site_name}\n▶️ Loadm\n{title}', 'url': hls, 'behaviorHints': {'proxyHeaders': {"request": {"Referer": player_url}}, 'notWebReady': True, 'bingeGroup': f'{site_name.lower()}'}})
logger.info(f"{site_name} on Loadm found results for the current ID")
return streams
#Testing
async def test_loadm():
from curl_cffi.requests import AsyncSession
async with AsyncSession() as client:
results = await loadm("https://loadm.cam/#6wx1p",client,{'streams': []},'guardoserie.live', 'Guardoserie', {},"")
print(results)
if __name__ == "__main__":
import asyncio
asyncio.run(test_loadm())
# https://loadm.cam/#cfnqx
+31
View File
@@ -0,0 +1,31 @@
import Src.Utilities.config as config
Icon = config.Icon
Name = config.Name
from Src.Utilities.mfp import build_mfp
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
from Src.Utilities.eval import eval_solver
async def mixdrop(url,client,MFP,MFP_CREDENTIALS,streams,site_name,proxies,ForwardProxy,language):
"""Extract Mixdrop URL."""
if "club" in url:
url = url.replace("club", "cv").split("/2")[0]
if "cfd" in url:
url = url.replace("cfd", "cv").replace("emb","e").split("/2")[0]
if MFP == "1":
url = await build_mfp(MFP_CREDENTIALS,url,"Mixdrop",client)
if url and "https%3ANone" not in url:
logger.info(f"{site_name} on Mixdrop found results for the current ID")
streams['streams'].append({'name': f"{Name} 🕵️‍♂️\n{language}",'title': f'{Icon}{site_name}\n▶️ MixDrop', 'url': url, 'behaviorHints':{'bingeGroup': f'{site_name.lower()}'}})
else:
headers = {"accept-language": "en-US,en;q=0.5"}
url = await eval_solver(url, proxies , ForwardProxy, client)
if url:
url = "https:" + url
logger.info(f"{site_name} on Mixdrop found results for the current ID")
streams['streams'].append({'name': f"{Name}{language}",'title': f'{Icon}{site_name}\n▶️ MixDrop', 'url': url, 'behaviorHints': {'proxyHeaders': {"request": {"User-Agent": 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'}}, 'notWebReady': True, 'bingeGroup': f'{site_name.lower()}'}})
return streams
+18
View File
@@ -0,0 +1,18 @@
import Src.Utilities.config as config
from Src.Utilities.eval import eval_solver
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
Icon = config.Icon
Name = config.Name
async def supervideo(supervideo_link,client,streams, site_name, proxies,ForwardProxy):
url = await eval_solver(supervideo_link,proxies, ForwardProxy, client)
if url:
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}{site_name}\n▶️ Supervideo', 'url': url, 'behaviorHints': {'bingeGroup': f'{site_name.lower()}'}})
logger.info(f"{site_name} on SuperVideo found results for the current ID")
return streams
+28
View File
@@ -0,0 +1,28 @@
from fake_headers import Headers
import Src.Utilities.config as config
Icon = config.Icon
Name = config.Name
from Src.Utilities.mfp import build_mfp
from fake_headers import Headers
import re
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
random_headers = Headers()
async def uqload(player_link,client,MFP,MFP_CREDENTIALS,streams,site_name,proxies,ForwardProxy):
headers = random_headers.generate()
if MFP == "1":
url = await build_mfp(MFP_CREDENTIALS, player_link, "Uqload",client)
streams['streams'].append({'name': f"{Name} 🕵️‍♂️",'title': f'{Icon}Guardaflix\n▶️ Uqload', 'url': url, 'behaviorHints': {'proxyHeaders': {"request": {"User-Agent": 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'}}, 'notWebReady': True, 'bingeGroup': 'guardaflix'}})
return streams
response = await client.get(ForwardProxy + player_link, headers = headers, proxies = proxies)
video_url_match = re.search(r'sources: \["(.*?)"]', response.text)
title = re.search(r'title: "(.*?)"', response.text).group(1)
if video_url_match:
url = video_url_match.group(1)
if url:
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}{site_name}\n▶️ Uqload\n{title}', 'url': url, 'behaviorHints': {'proxyHeaders': {"request": {"User-Agent": 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'}}, 'notWebReady': True, 'bingeGroup': f'{site_name.lower()}'}})
logger.info(f"{site_name} on Uqload found results for the current ID")
return streams
+71
View File
@@ -0,0 +1,71 @@
from fake_headers import Headers
import re
from bs4 import BeautifulSoup,SoupStrainer
random_headers = Headers()
import Src.Utilities.config as config
Icon = config.Icon
Name = config.Name
from Src.Utilities.mfp import build_mfp
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
SC_DOMAIN = config.SC_DOMAIN
User_Agent= "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"
async def vixcloud(link,client,MFP,MFP_CREDENTIALS,streams,site_name,proxies,ForwardProxy):
if MFP == "1":
final_url = await build_mfp(MFP_CREDENTIALS, link, "VixCloud",client)
quality = ""
mfp_icon = '🕵️‍♂️'
else:
mfp_icon = ''
headers = random_headers.generate()
headers['Referer'] = f"{SC_DOMAIN}/"
headers['Origin'] = f"{SC_DOMAIN}"
headers['User-Agent'] = User_Agent
headers['user-agent'] = User_Agent
response = await client.get(link)
if response.status_code != 200:
logger.warning("Failed to extract URL components, Invalid Request")
soup = BeautifulSoup(response.text, "lxml", parse_only=SoupStrainer("body"))
if soup:
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)
server_url = re.search(r"url:\s*'([^']+)'", script).group(1)
try:
quality = re.search(r'"quality":(\d+)', script).group(1)
except:
quality = ""
if "?b=1" in server_url:
final_url = f'{server_url}&token={token}&expires={expires}'
else:
final_url = f"{server_url}?token={token}&expires={expires}"
if "window.canPlayFHD = true" in script:
final_url += "&h=1"
if final_url:
logger.info(f"Vixcloud Found Results for the current ID")
streams['streams'].append({"name":f'{Name} {mfp_icon}\n{quality}', 'title': f'{Icon} StreamingCommunity\n▶️ Vixcloud','url': final_url,'behaviorHints': {'proxyHeaders': {"request": {"user-agent": User_Agent}}, 'notWebReady': True, 'bingeGroup': f'{site_name.lower()}{quality}'}})
return streams
#Testing
async def test_vixcloud():
from curl_cffi.requests import AsyncSession
async with AsyncSession() as client:
results = await vixcloud("https://vixsrc.to/tv/204082/1/3/",client,"0",['',''],{'streams': []},'guardoserie.live', {},'')
print(results)
if __name__ == "__main__":
import asyncio
asyncio.run(test_vixcloud())
+117
View File
@@ -0,0 +1,117 @@
from Src.Utilities.info import get_info_tmdb, is_movie, get_info_imdb
import Src.Utilities.config as config
from fake_headers import Headers
from Src.Utilities.loadenv import load_env
from urllib.parse import quote
from bs4 import BeautifulSoup, SoupStrainer
from Src.API.extractors.loadm import loadm
from Src.API.extractors.uqload import uqload
from Src.API.extractors.dropload import dropload
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
env_vars = load_env()
random_headers = Headers()
GF_DOMAIN = config.GF_DOMAIN
GF_PROXY = config.GF_PROXY
proxies = {}
if GF_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
}
GF_ForwardProxy = config.GF_ForwardProxy
if GF_ForwardProxy == "1":
ForwardProxy = env_vars.get('ForwardProxy')
else:
ForwardProxy = ""
async def get_player(page_link,MFP, MFP_CREDENTIALS,client, headers,streams):
response = await client.get(ForwardProxy + page_link, headers= headers, proxies = proxies)
soup = BeautifulSoup(response.text,'lxml', parse_only=SoupStrainer('iframe'))
iframe = soup.find('iframe')
player_link = iframe.get('data-src') or iframe.get('src')
if "loadm" in player_link:
referer = page_link.split('//')[1].split('/')[0]
streams = await loadm(player_link,client,streams,referer,"Guardaflix", proxies, ForwardProxy)
elif "uqload" in player_link:
streams = await uqload(player_link,client,MFP,MFP_CREDENTIALS,streams,"Guardaflix", proxies, ForwardProxy)
elif "dropload" in player_link:
streams = await dropload(player_link,client,streams,"Guardaflix", proxies, ForwardProxy)
return streams
async def search(showname,date,MFP,MFP_CREDENTIALS,client,streams):
headers = random_headers.generate()
headers['Origin'] = f'{GF_DOMAIN}'
headers['Referer'] = f'{GF_DOMAIN}/'
headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
showname = quote(showname)
data = {
'action': 'action_tr_search_suggest',
'nonce': '20115729b4',
'term': showname,
}
response = await client.post(ForwardProxy + f'{GF_DOMAIN}/wp-admin/admin-ajax.php', headers=headers, data=data, proxies = proxies)
soup = BeautifulSoup(response.text,'lxml', parse_only= SoupStrainer('a'))
a_tags = soup.find_all('a')
for a in a_tags:
href = a['href']
logger.info(href)
response = await client.get(ForwardProxy + href, headers = headers, proxies = proxies)
soup = BeautifulSoup(response.text,'lxml', parse_only = SoupStrainer(['iframe', 'span']))
year = soup.find('span',class_='year fa-calendar far').text
if year == date:
iframe = soup.find('iframe')
page_link = iframe.get('data-src') or iframe.get('src')
streams = await get_player(page_link,MFP,MFP_CREDENTIALS,client, headers,streams)
return streams
async def guardaflix(streams,id,client,MFP,MFP_CREDENTIALS):
try:
general = await is_movie(id)
ismovie = general[0]
clean_id = general[1]
type = "Guardaflix"
if ismovie == 0:
return streams
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)
logger.info(showname)
streams = await search(showname,date,MFP,MFP_CREDENTIALS,client,streams)
return streams
except Exception as e:
logger.warning(f'GF {e}')
return streams
async def test_guardaflix():
from curl_cffi.requests import AsyncSession
async with AsyncSession() as client:
results = await guardaflix({'streams': []},"tt16426418",client,"0",['test','test'])
print(results)
if __name__ == "__main__":
import asyncio
asyncio.run(test_guardaflix())
+15 -44
View File
@@ -4,8 +4,12 @@ import re
import Src.Utilities.config as config import Src.Utilities.config as config
from fake_headers import Headers from fake_headers import Headers
from Src.Utilities.loadenv import load_env from Src.Utilities.loadenv import load_env
from Src.Utilities.eval import eval_solver from Src.API.extractors.supervideo import supervideo
import json, random import json, random
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
env_vars = load_env() env_vars = load_env()
GH_PROXY = config.GH_PROXY GH_PROXY = config.GH_PROXY
proxies = {} proxies = {}
@@ -25,49 +29,16 @@ if GH_ForwardProxy == "1":
ForwardProxy = env_vars.get('ForwardProxy') ForwardProxy = env_vars.get('ForwardProxy')
else: else:
ForwardProxy = "" ForwardProxy = ""
#Get domain
GHD_DOMAIN = config.GHD_DOMAIN GHD_DOMAIN = config.GHD_DOMAIN
random_headers = Headers() random_headers = Headers()
async def get_supervideo_link(link,client):
headers = random_headers.generate()
response = await client.get(ForwardProxy + link, headers=headers, allow_redirects=True,timeout = 30, proxies = proxies)
s2 = re.search(r"\}\('(.+)',.+,'(.+)'\.split", response.text).group(2)
terms = s2.split("|")
file_index = terms.index('file')
#I start to loop from file cause hfs it's one or two position after it usually.
for i in range(file_index,len(terms)):
if "hfs" in terms[i]:
hfs = terms[i]
break
urlset_index = terms.index('urlset')
hls_index = terms.index('hls')
result = terms[urlset_index + 1 : hls_index]
#If the len is >1 then you have to merge the elements from the last to the first
reversed_elements = result[::-1]
base_url =f"https://{hfs}.serversicuro.cc/hls/"
if len(reversed_elements) == 1:
final_url = base_url + "," + reversed_elements[0] + ".urlset/master.m3u8"
lenght = len(reversed_elements)
i = 1
for element in reversed_elements:
base_url += element + ","
if lenght == i:
base_url += ".urlset/master.m3u8"
else:
i += 1
final_url = base_url
return final_url
async def search(clean_id,client): async def search(clean_id,client):
headers = random_headers.generate() headers = random_headers.generate()
response = await client.get(ForwardProxy + f"{GHD_DOMAIN}/set-movie-a/{clean_id}", allow_redirects=True, impersonate = "chrome124", headers = headers, proxies = proxies) response = await client.get(ForwardProxy + f"{GHD_DOMAIN}/set-movie-a/{clean_id}", allow_redirects=True, headers = headers, proxies = proxies)
if response.status_code != 200: if response.status_code != 200:
print(f"GuardaHD Failed to fetch search results: {response.status_code}") logger.warning(f"GuardaHD Failed to fetch search results: {response.status_code}")
soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('li')) soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('li'))
li_tag = soup.find('li') li_tag = soup.find('li')
href = "https:" + li_tag['data-link'] href = "https:" + li_tag['data-link']
@@ -75,26 +46,26 @@ async def search(clean_id,client):
async def guardahd(id,client): async def guardahd(streams,id,client):
try: try:
general = await is_movie(id) general = await is_movie(id)
ismovie = general[0] ismovie = general[0]
clean_id = general[1] clean_id = general[1]
if ismovie == 0: if ismovie == 0:
return None return streams
supervideo_link = await search(clean_id,client) supervideo_link = await search(clean_id,client)
final_url = await eval_solver(supervideo_link,proxies, ForwardProxy, client) streams = await supervideo(supervideo_link, client,streams,"GuardaHD",proxies, ForwardProxy)
return final_url return streams
except Exception as e: except Exception as e:
print("MammaMia: GuardaHD Failed",e) logger.warning(f"MammaMia: GuardaHD Failed {e}")
return None return streams
async def test_script(): async def test_script():
from curl_cffi.requests import AsyncSession from curl_cffi.requests import AsyncSession
async with AsyncSession() as client: async with AsyncSession() as client:
# Replace with actual id, for example 'anime_id:episode' format # Replace with actual id, for example 'anime_id:episode' format
test_id = "tt9218128" # This is an example ID format test_id = "tt16426418" # This is an example ID format
results = await guardahd(test_id, client) results = await guardahd({'streams': []},test_id, client)
print(results) print(results)
if __name__ == "__main__": if __name__ == "__main__":
+54 -72
View File
@@ -6,9 +6,14 @@ from fake_headers import Headers
from Src.Utilities.loadenv import load_env from Src.Utilities.loadenv import load_env
import json, random import json, random
from Src.Utilities.info import get_info_imdb,get_info_tmdb from Src.Utilities.info import get_info_imdb,get_info_tmdb
from Src.Utilities.eval import eval_solver
import urllib.parse import urllib.parse
from Src.Utilities.convert import get_IMDB_id_from_TMDb_id from Src.Utilities.convert import get_IMDB_id_from_TMDb_id
from Src.API.extractors.supervideo import supervideo
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
env_vars = load_env() env_vars = load_env()
GS_PROXY = config.GS_PROXY GS_PROXY = config.GS_PROXY
proxies = {} proxies = {}
@@ -32,51 +37,19 @@ else:
GS_DOMAIN = config.GS_DOMAIN GS_DOMAIN = config.GS_DOMAIN
random_headers = Headers() random_headers = Headers()
async def get_supervideo_link(link,client):
headers = random_headers.generate()
response = await client.get(ForwardProxy + link, headers=headers, allow_redirects=True,timeout = 30, proxies = proxies)
s2 = re.search(r"\}\('(.+)',.+,'(.+)'\.split", response.text).group(2)
terms = s2.split("|")
file_index = terms.index('file')
#I start to loop from file cause hfs it's one or two position after it usually.
for i in range(file_index,len(terms)):
if "hfs" in terms[i]:
hfs = terms[i]
break
urlset_index = terms.index('urlset')
hls_index = terms.index('hls')
result = terms[urlset_index + 1 : hls_index]
#If the len is >1 then you have to merge the elements from the last to the first
reversed_elements = result[::-1]
base_url =f"https://{hfs}.serversicuro.cc/hls/"
if len(reversed_elements) == 1:
final_url = base_url + "," + reversed_elements[0] + ".urlset/master.m3u8"
lenght = len(reversed_elements)
i = 1
for element in reversed_elements:
base_url += element + ","
if lenght == i:
base_url += ".urlset/master.m3u8"
else:
i += 1
final_url = base_url
return final_url
async def search_imdb(clean_id,client): async def search_imdb(clean_id,client):
try: try:
headers = random_headers.generate() headers = random_headers.generate()
response = await client.get(ForwardProxy + f'{GS_DOMAIN}/?story={clean_id}&do=search&subaction=search', allow_redirects=True, impersonate = "chrome124", headers = headers, proxies = proxies) response = await client.get(ForwardProxy + f'{GS_DOMAIN}/?story={clean_id}&do=search&subaction=search', allow_redirects=True, headers = headers, proxies = proxies)
if response.status_code != 200: if response.status_code != 200:
print(f"Guardaserie Failed to fetch search results: {response.status_code}") logger.warning(f"Guardaserie Failed to fetch search results: {response.status_code}")
soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('div',class_="mlnh-2")) soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('div',class_="mlnh-2"))
div_mlnh2 = soup.select_one('div.mlnh-2:nth-of-type(2)') div_mlnh2 = soup.select_one('div.mlnh-2:nth-of-type(2)')
a_tag = div_mlnh2.find('h2').find('a') a_tag = div_mlnh2.find('h2').find('a')
href = a_tag['href'] href = a_tag['href']
return href return href
except Exception as e: except Exception as e:
logger.warning(f'GS {e}')
return None return None
async def search(showname,date,client): async def search(showname,date,client):
@@ -85,7 +58,7 @@ async def search(showname,date,client):
showname = urllib.parse.quote(showname) showname = urllib.parse.quote(showname)
response = await client.get(ForwardProxy + f'{GS_DOMAIN}/?story={showname}&do=search&subaction=search', allow_redirects=True, impersonate = "chrome124", headers = headers, proxies = proxies) response = await client.get(ForwardProxy + f'{GS_DOMAIN}/?story={showname}&do=search&subaction=search', allow_redirects=True, impersonate = "chrome124", headers = headers, proxies = proxies)
if response.status_code != 200: if response.status_code != 200:
print(f"Guardaserie Failed to fetch search results: {response.status_code}") logger.warning(f"Guardaserie Failed to fetch search results: {response.status_code}")
soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('div')) soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('div'))
div_mlnew = soup.find_all('div', class_='mlnew') div_mlnew = soup.find_all('div', class_='mlnew')
for mlnew in div_mlnew: for mlnew in div_mlnew:
@@ -104,7 +77,7 @@ async def search(showname,date,client):
async def player_url(page_url, season, episode,client): async def player_url(page_url, season, episode,client):
try: try:
headers = random_headers.generate() headers = random_headers.generate()
response = await client.get(ForwardProxy + page_url, allow_redirects=True, impersonate = "chrome124", headers = headers, proxies = proxies) response = await client.get(ForwardProxy + page_url, allow_redirects=True, headers = headers, proxies = proxies)
soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('a')) soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('a'))
a_tag = soup.find('a', id = f"serie-{season}_{episode}") a_tag = soup.find('a', id = f"serie-{season}_{episode}")
href = a_tag['data-link'] href = a_tag['data-link']
@@ -116,19 +89,55 @@ async def player_url(page_url, season, episode,client):
async def guardaserie(id,client): async def guardaserie(streams,id,client):
try: try:
general = await is_movie(id) general = await is_movie(id)
ismovie = general[0] ismovie = general[0]
clean_id = general[1] clean_id = general[1]
if ismovie == 1:
return streams
if ismovie == 0:
season = general[2] season = general[2]
episode = general[3] episode = general[3]
''' type = "Guardaserie"
page_url = await search_imdb(clean_id,client)
supervideo_link =await player_url(page_url,season,episode,client)
if supervideo_link:
streams = await supervideo(supervideo_link, client, streams,"Guardaserie",proxies, ForwardProxy)
return streams
else:
logger.warning(" GS Couldn't find iframe source")
return streams
except Exception as e:
logger.warning(f"MammaMia: Guardaserie Failed{e}")
return streams
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 = "tt10919420:1:1" # This is an example ID format tt0460649
results = await guardaserie({'streams': []},test_id, client)
print(results)
if __name__ == "__main__":
import asyncio
asyncio.run(test_script())
'''
if "tt" not in clean_id: if "tt" not in clean_id:
clean_id = await get_IMDB_id_from_TMDb_id(clean_id,client) clean_id = await get_IMDB_id_from_TMDb_id(clean_id,client)
print(clean_id) print(clean_id)
''' '''
type = "Guardaserie" '''
if "tt" in id: if "tt" in id:
showname,date = await get_info_imdb(clean_id,ismovie,type,client) showname,date = await get_info_imdb(clean_id,ismovie,type,client)
else: else:
@@ -136,34 +145,7 @@ async def guardaserie(id,client):
showname = showname.replace("'"," ") showname = showname.replace("'"," ")
if "Guru" in showname: if "Guru" in showname:
showname = showname.split("-")[0] showname = showname.split("-")[0]
''' '''
if ismovie == 1: '''
return None
'''
page_url = await search_imdb(clean_id,client)
'''
page_url = await search(showname,date,client) page_url = await search(showname,date,client)
''' '''
supervideo_link =await player_url(page_url,season,episode,client)
if supervideo_link:
final_url = await eval_solver(supervideo_link,proxies, ForwardProxy, client)
return final_url
else:
print("Couldn't find iframe source")
return None
except Exception as e:
print("MammaMia: Guardaserie Failed",e)
return None
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 = "tt6226232:3:18" # This is an example ID format tt0460649
results = await guardaserie(test_id, client)
print(results)
if __name__ == "__main__":
import asyncio
asyncio.run(test_script())
+139
View File
@@ -0,0 +1,139 @@
from Src.Utilities.info import get_info_tmdb, is_movie, get_info_imdb
import Src.Utilities.config as config
from fake_headers import Headers
from Src.Utilities.loadenv import load_env
from urllib.parse import quote
from bs4 import BeautifulSoup, SoupStrainer
import re
from Src.API.extractors.uqload import uqload
from Src.API.extractors.loadm import loadm
from Src.API.extractors.dropload import dropload
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
env_vars = load_env()
random_headers = Headers()
GO_DOMAIN = config.GO_DOMAIN
GO_PROXY = config.GO_PROXY
proxies = {}
if GO_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
}
GO_ForwardProxy = config.GO_ForwardProxy
if GO_ForwardProxy == "1":
ForwardProxy = env_vars.get('ForwardProxy')
else:
ForwardProxy = ""
async def get_player(page_link,MFP,MFP_CREDENTIALS,client, headers, streams):
response = await client.get(ForwardProxy + page_link, headers= headers, proxies = proxies)
soup = BeautifulSoup(response.text,'lxml', parse_only=SoupStrainer('iframe'))
iframe = soup.find('iframe')
player_link = iframe.get('data-src') or iframe.get('src')
urls = []
if "loadm" in player_link:
referer = page_link.split('//')[1].split('/')[0]
streams = await loadm(player_link,client,streams,referer,"Guardoserie", proxies,ForwardProxy)
elif "uqload" in player_link:
streams = await uqload(player_link,client,MFP,MFP_CREDENTIALS,streams,"Guardoserie",proxies,ForwardProxy)
elif "dropload" in player_link:
streams = await dropload(player_link,client,streams,"Guardoserie",proxies,ForwardProxy)
return streams
async def search(showname,date,season,episode,MFP, MFP_CREDENTIALS,ismovie,client,streams,):
headers = random_headers.generate()
headers['Origin'] = f'{GO_DOMAIN}'
headers['Referer'] = f'{GO_DOMAIN}/'
headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
showname = quote(showname)
data = f's={showname}&action=searchwp_live_search&swpengine=default&swpquery={showname}'
response = await client.post(ForwardProxy + f'{GO_DOMAIN}/wp-admin/admin-ajax.php', data = data, headers = headers, proxies = proxies)
soup = BeautifulSoup(response.text,'lxml', parse_only= SoupStrainer('a', class_='ss-title'))
a_tags = soup.find_all('a')
for a in a_tags:
href = a['href']
response = await client.get(ForwardProxy + href, headers = headers, proxies = proxies)
pattern = r'(?<=/release-year\/)(\d{4})(?=\/" rel="tag">)'
match = re.search(pattern, response.text)
if match:
year = match.group(0)
if year == date:
if ismovie == 0:
soup = BeautifulSoup(response.text, 'lxml', parse_only= SoupStrainer('div', class_='les-content'))
divs = soup.find_all('div', class_='les-content')
actual_div = divs[int(season)-1]
episodes_a = actual_div.find_all('a')
actual_episode = episodes_a[int(episode)-1]
page_link = actual_episode['href']
logger.info(page_link)
elif ismovie == 1:
page_link = href
streams = await get_player(page_link,MFP,MFP_CREDENTIALS,client, headers,streams)
return streams
async def guardoserie(streams,id,client,MFP,MFP_CREDENTIALS):
try:
general = await is_movie(id)
ismovie = general[0]
clean_id = general[1]
type = "Guardoserie"
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)
logger.info(f'GO {showname}')
streams = await search(showname,date, season,episode,MFP,MFP_CREDENTIALS,ismovie,client,streams)
return streams
except Exception as e:
logger.warning(f'GO {e}')
return streams
async def test_guardoserie():
from curl_cffi.requests import AsyncSession
async with AsyncSession() as client:
results = await guardoserie({'streams': []},"tt16426418",client,"1",['test','test'])
print(results)
if __name__ == "__main__":
import asyncio
asyncio.run(test_guardoserie())
+25 -352
View File
@@ -1,14 +1,16 @@
from bs4 import BeautifulSoup,SoupStrainer from bs4 import BeautifulSoup,SoupStrainer
from Src.Utilities.convert import get_TMDb_id_from_IMDb_id from Src.Utilities.convert import get_TMDb_id_from_IMDb_id
from Src.Utilities.info import get_info_tmdb, is_movie, get_info_imdb from Src.Utilities.info import is_movie
import Src.Utilities.config as config import Src.Utilities.config as config
import json import json
import random import random
import re import re
from urllib.parse import urlparse, parse_qs
from fake_headers import Headers
from Src.Utilities.loadenv import load_env from Src.Utilities.loadenv import load_env
import urllib.parse from Src.API.extractors.vixcloud import vixcloud
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
User_Agent= "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0" User_Agent= "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0"
env_vars = load_env() env_vars = load_env()
@@ -51,354 +53,36 @@ else:
ForwardProxy = "" ForwardProxy = ""
#Get domain #Get domain
SC_DOMAIN = config.SC_DOMAIN SC_DOMAIN = config.SC_DOMAIN
Public_Instance = config.Public_Instance async def vixsrc(streams,id,client,MFP,MFP_CREDENTIALS):
Alternative_Link = env_vars.get('ALTERNATIVE_LINK') general = await is_movie(id)
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 extractor(link,client):
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
response = await client.get(link)
if response.status_code != 200:
print("Failed to extract URL components, Invalid Request")
soup = BeautifulSoup(response.text, "lxml", parse_only=SoupStrainer("body"))
if soup:
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)
server_url = re.search(r"url:\s*'([^']+)'", script).group(1)
quality = re.search(r'"quality":(\d+)', script).group(1)
if "?b=1" in server_url:
final_url = f'{server_url}&token={token}&expires={expires}'
else:
final_url = f"{server_url}?token={token}&expires={expires}"
if "window.canPlayFHD = true" in script:
final_url += "&h=1"
return final_url,quality
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] ismovie = general[0]
imdb_id = general[1] clean_id = general[1]
if "tt" in id:
tmdb_id = await get_TMDb_id_from_IMDb_id(clean_id,client)
else:
tmdb_id = clean_id
if ismovie == 0 : if ismovie == 0 :
season = int(general[2]) season = int(general[2])
episode = int(general[3]) episode = int(general[3])
#Check if fast search is enabled or disabled site_url = f'{SC_DOMAIN}/tv/{tmdb_id}/{general[2]}/{general[3]}/'
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: else:
#I just set n season to None to avoid bugs, but it is not needed if Fast search is enabled site_url = f'{SC_DOMAIN}/movie/{tmdb_id}/'
date = None streams = await vixcloud(site_url,client,MFP,MFP_CREDENTIALS,streams,"Vixcloud",proxies,ForwardProxy)
#else just equals them return streams
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
async def vixsrc(imdb,client,SC_FAST_SEARCH,MFP):
general = await is_movie(imdb)
ismovie = general[0]
id = general[1]
if "tt" in imdb:
tmdb = await get_TMDb_id_from_IMDb_id(id,client)
else:
tmdb = id
if ismovie == 0 :
season = int(general[2])
episode = int(general[3])
site_url = f'{SC_DOMAIN}/tv/{tmdb}/{general[2]}/{general[3]}/'
else:
site_url = f'{SC_DOMAIN}/movie/{tmdb}/'
if MFP == "1":
quality = "Unknown"
return site_url,quality,""
else:
full_url,quality = await extractor(site_url,client)
return full_url,quality,""
async def streaming_community(imdb,client,SC_FAST_SEARCH,MFP): async def streaming_community(streams,id,client,MFP,MFP_CREDENTIALS):
try: try:
if "vixsrc" in SC_DOMAIN: if "vixsrc" in SC_DOMAIN:
url,quality,slug = await vixsrc(imdb,client,SC_FAST_SEARCH,MFP) streams = await vixsrc(streams,id,client,MFP,MFP_CREDENTIALS)
elif "streaming" in SC_DOMAIN: return streams
url,quality,slug = await streamingcommunity_site(imdb,client,SC_FAST_SEARCH,MFP)
return url,quality,slug
except Exception as e: except Exception as e:
print("StreamingCommunity failed",e) logger.warning(f"StreamingCommunity failed {e}")
return None,None,None return streams
'''
'''
async def test_animeworld(): async def test_vixsrc():
from curl_cffi.requests import AsyncSession from curl_cffi.requests import AsyncSession
async with AsyncSession() as client: async with AsyncSession() as client:
# Replace with actual id, for example 'anime_id:episode' format # Replace with actual id, for example 'anime_id:episode' format
@@ -408,7 +92,7 @@ async def test_animeworld():
if __name__ == "__main__": if __name__ == "__main__":
import asyncio import asyncio
asyncio.run(test_animeworld()) asyncio.run(test_vixsrc())
@@ -418,14 +102,3 @@ if __name__ == "__main__":
'''
if Public_Instance == "1":
Weird_Link = json.loads(Alternative_Link)
link_post = random.choice(Weird_Link)
response = await client.get(f"{link_post}fetch-data/{SC_FAST_SEARCH}/{SC_DOMAIN}/{imdb}")
url_streaming_community = response.headers.get('x-url-streaming-community')
url_720_streaming_community = response.headers.get('x-url-720-streaming-community')
quality_sc = response.headers.get('x-quality-sc')
print(quality_sc,url_streaming_community)
return url_streaming_community,url_720_streaming_community,quality_sc
'''
+42 -21
View File
@@ -4,9 +4,37 @@ from Src.Utilities.info import get_info_tmdb, is_movie, get_info_imdb
import Src.Utilities.config as config import Src.Utilities.config as config
import re import re
import json import json
from Src.API.extractors.hdplayer import hdplayer
from Src.Utilities.loadenv import load_env
import logging
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
SW_DOMAIN = config.SW_DOMAIN SW_DOMAIN = config.SW_DOMAIN
env_vars = load_env()
SW_PROXY = config.SW_PROXY
proxies = {}
if SW_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
}
SW_ForwardProxy = config.SW_ForwardProxy
if SW_ForwardProxy == "1":
ForwardProxy = env_vars.get('ForwardProxy')
else:
ForwardProxy = ""
async def wponce_get(client): async def wponce_get(client):
response = await client.get(f"{SW_DOMAIN}/contatto/") response = await client.get(ForwardProxy + f"{SW_DOMAIN}/contatto/", proxies = proxies)
pattern = r'"admin_ajax_nonce":"(\w+)"' pattern = r'"admin_ajax_nonce":"(\w+)"'
matches = re.findall(pattern, response.text) matches = re.findall(pattern, response.text)
wponce = matches[1] wponce = matches[1]
@@ -41,7 +69,7 @@ async def search(showname,season,episode,date,ismovie,client):
cookies = { cookies = {
'wordpress_test_cookie': 'WP%20Cookie%20check', 'wordpress_test_cookie': 'WP%20Cookie%20check',
} }
response = await client.post(query,cookies=cookies, headers=headers, data=data) response = await client.post(ForwardProxy + query,cookies=cookies, headers=headers, data=data, proxies = proxies)
soup = BeautifulSoup(response.content,'lxml') soup = BeautifulSoup(response.content,'lxml')
all_page_dates = soup.find_all(id = 'search-cat-year') all_page_dates = soup.find_all(id = 'search-cat-year')
all_hrefs = soup.find_all('a') all_hrefs = soup.find_all('a')
@@ -50,7 +78,7 @@ async def search(showname,season,episode,date,ismovie,client):
if date == page_date: if date == page_date:
href = temp_href['href'] href = temp_href['href']
href = soup.find('a')['href'] href = soup.find('a')['href']
response = await client.get(href, allow_redirects=True, impersonate = "chrome124") response = await client.get(ForwardProxy + href, allow_redirects=True, proxies = proxies)
soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('iframe')) soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('iframe'))
iframe = soup.find('iframe') iframe = soup.find('iframe')
hdplayer = iframe.get('data-lazy-src') hdplayer = iframe.get('data-lazy-src')
@@ -58,11 +86,11 @@ async def search(showname,season,episode,date,ismovie,client):
return hdplayer return hdplayer
elif ismovie == 0: elif ismovie == 0:
#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 #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
id_response = await client.get(f'{SW_DOMAIN}/wp-json/wp/v2/categories?search={showname}&_fields=id', allow_redirects=True, impersonate = "chrome120") id_response = await client.get(ForwardProxy + f'{SW_DOMAIN}/wp-json/wp/v2/categories?search={showname}&_fields=id', allow_redirects=True, proxies = proxies)
data = json.loads(id_response.text) data = json.loads(id_response.text)
category_id = data[0]['id'] category_id = data[0]['id']
query = f'{SW_DOMAIN}/wp-json/wp/v2/posts?categories={category_id}&per_page=100' query = f'{SW_DOMAIN}/wp-json/wp/v2/posts?categories={category_id}&per_page=100'
response = await client.get(query, allow_redirects=True, impersonate = "chrome120") response = await client.get(ForwardProxy + query, allow_redirects=True, impersonate = "chrome120", proxies = proxies)
data_json = response.text data_json = response.text
data = json.loads(data_json) data = json.loads(data_json)
for entry in data: for entry in data:
@@ -75,13 +103,8 @@ async def search(showname,season,episode,date,ismovie,client):
end = content.find('"', start) #end of url end = content.find('"', start) #end of url
hdplayer = content[start:end] hdplayer = content[start:end]
return hdplayer return hdplayer
async def hls_url(hdplayer,client):
response = await client.get(hdplayer, allow_redirects=True, impersonate = "chrome120")
match = re.search(r'sources:\s*\[\s*\{\s*file\s*:\s*"([^"]*)"', response.text)
url = match.group(1)
return url async def streamingwatch(streams,imdb,client):
async def streamingwatch(imdb,client):
try: try:
general = await is_movie(imdb) general = await is_movie(imdb)
ismovie = general[0] ismovie = general[0]
@@ -103,23 +126,21 @@ async def streamingwatch(imdb,client):
tmdba = imdb_id tmdba = imdb_id
showname,date = get_info_tmdb(tmdba,ismovie,type) showname,date = get_info_tmdb(tmdba,ismovie,type)
showname = showname.replace(" ", "+").replace("–", "+").replace("—","+").replace("&","") showname = showname.replace(" ", "+").replace("–", "+").replace("—","+").replace("&","")
hdplayer = await search(showname,season,episode,date,ismovie,client) url_hdplayer = await search(showname,season,episode,date,ismovie,client)
url = await hls_url(hdplayer,client) streams = await hdplayer(url_hdplayer,client,streams,url_hdplayer,"Streamingwatch",proxies,ForwardProxy)
if url: return streams
#Fix for Exoplayer which needs .m3u8 in the url to play the file
url = url + ".m3u8"
return url,hdplayer
except Exception as e: except Exception as e:
print("MammaMia: StreamingWatch Failed",e) logger.warning(f"MammaMia: StreamingWatch Failed {e}")
return None,None return streams
async def test_animeworld(): async def test_animeworld():
from curl_cffi.requests import AsyncSession from curl_cffi.requests import AsyncSession
async with AsyncSession() as client: async with AsyncSession() as client:
# Replace with actual id, for example 'anime_id:episode' format # Replace with actual id, for example 'anime_id:episode' format
test_id = "tt1190634:4:8" # This is an example ID format test_id = "tt16426418" # This is an example ID format
results = await streamingwatch(test_id, client) results = await streamingwatch({'streams': []},test_id, client)
print(results)
if __name__ == "__main__": if __name__ == "__main__":
import asyncio import asyncio
+19 -26
View File
@@ -1,6 +1,6 @@
#LOAD THE CONFIG #LOAD THE CONFIG
import json import json
import logging
# Open the configuration file # Open the configuration file
with open('config.json') as f: with open('config.json') as f:
# Load JSON data from file # Load JSON data from file
@@ -8,36 +8,24 @@ with open('config.json') as f:
# Accessing SC_DOMAIN # Accessing SC_DOMAIN
SITE = config["Siti"] SITE = config["Siti"]
FT_DOMAIN = SITE["Filmpertutti"]['url']
SC_DOMAIN = SITE["StreamingCommunity"]['url'] SC_DOMAIN = SITE["StreamingCommunity"]['url']
TF_DOMAIN = SITE["Tantifilm"]['url']
LC_DOMAIN = SITE["LordChannel"]['url']
SW_DOMAIN = SITE["StreamingWatch"]['url'] SW_DOMAIN = SITE["StreamingWatch"]['url']
AW_DOMAIN = SITE['AnimeWorld']['url'] AW_DOMAIN = SITE['AnimeWorld']['url']
SKY_DOMAIN = SITE['SkyStreaming']['url']
CB_DOMAIN = SITE['CB01']['url'] CB_DOMAIN = SITE['CB01']['url']
DDL_DOMAIN = SITE['DDLStream']['url']
DLHD_DOMAIN = SITE['DaddyLiveHD']['url']
GS_DOMAIN = SITE['Guardaserie']['url'] GS_DOMAIN = SITE['Guardaserie']['url']
GHD_DOMAIN = SITE['GuardaHD']['url'] GHD_DOMAIN = SITE['GuardaHD']['url']
OST_DOMAIN = SITE['Onlineserietv']['domain']
ES_DOMAIN = SITE['Eurostreaming']['url'] ES_DOMAIN = SITE['Eurostreaming']['url']
GF_DOMAIN = SITE['Guardaflix']['url']
GO_DOMAIN = SITE['Guardoserie']['url']
SC = SITE['StreamingCommunity']['enabled'] SC = SITE['StreamingCommunity']['enabled']
FT = SITE['Filmpertutti']['enabled']
TF = SITE['Tantifilm']['enabled']
LC = SITE['LordChannel']['enabled']
SW = SITE['StreamingWatch']['enabled'] SW = SITE['StreamingWatch']['enabled']
AW = SITE['AnimeWorld']['enabled'] AW = SITE['AnimeWorld']['enabled']
SKY = SITE['SkyStreaming']['enabled']
CB = SITE['CB01']['enabled'] CB = SITE['CB01']['enabled']
DDL = SITE['DDLStream']['enabled']
MYSTERIUS = SITE['Mysterius']['enabled']
GS = SITE['Guardaserie']['enabled'] GS = SITE['Guardaserie']['enabled']
GHD = SITE['GuardaHD']['enabled'] GHD = SITE['GuardaHD']['enabled']
OST = SITE['Onlineserietv']['enabled']
ES= SITE['Eurostreaming']['enabled'] ES= SITE['Eurostreaming']['enabled']
DLHD = SITE['DaddyLiveHD']['enabled'] GF = SITE['Guardaflix']['enabled']
TF_ForwardProxy = SITE['Tantifilm']["TF_ForwardProxy"] GO = SITE['Guardoserie']['enabled']
SC_ForwardProxy = SITE['StreamingCommunity']["SC_ForwardProxy"] SC_ForwardProxy = SITE['StreamingCommunity']["SC_ForwardProxy"]
GS_ForwardProxy = SITE['Guardaserie']["GS_ForwardProxy"] GS_ForwardProxy = SITE['Guardaserie']["GS_ForwardProxy"]
GH_ForwardProxy = SITE['GuardaHD']["GH_ForwardProxy"] GH_ForwardProxy = SITE['GuardaHD']["GH_ForwardProxy"]
@@ -45,22 +33,21 @@ VX_ForwardProxy = SITE['StreamingCommunity']["VX_ForwardProxy"]
AW_ForwardProxy = SITE['AnimeWorld']["AW_ForwardProxy"] AW_ForwardProxy = SITE['AnimeWorld']["AW_ForwardProxy"]
MX_ForwardProxy = SITE['CB01']["MX_ForwardProxy"] MX_ForwardProxy = SITE['CB01']["MX_ForwardProxy"]
CB_ForwardProxy = SITE['CB01']["CB_ForwardProxy"] CB_ForwardProxy = SITE['CB01']["CB_ForwardProxy"]
OST_ForwardProxy = SITE['Onlineserietv']["OST_ForwardProxy"]
ES_ForwardProxy = SITE['Eurostreaming']['ES_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']
GS_PROXY = SITE['Guardaserie']["GS_PROXY"] GS_PROXY = SITE['Guardaserie']["GS_PROXY"]
GH_PROXY = SITE['GuardaHD']["GH_PROXY"] GH_PROXY = SITE['GuardaHD']["GH_PROXY"]
TF_PROXY = SITE['Tantifilm']["TF_PROXY"]
CB_PROXY = SITE['CB01']["CB_PROXY"] CB_PROXY = SITE['CB01']["CB_PROXY"]
SC_PROXY = SITE['StreamingCommunity']["SC_PROXY"] SC_PROXY = SITE['StreamingCommunity']["SC_PROXY"]
VX_PROXY = SITE['StreamingCommunity']["VX_PROXY"] VX_PROXY = SITE['StreamingCommunity']["VX_PROXY"]
AW_PROXY = SITE['AnimeWorld']["AW_PROXY"] AW_PROXY = SITE['AnimeWorld']["AW_PROXY"]
MX_PROXY = SITE['CB01']["MX_PROXY"] MX_PROXY = SITE['CB01']["MX_PROXY"]
OST_PROXY = SITE['Onlineserietv']["OST_PROXY"]
ES_PROXY = SITE['Eurostreaming']['ES_PROXY'] ES_PROXY = SITE['Eurostreaming']['ES_PROXY']
ips4_device_key = SITE['DDLStream']['cookies']["ips4_device_key"] GF_PROXY = SITE['Guardaflix']['GF_PROXY']
ips4_IPSSessionFront = SITE['DDLStream']['cookies']["ips4_IPSSessionFront"] GO_PROXY = SITE['Guardoserie']['GO_PROXY']
ips4_member_id = SITE['DDLStream']['cookies']["ips4_member_id"] SW_PROXY = SITE['StreamingWatch']['SW_PROXY']
ips4_login_key = SITE['DDLStream']['cookies']["ips4_login_key"]
#General #General
GENERAL = config['General'] GENERAL = config['General']
dotenv = GENERAL["load_env"] dotenv = GENERAL["load_env"]
@@ -68,6 +55,12 @@ HOST = GENERAL["HOST"]
PORT = GENERAL["PORT"] PORT = GENERAL["PORT"]
Icon = GENERAL["Icon"] Icon = GENERAL["Icon"]
Name = GENERAL["Name"] Name = GENERAL["Name"]
Public_Instance = GENERAL["Public_Instance"] LEVEL = GENERAL["level"]
Remote_Instance = GENERAL["Remote_Instance"]
Global_Proxy = GENERAL["Global_Proxy"] Global_Proxy = GENERAL["Global_Proxy"]
def setup_logging(LEVEL):
LEVEL = LEVEL.upper()
level = getattr(logging, LEVEL, logging.DEBUG)
logging.basicConfig(level=level,format='%(message)s')
logger = logging.getLogger(__name__)
return logger
-2
View File
@@ -13,10 +13,8 @@ async def get_TMDb_id_from_IMDb_id(imdb_id,client):
else: else:
return None return None
async def get_IMDB_id_from_TMDb_id(tmdb_id,client): async def get_IMDB_id_from_TMDb_id(tmdb_id,client):
print(tmdb_id)
url = f"https://api.themoviedb.org/3/movie/{tmdb_id}?api_key={TMDB_KEY}" url = f"https://api.themoviedb.org/3/movie/{tmdb_id}?api_key={TMDB_KEY}"
response = await client.get(url) response = await client.get(url)
print(response.text)
if response.status_code == 200: if response.status_code == 200:
data = response.json() data = response.json()
imdb_id = data.get('imdb_id') imdb_id = data.get('imdb_id')
+21 -58
View File
@@ -1,17 +1,4 @@
import Src.Utilities.config as config import Src.Utilities.config as config
SKY_DOMAIN = config.SKY_DOMAIN
okru = {
"rai-1": "https://ok.ru/videoembed/9340203179632?nochat=1",
"rai-2": "https://ok.ru/videoembed/9267281010288?nochat=1",
"canale-5": "https://ok.ru/videoembed/7871149252208?nochat=1",
"italia-1": "https://ok.ru/videoembed/7393558339184?nochat=1",
"rai-premium": "https://ok.ru/videoembed/7363152715376?nochat=1",
"rai-movie": "https://ok.ru/videoembed/7384012693104?nochat=1",
"tv8": "https://ok.ru/videoembed/8077072998000?nochat=1",
"rsi-la-2": "https://ok.ru/videoembed/7681648107120?nochat=1",
"mediaset-extra": "https://ok.ru/videoembed/7363151601264?nochat=1",
"mediaset-infinity": "https://ok.ru/videoembed/6323249159792%3Fnochat=1"
}
STREAM = { STREAM = {
"channels": [ "channels": [
@@ -29,7 +16,7 @@ STREAM = {
"name": "Full HD Http", "name": "Full HD Http",
"genres": ["Rai"], "genres": ["Rai"],
"poster": "https://i.imgur.com/bb72vqh.jpeg", "poster": "https://i.imgur.com/bb72vqh.jpeg",
"url": "http://173.208.52.200/rai1/index.m3u8" "url": "https://viamotionhsi.netplus.ch/live/eds/rai1/browser-HLS8/rai1.m3u8"
}, },
{ {
"id": "rai-2", "id": "rai-2",
@@ -37,7 +24,7 @@ STREAM = {
"name": "Full HD Http", "name": "Full HD Http",
"genres": ["Rai"], "genres": ["Rai"],
"poster": "https://i.imgur.com/jX95Qod.jpeg", "poster": "https://i.imgur.com/jX95Qod.jpeg",
"url": "http://173.208.52.200/rai2/index.m3u8" "url": "https://viamotionhsi.netplus.ch/live/eds/rai2/browser-HLS8/rai2.m3u8"
}, },
{ {
"id": "rai-3", "id": "rai-3",
@@ -45,7 +32,7 @@ STREAM = {
"name": "Full HD Http", "name": "Full HD Http",
"genres": ["Rai"], "genres": ["Rai"],
"poster": "https://i.imgur.com/fgAh9if.jpeg", "poster": "https://i.imgur.com/fgAh9if.jpeg",
"url": "http://173.208.52.200/rai3/index.m3u8" "url": "https://viamotionhsi.netplus.ch/live/eds/rai3/browser-HLS8/rai3.m3u8"
}, },
{ {
"id": "rai-4", "id": "rai-4",
@@ -53,7 +40,7 @@ STREAM = {
"name": "Full HD Http", "name": "Full HD Http",
"genres": ["Rai"], "genres": ["Rai"],
"poster": "https://i.imgur.com/NryLzhA.jpeg", "poster": "https://i.imgur.com/NryLzhA.jpeg",
"url": "http://173.208.52.200/rai4/index.m3u8" "url": "https://raiquattro1-dash-live.akamaized.net/dash/live/663977/raiquattro1/manifest.mpd"
}, },
{ {
"id": "rai-premium", "id": "rai-premium",
@@ -61,7 +48,7 @@ STREAM = {
"name": "Full HD", "name": "Full HD",
"genres": ["Rai"], "genres": ["Rai"],
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/rai-premium_c.png", "poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/rai-premium_c.png",
"url": "https://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=746992" "url": "https://raipremium1-dash-live.akamaized.net/dash/live/663979/raipremium1/manifest.mpd"
}, },
{ {
"id": "rai-4k", "id": "rai-4k",
@@ -78,7 +65,7 @@ STREAM = {
"name": "", "name": "",
"genres": ["Rai"], "genres": ["Rai"],
"poster": "https://is1-ssl.mzstatic.com/image/thumb/Purple221/v4/31/05/eb/3105eb24-a953-7bb9-876d-0fcfb0a19055/AppIcon-0-0-1x_U007epad-0-10-0-0-85-220.png/1200x630wa.png", "poster": "https://is1-ssl.mzstatic.com/image/thumb/Purple221/v4/31/05/eb/3105eb24-a953-7bb9-876d-0fcfb0a19055/AppIcon-0-0-1x_U007epad-0-10-0-0-85-220.png/1200x630wa.png",
"url": "https://streamcdnb4-8e7439fdb1694c8da3a0fd63e4dda518.msvdn.net/rainews1/hls/playlist_mo.m3u8" "url": "https://streamcdnb2-8e7439fdb1694c8da3a0fd63e4dda518.msvdn.net/rainews1/hls/playlist_mo.m3u8"
}, },
{ {
"id": "rai-movie", "id": "rai-movie",
@@ -86,7 +73,7 @@ STREAM = {
"name": "", "name": "",
"genres": ["Rai"], "genres": ["Rai"],
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/rai-movie_c.png", "poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/rai-movie_c.png",
"url": "https://m3u.iranvids.com/rai-movie/output.m3u8" "url": "https://raimovie1-dash-live.akamaized.net/dash/live/663983/raimovie1/manifest.mpd"
}, },
{ {
"id": "rai-sport", "id": "rai-sport",
@@ -94,7 +81,7 @@ STREAM = {
"name": "", "name": "",
"genres": ["Rai"], "genres": ["Rai"],
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/rai-sport_c.png", "poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/rai-sport_c.png",
"url": "https://m3u.iranvids.com/rai-sport01/output.m3u8" "url": "https://viamotionhsi.netplus.ch/live/eds/raisport1/browser-HLS8/raisport1.m3u8"
}, },
{ {
"id": "rete-4", "id": "rete-4",
@@ -102,7 +89,7 @@ STREAM = {
"name": "Full HD Http", "name": "Full HD Http",
"genres": ["Mediaset"], "genres": ["Mediaset"],
"poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/Rete_4_2018.svg/1024px-Rete_4_2018.svg.png", "poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/Rete_4_2018.svg/1024px-Rete_4_2018.svg.png",
"url": "http://173.208.52.200/rete4/index.m3u8" "url": "https://live02-seg.msf.cdn.mediaset.net/live/ch-r4/r4-clr.isml/index.m3u8"
}, },
{ {
"id": "euronews", "id": "euronews",
@@ -118,7 +105,7 @@ STREAM = {
"name": "Full HD Http", "name": "Full HD Http",
"genres": ["Mediaset"], "genres": ["Mediaset"],
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/canale-5_c.png", "poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/canale-5_c.png",
"url": "http://173.208.52.200/canale5/index.m3u8" "url": "https://viamotionhsi.netplus.ch/live/eds/canale5/browser-HLS8/canale5.m3u8"
}, },
{ {
"id": "italia-1", "id": "italia-1",
@@ -126,7 +113,7 @@ STREAM = {
"name": "Full HD Http", "name": "Full HD Http",
"genres": ["Mediaset"], "genres": ["Mediaset"],
"poster": "https://upload.wikimedia.org/wikipedia/en/thumb/e/e2/Italia_1.svg/1024px-Italia_1.svg.png", "poster": "https://upload.wikimedia.org/wikipedia/en/thumb/e/e2/Italia_1.svg/1024px-Italia_1.svg.png",
"url": "http://173.208.52.200/italia1/index.m3u8" "url": "https://viamotionhsi.netplus.ch/live/eds/italia1/browser-HLS8/italia1.m3u8"
}, },
{ {
"id": "topcrime", "id": "topcrime",
@@ -543,12 +530,12 @@ webru_dlhd = {
} }
extra_sources = { extra_sources = {
"rai-1": ["https://m3u.iranvids.com/rai01/output.m3u8"], "rai-1": ["https://ilglobotv-live.akamaized.net/channels/RAI1/Live.m3u8"],
"rai-2": ["https://m3u.iranvids.com/rai02/output.m3u8"], "rai-2": ["https://ilglobotv-live.akamaized.net/channels/RAI2/Live.m3u8"],
"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"], "rai-3": ["https://ilglobotv-live.akamaized.net/channels/RAI2/Live.m3u8","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"],
"rete-4":["https://tvit.leicaflorianrobert.dev/mediaset/rete-4/stream.m3u8","https://live02-seg.msf.cdn.mediaset.net/live/ch-r4/r4-clr.isml/index.m3u8"], "rete-4":["https://tvit.leicaflorianrobert.dev/mediaset/rete-4/stream.m3u8","https://timlivetu0.cb.ticdn.it/Content/DASH/Live/channel(rete4)/manifest.mpd"],
"canale-5":["https://live02-seg.msf.cdn.mediaset.net/live/ch-c5/c5-clr.isml/index.m3u8","https://tvit.leicaflorianrobert.dev/mediaset/canale-5/stream.m3u8"], "canale-5":["https://timlivetu0.cb.ticdn.it/Content/DASH/Live/channel(canale5)/manifest.mpd","https://tvit.leicaflorianrobert.dev/mediaset/canale-5/stream.m3u8",'https://timlivetu0.cb.ticdn.it/Content/DASH/Live/channel(canale5)/manifest.mpd','https://live02-seg.msf.cdn.mediaset.net/live/ch-c5/c5-clr.isml/index.m3u8'],
"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"], "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",'https://timlivetu0.cb.ticdn.it/Content/DASH/Live/channel(italia1)/manifest.mpd'],
"rai-4k": ["https://list.iptvcat.com/my_list/s/fbf04fbd9694eee71b5af9f12e49538d.m3u8"], "rai-4k": ["https://list.iptvcat.com/my_list/s/fbf04fbd9694eee71b5af9f12e49538d.m3u8"],
"rai-news":["https://8e7439fdb1694c8da3a0fd63e4dda518.msvdn.net/rainews1/hls/playlist_mo.m3u8"], "rai-news":["https://8e7439fdb1694c8da3a0fd63e4dda518.msvdn.net/rainews1/hls/playlist_mo.m3u8"],
"topcrime": ["https://tvit.leicaflorianrobert.dev/mediaset/top-crime/stream.m3u8"], "topcrime": ["https://tvit.leicaflorianrobert.dev/mediaset/top-crime/stream.m3u8"],
@@ -564,33 +551,7 @@ extra_sources = {
"doctor-who": ["https://amg00793-amg00793c17-samsung-it-4577.playouts.now.amagi.tv/playlist/amg00793-bbcstudios-drwhoitaly-samsungit/playlist.m3u8"], "doctor-who": ["https://amg00793-amg00793c17-samsung-it-4577.playouts.now.amagi.tv/playlist/amg00793-bbcstudios-drwhoitaly-samsungit/playlist.m3u8"],
"supertennis": ["https://live-embed.supertennix.hiway.media/restreamer/supertennix_client/gpu-a-c0-16/restreamer/outgest/h24_supertennix/manifest.m3u8"] "supertennis": ["https://live-embed.supertennix.hiway.media/restreamer/supertennix_client/gpu-a-c0-16/restreamer/outgest/h24_supertennix/manifest.m3u8"]
} }
skystreaming ={
"sky-sport-tennis": f"{SKY_DOMAIN}/embed/MKCKP",
"sky-sport-24": f"{SKY_DOMAIN}/embed/GB7zq",
"sky-sport-251": f"{SKY_DOMAIN}/embed/drHbM",
"sky-sport-252": f"{SKY_DOMAIN}/embed/m5kfg",
"sky-sport-253": f"{SKY_DOMAIN}/embed/YprHf",
"sky-sport-254": f"{SKY_DOMAIN}/embed/wroRV",
"sky-sport-255": f"{SKY_DOMAIN}/embed/0TixN",
"sky-sport-256": f"{SKY_DOMAIN}/embed/8g8bh",
"sky-sport-257": f"{SKY_DOMAIN}/embed/ri859",
"sky-sport-258": f"{SKY_DOMAIN}/embed/UoJuW",
"sky-sport-259": f"{SKY_DOMAIN}/embed/squCy",
"sky-sport-260": f"{SKY_DOMAIN}/embed/Z5h2e",
"sky-sport-261": f"{SKY_DOMAIN}/embed/Hz9FW",
"sky-sport-uno": f"{SKY_DOMAIN}/embed/tb1np",
"sky-sport-f1": f"{SKY_DOMAIN}/embed/MLkym",
"sky-sport-motogp": f"{SKY_DOMAIN}/embed/ARFFv",
"sky-sport-calcio": f"{SKY_DOMAIN}/embed/STOZT",
"sky-sport-arena": f"{SKY_DOMAIN}/embed/NkEda",
"sky-sport-max": f"{SKY_DOMAIN}/embed/4QzWz",
"sky-sport-nba": f"{SKY_DOMAIN}/embed/saR8j",
"sky-sport-golf": f"{SKY_DOMAIN}/embed/s9L5f",
"eurosport-1": f"{SKY_DOMAIN}/embed/Vyv99",
"eurosport-2": f"{SKY_DOMAIN}/embed/um8E5",
"dazn-zona-a": ["https://hls.kangal.sbs/hls/serie/index.m3u8","https://hls.kangal.sbs/hls/serie/index.m3u8"],
"sportitalia": "https://hls.kangal.sbs/hls/sportitalia/index.m3u8",
}
huhu = { huhu = {
"canale-5": "1101559666", "canale-5": "1101559666",
"sky-sport-motogp": "2090703806", "sky-sport-motogp": "2090703806",
@@ -619,5 +580,7 @@ provider_map = {
"GS": "GUARDASERIE", "GS": "GUARDASERIE",
"GHD": "GUARDAHD", "GHD": "GUARDAHD",
"OST": "ONLINESERIETV", "OST": "ONLINESERIETV",
"ES": "EUROSTREAMING" "ES": "EUROSTREAMING",
"GO": "GUARDOSERIE",
"GF": "GUARDAFLIX"
} }
+7 -3
View File
@@ -14,6 +14,11 @@ from fake_headers import Headers
"""Unpacker for Dean Edward's p.a.c.k.e.r""" """Unpacker for Dean Edward's p.a.c.k.e.r"""
import re import re
from bs4 import BeautifulSoup, SoupStrainer from bs4 import BeautifulSoup, SoupStrainer
import logging
import Src.Utilities.config as config
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
def detect(source): def detect(source):
if "eval(function(p,a,c,k,e,d)" in source: if "eval(function(p,a,c,k,e,d)" in source:
@@ -142,7 +147,7 @@ async def eval_solver(stream_link,proxies, ForwardProxy, client):
headers["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" headers["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"
headers["accept-language"] = 'en-US,en;q=0.5' headers["accept-language"] = 'en-US,en;q=0.5'
response = await client.get( ForwardProxy + stream_link, allow_redirects=True, timeout=30, headers = headers, proxies = proxies, impersonate = "chrome124") response = await client.get( ForwardProxy + stream_link, allow_redirects=True, timeout=30, headers = headers, proxies = proxies, impersonate = "chrome124")
print("Eval:",response.status_code) logger.debug("Eval:",response.status_code)
soup = BeautifulSoup(response.text, "lxml",parse_only=SoupStrainer("script")) soup = BeautifulSoup(response.text, "lxml",parse_only=SoupStrainer("script"))
script_all = soup.find_all("script") script_all = soup.find_all("script")
for i in script_all: for i in script_all:
@@ -158,7 +163,7 @@ async def eval_solver(stream_link,proxies, ForwardProxy, client):
m3u8_url = match.group(1) m3u8_url = match.group(1)
return m3u8_url return m3u8_url
except Exception as e: except Exception as e:
print("Eval solver error\n",e) logger.debug("Eval solver error\n",e)
raise Exception("Error in eval_solver") raise Exception("Error in eval_solver")
@@ -167,7 +172,6 @@ async def test_animeworld():
from curl_cffi.requests import AsyncSession from curl_cffi.requests import AsyncSession
async with AsyncSession() as client: async with AsyncSession() as client:
results = await eval_solver("https://mixdrop.cv/e/l6kqxrm4t4l4or",{},"",client) results = await eval_solver("https://mixdrop.cv/e/l6kqxrm4t4l4or",{},"",client)
print("https:"+results)
if __name__ == "__main__": if __name__ == "__main__":
import asyncio import asyncio
+24 -1
View File
@@ -57,6 +57,10 @@ def get_info_tmdb(tmbda,ismovie,type):
date = show.first_air_date date = show.first_air_date
date = date.split("-")[0] date = date.split("-")[0]
return showname,date return showname,date
elif type == "Guardoserie":
date = show.first_air_date
date = date.split("-")[0]
return showname,date
elif ismovie == 1: elif ismovie == 1:
movie = Movie() movie = Movie()
@@ -97,6 +101,14 @@ def get_info_tmdb(tmbda,ismovie,type):
date = show.release_date date = show.release_date
date = date.split("-")[0] date = date.split("-")[0]
return showname,date return showname,date
elif type == "Guardoserie":
date = show.release_date
date = date.split("-")[0]
return showname,date
elif type == 'Guardaflix':
date = show.release_date
date = date.split("-")[0]
return showname,date
async def get_info_imdb(imdb_id, ismovie, type,client): 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') resp = await client.get(f'https://api.themoviedb.org/3/find/{imdb_id}?api_key={TMDB_KEY}&language=it&external_source=imdb_id')
@@ -141,7 +153,10 @@ async def get_info_imdb(imdb_id, ismovie, type,client):
date = data['tv_results'][0]['first_air_date'] date = data['tv_results'][0]['first_air_date']
date = date.split("-")[0] date = date.split("-")[0]
return showname,date return showname,date
elif type == "Guardoserie":
date = data['tv_results'][0]['first_air_date']
date = date.split("-")[0]
return showname,date
elif ismovie == 1: elif ismovie == 1:
showname= data['movie_results'][0]['title'] showname= data['movie_results'][0]['title']
if type == "Filmpertutti": if type == "Filmpertutti":
@@ -172,6 +187,14 @@ async def get_info_imdb(imdb_id, ismovie, type,client):
date = data['movie_results'][0]['release_date'] date = data['movie_results'][0]['release_date']
date = date.split("-")[0] date = date.split("-")[0]
return showname,date return showname,date
elif type == "Guardoserie":
date = data['movie_results'][0]['release_date']
date = date.split("-")[0]
return showname,date
elif type == 'Guardaflix':
date = data['movie_results'][0]['release_date']
date = date.split("-")[0]
return showname,date
async def get_info_kitsu(kitsu_id,client): async def get_info_kitsu(kitsu_id,client):
+1 -6
View File
@@ -1,8 +1,6 @@
import os import os
import Src.Utilities.config as config import Src.Utilities.config as config
MYSTERIUS = config.MYSTERIUS
dotenv = config.dotenv dotenv = config.dotenv
Public_Instance = config.Public_Instance
#You need to keep dotenv disabled on remote servers #You need to keep dotenv disabled on remote servers
if dotenv == "1": if dotenv == "1":
from dotenv import load_dotenv from dotenv import load_dotenv
@@ -12,10 +10,7 @@ if dotenv == "1":
def load_env(): def load_env():
env_vars = {} env_vars = {}
env_vars['TMDB_KEY'] = os.getenv('TMDB_KEY') env_vars['TMDB_KEY'] = os.getenv('TMDB_KEY')
if MYSTERIUS == "1":
env_vars['MYSTERIUS_KEY'] = os.getenv('MYSTERIUS_KEY')
env_vars['PROXY_CREDENTIALS'] = os.getenv('PROXY') env_vars['PROXY_CREDENTIALS'] = os.getenv('PROXY')
if Public_Instance == "1":
env_vars['ALTERNATIVE_LINK'] = os.getenv('ALTERNATIVE_LINK')
env_vars['ForwardProxy'] = os.getenv('FORWARDPROXY') env_vars['ForwardProxy'] = os.getenv('FORWARDPROXY')
env_vars['PORT_ENV'] = os.getenv('PORT')
return env_vars return env_vars
+27
View File
@@ -0,0 +1,27 @@
import logging
import Src.Utilities.config as config
from Src.Utilities.config import setup_logging
import urllib.parse
level = config.LEVEL
logger = setup_logging(level)
async def transform_mfp(mfp_stream_url,client):
try:
response = await client.get(mfp_stream_url)
data = response.json()
url = data['mediaflow_proxy_url'] + "?api_password=" + data['query_params']['api_password'] + "&d=" + urllib.parse.quote(data['destination_url'])
for i in data['request_headers']:
url += f"&h_{i}={urllib.parse.quote(data['request_headers'][i])}"
return url
except Exception as e:
logger.warning(f"Converting MFP failed {e}")
return None
async def build_mfp(MFP_CREDENTIALS,url,host,client):
MFP_url = MFP_CREDENTIALS[0]
MFP_password = MFP_CREDENTIALS[1]
url_mfp = f'{MFP_url}/extractor/video?api_password={MFP_password}&d={url}&host={host}&redirect_stream=false'
#To build pieces together
url_mfp = await transform_mfp(url_mfp,client)
return url_mfp
+4
View File
@@ -0,0 +1,4 @@
{
"projectName": "MammaMia",
"lastCommit": "10f381b"
}
+17 -45
View File
@@ -8,47 +8,22 @@
"VX_PROXY": "0", "VX_PROXY": "0",
"enabled": "1" "enabled": "1"
}, },
"Filmpertutti": {
"url": "https://filmpertutti.motorcycles",
"enabled": "0"
},
"Tantifilm":{
"url": "https://www.tanti.bond",
"TF_ForwardProxy": "1",
"TF_PROXY": "0",
"enabled": "0"
},
"Mysterius":{
"enabled": "0"
},
"LordChannel":{
"url":"https://lordchannel.net",
"enabled":"0"
},
"StreamingWatch":{ "StreamingWatch":{
"url":"https://www.streamingwatch.org", "url":"https://www.streamingwatch.org",
"SW_PROXY": "0",
"SW_ForwardProxy": "0",
"enabled":"1" "enabled":"1"
}, },
"CB01":{ "CB01":{
"url":"https://cb01new.loan", "url":"https://cb01.uno",
"CB_PROXY":"0", "CB_PROXY":"0",
"CB_ForwardProxy":"0", "CB_ForwardProxy":"0",
"MX_ForwardProxy":"0", "MX_ForwardProxy":"0",
"MX_PROXY":"0", "MX_PROXY":"0",
"enabled":"1" "enabled":"1"
}, },
"DDLStream":{
"url":"https://ddlstreamitaly.co",
"cookies" : {
"ips4_device_key": null,
"ips4_IPSSessionFront": null,
"ips4_member_id": null,
"ips4_login_key": null
},
"enabled":"0"
},
"Guardaserie":{ "Guardaserie":{
"url":"https://guardaserietv.cc", "url":"https://guardaserie.qpon",
"enabled":"1", "enabled":"1",
"GS_ForwardProxy":"0", "GS_ForwardProxy":"0",
"GS_PROXY":"0" "GS_PROXY":"0"
@@ -59,31 +34,29 @@
"GH_ForwardProxy":"0", "GH_ForwardProxy":"0",
"GH_PROXY":"0" "GH_PROXY":"0"
}, },
"Onlineserietv":{
"domain":"com",
"enabled":"0",
"OST_ForwardProxy":"0",
"OST_PROXY":"0"
},
"Eurostreaming":{ "Eurostreaming":{
"url": "https://eurostreaming.garden", "url": "https://eurostreaming.garden",
"enabled": "1", "enabled": "1",
"ES_ForwardProxy": "0", "ES_ForwardProxy": "0",
"ES_PROXY": "0" "ES_PROXY": "0"
}, },
"Guardaflix":{
"url": "https://guardaflix.live",
"enabled": "1",
"GF_ForwardProxy": "0",
"GF_PROXY": "0"
},
"Guardoserie":{
"url": "https://guardoserie.live",
"enabled": "1",
"GO_ForwardProxy": "0",
"GO_PROXY": "0"
},
"AnimeWorld":{ "AnimeWorld":{
"url":"https://www.animeworld.so", "url":"https://www.animeworld.so",
"enabled":"1", "enabled":"1",
"AW_ForwardProxy":"0", "AW_ForwardProxy":"0",
"AW_PROXY":"0" "AW_PROXY":"0"
},
"SkyStreaming":{
"url":"https://skystreaming.watch",
"enabled":"1"
},
"DaddyLiveHD":{
"url":"https://daddylive.mp",
"enabled":"1"
} }
}, },
"General":{ "General":{
@@ -92,8 +65,7 @@
"PORT": 8080, "PORT": 8080,
"Name": "MammaMia", "Name": "MammaMia",
"Icon": "🍕️", "Icon": "🍕️",
"Public_Instance": "0", "level": "info",
"Remote_Instance": "0",
"Global_Proxy": "0" "Global_Proxy": "0"
} }
} }
+2
View File
@@ -9,3 +9,5 @@ lxml
slowapi slowapi
curl_cffi curl_cffi
fake-headers fake-headers
pycryptodome
rich
+62 -220
View File
@@ -1,37 +1,41 @@
from fastapi import FastAPI, HTTPException,Request from fastapi import FastAPI, HTTPException,Request
from fastapi.responses import JSONResponse,RedirectResponse,HTMLResponse from fastapi.responses import JSONResponse,RedirectResponse,HTMLResponse
from Src.API.filmpertutti import filmpertutti
from Src.API.streamingcommunity import streaming_community
from Src.API.tantifilm import tantifilm
from Src.API.lordchannel import lordchannel
from Src.API.streamingwatch import streamingwatch
from Src.API.ddlstream import ddlstream
from Src.API.cb01 import cb01
from Src.API.guardaserie import guardaserie
from Src.API.guardahd import guardahd
import Src.Utilities.config as config
import logging
from Src.API.okru import okru_get_url
from Src.API.animeworld import animeworld
from Src.Utilities.dictionaries import okru,STREAM,extra_sources,webru_vary,webru_dlhd,provider_map,skystreaming
from Src.API.epg import tivu, tivu_get,epg_guide,convert_bho_1,convert_bho_2,convert_bho_3
from Src.API.webru import webru,get_skystreaming
from Src.API.onlineserietv import onlineserietv
from Src.API.eurostreaming import eurostreaming
from curl_cffi.requests import AsyncSession
from slowapi import Limiter from slowapi import Limiter
from slowapi.util import get_remote_address from slowapi.util import get_remote_address
from slowapi.middleware import SlowAPIMiddleware from slowapi.middleware import SlowAPIMiddleware
from static.static import HTML from static.static import HTML
from static.configure import CONFIGURE
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
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.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
import logging
from urllib.parse import unquote from urllib.parse import unquote
from Src.Utilities.m3u8 import router as m3u8_clone from curl_cffi.requests import AsyncSession
import urllib.parse import base64
import Src.Utilities.config as config
from Src.Utilities.config import setup_logging
level = config.LEVEL
logger = setup_logging(level)
from Src.Utilities.loadenv import load_env
env_vars = load_env()
#Configure Env Vars #Configure Env Vars
Global_Proxy = config.Global_Proxy Global_Proxy = config.Global_Proxy
if Global_Proxy == "1": if Global_Proxy == "1":
from Src.Utilities.loadenv import load_env
env_vars = load_env()
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS') PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
proxies = { proxies = {
"http": PROXY_CREDENTIALS, "http": PROXY_CREDENTIALS,
"https": PROXY_CREDENTIALS "https": PROXY_CREDENTIALS
@@ -39,41 +43,31 @@ if Global_Proxy == "1":
else: else:
proxies = {} proxies = {}
# Configure config # Configure config
MYSTERIUS = config.MYSTERIUS
DLHD = config.DLHD
SC = config.SC SC = config.SC
SC_DOMAIN = config.SC_DOMAIN SC_DOMAIN = config.SC_DOMAIN
FT = config.FT
TF = config.TF
LC = config.LC
SW = config.SW SW = config.SW
AW = config.AW AW = config.AW
SKY = config.SKY
CB = config.CB CB = config.CB
DDL = config.DDL
GS = config.GS GS = config.GS
GHD = config.GHD GHD = config.GHD
OST = config.OST
ES = config.ES ES = config.ES
GF = config.GF
GO = config.GO
HOST = config.HOST HOST = config.HOST
PORT = int(config.PORT) PORT = int(config.PORT)
if env_vars.get('PORT_ENV'):
PORT = int(env_vars.get('PORT_ENV'))
Icon = config.Icon Icon = config.Icon
Name = config.Name Name = config.Name
SKY_DOMAIN = config.SKY_DOMAIN
Remote_Instance = config.Remote_Instance
#Cool code to set the hugging face if the service is hosted there. #Cool code to set the hugging face if the service is hosted there.
if MYSTERIUS == "1":
from Src.API.cool import cool
DDL_DOMAIN = config.DDL_DOMAIN
app = FastAPI() app = FastAPI()
app.include_router(m3u8_clone)
limiter = Limiter(key_func=get_remote_address) limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter app.state.limiter = limiter
app.add_middleware(SlowAPIMiddleware) 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" User_Agent= "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"
MANIFEST = { MANIFEST = {
"id": "org.stremio.mammamia", "id": "org.stremio.mammamia",
"version": "1.5.0", "version": "2.0.0",
"catalogs": [ "catalogs": [
{ {
"type": "tv", "type": "tv",
@@ -105,24 +99,20 @@ def respond_with(data):
resp.headers['Access-Control-Allow-Origin'] = '*' resp.headers['Access-Control-Allow-Origin'] = '*'
resp.headers['Access-Control-Allow-Headers'] = '*' resp.headers['Access-Control-Allow-Headers'] = '*'
return resp return resp
async def transform_mfp(mfp_stream_url,client):
try:
response = await client.get(mfp_stream_url)
data = response.json()
url = data['mediaflow_proxy_url'] + "?api_password=" + data['query_params']['api_password'] + "&d=" + urllib.parse.quote(data['destination_url'])
for i in data['request_headers']:
url += f"&h_{i}={urllib.parse.quote(data['request_headers'][i])}"
return url
except Exception as e:
print("Converting MFP failed",e) @app.get('/configure',response_class=HTMLResponse)
return None def config(request: Request):
@app.get('/config') forwarded_proto = request.headers.get("x-forwarded-proto")
def config(): scheme = forwarded_proto if forwarded_proto else request.url.scheme
return RedirectResponse(url="/") instance_url = f"{scheme}://{request.url.netloc}"
html_content = CONFIGURE.replace("{instance_url}", instance_url)
return html_content
@app.get('/{config:path}/manifest.json') @app.get('/{config:path}/manifest.json')
def addon_manifest(config: str): def addon_manifest(config: str):
manifest_copy = MANIFEST.copy() manifest_copy = MANIFEST.copy()
config = base64.b64decode(config).decode('utf-8')
if "LIVETV" in config: if "LIVETV" in config:
return respond_with(manifest_copy) return respond_with(manifest_copy)
elif "LIVETV" not in config: elif "LIVETV" not in config:
@@ -187,7 +177,6 @@ async def addon_meta(request: Request,id: str):
description,title = await epg_guide(channel["id"],client) description,title = await epg_guide(channel["id"],client)
elif channel["id"] in tivu: elif channel["id"] in tivu:
description = await tivu_get(channel["id"],client) description = await tivu_get(channel["id"],client)
print(description)
title = "" title = ""
else: else:
description = f'Watch {channel["title"]}' description = f'Watch {channel["title"]}'
@@ -217,6 +206,7 @@ async def addon_stream(request: Request,config, type, id,):
if type not in MANIFEST['types']: if type not in MANIFEST['types']:
raise HTTPException(status_code=404) raise HTTPException(status_code=404)
streams = {'streams': []} streams = {'streams': []}
config = base64.b64decode(config).decode('utf-8')
if "|" in config: if "|" in config:
config_providers = config.split('|') config_providers = config.split('|')
elif "%7C" in config: elif "%7C" in config:
@@ -232,12 +222,17 @@ async def addon_stream(request: Request,config, type, id,):
# Split the data by comma to get proxy URL and password # Split the data by comma to get proxy URL and password
MFP_url, MFP_password = mfp_data.split(",") MFP_url, MFP_password = mfp_data.split(",")
MFP_password = MFP_password[:-2] MFP_password = MFP_password[:-2]
#If mfp_url ends with a string we remove it
if MFP_url.endswith('/'):
MFP_url = MFP_url[:-1]
# Store them in a list # Store them in a list
MFP_CREDENTIALS = [MFP_url, MFP_password] MFP_CREDENTIALS = [MFP_url, MFP_password]
if MFP_url and MFP_password: if MFP_url and MFP_password:
MFP = "1" MFP = "1"
else: else:
MFP = "0" MFP = "0"
MFP_CREDENTIALS = ['','']
async with AsyncSession(proxies = proxies) as client: async with AsyncSession(proxies = proxies) as client:
if type == "tv": if type == "tv":
for channel in STREAM["channels"]: for channel in STREAM["channels"]:
@@ -245,190 +240,37 @@ async def addon_stream(request: Request,config, type, id,):
i = 0 i = 0
if 'url' in channel: if 'url' in channel:
i = i+1 i = i+1
streams['streams'].append({ streams['streams'].append({'title': f"{Icon}Server {i} " + f" "+ channel['name'] + " " + channel['title'] ,'url': channel['url']})
'title': f"{Icon}Server {i} " + f" "+ channel['name'] + " " + channel['title'] ,
'url': channel['url']
})
if id in okru:
i = i+1
channel_url = await okru_get_url(id,client)
streams['streams'].append({'title': f"{Icon}Server {i} " + channel['title'] + " OKRU",'url': channel_url, "behaviorHints": {"notWebReady": True, "proxyHeaders": {"request": {"User-Agent": User_Agent}}}})
if id in extra_sources: if id in extra_sources:
list_sources = extra_sources[id] list_sources = extra_sources[id]
for item in list_sources: for item in list_sources:
i = i+1 i = i+1
if "iran" in item:
streams['streams'].append({'title':f"{Icon}Server {i} " + channel['title'],'url': item, "behaviorHints": {"notWebReady": True, "proxyHeaders": {"request": {"Origin": "https://babaktv.com", "Referer": "https://babaktv.com/"}}}})
else:
streams['streams'].append({'title':f"{Icon}Server {i} " + channel['title'],'url': item}) streams['streams'].append({'title':f"{Icon}Server {i} " + channel['title'],'url': item})
if id in skystreaming and SKY == "1":
url,Host,Sky_Origin = await get_skystreaming(id,client)
i = i+1
if url:
streams['streams'].append({'title': f'{Icon}Server S {i}' + channel['title'], 'url': url, "behaviorHints": {"notWebReady": True, "proxyHeaders": {"request": {"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0", "Accept": "*/*", "Accept-Language": "en-US,en;q=0.5", "Origin": Sky_Origin, "DNT": "1", "Sec-GPC": "1", "Connection": "keep-alive", "Referer": f"{Sky_Origin}/", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "cross-site", "Pragma": "no-cache", "Cache-Control": "no-cache", "TE": "trailers","Host": Host}}}})
if id in webru_vary:
i = i+1
webru_url, Referer_webru_url,Origin_webru_url = await webru(id,"vary",client)
if MFP== "1" and webru_url:
webru_url = f'{MFP_url}/proxy/hls/manifest.m3u8?api_password={MFP_password}&d={webru_url}&h_Referer={Referer_webru_url}&h_Origin={Origin_webru_url}&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'
streams['streams'].append({'title': f"{Icon}Proxied Server X-{i} " + channel['title'],'url': webru_url})
else:
if webru_url:
streams['streams'].append({'title': f'{Icon}Server X-{i}' + channel['title'], 'url': webru_url, "behaviorHints": {"notWebReady": True, "proxyHeaders": {"request": {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3", "Accept": "*/*", "Accept-Language": "en-US,en;q=0.5", "Origin": Origin_webru_url, "DNT": "1", "Sec-GPC": "1", "Connection": "keep-alive", "Referer": Referer_webru_url, "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "cross-site", "Pragma": "no-cache", "Cache-Control": "no-cache", "TE": "trailers"}}}})
if id in webru_dlhd:
if DLHD == "1":
i = i+1
webru_url_2,Referer_webru_url_2,Origin_webru_url_2 = await webru(id,"dlhd",client)
if MFP== "1":
webru_url_2 = f'{MFP_url}/proxy/hls/manifest.m3u8?api_password={MFP_password}&d={webru_url_2}&h_Referer={Referer_webru_url_2}&h_Origin={Origin_webru_url_2}&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'
streams['streams'].append({'title': f"{Icon}Proxied Server D-{i} " + channel['title'],'url': webru_url_2})
else:
streams['streams'].append({'title': f'{Icon}Server D-{i}' + channel['title'], 'url': webru_url_2, "behaviorHints": {"notWebReady": True, "proxyHeaders": {"request": {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3", "Accept": "*/*", "Accept-Language": "en-US,en;q=0.5", "Origin": Origin_webru_url_2, "DNT": "1", "Sec-GPC": "1", "Connection": "keep-alive", "Referer": Referer_webru_url_2, "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "cross-site", "Pragma": "no-cache", "Cache-Control": "no-cache", "TE": "trailers"}}}})
if not streams['streams']: if not streams['streams']:
raise HTTPException(status_code=404) raise HTTPException(status_code=404)
return respond_with(streams) return respond_with(streams)
elif "tt" in id or "tmdb" in id or "kitsu" in id: elif "tt" in id or "tmdb" in id or "kitsu" in id:
logger.info(f"Handling movie or series: {id}")
print(f"Handling movie or series: {id}")
if "kitsu" in id: if "kitsu" in id:
if provider_maps['ANIMEWORLD'] == "1" and AW == "1": if provider_maps['ANIMEWORLD'] == "1" and AW == "1":
animeworld_urls = await animeworld(id,client) streams = await animeworld(streams,id,client)
if animeworld_urls:
print(f"AnimeWorld Found Results for {id}")
i = 0
for url in animeworld_urls:
if url:
if i == 0:
title = "Original"
elif i == 1:
title = "Italian"
streams['streams'].append({'title': f'{Icon}Animeworld {title}', 'url': url})
i+=1
else: else:
import time
current_time = int(time.time())
if 1743487223 <= current_time <= 1743544823:
streams['streams'].append({'name': f"{Name} 4K",'title': f'{Icon}Netflix/Prime Extractor 4K', 'url': "https://cdn-cf-east.streamable.com/video/mp4/jkx9gr.mp4?Expires=1743457311748&Key-Pair-Id=APKAIEYUVEN4EVB2OKEQ&Signature=gpixXPFJb5huM8D6AMkbzNqmAON-9zBUVIN5AeWcHiXBVROSz6BlmctAVx0qpe-hM1DN3OO7YtIdBKKOk3IthF33agmVmVjSyNI-emjf~iuqxclbaousBJTPXMIjDQTxBxINr0SUbyS4MiIwhar~luiqqvbPHN9jS-AXT2r1chhZylE4Zol~bKSCCT10TzN3En630XMk0UiTFCgwoAxfitI4mnuCXu4M3-mcnN~kpxx9j6VgE0jVzBKFq9qYbi-CtWOCL7mVaVaCwrTPPe9syZVQgIlgQJt175raLM2G2~faR~wuDOda7KmGNJJH2hDfdd~-sPsr6SSNV0B9ZZ3eaw__"})
if MYSTERIUS == "1":
results = await cool(id,client)
if results:
print(f"Mysterius Found Results for {id}")
for resolution, link in results.items():
streams['streams'].append({'title': f'{Icon}Mysterious {resolution}', 'url': link, 'behaviorHints': {'bingeGroup': f'mysterius{resolution}'}})
if provider_maps['STREAMINGCOMMUNITY'] == "1" and SC == "1": if provider_maps['STREAMINGCOMMUNITY'] == "1" and SC == "1":
SC_FAST_SEARCH = provider_maps['SC_FAST_SEARCH'] streams = await streaming_community(streams,id,client,MFP,MFP_CREDENTIALS)
url_streaming_community,quality_sc, slug_sc = await streaming_community(id,client,SC_FAST_SEARCH,MFP)
if url_streaming_community is not None:
print(f"StreamingCommunity Found Results for {id}")
if MFP == "1":
url_streaming_community = f'{MFP_url}/extractor/video?api_password={MFP_password}&d={url_streaming_community}&host=VixCloud&redirect_stream=false'
url_streaming_community = await transform_mfp(url_streaming_community,client)
streams['streams'].append({"name":f'{Name}\n{quality_sc} Max', 'title': f'{Icon}StreamingCommunity\n {slug_sc.replace("-"," ").capitalize()}','url': url_streaming_community,'behaviorHints':{'notWebReady': False, 'bingeGroup': f'streamingcommunity{quality_sc}'}})
else:
streams['streams'].append({"name":f'{Name}\n{quality_sc}p Max', 'title': f'{Icon}StreamingCommunity\n {slug_sc.replace("-"," ").capitalize()}\n This will work only on a local instance','url': url_streaming_community,'behaviorHints': {'proxyHeaders': {"request": {"user-agent": User_Agent}}, 'notWebReady': True, 'bingeGroup': f'streamingcommunity{quality_sc}'}})
if provider_maps['LORDCHANNEL'] == "1" and LC == "1":
url_lordchannel,quality_lordchannel = await lordchannel(id,client)
if quality_lordchannel == "FULL HD" and url_lordchannel != None:
print(f"LordChannel Found Results for {id}")
streams['streams'].append({'name': f"{Name}\n1080p",'title': f'{Icon}LordChannel', 'url': url_lordchannel,'behaviorHints': {'bingeGroup': 'lordchannel1080'}})
elif url_lordchannel != None:
print(f"LordChannel Found Results for {id}")
streams['streams'].append({"name": f"{Name}\n720p",'title': f'{Icon}LordChannel 720p', 'url': url_lordchannel, 'behaviorHints': {'bingeGroup': 'lordchannel720'}})
if provider_maps['FILMPERTUTTI'] == "1" and FT == "1":
url_filmpertutti,Host = await filmpertutti(id,client, MFP)
if url_filmpertutti is not None and Host is not None:
if MFP == "1":
url_filmpertutti = f'{MFP_url}/extractor/video?api_password={MFP_password}&d={url_filmpertutti}&host={Host}&redirect_stream=true'
print(url_filmpertutti)
streams['streams'].append({'name': f'{Name}', 'title': f'{Icon}Filmpertutti', 'url': url_filmpertutti,'behaviorHints': {'bingeGroup': 'filmpertutti'}})
else:
streams['streams'].append({'name': f'{Name}', 'title': f'{Icon}Filmpertutti', 'url': url_filmpertutti,'behaviorHints': {'proxyHeaders': {"request": {"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"}}, 'notWebReady': True, 'bingeGroup': 'filmpertutti'}})
print(f"Filmpertutti Found Results for {id}")
if provider_maps['TANTIFILM'] == "1" and TF == "1":
TF_FAST_SEARCH = provider_maps['TF_FAST_SEARCH']
url_tantifilm = await tantifilm(id,client,TF_FAST_SEARCH)
if url_tantifilm != "{'Doodstream HD': None}" and url_tantifilm != None:
print(f"TantiFilm Found Results for {id}")
if not isinstance(url_tantifilm, str):
for title, url in url_tantifilm.items():
streams['streams'].append({'title': f'{Icon}Tantifilm {title}', 'url': url, 'behaviorHints': {'proxyHeaders': {"request": {"Referer": "https://d000d.com/"}}, 'notWebReady': True, 'bingeGroup': f'tantifilm{title}'}})
else:
streams['streams'].append({'title': f'{Icon}Tantifilm', 'url': url_tantifilm, 'behaviorHints': {'proxyHeaders': {"request": {"Referer": "https://d000d.com/"}}, 'notWebReady': True, 'bingeGroup': 'tantifilm'}})
if provider_maps['STREAMINGWATCH'] == "1" and SW == "1": if provider_maps['STREAMINGWATCH'] == "1" and SW == "1":
url_streamingwatch,Referer = await streamingwatch(id,client) streams = await streamingwatch(streams,id,client)
if url_streamingwatch:
print(f"StreamingWatch Found Results for {id}")
streams['streams'].append({'name': f"{Name}\n720/1080p",'title': f'{Icon}StreamingWatch', 'url': url_streamingwatch, 'behaviorHints': {'proxyHeaders': {"request": {"Referer": Referer}}, 'notWebReady': True, 'bingeGroup': 'streamingwatch'}})
if provider_maps['DDLSTREAM'] == "1" and DDL == "1":
if MFP == "1":
results = await ddlstream(id,client)
if results:
print(f"DDLStreamItaly Found Results for {id}")
url_ddlstream = results[0]
quality = results[1]
name = unquote(url_ddlstream.split('/')[-1].replace(".mp4",""))
url_ddlstream = f'{MFP_url}/proxy/stream?api_password={MFP_password}&d={url_ddlstream}&h_Referer=https://ddlstreamitaly.{DDL_DOMAIN}/'
streams['streams'].append({'name': f"{Name}\n{quality}",'title': f'{Icon}DDLStream \n {name}', 'url': url_ddlstream, 'behaviorHints': {'bingeGroup': 'ddlstream'}})
if provider_maps['CB01'] == "1" and CB == "1": if provider_maps['CB01'] == "1" and CB == "1":
url_cbo1 = await cb01(id,client,MFP) streams = await cb01(streams,id,MFP,MFP_CREDENTIALS,client)
if url_cbo1:
print(f"CB01 Found Results for {id}")
if "mixdrop" in url_cbo1:
if MFP == "1":
url_cbo1 = f'{MFP_url}/extractor/video?api_password={MFP_password}&d={url_cbo1}&host=Mixdrop&redirect_stream=false'
url_cbo1 = await transform_mfp(url_cbo1,client)
if url_cbo1:
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}CB01', 'url': url_cbo1, 'behaviorHints': {'bingeGroup': 'cb01'}})
elif "delivery" in url_cbo1:
streams['streams'].append({'name': f'{Name}', 'title': f'{Icon}CB01\n MixDrop Will work only on a local instance!', 'url': url_cbo1,'behaviorHints': {'proxyHeaders': {"request": {"User-Agent": User_Agent}}, 'notWebReady': True, 'bingeGroup': 'cb01'}})
else:
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}CB01\n MaxStream', 'url': url_cbo1, 'behaviorHints': {'bingeGroup': 'cb01'}})
if provider_maps['GUARDASERIE'] == "1" and GS == "1": if provider_maps['GUARDASERIE'] == "1" and GS == "1":
url_guardaserie = await guardaserie(id,client) streams = await guardaserie(streams,id,client)
if url_guardaserie:
print(f"Guardaserie Found Results for {id}")
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}Guardaserie', 'url': url_guardaserie, 'behaviorHints': {'bingeGroup': 'guardaserie'}})
if provider_maps['GUARDAHD'] == "1" and GHD == "1": if provider_maps['GUARDAHD'] == "1" and GHD == "1":
url_guardahd = await guardahd(id,client) streams = await guardahd(streams,id,client)
if url_guardahd:
print(f"GuardaHD Found Results for {id}")
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}GuardaHD', 'url': url_guardahd, 'behaviorHints': {'bingeGroup': 'guardahd'}})
if provider_maps['ONLINESERIETV'] == "1" and OST == "1":
url_onlineserietv,name = await onlineserietv(id,client)
if url_onlineserietv:
print(f"OnlineSerieTV Found Results for {id}")
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}OnlineSerieTV\n{name}', 'url': url_onlineserietv, 'behaviorHints': {'proxyHeaders': {'request': {"User-Agent": 'Mozilla/5.0 (Linux; Android 12) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.71 Mobile Safari/537.36', "Referer": "https://flexy.stream/"}}, 'bingeGroup': 'onlineserietv', 'notWebReady': True}})
if provider_maps['EUROSTREAMING'] == "1" and ES == "1": if provider_maps['EUROSTREAMING'] == "1" and ES == "1":
urls_eurostreaming = await eurostreaming(id,client,MFP) streams = await eurostreaming(streams,id,client,MFP,MFP_CREDENTIALS)
if urls_eurostreaming: if provider_maps['GUARDAFLIX'] == "1" and GF == "1":
i = 0 streams = await guardaflix(streams,id,client,MFP,MFP_CREDENTIALS)
for url_eurostreaming,name_es in urls_eurostreaming.items(): if provider_maps['GUARDOSERIE'] == "1" and GO == "1":
if len(urls_eurostreaming) == 1: streams = await guardoserie(streams,id,client,MFP,MFP_CREDENTIALS)
language = "ITA/SUB ITA"
elif len(urls_eurostreaming)>1:
if i == 0:
language = "ITA"
else:
language = "SUB ITA"
if "cdn.net" in url_eurostreaming:
streams['streams'].append({'name': f"{Name}\n{language}",'title': f'{Icon}Eurostreaming\nDeltabit\n{name_es}', 'url': url_eurostreaming, 'behaviorHints': {'bingeGroup': 'eurostreaming'}})
elif "delivery" in url_eurostreaming:
streams['streams'].append({'name': f"{Name}\n{language}",'title': f'{Icon}Eurostreaming\nMixDrop\n{name_es}', 'url': url_eurostreaming, 'behaviorHints': {'proxyHeaders': {"request": {"User-Agent": 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'}}, 'notWebReady': True, 'bingeGroup': 'eurostreaming'}})
elif "mixdrop" in url_eurostreaming:
if MFP == "1":
url_eurostreaming = f'{MFP_url}/extractor/video?api_password={MFP_password}&d={url_eurostreaming}&host=Mixdrop&redirect_stream=false'
url_eurostreaming = await transform_mfp(url_eurostreaming,client)
if url_eurostreaming:
streams['streams'].append({'name': f"{Name}\n{language}",'title': f'{Icon}Eurostreaming\nMixDrop\n{name_es}', 'url': url_eurostreaming, 'behaviorHints':{'bingeGroup': 'eurostreaming'}})
i+=1
if not streams['streams']: if not streams['streams']:
raise HTTPException(status_code=404) raise HTTPException(status_code=404)
@@ -437,5 +279,5 @@ async def addon_stream(request: Request,config, type, id,):
if __name__ == '__main__': if __name__ == '__main__':
import uvicorn import uvicorn
uvicorn.run("run:app", host=HOST, port=PORT, log_level="info") uvicorn.run("run:app", host=HOST, port=PORT, log_level=level)
+317
View File
@@ -0,0 +1,317 @@
# static.py
CONFIGURE = """
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mamma Mia</title>
<link rel="icon" href="https://creazilla-store.fra1.digitaloceanspaces.com/emojis/49647/pizza-emoji-clipart-md.png" type="image/x-icon">
<title>Fast Search Example</title>
<style>
* {
box-sizing: border-box;
}
body, html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-size: 2.2vh;
font-family: 'Open Sans', Arial, sans-serif;
color: white;
background: url('https://i.postimg.cc/ry3p76HY/italian-seamless-free-vector-pattern3.png') center center repeat;
background-size: cover;
display: flex;
align-items: flex-start;
justify-content: center;
overflow-y: auto;
}
#addon {
background: rgba(0, 0, 0, 0.8);
padding: 0.5vh;
border-radius: 10px;
width: 65vh;
max-width: 100%;
text-align: center;
margin-top: 10vh;
}
.logo {
width: 12vh;
margin: 0 auto;
margin-bottom: 3vh;
margin-top: -3vh;
}
.logo img {
width: 100%;
height: auto;
}
h1, h2, h3 {
margin: 0;
text-shadow: 0 0 1vh rgba(0, 0, 0, 0.15);
}
h1 {
font-size: 4.5vh;
font-weight: 700;
}
h2 {
font-size: 2vh;
font-weight: normal;
font-style: italic;
opacity: 0.8;
margin-bottom: 20px;
}
h3 {
font-size: 2.2vh;
margin-bottom: 10px;
}
.provider-group {
display: flex;
align-items: center; /* Vertically align items */
justify-content: space-between; /* Spread items across the available space */
margin-bottom: 2vh;
background: rgba(255, 255, 255, 0.1);
padding: 1.5vh;
border-radius: 5px;
overflow: hidden;
width: 100%;
}
.provider-group label {
display: flex;
align-items: center; /* Align items within label vertically centered */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-grow: 1; /* Let the label take as much space as possible */
font-size: 2.2vh;
}
.provider-group input[type="checkbox"] {
margin-right: 1.5vh;
width: 4vh;
height: 4vh;
}
.parent-container {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
.contact {
position: absolute;
left: 0;
bottom: 4vh;
width: 100%;
text-align: center;
}
.contact a {
font-size: 1.4vh;
font-style: italic;
}
button {
border: 0;
outline: 0;
color: white;
background: #8A5AAB;
padding: 1.2vh 3.5vh;
text-align: center;
font-family: 'Open Sans', Arial, sans-serif;
font-size: 2.2vh;
font-weight: 600;
cursor: pointer;
display: block;
box-shadow: 0 0.5vh 1vh rgba(0, 0, 0, 0.2);
transition: box-shadow 0.1s ease-in-out;
width: 80%;
max-width: 35vh;
margin: 1vh auto;
}
button:hover {
box-shadow: none;
}
button:active {
box-shadow: 0 0 0 0.5vh white inset;
}
#manifestBox {
margin-top: 2vh;
padding: 2vh;
background: rgba(255, 255, 255, 0.2);
border-radius: 5px;
display: none;
text-align: left;
white-space: pre-wrap;
}
#generateManifestButton {
background: #4CAF50;
}
#installButton {
background: #FF5722;
}
#installButton a {
color: white;
text-decoration: none;
}
#additionalText {
margin-top: 2vh;
font-size: 1.8vh;
text-align: left;
}
/* Responsive adjustments for smaller screens */
@media (max-width: 600px) {
.provider-group label {
font-size: 2vh;
white-space: nowrap;
}
}
</style>
</head>
<body>
<div id="addon">
<div class="logo">
<img src="https://creazilla-store.fra1.digitaloceanspaces.com/emojis/49647/pizza-emoji-clipart-md.png" alt="Logo">
</div>
<h1 class="name">Mamma Mia</h1>
<h2 class="version">v1.5.0</h2>
<div id="additionalText">
<h2>This addon provides Movie, Series, Anime, and Live TV HTTPS Streams.<br> https://github.com/UrloMythus/MammaMia/</h2>
</div>
<p class="description">🕵️‍♂️ = Mediaflowproxy might be needed</p>
<h3 class="gives">Select Providers:</h3>
<form class="pure-form" id="provider-form">
<div class="provider-group">
<label for="streamingwatch" class="provider-label">
<input type="checkbox" id="streamingwatch"> StreamingWatch
</label>
</div>
<div class="provider-group">
<label for="guardoserie" class="provider-label">
<input type="checkbox" id="guardoserie"> Guardoserie
</label>
</div>
<div class="provider-group">
<label for="guardaflix" class="provider-label">
<input type="checkbox" id="guardaflix"> Guardaflix
</label>
</div>
<div class="provider-group">
<label for="animeworld" class="provider-label">
<input type="checkbox" id="animeworld"> Animeworld
</label>
</div>
<div class="provider-group">
<label for="guardaserie" class="provider-label">
<input type="checkbox" id="guardaserie"> Guardaserie
</label>
</div>
<div class="provider-group">
<label for="guardahd" class="provider-label">
<input type="checkbox" id="guardahd"> GuardaHD
</label>
</div>
<div>
</div>
<div class="provider-group">
<label for="cb01" class="provider-label">
<input type="checkbox" id="cb01"> CB01 🕵️‍♂️
</label>
</div>
<div class="provider-group">
<label for="streamingcommunity" class="provider-label">
<input type="checkbox" id="streamingcommunity"> StreamingCommunity 🕵️‍♂️
</label>
</div>
<div class="provider-group">
<label for="eurostreaming" class="provider-label">
<input type="checkbox" id="eurostreaming"> Eurostreaming 🕵️‍♂️
</label>
</div>
<div class="provider-group">
<label for="livetv" class="provider-label">
<input type="checkbox" id="livetv"> LiveTV
</label>
</div>
<div class="provider-group">
<label for="mediaflowproxy" class="provider-label">
<input type="checkbox" id="mediaflowproxy"> MediaFlow Proxy
</label>
<button type="button" id="mediaFlowProxyButton">Insert Proxy Info</button>
</div>
<div id="mediaFlowProxyInputContainer" style="display: none;">
<input type="text" id="mediaFlowProxyInput" placeholder="Proxy URL">
</div>
<div id="mediaFlowProxyPasswordContainer" style="display: none;">
<input type="password" id="mediaFlowProxyPassword" placeholder="Insert Password">
</div>
</form>
<button id="generateManifestButton">Generate Manifest</button>
<div id="manifestBox"></div>
<button id="installButton">Install in Stremio</button>
</div>
<script>
// Toggle visibility of proxy input fields
document.getElementById('mediaFlowProxyButton').addEventListener('click', function() {
const inputContainer = document.getElementById('mediaFlowProxyInputContainer');
const passwordInputContainer = document.getElementById('mediaFlowProxyPasswordContainer');
inputContainer.style.display = inputContainer.style.display === 'none' ? 'block' : 'none';
passwordInputContainer.style.display = passwordInputContainer.style.display === 'none' ? 'block' : 'none';
});
// Function to generate the manifest URL
function generateManifest() {
let manifest = "|";
const providers = {
"streamingcommunity": "SC",
"streamingwatch": "SW",
"animeworld": "AW",
"livetv": "LIVETV",
"cb01": "CB",
"guardaserie": "GS",
"guardahd": "GHD",
"guardoserie": "GO",
"guardaflix": "GF",
"eurostreaming": "ES",
"mediaflowproxy": "MFP"
};
// Loop through providers and add selected ones to the manifest
for (const id in providers) {
if (document.getElementById(id).checked) {
if (id === "mediaflowproxy") {
// Add proxy details if MFP is selected
const proxyUrl = document.getElementById("mediaFlowProxyInput").value.trim();
const proxyPassword = document.getElementById("mediaFlowProxyPassword").value.trim();
if (proxyUrl && proxyPassword) {
manifest += `MFP[${proxyUrl},${proxyPassword}]|`;
} else {
manifest += providers[id] + "|"; // Fallback to just "MFP" if no details provided
}
} else {
manifest += providers[id] + "|";
}
}
}
const encodedProviders = btoa(manifest);
const instanceUrl = "{instance_url}"; // Replace with your instance URL
const manifestUrl = instanceUrl + "/" + encodedProviders + "/" + "manifest.json";
return manifestUrl;
}
// Generate manifest URL and display it
document.getElementById('generateManifestButton').addEventListener('click', function() {
const manifestUrl = generateManifest();
const manifestBox = document.getElementById("manifestBox");
manifestBox.style.display = "block";
manifestBox.innerText = manifestUrl;
});
// Install the manifest in Stremio
document.getElementById('installButton').addEventListener('click', function() {
let manifestUrl = generateManifest();
manifestUrl = manifestUrl.replace("http://", "");
manifestUrl = manifestUrl.replace("https://", "");
const stremioUrl = "stremio://" + manifestUrl;
window.location.href = stremioUrl;
});
</script>
</body>
</html>
"""
+22 -25
View File
@@ -85,16 +85,6 @@ HTML = """
flex-grow: 1; /* Let the label take as much space as possible */ flex-grow: 1; /* Let the label take as much space as possible */
font-size: 2.2vh; font-size: 2.2vh;
} }
.fast-search {
display: flex;
align-items: center; /* Align the Fast Search checkbox vertically centered */
margin-left: 10px; /* Space between provider and Fast Search */
}
.fast-search input[type="checkbox"] {
margin-right: 0.5vh; /* Space between the checkbox and label */
width: 3vh;
height: 3vh;
}
.provider-group input[type="checkbox"] { .provider-group input[type="checkbox"] {
margin-right: 1.5vh; margin-right: 1.5vh;
width: 4vh; width: 4vh;
@@ -184,21 +174,29 @@ HTML = """
<div id="additionalText"> <div id="additionalText">
<h2>This addon provides Movie, Series, Anime, and Live TV HTTPS Streams.<br> https://github.com/UrloMythus/MammaMia/</h2> <h2>This addon provides Movie, Series, Anime, and Live TV HTTPS Streams.<br> https://github.com/UrloMythus/MammaMia/</h2>
</div> </div>
<p class="description">Configure your providers: Note that if you enable Fast Search results will be less accurate but faster</p> <p class="description">🕵️‍♂️ = Mediaflowproxy might be needed</p>
<h3 class="gives">Select Providers:</h3> <h3 class="gives">Select Providers:</h3>
<form class="pure-form" id="provider-form"> <form class="pure-form" id="provider-form">
<div class="provider-group"> <div class="provider-group">
<label for="streamingwatch" class="provider-label"> <label for="streamingwatch" class="provider-label">
<input type="checkbox" id="streamingwatch"> StreamingWatch <input type="checkbox" id="streamingwatch"> StreamingWatch
</label> </label>
</div>
<div class="provider-group">
<label for="guardoserie" class="provider-label">
<input type="checkbox" id="guardoserie"> Guardoserie
</label>
</div>
<div class="provider-group">
<label for="guardaflix" class="provider-label">
<input type="checkbox" id="guardaflix"> Guardaflix
</label>
</div> </div>
<div class="provider-group"> <div class="provider-group">
<label for="animeworld" class="provider-label"> <label for="animeworld" class="provider-label">
<input type="checkbox" id="animeworld"> Animeworld <input type="checkbox" id="animeworld"> Animeworld
</label> </label>
</div> </div>
<p>To use the following provider you need to have a local instance/ set the proxy enviroment variable... Leave it as it is if you do not know what this is about
</p>
<div class="provider-group"> <div class="provider-group">
<label for="guardaserie" class="provider-label"> <label for="guardaserie" class="provider-label">
<input type="checkbox" id="guardaserie"> Guardaserie <input type="checkbox" id="guardaserie"> Guardaserie
@@ -210,24 +208,21 @@ HTML = """
</label> </label>
</div> </div>
<div> <div>
<p>Mediaflowproxy
</p>
</div> </div>
<div class="provider-group"> <div class="provider-group">
<label for="cb01" class="provider-label"> <label for="cb01" class="provider-label">
<input type="checkbox" id="cb01"> CB01 <input type="checkbox" id="cb01"> CB01 🕵️‍♂️
</label> </label>
</div> </div>
<p>Local/MFP with good IP</p>
<div class="provider-group"> <div class="provider-group">
<label for="streamingcommunity" class="provider-label"> <label for="streamingcommunity" class="provider-label">
<input type="checkbox" id="streamingcommunity"> StreamingCommunity <input type="checkbox" id="streamingcommunity"> StreamingCommunity 🕵️‍♂️
</label> </label>
<span class="fast-search"> </div>
<label for="fast_search_sc"> <div class="provider-group">
<input type="checkbox" id="fast_search_sc"> Fast Search <label for="eurostreaming" class="provider-label">
<input type="checkbox" id="eurostreaming"> Eurostreaming 🕵️‍♂️
</label> </label>
</span>
</div> </div>
<div class="provider-group"> <div class="provider-group">
<label for="livetv" class="provider-label"> <label for="livetv" class="provider-label">
@@ -265,13 +260,15 @@ HTML = """
let manifest = "|"; let manifest = "|";
const providers = { const providers = {
"streamingcommunity": "SC", "streamingcommunity": "SC",
"fast_search_sc": "SC_FS",
"streamingwatch": "SW", "streamingwatch": "SW",
"animeworld": "AW", "animeworld": "AW",
"livetv": "LIVETV", "livetv": "LIVETV",
"cb01": "CB", "cb01": "CB",
"guardaserie": "GS", "guardaserie": "GS",
"guardahd": "GHD", "guardahd": "GHD",
"guardoserie": "GO",
"guardaflix": "GF",
"eurostreaming": "ES",
"mediaflowproxy": "MFP" "mediaflowproxy": "MFP"
}; };
@@ -292,9 +289,9 @@ HTML = """
} }
} }
} }
const encodedProviders = btoa(manifest);
const instanceUrl = "{instance_url}"; // Replace with your instance URL const instanceUrl = "{instance_url}"; // Replace with your instance URL
const manifestUrl = instanceUrl + "/" + manifest + "/" + "manifest.json"; const manifestUrl = instanceUrl + "/" + encodedProviders + "/" + "manifest.json";
return manifestUrl; return manifestUrl;
} }