Compare commits
156
Commits
dev
...
release-2.1
@@ -0,0 +1,121 @@
|
|||||||
|
name: Conditional Sync Upstream, Build, and Push Docker Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 * * * *' # ogni ora
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
sync-build-push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Backup files and force sync upstream
|
||||||
|
id: sync
|
||||||
|
run: |
|
||||||
|
git config user.name "github-actions"
|
||||||
|
git config user.email "[email protected]"
|
||||||
|
|
||||||
|
git remote get-url upstream || git remote add upstream https://github.com/UrloMythus/MammaMia.git
|
||||||
|
git fetch upstream
|
||||||
|
|
||||||
|
# Controlla se ci sono differenze PRIMA del reset
|
||||||
|
if git diff --quiet HEAD upstream/main; then
|
||||||
|
echo "Repository already up to date"
|
||||||
|
echo "no_change=true" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "Changes detected, proceeding with sync and build"
|
||||||
|
|
||||||
|
backup_dir=".git/backup_files"
|
||||||
|
mkdir -p "$backup_dir/.github/workflows"
|
||||||
|
mkdir -p "$backup_dir/Dockerfiles"
|
||||||
|
|
||||||
|
if [ -f config.json ]; then
|
||||||
|
cp config.json "$backup_dir/config.json"
|
||||||
|
else
|
||||||
|
echo "⚠️ config.json non trovato, skipping backup"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f update_domains.py ]; then
|
||||||
|
cp update_domains.py "$backup_dir/update_domains.py"
|
||||||
|
else
|
||||||
|
echo "⚠️ update_domains.py non trovato, skipping backup"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d .github/workflows ]; then
|
||||||
|
cp -r .github/workflows/* "$backup_dir/.github/workflows/" || echo "⚠️ No workflows to backup"
|
||||||
|
else
|
||||||
|
echo "⚠️ Cartella .github/workflows non trovata, skipping backup"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d Dockerfiles ]; then
|
||||||
|
cp -r Dockerfiles/* "$backup_dir/Dockerfiles/" || echo "⚠️ No Dockerfiles to backup"
|
||||||
|
else
|
||||||
|
echo "⚠️ Cartella Dockerfiles non trovata, skipping backup"
|
||||||
|
fi
|
||||||
|
|
||||||
|
git checkout main || git checkout -b main
|
||||||
|
git reset --hard upstream/main
|
||||||
|
|
||||||
|
if [ -f "$backup_dir/config.json" ]; then
|
||||||
|
cp "$backup_dir/config.json" config.json
|
||||||
|
else
|
||||||
|
echo "⚠️ File config.json non trovato nel backup, skipping restore"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$backup_dir/update_domains.py" ]; then
|
||||||
|
cp "$backup_dir/update_domains.py" update_domains.py
|
||||||
|
else
|
||||||
|
echo "⚠️ File update_domains.py non trovato nel backup, skipping restore"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p .github/workflows
|
||||||
|
if [ -d "$backup_dir/.github/workflows" ]; then
|
||||||
|
cp -r "$backup_dir/.github/workflows/"* .github/workflows/ || echo "⚠️ No workflows to restore"
|
||||||
|
else
|
||||||
|
echo "⚠️ Backup workflows folder mancante, skipping restore"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p Dockerfiles
|
||||||
|
if [ -d "$backup_dir/Dockerfiles" ]; then
|
||||||
|
cp -r "$backup_dir/Dockerfiles/"* Dockerfiles/ || echo "⚠️ No Dockerfiles to restore"
|
||||||
|
else
|
||||||
|
echo "⚠️ Backup Dockerfiles folder mancante, skipping restore"
|
||||||
|
fi
|
||||||
|
|
||||||
|
git add .
|
||||||
|
git commit -m "Restore files after forced sync" || echo "No changes needed"
|
||||||
|
git push origin main --force
|
||||||
|
echo "no_change=false" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
rm -rf "$backup_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check if build is needed
|
||||||
|
run: echo "Changes detected, proceed with build."
|
||||||
|
if: steps.sync.outputs.no_change == 'false'
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
if: steps.sync.outputs.no_change == 'false'
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
if: steps.sync.outputs.no_change == 'false'
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: dula117/mammamia:latest
|
||||||
|
if: steps.sync.outputs.no_change == 'false'
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
name: Update Domains
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 20 * * *" # Esegui alle 20:00 ogni giorno
|
||||||
|
workflow_dispatch: # Permette di avviare manualmente il workflow
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-domains:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.12'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
pip install requests
|
||||||
|
|
||||||
|
- name: Update domains in config.json
|
||||||
|
run: |
|
||||||
|
python update_domains.py
|
||||||
|
|
||||||
|
- name: Commit and push changes
|
||||||
|
run: |
|
||||||
|
git config --global user.email "[email protected]"
|
||||||
|
git config --global user.name "Your Name"
|
||||||
|
git add config.json
|
||||||
|
git commit -m "Aggiornamento domini in config.json"
|
||||||
|
git push
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
.env
|
.env
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
.vercel
|
||||||
|
beamup.json
|
||||||
+10
-8
@@ -1,15 +1,17 @@
|
|||||||
# 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
|
|
||||||
# (including run.py, filmpertutti.py, and requirements.txt)
|
|
||||||
ADD . /app
|
ADD . /app
|
||||||
# Install any needed packages specified in requirements.txt
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y tesseract-ocr libtesseract-dev && \
|
||||||
|
apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
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
|
RUN pip install --no-cache-dir pytesseract
|
||||||
|
|
||||||
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,23 +1,15 @@
|
|||||||
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
|
||||||
|
|
||||||
# Install git
|
|
||||||
RUN apt-get update && apt-get install -y git
|
RUN apt-get update && apt-get install -y git
|
||||||
|
|
||||||
# Clone the repository
|
|
||||||
RUN git clone https://github.com/UrloMythus/MammaMia.git .
|
RUN git clone https://github.com/UrloMythus/MammaMia.git .
|
||||||
|
|
||||||
# Copy the local config.json file to the container
|
|
||||||
COPY config.json /app/config.json
|
COPY config.json /app/config.json
|
||||||
|
|
||||||
# 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
|
ENTRYPOINT ["python", "run.py"]
|
||||||
CMD ["python", "run.py"]
|
|
||||||
@@ -1,21 +1,14 @@
|
|||||||
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
|
||||||
|
|
||||||
# Install git
|
|
||||||
RUN apt-get update && apt-get install -y git
|
RUN apt-get update && apt-get install -y git
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
# 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"]
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
FROM python:3.11-slim-bullseye
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y git tesseract-ocr libtesseract-dev && \
|
||||||
|
apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN git clone https://github.com/vitouchiha/MammaMia.git .
|
||||||
|
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
RUN pip install --no-cache-dir pytesseract
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
ENTRYPOINT ["python", "run.py"]
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
A Stremio Addon for high quality HTTPS Streams in Italian
|
A Stremio Addon for HTTPS Streams in Italian
|
||||||
|
|
||||||
Movies, Series, Anime and Live TV are supported.
|
Movies, Series, Anime and Live TV are supported.
|
||||||
|
|
||||||
@@ -25,23 +25,6 @@ Movies, Series, Anime and Live TV are supported.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
While hosting, this project, remember that Filmpertutti uses Mixdrop. Mixdrop only allows seeing the videos from the same IP where they were generated so, if you want to scrape filmpertutti, you will have to host this project locally. Else, you can only scrape other providers.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Hosting your own instance is suggested, but you can use the public instance [linked](https://mammamia-urlo-mammamia.hf.space/) in the About Page of the repo.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
@@ -69,13 +52,28 @@ Hosting your own instance is suggested, but you can use the public instance [lin
|
|||||||
|
|
||||||
``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:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -97,7 +95,7 @@ Hosting your own instance is suggested, but you can use the public instance [lin
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
To host this project with Hugging Face, go to the [linked](https://huggingface.co/spaces/MammaMia-Urlo/CloneThisSpace/) 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).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -107,75 +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.
|
||||||
|
[!WARNING] The Space must be Public or else you won't be able to access it
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
2. Go to [linked](https://huggingface.co/spaces/MammaMia-Urlo/CloneThisSpace) page and click on three dots on the top (right) part of the screen
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
3. Click Duplicate this Space
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
4. Insert TMDB Key and set visibility to Public
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
5. Clone the Project
|
|
||||||
|
|
||||||
|
|
||||||
6. Go into settings and click on Factory Rebuild.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
7. You are done!
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
9. How do I handle updates? To update the addon you will have to Factory Rebuild your space (in Settings) and, if there are any changes to config.json, copy them from [here](https://github.com/UrloMythus/MammaMia/blob/main/config.json) to the config.json in your Space, under Files.
|
|
||||||
|
|
||||||
|
|
||||||
10. How can I use Live TV? For now it won't work on public instances. Wait until next update.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Technical Details:
|
|
||||||
On Hugging Face you are forced to use the 8080 port because it is the only one allowed to send/get network requests. Moreover, remember that load_env and Public Instance need to be disabled in the config.json (it should be by default if you clone the project from HF)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -192,6 +171,7 @@ On Hugging Face you are forced to use the 8080 port because it is the only one a
|
|||||||
|
|
||||||
To install this project on [Render](https://render.com/) follow these steps:
|
To install this project on [Render](https://render.com/) follow these steps:
|
||||||
|
|
||||||
|
[!WARNING] Render might ban your account. Modify the static.py file might help with that
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -222,7 +202,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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -244,7 +224,13 @@ 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
|
Remember, load_env needs to be disabled in the config.json
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Vercel
|
||||||
|
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FUrloMythus%2FMammaMia&env=PORT,TMDB_KEY&envDescription=PORT%20(8080)%20and%20API%20KEY%20of%20TMDB&envLink=https%3A%2F%2Fgithub.com%2FUrloMythus%2FMammaMia%2Fblob%2Fmain%2Fexample.env)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -256,21 +242,6 @@ Remember, load_env and Public Instance needs to be disabled in the config.json
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Enviroment Variables
|
# Enviroment Variables
|
||||||
|
|
||||||
@@ -285,14 +256,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/" |
|
||||||
|
|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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -306,7 +275,9 @@ Here is [linked](https://www.themoviedb.org/settings/api) a tutorial about how t
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
In the repo there is a config.json that you can modify to change some aspects of the addon like the domains of the sites. Down here all explained:
|
In the repo there is a config.json that you can modify to change some aspects of the addon like the domains of the sites. "1" means True, "0" means False
|
||||||
|
|
||||||
|
Down here all explained:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -315,17 +286,15 @@ In the repo there is a config.json that you can modify to change some aspects of
|
|||||||
| 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. "1" means true. "0" means false. Remember, there is no point in enabling filmpertutti on a remote server since it's IP-LOCKED|
|
|enabled | If the site is enabled or not. This will override user-preference in the configuration|
|
||||||
|fast_search|"1" for enabled, "0" for disabled. It enables a faster search for supported providers but it is less accurate|
|
|**_ForwardProxy| Whether or not to use the ForwardProxy for the specific site.|
|
||||||
|load_env|Put "1" if enabled, "0" if disabled. 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. |
|
|**_Proxy| Whether or not to use the Proxies for the specific site.|
|
||||||
|
|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.|
|
||||||
|
|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.
|
|
||||||
|
|
||||||
For now Tantifilm, even if its player is not IP-Locked, does not work on Hugging Face.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -333,7 +302,6 @@ Check those links to get the new Domain for the providers.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[FILMPERTUTTI](https://filmpertuttiiii.nuovo.live/)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -341,7 +309,6 @@ Check those links to get the new Domain for the providers.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[TANTIFILM](https://tantinuovo.com/tantifilm-nuovo-indirizzo/)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -349,20 +316,33 @@ Check those links to get the new Domain for the providers.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[LORDCHANNEL](https://t.me/+5MQwrb3eqb81NGI0)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[ANIMEWORLD](https://t.me/AnimeWorldITA2)
|
[ANIMEWORLD](https://t.me/AnimeWorldITA2)
|
||||||
|
|
||||||
|
[CB01](https://cb01.uno/)
|
||||||
|
|
||||||
|
[GUARDAFLIX](https://guardoserie.it/)
|
||||||
|
|
||||||
|
[GUARDOSERIE](https://guardoserie.it/)
|
||||||
|
|
||||||
|
[EUROSTREAMING](https://eurostreaming-nuovo-indirizzo.online/)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 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/).
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
- Big thanks to [Lovi0](https://github.com/Lovi-0), the creator of StreamingCommunity downloader, for helping me with some aspects of this project.
|
- Big thanks to [Lovi0](https://github.com/Lovi-0), the creator of StreamingCommunity downloader, for helping me with some aspects of this project.
|
||||||
- This project uses [MediaFlowProxy](https://github.com/mhdzumair/mediaflow-proxy/) in order to be able to play some Live TV channels. Big thanks to his creator, [mhdzumair](https://github.com/mhdzumair)
|
- This project uses [MediaFlowProxy](https://github.com/mhdzumair/mediaflow-proxy/) in order to be able to play some Live TV channels and to proxy some streams. Big thanks to his creator, [mhdzumair](https://github.com/mhdzumair)
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
This project does not host any illegal content on his servers, if you want any content to be taken down, please contact the actual owners of those sites.
|
|
||||||
The Live TV sources are taken from online sites, avaiable on the web and indixed by Google.
|
|
||||||
|
|
||||||
|
We hereby issue this notice to inform you that this Add-On just function like an ordinary browser (like your browser) that fetch video files from internet, and do not violate the provisions of the Digital Millennium Copyright Act (DMCA). The Content these extensions may access is not hosted or made avaiable by us or the Stremio application but the websites they are browsing in their autonomous mode. It is sole responsibility of the user and his/her countries' or states' law. If you think they are violating any intellectual property then please contact the actual file hosts not the owners of this repository or the Stremio app.
|
||||||
|
|
||||||
|
Thank You.
|
||||||
|
|
||||||
|
|||||||
+152
-67
@@ -1,10 +1,43 @@
|
|||||||
|
|
||||||
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
|
||||||
|
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()
|
||||||
|
proxies = {}
|
||||||
|
from Src.Utilities.loadenv import load_env
|
||||||
|
env_vars = load_env()
|
||||||
|
AW_PROXY = config.AW_PROXY
|
||||||
|
AW_ForwardProxy = config.AW_ForwardProxy
|
||||||
|
if AW_PROXY == "1":
|
||||||
|
import random
|
||||||
|
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
|
||||||
|
proxy_list = json.loads(PROXY_CREDENTIALS)
|
||||||
|
proxy = random.choice(proxy_list)
|
||||||
|
if proxy == "":
|
||||||
|
proxies = {}
|
||||||
|
else:
|
||||||
|
proxies = {
|
||||||
|
"http": proxy,
|
||||||
|
"https": proxy
|
||||||
|
}
|
||||||
|
if AW_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy = ""
|
||||||
|
|
||||||
|
|
||||||
AW_DOMAIN = config.AW_DOMAIN
|
AW_DOMAIN = config.AW_DOMAIN
|
||||||
months = {
|
months = {
|
||||||
"Gennaio": "January", "Febbraio": "February", "Marzo": "March",
|
"Gennaio": "January", "Febbraio": "February", "Marzo": "March",
|
||||||
@@ -18,17 +51,38 @@ showname_replace = {
|
|||||||
" ": " ",
|
" ": " ",
|
||||||
"Shippuuden": "Shippuden",
|
"Shippuuden": "Shippuden",
|
||||||
" ": "+",
|
" ": "+",
|
||||||
|
"Solo+Leveling+2": "Solo+Leveling+2:",
|
||||||
|
"-": ""
|
||||||
}
|
}
|
||||||
|
async def security_cookie (response):
|
||||||
async def get_mp4(anime_url,ismovie,episode,client):
|
match = re.search(r'SecurityAW-([A-Za-z0-9]{2})=([^;]+)', response.text)
|
||||||
response = await client.get(anime_url,allow_redirects=True, impersonate = "chrome120")
|
if match:
|
||||||
|
unknown_chars = match.group(1).strip()
|
||||||
|
Security_Cookie = match.group(2).strip()
|
||||||
|
cookies = {
|
||||||
|
f"SecurityAW-{unknown_chars}": Security_Cookie
|
||||||
|
}
|
||||||
|
return cookies
|
||||||
|
async def get_mp4(anime_url,ismovie,episode,client,i,streams):
|
||||||
|
cookies = {}
|
||||||
|
if ForwardProxy != "":
|
||||||
|
response = await client.get(ForwardProxy + anime_url,allow_redirects=True,impersonate = "chrome124",proxies=proxies)
|
||||||
|
anime_url = f'{AW_DOMAIN}/{response.url.replace(ForwardProxy,"")}?d=1'
|
||||||
|
response = await client.get(ForwardProxy + anime_url, allow_redirects=True, cookies = cookies,impersonate = "chrome124",proxies=proxies)
|
||||||
|
cookies = await security_cookie(response)
|
||||||
|
response = await client.get(ForwardProxy + anime_url, allow_redirects=True, cookies = cookies,impersonate = "chrome124",proxies=proxies)
|
||||||
|
else:
|
||||||
|
response = await client.get(ForwardProxy + anime_url, allow_redirects=True, cookies = cookies,impersonate = "chrome124",proxies=proxies)
|
||||||
soup = BeautifulSoup(response.text,'lxml')
|
soup = BeautifulSoup(response.text,'lxml')
|
||||||
if ismovie == 0:
|
if ismovie == 0:
|
||||||
episode_page = soup.find('a', {'data-episode-num':episode })
|
episode_page = soup.find('a', {'data-episode-num':episode })
|
||||||
if episode_page is None:
|
if episode_page is None:
|
||||||
return None
|
return streams
|
||||||
episode_page = f'https://animeworld.{AW_DOMAIN}{episode_page["href"]}'
|
episode_page = f'{AW_DOMAIN}{episode_page["href"]}'
|
||||||
response = await client.get(episode_page,allow_redirects=True, impersonate = "chrome120")
|
response = await client.get(ForwardProxy + episode_page,allow_redirects=True, cookies = cookies,impersonate = "chrome124", proxies=proxies)
|
||||||
|
if response.status_code == 202:
|
||||||
|
cookies = await security_cookie(response)
|
||||||
|
response = await client.get(ForwardProxy + episode_page,allow_redirects=True, cookies = cookies,impersonate = "chrome124", proxies=proxies)
|
||||||
soup = BeautifulSoup(response.text,'lxml')
|
soup = BeautifulSoup(response.text,'lxml')
|
||||||
|
|
||||||
a_tag = soup.find('a', {'id': 'alternativeDownloadLink', 'class': 'm-1 btn btn-sm btn-primary'})
|
a_tag = soup.find('a', {'id': 'alternativeDownloadLink', 'class': 'm-1 btn btn-sm btn-primary'})
|
||||||
@@ -36,7 +90,96 @@ 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,streams):
|
||||||
|
search_year = date[:4]
|
||||||
|
headers = random_headers.generate()
|
||||||
|
link = f'{AW_DOMAIN}/filter?year={search_year}&sort=2&keyword={showname}'
|
||||||
|
response = await client.get(ForwardProxy + link,allow_redirects=True, impersonate = "chrome124", headers = headers, proxies = proxies)
|
||||||
|
if response.status_code == 202:
|
||||||
|
cookies = await security_cookie(response)
|
||||||
|
response = await client.get(ForwardProxy + link,allow_redirects=True, impersonate = "chrome124", proxies = proxies, headers = headers, cookies = cookies)
|
||||||
|
else:
|
||||||
|
cookies = {}
|
||||||
|
soup = BeautifulSoup(response.text,'lxml')
|
||||||
|
anime_list = soup.find_all('a', class_=['poster', 'tooltipstered'])
|
||||||
|
i = 0
|
||||||
|
for anime in anime_list:
|
||||||
|
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)
|
||||||
|
if response.status_code == 202:
|
||||||
|
cookies = await security_cookie(response)
|
||||||
|
response = await client.get(ForwardProxy + anime_info_url,allow_redirects=True, impersonate = "chrome124", cookies = cookies, proxies = proxies)
|
||||||
|
pattern = r'<label>Data di uscita:</label>\s*<span>\s*(.*?)\s*</span>'
|
||||||
|
match = re.search(pattern, response.text, re.S)
|
||||||
|
release_date = match.group(1).strip()
|
||||||
|
for ita, eng in months.items():
|
||||||
|
release_date = release_date.replace(ita, eng)
|
||||||
|
release_date_object = datetime.datetime.strptime(release_date, "%d %B %Y")
|
||||||
|
date_object = datetime.datetime.strptime(date, "%Y-%m-%d")
|
||||||
|
release_date = release_date_object.strftime("%Y-%m-%d")
|
||||||
|
if (release_date == date 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")):
|
||||||
|
anime_url = f'{AW_DOMAIN}{anime["href"]}'
|
||||||
|
streams = await get_mp4(anime_url,ismovie,episode,client,i,streams)
|
||||||
|
i+=1
|
||||||
|
logger.info(f"AnimeWorld Found Results for current ID")
|
||||||
|
|
||||||
|
return streams
|
||||||
|
|
||||||
|
async def animeworld(streams,id,client):
|
||||||
|
try:
|
||||||
|
kitsu_id = id.split(":")[1]
|
||||||
|
ismovie = 1 if len(id.split(":")) == 2 else 0
|
||||||
|
if ismovie == 1:
|
||||||
|
episode = None
|
||||||
|
else:
|
||||||
|
episode = id.split(":")[2]
|
||||||
|
showname,date = await get_info_kitsu(kitsu_id,client)
|
||||||
|
#Format Showname
|
||||||
|
for key in showname_replace:
|
||||||
|
if key in showname: # Check if the key is a substring of showname
|
||||||
|
showname = showname.replace(key, showname_replace[key])
|
||||||
|
if "Naruto:" in showname:
|
||||||
|
showname = showname.replace(":", "")
|
||||||
|
if "’" in showname:
|
||||||
|
showname = showname.split("’")[0]
|
||||||
|
if ":" in showname:
|
||||||
|
showname = showname.split(":")[0]
|
||||||
|
streams = await search(showname,date,ismovie,episode,client,streams)
|
||||||
|
return streams
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Animeworld failed {e}")
|
||||||
|
return streams
|
||||||
|
|
||||||
|
async def test_animeworld():
|
||||||
|
async with AsyncSession() as client:
|
||||||
|
# Replace with actual id, for example 'anime_id:episode' format
|
||||||
|
test_id = "kitsu:12:1" # This is an example ID format
|
||||||
|
results = await animeworld({'streams': []},test_id, client)
|
||||||
|
print(results)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from curl_cffi.requests import AsyncSession
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_animeworld())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -72,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 = "chrome120")
|
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 = []
|
||||||
@@ -93,7 +236,7 @@ async def old_search(showname,date,ismovie,episode,client):
|
|||||||
params = {
|
params = {
|
||||||
'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 = "chrome120")
|
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"]
|
||||||
@@ -109,61 +252,3 @@ async def old_search(showname,date,ismovie,episode,client):
|
|||||||
final_urls.append(final_url)
|
final_urls.append(final_url)
|
||||||
break
|
break
|
||||||
return final_urls
|
return final_urls
|
||||||
|
|
||||||
async def search(showname,date,ismovie,episode,client):
|
|
||||||
search_year = date[:4]
|
|
||||||
response = await client.get(f'https://www.animeworld.so/filter?year={search_year}&sort=2&keyword={showname}',allow_redirects=True, impersonate = "chrome120")
|
|
||||||
soup = BeautifulSoup(response.text,'lxml')
|
|
||||||
anime_list = soup.find_all('a', class_=['poster', 'tooltipstered'])
|
|
||||||
final_urls = []
|
|
||||||
for anime in anime_list:
|
|
||||||
anime_info_url = f'https://www.animeworld.{AW_DOMAIN}/{anime["data-tip"]}'
|
|
||||||
response = await client.get(anime_info_url,allow_redirects=True, impersonate = "chrome120")
|
|
||||||
pattern = r'<label>Data di uscita:</label>\s*<span>\s*(.*?)\s*</span>'
|
|
||||||
match = re.search(pattern, response.text, re.S)
|
|
||||||
release_date = match.group(1).strip()
|
|
||||||
for ita, eng in months.items():
|
|
||||||
release_date = release_date.replace(ita, eng)
|
|
||||||
release_date = datetime.datetime.strptime(release_date, "%d %B %Y")
|
|
||||||
release_date = release_date.strftime("%Y-%m-%d")
|
|
||||||
if release_date == date:
|
|
||||||
anime_url = f'https://www.animeworld.{AW_DOMAIN}{anime["href"]}'
|
|
||||||
final_url = await get_mp4(anime_url,ismovie,episode,client)
|
|
||||||
if final_url:
|
|
||||||
final_urls.append(final_url)
|
|
||||||
|
|
||||||
return final_urls
|
|
||||||
|
|
||||||
async def animeworld(id,client):
|
|
||||||
try:
|
|
||||||
print(id)
|
|
||||||
kitsu_id = id.split(":")[1]
|
|
||||||
ismovie = 1 if len(id.split(":")) == 2 else 0
|
|
||||||
if ismovie == 1:
|
|
||||||
episode = None
|
|
||||||
else:
|
|
||||||
episode = id.split(":")[2]
|
|
||||||
showname,date = await get_info_kitsu(kitsu_id,client)
|
|
||||||
for key in showname_replace:
|
|
||||||
if key in showname: # Check if the key is a substring of showname
|
|
||||||
showname = showname.replace(key, showname_replace[key])
|
|
||||||
if "Naruto:" in showname:
|
|
||||||
showname = showname.replace(":", "")
|
|
||||||
final_urls = await search(showname,date,ismovie,episode,client)
|
|
||||||
return final_urls
|
|
||||||
except:
|
|
||||||
print("Animeworld failed")
|
|
||||||
return None
|
|
||||||
'''
|
|
||||||
async def test_animeworld():
|
|
||||||
async with AsyncSession() as client:
|
|
||||||
# Replace with actual id, for example 'anime_id:episode' format
|
|
||||||
test_id = "kitsu:11407" # This is an example ID format
|
|
||||||
results = await animeworld(test_id, client)
|
|
||||||
print(results)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
from curl_cffi.requests import AsyncSession
|
|
||||||
import asyncio
|
|
||||||
asyncio.run(test_animeworld())
|
|
||||||
'''
|
|
||||||
+147
-147
@@ -4,8 +4,63 @@ from Src.Utilities.info import is_movie,get_info_tmdb,get_info_imdb
|
|||||||
from Src.Utilities.convert import get_TMDb_id_from_IMDb_id
|
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
|
||||||
ForwardProxy_list = config.ForwardProxy
|
from Src.Utilities.loadenv import load_env
|
||||||
ForwardProxy = ForwardProxy_list[0]
|
from Src.API.extractors.mixdrop import mixdrop
|
||||||
|
from Src.API.extractors.maxstream import maxstream
|
||||||
|
from Src.API.extractors.uprot import bypass_uprot
|
||||||
|
import logging
|
||||||
|
from Src.Utilities.config import setup_logging
|
||||||
|
level = config.LEVEL
|
||||||
|
logger = setup_logging(level)
|
||||||
|
CB_DOMAIN = config.CB_DOMAIN
|
||||||
|
CB_PROXY = config.CB_PROXY
|
||||||
|
MX_PROXY = config.MX_PROXY
|
||||||
|
Icon = config.Icon
|
||||||
|
Name = config.Name
|
||||||
|
proxies = {}
|
||||||
|
proxies2 = {}
|
||||||
|
env_vars = load_env()
|
||||||
|
import random
|
||||||
|
import json
|
||||||
|
from Src.Utilities.mfp import build_mfp
|
||||||
|
if MX_PROXY == "1":
|
||||||
|
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
|
||||||
|
proxy_list = json.loads(PROXY_CREDENTIALS)
|
||||||
|
proxy = random.choice(proxy_list)
|
||||||
|
if proxy == "":
|
||||||
|
proxies2 = {}
|
||||||
|
else:
|
||||||
|
proxies2 = {
|
||||||
|
"http": proxy,
|
||||||
|
"https": proxy
|
||||||
|
}
|
||||||
|
if CB_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
|
||||||
|
}
|
||||||
|
proxies2 = proxies
|
||||||
|
|
||||||
|
CB_ForwardProxy = config.CB_ForwardProxy
|
||||||
|
MX_ForwardProxy = config.MX_ForwardProxy
|
||||||
|
if CB_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
ForwardProxy2 = ForwardProxy
|
||||||
|
if MX_ForwardProxy == "1":
|
||||||
|
ForwardProxy2 = ForwardProxy
|
||||||
|
elif MX_ForwardProxy == "1":
|
||||||
|
ForwardProxy2 = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy2 = ""
|
||||||
|
ForwardProxy = ""
|
||||||
|
|
||||||
|
|
||||||
fake_headers = Headers()
|
fake_headers = Headers()
|
||||||
|
|
||||||
async def get_stayonline(link,client):
|
async def get_stayonline(link,client):
|
||||||
@@ -15,85 +70,34 @@ async def get_stayonline(link,client):
|
|||||||
'x-requested-with': 'XMLHttpRequest',
|
'x-requested-with': 'XMLHttpRequest',
|
||||||
}
|
}
|
||||||
data = {'id': link.split("/")[-2], 'ref': ''}
|
data = {'id': link.split("/")[-2], 'ref': ''}
|
||||||
response = await client.post('https://stayonline.pro/ajax/linkEmbedView.php', headers=headers, data=data)
|
response = await client.post('https://stayonline.pro/ajax/linkEmbedView.php', headers=headers, data=data, proxies = proxies2)
|
||||||
real_url = response.json()['data']['value']
|
real_url = response.json()['data']['value']
|
||||||
print(real_url)
|
|
||||||
return real_url
|
return real_url
|
||||||
|
|
||||||
|
async def get_maxstream(link,streams,client):
|
||||||
async def get_uprot(link,client):
|
if 'stayonline' in link:
|
||||||
if "msf" in link:
|
uprot_link = await get_stayonline(link,client)
|
||||||
link = link.replace("msf","mse")
|
|
||||||
|
|
||||||
headers = fake_headers.generate()
|
|
||||||
response = await client.get(link, headers=headers, allow_redirects=True, timeout=10)
|
|
||||||
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):
|
|
||||||
try:
|
|
||||||
import string
|
|
||||||
headers = fake_headers.generate()
|
|
||||||
response = await client.get(real_link, headers=headers, allow_redirects=True,timeout = 30)
|
|
||||||
[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:
|
|
||||||
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(maxstream_url, headers=headers, allow_redirects=True, timeout=10)
|
|
||||||
[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:
|
else:
|
||||||
first_url_part += first_part + "-"
|
uprot_link = link
|
||||||
|
maxstream_link = await bypass_uprot(client,uprot_link)
|
||||||
|
if maxstream_link:
|
||||||
|
streams = await maxstream(maxstream_link,client,streams,'CB01','',proxies2,ForwardProxy)
|
||||||
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:
|
else:
|
||||||
i += 1
|
if maxstream_link == False:
|
||||||
final_url = base_url
|
return streams
|
||||||
return final_url
|
else:
|
||||||
|
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}CB01\n▶️ Please do the captcha at /uprot in order to be able to play this content! \n Remember to refresh the sources!\nIf you recently did the captcha then dont worry, just refresh the sources', 'url': 'https://github.com/UrloMythus/MammaMia', 'behaviorHints': { 'bingeGroup': 'cb01'}})
|
||||||
|
|
||||||
|
return streams
|
||||||
async def search_movie(showname,date,client):
|
async def search_movie(showname,date,client):
|
||||||
try:
|
try:
|
||||||
showname = showname.replace(" ","+")
|
showname = showname.replace(" ","+").replace("ò","o").replace("è","e").replace("à","a").replace("ù","u").replace("ì","i")
|
||||||
headers = fake_headers.generate()
|
headers = fake_headers.generate()
|
||||||
headers['Referer'] = 'https://cb01.technology/'
|
headers['Referer'] = f'{CB_DOMAIN}/'
|
||||||
query = f'https://cb01.technology/?s={showname}'
|
query = f'{CB_DOMAIN}/?s={showname}'
|
||||||
response = await client.get(query,headers=headers)
|
response = await client.get(ForwardProxy + query,headers=headers, proxies = proxies)
|
||||||
|
if response.status_code != 200:
|
||||||
|
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}')
|
||||||
@@ -101,29 +105,28 @@ async def search_movie(showname,date,client):
|
|||||||
# Find the link inside the current card
|
# Find the link inside the current card
|
||||||
link_tag = card.find('h3', class_='card-title').find('a')
|
link_tag = card.find('h3', class_='card-title').find('a')
|
||||||
href = link_tag['href']
|
href = link_tag['href']
|
||||||
|
|
||||||
# Find the date span and extract possible years
|
# Find the date span and extract possible years
|
||||||
date_span = card.find('span', style=re.compile('color'))
|
|
||||||
if date_span:
|
date_text = href.split("/")[-2]
|
||||||
date_text = date_span.text
|
|
||||||
# Search for the first occurrence of a year (starting with 19 or 20)
|
# Search for the first occurrence of a year (starting with 19 or 20)
|
||||||
match = year_pattern.search(date_text)
|
match = year_pattern.search(date_text)
|
||||||
if match:
|
if match:
|
||||||
year = match.group(0)
|
year = match.group(0)
|
||||||
if year == date : # Check if the year is 2011
|
if year == date :
|
||||||
print(f"Link: {href}")
|
|
||||||
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):
|
||||||
try:
|
try:
|
||||||
showname = showname.replace(" ","+")
|
showname = showname.replace(" ","+")
|
||||||
headers = fake_headers.generate()
|
headers = fake_headers.generate()
|
||||||
headers['Referer'] = 'https://cb01.technology/serietv/'
|
headers['Referer'] = f'{CB_DOMAIN}/serietv/'
|
||||||
query = f'https://cb01.technology/serietv/?s={showname}'
|
query = f'{CB_DOMAIN}/serietv/?s={showname}'
|
||||||
response = await client.get(query,headers=headers)
|
response = await client.get(ForwardProxy + query,headers=headers, proxies = proxies)
|
||||||
|
if response.status_code != 200:
|
||||||
|
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}')
|
||||||
@@ -131,7 +134,6 @@ async def search_series(showname,date,client):
|
|||||||
# Find the link inside the current card
|
# Find the link inside the current card
|
||||||
link_tag = card.find('h3', class_='card-title').find('a')
|
link_tag = card.find('h3', class_='card-title').find('a')
|
||||||
href = link_tag['href']
|
href = link_tag['href']
|
||||||
|
|
||||||
# Find the date span and extract possible years
|
# Find the date span and extract possible years
|
||||||
date_span = card.find('span', style=re.compile('color'))
|
date_span = card.find('span', style=re.compile('color'))
|
||||||
if date_span:
|
if date_span:
|
||||||
@@ -140,78 +142,75 @@ async def search_series(showname,date,client):
|
|||||||
match = year_pattern.search(date_text)
|
match = year_pattern.search(date_text)
|
||||||
if match:
|
if match:
|
||||||
year = match.group(0)
|
year = match.group(0)
|
||||||
if year == date : # Check if the year is 2011
|
if (int(year) - int(date)) == 0 or (int(year)-int(date)) == 1 or (int(year)-int(date)) == -1 : # Check if the year is 2011
|
||||||
print(f"Link: {href}")
|
|
||||||
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):
|
async def movie_redirect_url(link,client,MFP,MFP_CREDENTIALS,streams):
|
||||||
headers = fake_headers.generate()
|
headers = fake_headers.generate()
|
||||||
response = client.get(link, headers=headers, allow_redirects=True, timeout=10)
|
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', id='iframen1'))
|
soup = BeautifulSoup(response.text, "lxml",parse_only=SoupStrainer('div'))
|
||||||
redirect_url = soup.find("div", id="iframen1").get("data-src")
|
redirect_url = soup.find("div", id="iframen2").get("data-src")
|
||||||
return redirect_url
|
redirect_url_2 = soup.find("div", id="iframen1").get("data-src")
|
||||||
async def series_redirect_url(link,season,episode,client):
|
if "stayonline" in redirect_url:
|
||||||
if len(episode) == 1:
|
mixdrop_real_link = await get_stayonline(redirect_url,client)
|
||||||
episode = f'0{episode}'
|
streams,status = await mixdrop(mixdrop_real_link,client,MFP,MFP_CREDENTIALS,streams,"CB01",proxies,ForwardProxy,"")
|
||||||
|
if status == False:
|
||||||
|
streams = await get_maxstream(redirect_url_2,streams,client)
|
||||||
|
return streams
|
||||||
|
|
||||||
|
async def series_search_streams(text,search_text,response_text,headers,season,episode,client,MFP,MFP_CREDENTIALS,streams):
|
||||||
|
if "A" in text:
|
||||||
|
captcha = re.search(rf'{search_text}.*?href="([^"]+)',response_text,re.DOTALL)
|
||||||
|
if captcha:
|
||||||
|
response = await client.get(ForwardProxy + captcha.group(1), headers = headers, allow_redirects = True, proxies = proxies)
|
||||||
|
season = season.zfill(2)
|
||||||
|
match = re.search(rf"(S{season}E{episode}|{season}x{episode}).+?href='([^']+)",response.text)
|
||||||
|
print(match.group(2))
|
||||||
|
if match:
|
||||||
|
streams = await get_maxstream(match.group(2),streams,client)
|
||||||
|
else:
|
||||||
|
match = re.search(rf'{season}×{episode}\s*–\s*<a[^>]*href="[^"]*"[^>]*>[^<]*</a>\s– <a[^>]*href="[^"]*',response_text)
|
||||||
|
if match:
|
||||||
|
links = match.group(0)
|
||||||
|
soup = BeautifulSoup(links,'lxml',parse_only=SoupStrainer('a'))
|
||||||
|
host_links = soup.find_all('a')
|
||||||
|
mixdrop_real_link = await get_stayonline(host_links[1]['href'],client)
|
||||||
|
status = False
|
||||||
|
#streams,status = await mixdrop(mixdrop_real_link,client,MFP,MFP_CREDENTIALS,streams,"CB01",proxies,ForwardProxy,"")
|
||||||
|
if status == False:
|
||||||
|
streams = await get_maxstream(host_links[0]['href'],streams,client)
|
||||||
|
return streams
|
||||||
|
async def series_redirect_url(link,season,episode,client,MFP,MFP_CREDENTIALS,streams):
|
||||||
|
episode = episode.zfill(2)
|
||||||
headers = fake_headers.generate()
|
headers = fake_headers.generate()
|
||||||
response = await client.get(link, headers=headers, allow_redirects=True, timeout=10)
|
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:
|
||||||
text = season_text.text
|
text = season_text.text
|
||||||
|
search_text = season_text.text
|
||||||
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:
|
streams = await series_search_streams(text,search_text,response.text,headers,season,episode,client,MFP,MFP_CREDENTIALS,streams)
|
||||||
if len(season) == 1:
|
elif f'STAGIONE' in text and 'A' in text.replace("STAGIONE","").replace("ITA", ""):
|
||||||
season = f'0{season}'
|
parts = text.split('STAGIONE ')[1].split(' A ')
|
||||||
sp_body = season_text.find_next('div', class_='sp-body')
|
num1 = int(parts[0])
|
||||||
link_tag = sp_body.find('a')
|
num2 = int(parts[1][0])
|
||||||
uprot_long = link_tag.get('href')
|
if int(season) in range(num1,num2):
|
||||||
response = await client.get(uprot_long, headers=headers, allow_redirects=True, timeout=10)
|
streams = await series_search_streams(text,search_text,response.text,headers,season,episode,client,MFP,MFP_CREDENTIALS,streams)
|
||||||
season = "01"
|
return streams
|
||||||
episode = "04"
|
|
||||||
pattern1 = rf"(?i)\S*?\.{season}x{episode}\S*?\.mkv.*?href=['\"](.*?)['\"]"
|
|
||||||
pattern2 = rf"\S*\.S{season}E{episode}\S*?\.mkv.*?href=['\"](.*?)['\"]"
|
|
||||||
match = re.search(pattern1, response.text)
|
|
||||||
if match:
|
|
||||||
maxstream_link = match.group(1)
|
|
||||||
else:
|
|
||||||
match = re.search(pattern2, response.text)
|
|
||||||
if match:
|
|
||||||
maxstream_link = match.group(1)
|
|
||||||
print(maxstream_link)
|
|
||||||
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)
|
|
||||||
print(final_url)
|
|
||||||
|
|
||||||
else:
|
|
||||||
pattern = re.compile(r'4×03\s*–.*?<a href="(.*?)".*?>Maxstream</a>\s*–.*?<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)
|
|
||||||
final_url = await get_true_link_mixdrop(mixdrop_real_link,client)
|
|
||||||
if final_url == None:
|
|
||||||
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)
|
|
||||||
print(final_url)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def cb01(id,client):
|
|
||||||
|
async def cb01(streams,id,MFP,MFP_CREDENTIALS,client):
|
||||||
try:
|
try:
|
||||||
general = is_movie(id)
|
general = await is_movie(id)
|
||||||
ismovie = general[0]
|
ismovie = general[0]
|
||||||
real_id = general[1]
|
real_id = general[1]
|
||||||
type = "Cb01"
|
type = "Cb01"
|
||||||
@@ -223,15 +222,18 @@ async def cb01(id,client):
|
|||||||
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)
|
||||||
redirect_url = await series_redirect_url(link,season,episode,client)
|
streams = await series_redirect_url(link,season,episode,client,MFP,MFP_CREDENTIALS,streams)
|
||||||
|
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)
|
streams = await movie_redirect_url(link,client,MFP,MFP_CREDENTIALS,streams)
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -250,16 +252,14 @@ async def cb01(id,client):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
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
|
test_id = "tt0158552:1:2" # This is an example ID format
|
||||||
test_id = "tt0158552:1:1" # This is an example ID format
|
MFP = "0"
|
||||||
results = await cb01(test_id, client)
|
results = await cb01({'streams': []},test_id,MFP,['test','test'],client)
|
||||||
|
print(results)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import asyncio
|
import asyncio
|
||||||
asyncio.run(test_animeworld())
|
asyncio.run(test_animeworld())
|
||||||
'''
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{'PHPSESSID': '351o0p0f00aaa7m0rughtn63og', 'captch5': 'e6cf235e0bcfee6044841d9dc4a7ea82'}
|
||||||
+15
-10
@@ -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
|
||||||
|
|
||||||
@@ -186,28 +190,28 @@ async def epg_guide(id,client):
|
|||||||
elif id in convert_bho_2:
|
elif id in convert_bho_2:
|
||||||
new_id = convert_bho_2[id]
|
new_id = convert_bho_2[id]
|
||||||
new_id = new_id.replace(" ","%20")
|
new_id = new_id.replace(" ","%20")
|
||||||
response = await client.get(f"https://mammamia-urlo-boh2.hf.space/{new_id}/now")
|
response = await client.get(f"https://aimammam-boh2.hf.space/{new_id}/now")
|
||||||
elif id in convert_bho_3:
|
elif id in convert_bho_3:
|
||||||
new_id = convert_bho_3[id]
|
new_id = convert_bho_3[id]
|
||||||
new_id = new_id.replace(" ","%20")
|
new_id = new_id.replace(" ","%20")
|
||||||
response = await client.get(f"https://mammamia-urlo-boh3.hf.space/{new_id}/now")
|
response = await client.get(f"https://aimammam-boh3.hf.space/{new_id}/now")
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
#async def test_animeworld():
|
async def test_animeworld():
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
test_id = "rai-news" # Replace with actual ID
|
test_id = "rai-1" # Replace with actual ID
|
||||||
try:
|
try:
|
||||||
results = await epg_guide(test_id, client)
|
results = await epg_guide(test_id, client)
|
||||||
print(results)
|
print(results)
|
||||||
@@ -216,7 +220,8 @@ async def epg_guide(id,client):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"An error occurred: {e}")
|
print(f"An error occurred: {e}")
|
||||||
|
|
||||||
#if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import httpx
|
import httpx
|
||||||
import asyncio
|
import asyncio
|
||||||
asyncio.run(test_animeworld())
|
asyncio.run(test_animeworld())
|
||||||
|
'''
|
||||||
@@ -0,0 +1,257 @@
|
|||||||
|
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 urllib.parse import quote
|
||||||
|
from Src.Utilities.loadenv import load_env
|
||||||
|
from Src.API.extractors.mixdrop import mixdrop
|
||||||
|
from Src.API.extractors.deltabit import deltabit
|
||||||
|
from Src.API.extractors.maxstream import maxstream
|
||||||
|
from Src.API.extractors.uprot import bypass_uprot
|
||||||
|
import re
|
||||||
|
import logging
|
||||||
|
from Src.Utilities.config import setup_logging
|
||||||
|
level = config.LEVEL
|
||||||
|
logger = setup_logging(level)
|
||||||
|
from bs4 import BeautifulSoup,SoupStrainer
|
||||||
|
env_vars = load_env()
|
||||||
|
random_headers = Headers()
|
||||||
|
try:
|
||||||
|
import pytesseract
|
||||||
|
from PIL import Image
|
||||||
|
except Exception as e:
|
||||||
|
print("You can not use ES")
|
||||||
|
|
||||||
|
import base64
|
||||||
|
from io import BytesIO
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import difflib
|
||||||
|
import random
|
||||||
|
from Src.Utilities.mfp import build_mfp
|
||||||
|
ES_DOMAIN = config.ES_DOMAIN
|
||||||
|
|
||||||
|
ES_PROXY = config.ES_PROXY
|
||||||
|
proxies = {}
|
||||||
|
if ES_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
|
||||||
|
}
|
||||||
|
ES_ForwardProxy = config.ES_ForwardProxy
|
||||||
|
if ES_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy = ""
|
||||||
|
|
||||||
|
|
||||||
|
async def get_maxstream(uprot_link,streams,language,client):
|
||||||
|
maxstream_link = await bypass_uprot(client,uprot_link)
|
||||||
|
if maxstream_link:
|
||||||
|
streams = await maxstream(maxstream_link,client,streams,'Eurostreaming',language,proxies,ForwardProxy)
|
||||||
|
else:
|
||||||
|
if maxstream_link == False:
|
||||||
|
return streams
|
||||||
|
else:
|
||||||
|
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}Eurostreaming\n▶️ Please do the captcha at /uprot in order to be able to play this content! \n Remember to refresh the sources!\nIf you recently did the captcha then dont worry, just refresh the sources', 'url': 'https://github.com/UrloMythus/MammaMia', 'behaviorHints': { 'bingeGroup': 'cb01'}})
|
||||||
|
|
||||||
|
return streams
|
||||||
|
|
||||||
|
|
||||||
|
def convert_numbers(base64_data):
|
||||||
|
image_data = base64.b64decode(base64_data)
|
||||||
|
image = Image.open(BytesIO(image_data))
|
||||||
|
custom_config = r'--oem 3 --psm 6 outputbase digits'
|
||||||
|
number_string = pytesseract.image_to_string(image, config=custom_config)
|
||||||
|
return number_string.strip()
|
||||||
|
|
||||||
|
|
||||||
|
async def get_numbers(safego_url,client):
|
||||||
|
headers = random_headers.generate()
|
||||||
|
headers['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64; rv:146.0) Gecko/20100101 Firefox/146.0'
|
||||||
|
headers['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
|
||||||
|
response = await client.get(ForwardProxy + safego_url,headers = headers, proxies = proxies, impersonate = 'chrome')
|
||||||
|
cookies = (response.cookies.get_dict())
|
||||||
|
soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('img'))
|
||||||
|
numbers = soup.img['src'].split(',')[1]
|
||||||
|
return numbers,cookies
|
||||||
|
|
||||||
|
async def real_page(safego_url,client):
|
||||||
|
try:
|
||||||
|
current_directory = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
file_path = os.path.join(current_directory, 'cookie.txt')
|
||||||
|
headers = random_headers.generate()
|
||||||
|
headers['Origin'] = 'https://safego.cc'
|
||||||
|
headers['Referer'] = safego_url
|
||||||
|
headers['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64; rv:146.0) Gecko/20100101 Firefox/146.0'
|
||||||
|
|
||||||
|
with open(file_path, 'r') as file:
|
||||||
|
cookies = file.read()
|
||||||
|
cookies = json.loads(cookies.replace("'", '"'))
|
||||||
|
response = await client.post(ForwardProxy + safego_url,headers=headers, cookies = cookies, proxies = proxies)
|
||||||
|
soup = BeautifulSoup(response.text,'lxml', parse_only=SoupStrainer('a'))
|
||||||
|
if len(soup)>= 1:
|
||||||
|
return soup.a['href']
|
||||||
|
else:
|
||||||
|
logger.info("Getting numbers")
|
||||||
|
numbers,cookies = await get_numbers(safego_url,client)
|
||||||
|
numbers = convert_numbers(numbers)
|
||||||
|
data = {'captch5': numbers}
|
||||||
|
response = await client.post(ForwardProxy + safego_url,headers=headers, data=data, cookies = cookies, proxies = proxies)
|
||||||
|
cap4 = response.headers.get('set-cookie').split(';')[0]
|
||||||
|
cookies[cap4.split('=')[0]] = cap4.split('=')[1]
|
||||||
|
with open(file_path, 'w') as file:
|
||||||
|
file.write(str(cookies))
|
||||||
|
soup = BeautifulSoup(response.text,'lxml', parse_only=SoupStrainer('a'))
|
||||||
|
return soup.a['href']
|
||||||
|
except Exception as e:
|
||||||
|
logger.info(f"ES{e}")
|
||||||
|
async def get_host_link(pattern,atag,client):
|
||||||
|
match = re.search(pattern, atag)
|
||||||
|
headers = random_headers.generate()
|
||||||
|
if match:
|
||||||
|
href_value = match.group(1)
|
||||||
|
response = await client.head(ForwardProxy + href_value, headers={**headers, 'Range': 'bytes=0-0'}, proxies = proxies)
|
||||||
|
href_value = response.url
|
||||||
|
href = await real_page(href_value,client)
|
||||||
|
return href
|
||||||
|
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.
|
||||||
|
if "MixDrop" in atag and "DeltaBit" in atag:
|
||||||
|
pattern = r'<a\s+href="([^"]+)"[^>]*rel="noopener"[^>]*>DeltaBit</a>'
|
||||||
|
href = await get_host_link(pattern,atag,client)
|
||||||
|
try:
|
||||||
|
streams = await deltabit(href,client,streams,"Eurostreaming",proxies,ForwardProxy,language)
|
||||||
|
except Exception as e:
|
||||||
|
pattern = r'<a\s+href="([^"]+)"[^>]*rel="noopener"[^>]*>MixDrop</a>'
|
||||||
|
href = await get_host_link(pattern,atag,client)
|
||||||
|
streams,status = await mixdrop(href,client,MFP,MFP_CREDENTIALS,streams,"Eurostreaming",proxies,ForwardProxy,language)
|
||||||
|
return streams
|
||||||
|
if "MixDrop" in atag and "DeltaBit" not in atag:
|
||||||
|
try:
|
||||||
|
pattern = r'<a\s+href="([^"]+)"[^>]*rel="noopener"[^>]*>MixDrop</a>'
|
||||||
|
href = await get_host_link(pattern,atag,client)
|
||||||
|
streams,status = await mixdrop(href,client,MFP,MFP_CREDENTIALS,streams,"Eurostreaming",proxies,ForwardProxy,language)
|
||||||
|
return streams
|
||||||
|
except Exception as e:
|
||||||
|
return streams
|
||||||
|
if 'DeltaBit' in atag and "MixDrop" not in atag:
|
||||||
|
try:
|
||||||
|
pattern = r'<a\s+href="([^"]+)"[^>]*rel="noopener"[^>]*>DeltaBit</a>'
|
||||||
|
href = await get_host_link(pattern,atag,client)
|
||||||
|
streams = await deltabit(href,client,streams,"Eurostreaming",proxies,ForwardProxy,language)
|
||||||
|
return streams
|
||||||
|
except Exception as e:
|
||||||
|
return streams
|
||||||
|
if 'DeltaBit' not in atag and 'MixDrop' not in atag and 'MaxStream' in atag:
|
||||||
|
try:
|
||||||
|
pattern = r'<a\s+href="([^"]+)"[^>]*rel="noopener"[^>]*>MaxStream</a>'
|
||||||
|
match = re.search(pattern, atag)
|
||||||
|
if match:
|
||||||
|
href_value = match.group(1)
|
||||||
|
streams = await get_maxstream(href_value,streams,language,client)
|
||||||
|
return streams
|
||||||
|
except Exception as e:
|
||||||
|
return streams
|
||||||
|
if 'DeltaBit' not in atag and 'MixDrop' not in atag and 'MaxStream' not in atag:
|
||||||
|
logger.info("Just give up")
|
||||||
|
return streams
|
||||||
|
|
||||||
|
async def episodes_find(description,season,episode,MFP,MFP_CREDENTIALS,client,streams):
|
||||||
|
t = 0
|
||||||
|
episode = episode.zfill(2)
|
||||||
|
pattern = rf'\b{season}×{episode}\s*(.*?)(?=<br\s*/?>)'
|
||||||
|
match = re.findall(pattern, description)
|
||||||
|
if match:
|
||||||
|
for episode_details in match:
|
||||||
|
if "href" in episode_details:
|
||||||
|
if t == 0:
|
||||||
|
language = "\nITA"
|
||||||
|
elif t == 1:
|
||||||
|
language = "\nSUB-ITA"
|
||||||
|
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()
|
||||||
|
|
||||||
|
response = await client.get(ForwardProxy + f"{ES_DOMAIN}/wp-json/wp/v2/search?search={quote(showname)}&_fields=id", proxies = proxies, headers = headers)
|
||||||
|
results = response.json()
|
||||||
|
for i in results:
|
||||||
|
response = await client.get(ForwardProxy + f"{ES_DOMAIN}/wp-json/wp/v2/posts/{i['id']}?_fields=content,title", proxies = proxies, headers = headers)
|
||||||
|
if f'ID articolo non valido' in response.text:
|
||||||
|
continue
|
||||||
|
description = response.json()
|
||||||
|
title = description['title']['rendered']
|
||||||
|
description = description['content']['rendered']
|
||||||
|
ratio = difflib.SequenceMatcher(None, title, showname).ratio()
|
||||||
|
if ratio >=0.96:
|
||||||
|
streams = await episodes_find(description,season,episode,MFP,MFP_CREDENTIALS,client,streams)
|
||||||
|
return streams
|
||||||
|
else:
|
||||||
|
year_pattern = re.compile(r'(?<!/)(19|20)\d{2}(?!/)')
|
||||||
|
match = year_pattern.search(description)
|
||||||
|
if match:
|
||||||
|
year = match.group(0)
|
||||||
|
|
||||||
|
else:
|
||||||
|
pattern = r'<a\s+href="([^"]+)"[^>]*>Continua a leggere</a>'
|
||||||
|
match = re.search(pattern, description)
|
||||||
|
if match:
|
||||||
|
href_value = match.group(1)
|
||||||
|
response_2 = await client.get(ForwardProxy + href_value, proxies = proxies, headers = headers)
|
||||||
|
match = year_pattern.search(response_2.text)
|
||||||
|
if match:
|
||||||
|
year = match.group(0)
|
||||||
|
if abs(int(year) - int(date)) <=1:
|
||||||
|
streams = await episodes_find(description,season,episode,MFP,MFP_CREDENTIALS,client,streams)
|
||||||
|
return streams
|
||||||
|
return streams
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def eurostreaming(streams,id,client,MFP,MFP_CREDENTIALS):
|
||||||
|
try:
|
||||||
|
general = await is_movie(id)
|
||||||
|
ismovie = general[0]
|
||||||
|
clean_id = general[1]
|
||||||
|
type = "Eurostreaming"
|
||||||
|
if ismovie == 0 :
|
||||||
|
season = str(general[2])
|
||||||
|
episode = str(general[3])
|
||||||
|
elif ismovie == 1:
|
||||||
|
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(f"ES {showname}")
|
||||||
|
streams = await search(showname,date, season,episode,MFP,MFP_CREDENTIALS,client,streams)
|
||||||
|
return streams
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"ES {e}")
|
||||||
|
return streams
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def test_euro():
|
||||||
|
from curl_cffi.requests import AsyncSession
|
||||||
|
async with AsyncSession() as client:
|
||||||
|
results = await eurostreaming({'streams': []},"tt0460681:11:1",client,"0",['test','test'])
|
||||||
|
print(results)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_euro())
|
||||||
|
#python3 -m Src.API.eurostreaming
|
||||||
|
|
||||||
|
'''tt11950864
|
||||||
|
'''
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
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,streams,site_name,proxies,ForwardProxy,language)
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#Testing
|
||||||
|
async def test_deltabit():
|
||||||
|
from curl_cffi.requests import AsyncSession
|
||||||
|
async with AsyncSession() as client:
|
||||||
|
results = await deltabit("https://deltabit.co/a54ehb8w42pe",client,{'streams': []},'Deltabit', {},"","")
|
||||||
|
print(results)
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_deltabit())
|
||||||
|
|
||||||
|
# https://loadm.cam/#cfnqx
|
||||||
@@ -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
|
||||||
@@ -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())
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
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']
|
||||||
|
m3u8 = data['source']
|
||||||
|
if hls:
|
||||||
|
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}{site_name}\n▶️ Loadm\nPlayer One\n{title}', 'url': hls, 'behaviorHints': {'proxyHeaders': {"request": {"Referer": player_url}}, 'notWebReady': True, 'bingeGroup': f'{site_name.lower()}hls'}})
|
||||||
|
logger.info(f"{site_name} on Loadm found results for player one in the current ID")
|
||||||
|
if m3u8:
|
||||||
|
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}{site_name}\n▶️ Loadm\nPlayer Two\n{title}', 'url': m3u8, 'behaviorHints': {'proxyHeaders': {"request": {"Referer": player_url}}, 'notWebReady': True, 'bingeGroup': f'{site_name.lower()}m3u8'}})
|
||||||
|
logger.info(f"{site_name} on Loadm found results for player two in 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
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
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
|
||||||
|
from fake_headers import Headers
|
||||||
|
random_headers = Headers()
|
||||||
|
import re
|
||||||
|
|
||||||
|
async def maxstream(url,client,streams,site_name,language,proxies,ForwardProxy):
|
||||||
|
headers = random_headers.generate()
|
||||||
|
response = await client.get( ForwardProxy + url, allow_redirects=True, timeout=30, headers = headers, proxies = proxies, impersonate = "chrome")
|
||||||
|
pattern = r'sources\W+src\W+(.*)",'
|
||||||
|
match = re.search(pattern,response.text)
|
||||||
|
if match:
|
||||||
|
url = match.group(1)
|
||||||
|
logger.info(f"{site_name} on Maxstream found results for the current ID")
|
||||||
|
streams['streams'].append({'name': f"{Name}{language}",'title': f'{Icon}{site_name}\n▶️ Maxstream', 'url': url, 'behaviorHints': { 'bingeGroup': f'{site_name.lower()}'}})
|
||||||
|
return streams
|
||||||
|
|
||||||
|
async def test_maxstream():
|
||||||
|
from curl_cffi.requests import AsyncSession
|
||||||
|
async with AsyncSession() as client:
|
||||||
|
results = await maxstream("https://maxstream.video/emvvv/a7wc8bb0h68c",client,{'streams': []},'CB01', {},'')
|
||||||
|
print(results)
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_maxstream())
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
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."""
|
||||||
|
status = False
|
||||||
|
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")
|
||||||
|
status = True
|
||||||
|
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")
|
||||||
|
status = True
|
||||||
|
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,status
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
import os
|
||||||
|
from bs4 import BeautifulSoup,SoupStrainer
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import Src.Utilities.config as config
|
||||||
|
from Src.Utilities.config import setup_logging
|
||||||
|
from Src.Utilities.loadenv import load_env
|
||||||
|
|
||||||
|
UT_PROXY = config.UT_PROXY
|
||||||
|
UT_ForwardProxy = config.UT_ForwardProxy
|
||||||
|
level = config.LEVEL
|
||||||
|
env_vars = load_env()
|
||||||
|
import random
|
||||||
|
logger = setup_logging(level)
|
||||||
|
#Set up proxies
|
||||||
|
proxies = {}
|
||||||
|
if UT_PROXY == "1":
|
||||||
|
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
|
||||||
|
proxy_list = json.loads(PROXY_CREDENTIALS)
|
||||||
|
proxy = random.choice(proxy_list)
|
||||||
|
if proxy == "":
|
||||||
|
proxies = {}
|
||||||
|
else:
|
||||||
|
proxies = {
|
||||||
|
"http": proxy,
|
||||||
|
"https": proxy
|
||||||
|
}
|
||||||
|
if UT_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy = ""
|
||||||
|
|
||||||
|
url = 'https://uprot.net/msf/r4hcq47tarq8'
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:146.0) Gecko/20100101 Firefox/146.0',
|
||||||
|
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||||
|
'Accept-Language': 'en-US,en;q=0.5',
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
'Origin': url.split('msf')[0],
|
||||||
|
'Sec-GPC': '1',
|
||||||
|
'Connection': 'keep-alive',
|
||||||
|
'Referer': url,
|
||||||
|
'Upgrade-Insecure-Requests': '1',
|
||||||
|
'Sec-Fetch-Dest': 'document',
|
||||||
|
'Sec-Fetch-Mode': 'navigate',
|
||||||
|
'Sec-Fetch-Site': 'same-origin',
|
||||||
|
'Sec-Fetch-User': '?1',
|
||||||
|
'DNT': '1',
|
||||||
|
'Priority': 'u=0, i',
|
||||||
|
}
|
||||||
|
async def get_uprot_numbers(client):
|
||||||
|
try:
|
||||||
|
response = await client.post(ForwardProxy + url, headers=headers, proxies = proxies)
|
||||||
|
set_cookie = response.headers.get('set-cookie')
|
||||||
|
parts = set_cookie.split(';')[0].split('=')
|
||||||
|
key = parts[0]
|
||||||
|
value = parts[1]
|
||||||
|
cookies = {
|
||||||
|
key:value
|
||||||
|
}
|
||||||
|
soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('img'))
|
||||||
|
|
||||||
|
img = soup.find('img')['src']
|
||||||
|
return img,cookies
|
||||||
|
except Exception as e:
|
||||||
|
logger.info(f'Uprot failed to generate numberers/cookies: {e}')
|
||||||
|
return None,None
|
||||||
|
async def generate_uprot_txt(numbers,cookies,client):
|
||||||
|
try:
|
||||||
|
data = {
|
||||||
|
'captcha': str(numbers),
|
||||||
|
}
|
||||||
|
response = await client.post(ForwardProxy + url, cookies=cookies, headers=headers, data=data, proxies = proxies)
|
||||||
|
if response.status_code != 200:
|
||||||
|
return False
|
||||||
|
set_cookie = response.headers.get('set-cookie')
|
||||||
|
parts = set_cookie.split(';')[0].split('=')
|
||||||
|
key = parts[0]
|
||||||
|
value = parts[1]
|
||||||
|
cookies[key] = value
|
||||||
|
current_directory = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
file_path = os.path.join(current_directory, 'uprot.txt')
|
||||||
|
with open(file_path,'w') as file:
|
||||||
|
file.write(f'{str(cookies)}\n{str(data)}')
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
logger.info(f'Uprot failed to generate captcha cookie: {e}')
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def get_maxstream_link(text,client):
|
||||||
|
soup = BeautifulSoup(text,'lxml',parse_only=SoupStrainer('a'))
|
||||||
|
a_tags = soup.find_all('a')
|
||||||
|
|
||||||
|
max_stream = None
|
||||||
|
for tag in a_tags:
|
||||||
|
if 'C O N T I N U E' in tag.text.upper():
|
||||||
|
max_stream = tag['href']
|
||||||
|
if max_stream:
|
||||||
|
redirect = max_stream
|
||||||
|
time = 0
|
||||||
|
while 'uprots' in redirect:
|
||||||
|
response = await client.head(ForwardProxy + max_stream,headers=headers,impersonate = 'chrome', allow_redirects = True, proxies = proxies)
|
||||||
|
redirect = response.url
|
||||||
|
time+=1
|
||||||
|
if time == 1000:
|
||||||
|
return False
|
||||||
|
max_stream = 'https://maxstream.video/emvvv/' + response.url.split('watchfree/')[1].split('/')[1]
|
||||||
|
return max_stream
|
||||||
|
|
||||||
|
async def bypass_uprot(client,link):
|
||||||
|
try:
|
||||||
|
if 'mse' in link:
|
||||||
|
link = link.replace('mse','msf')
|
||||||
|
current_directory = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
file_path = os.path.join(current_directory, 'uprot.txt')
|
||||||
|
with open(file_path,'r') as file:
|
||||||
|
text = file.read()
|
||||||
|
parts = text.split('\n')
|
||||||
|
cookies = json.loads(parts[0].replace("'", '"'))
|
||||||
|
data = json.loads(parts[1].replace("'", '"'))
|
||||||
|
response = await client.post(ForwardProxy + link, cookies=cookies, headers=headers, data =data, impersonate = 'chrome', proxies = proxies)
|
||||||
|
max_stream = await get_maxstream_link(response.text,client)
|
||||||
|
return max_stream
|
||||||
|
except Exception as e:
|
||||||
|
logger.info(f'Uprot failed: {e}')
|
||||||
|
if '[Errno 2] No such file or directory' in e:
|
||||||
|
return None
|
||||||
|
return False
|
||||||
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
{'PHPSESSID': 'bm1qtf1pe0dnr4u4nhvofitk8u', 'captcha': 'ca5612d51c9bbc60f8d76051693d3315'}
|
||||||
|
{'captcha': '853'}
|
||||||
@@ -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}{site_name}\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
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
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 = '🕵️♂️'
|
||||||
|
if final_url:
|
||||||
|
streams['streams'].append({"name":f'{Name} {mfp_icon}\n{quality}', 'title': f'{Icon} StreamingCommunity\n▶️ Vixcloud','url': final_url,'behaviorHints': {'bingeGroup': f'{site_name.lower()}{quality}'}})
|
||||||
|
return streams
|
||||||
|
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(f"Failed to extract URL components from VixSRC, Invalid Request: {response.status_code}")
|
||||||
|
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")
|
||||||
|
#We add .m3u8 after the VixID in order to make the video playable by ExoPlayer
|
||||||
|
parts_final_url = final_url.split("?")
|
||||||
|
first_part_final_url = parts_final_url[0] + ".m3u8"
|
||||||
|
final_url = first_part_final_url + "?" + parts_final_url[1]
|
||||||
|
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())
|
||||||
|
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
'''
|
||||||
|
Code taken from https://github.com/mhdzumair/mediaflow-proxy/blob/main/mediaflow_proxy/extractors/voe.py adpted to work with MammaMia
|
||||||
|
The owner of MammaMia should not be thanked for any code in this script.
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import re
|
||||||
|
from typing import Dict, Any
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
import Src.Utilities.config as config
|
||||||
|
from Src.Utilities.config import setup_logging
|
||||||
|
from Src.Utilities.mfp import build_mfp
|
||||||
|
|
||||||
|
level = config.LEVEL
|
||||||
|
logger = setup_logging(level)
|
||||||
|
Icon = config.Icon
|
||||||
|
Name = config.Name
|
||||||
|
from fake_headers import Headers
|
||||||
|
random_headers = Headers()
|
||||||
|
|
||||||
|
|
||||||
|
async def voe(url,streams,site_name,MFP,MFP_CREDENTIALS,proxies,ForwardProxy,client):
|
||||||
|
if MFP == '1':
|
||||||
|
url = await build_mfp(MFP_CREDENTIALS,url,"Voe",client)
|
||||||
|
if url and "https%3ANone" not in url:
|
||||||
|
logger.info(f"{site_name} on Voe found results for the current ID")
|
||||||
|
streams['streams'].append({'name': f"{Name} 🕵️♂️",'title': f'{Icon}{site_name}\n▶️ Voe', 'url': url, 'behaviorHints':{'bingeGroup': f'{site_name.lower()}'}})
|
||||||
|
return streams
|
||||||
|
|
||||||
|
|
||||||
|
headers = random_headers.generate()
|
||||||
|
response = await client.get(ForwardProxy + url,headers=headers, impersonate = 'chrome', proxies = proxies)
|
||||||
|
|
||||||
|
# See https://github.com/Gujal00/ResolveURL/blob/master/script.module.resolveurl/lib/resolveurl/plugins/voesx.py
|
||||||
|
redirect_pattern = r'''window\.location\.href\s*=\s*'([^']+)'''
|
||||||
|
redirect_match = re.search(redirect_pattern, response.text, re.DOTALL)
|
||||||
|
if redirect_match:
|
||||||
|
if redirected:
|
||||||
|
logger.info("VOE: too many redirects")
|
||||||
|
|
||||||
|
return await voe(redirect_match.group(1))
|
||||||
|
|
||||||
|
code_and_script_pattern = r'json">\["([^"]+)"]</script>\s*<script\s*src="([^"]+)'
|
||||||
|
code_and_script_match = re.search(code_and_script_pattern, response.text, re.DOTALL)
|
||||||
|
if not code_and_script_match:
|
||||||
|
logger.info("VOE: unable to locate obfuscated payload or external script URL")
|
||||||
|
|
||||||
|
|
||||||
|
script_response = await client.get(ForwardProxy+urljoin(url, code_and_script_match.group(2)),headers=headers, proxies = proxies)
|
||||||
|
|
||||||
|
luts_pattern = r"(\[(?:'\W{2}'[,\]]){1,9})"
|
||||||
|
luts_match = re.search(luts_pattern, script_response.text, re.DOTALL)
|
||||||
|
if not luts_match:
|
||||||
|
logger.info("VOE: unable to locate LUTs in external script")
|
||||||
|
|
||||||
|
data = voe_decode(code_and_script_match.group(1), luts_match.group(1))
|
||||||
|
|
||||||
|
final_url = data.get('source')
|
||||||
|
if not final_url:
|
||||||
|
logger.info("VOE: failed to extract video URL")
|
||||||
|
return streams
|
||||||
|
if final_url:
|
||||||
|
logger.info(f"{site_name} on Voe found results for the current ID")
|
||||||
|
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}{site_name}\n▶️ Voe', 'url': final_url, 'behaviorHints': {'proxyHeaders': {"request": {"Referer": url}}, 'notWebReady': True, 'bingeGroup': f'{site_name.lower()}'}})
|
||||||
|
|
||||||
|
return streams
|
||||||
|
|
||||||
|
def voe_decode(ct: str, luts: str) -> Dict[str, Any]:
|
||||||
|
import json
|
||||||
|
lut = [''.join([('\\' + x) if x in '.*+?^${}()|[]\\' else x for x in i]) for i in luts[2:-2].split("','")]
|
||||||
|
txt = ''
|
||||||
|
for i in ct:
|
||||||
|
x = ord(i)
|
||||||
|
if 64 < x < 91:
|
||||||
|
x = (x - 52) % 26 + 65
|
||||||
|
elif 96 < x < 123:
|
||||||
|
x = (x - 84) % 26 + 97
|
||||||
|
txt += chr(x)
|
||||||
|
for i in lut:
|
||||||
|
txt = re.sub(i, '', txt)
|
||||||
|
ct = base64.b64decode(txt).decode('utf-8')
|
||||||
|
txt = ''.join([chr(ord(i) - 3) for i in ct])
|
||||||
|
txt = base64.b64decode(txt[::-1]).decode('utf-8')
|
||||||
|
return json.loads(txt)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def test_voe():
|
||||||
|
from curl_cffi.requests import AsyncSession
|
||||||
|
async with AsyncSession() as client:
|
||||||
|
results = await voe("https://crystaltreatmenteast.com/wnnov1m62xzy",{'streams': []},'ToonItalia','1','[https:idk.com,a]',{},'',client)
|
||||||
|
print(results)
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_voe())
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
|
|
||||||
from tmdbv3api import TMDb, Movie, TV
|
|
||||||
from bs4 import BeautifulSoup,SoupStrainer
|
|
||||||
import string
|
|
||||||
import re
|
|
||||||
import dateparser
|
|
||||||
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.convert_date import convert_US_date
|
|
||||||
import Src.Utilities.config as config
|
|
||||||
FT_DOMAIN = config.FT_DOMAIN
|
|
||||||
import urllib.parse
|
|
||||||
WOA = 0
|
|
||||||
#Some basic headers
|
|
||||||
headers = {
|
|
||||||
'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',
|
|
||||||
'Accept-Language': 'en-US,en;q=0.5'
|
|
||||||
}
|
|
||||||
#Map months to check if date = date
|
|
||||||
month_mapping = {
|
|
||||||
'Jan': 'Gennaio', 'Feb': 'Febbraio', 'Mar': 'Marzo', 'Apr': 'Aprile',
|
|
||||||
'May': 'Maggio', 'Jun': 'Giugno', 'Jul': 'Luglio', 'Aug': 'Agosto',
|
|
||||||
'Sep': 'Settembre', 'Oct': 'Ottobre', 'Nov': 'Novembre', 'Dec': 'Dicembre'
|
|
||||||
}
|
|
||||||
|
|
||||||
async def search(query,date,client,season,ismovie):
|
|
||||||
response = await client.get(query)
|
|
||||||
response = response.json()
|
|
||||||
#Get link tid of every item and then open the link to see if the date = date
|
|
||||||
for json in response:
|
|
||||||
link = json['link']
|
|
||||||
tid = json['id']
|
|
||||||
series_response = await client.get(link, headers=headers, allow_redirects=True, timeout = 30)
|
|
||||||
series_soup = BeautifulSoup(series_response.text, 'lxml')
|
|
||||||
release_span = series_soup.find('span', class_='released')
|
|
||||||
if release_span:
|
|
||||||
if release_span.text != "Data di uscita: N/A":
|
|
||||||
date_string = release_span.text.split(': ')[-1] # Get the date part
|
|
||||||
release_date = date_string[-4:]
|
|
||||||
if WOA:
|
|
||||||
for eng, ita in month_mapping.items():
|
|
||||||
date_string = re.sub(rf'\b{eng}\b', ita, date_string)
|
|
||||||
|
|
||||||
# Swap to YY-MM-DD formatting using dateparser
|
|
||||||
release_date = dateparser.parse(date_string, languages=['it']).strftime("%Y-%m-%d")
|
|
||||||
if release_date == date:
|
|
||||||
url = link
|
|
||||||
tid = tid
|
|
||||||
if ismovie == 0:
|
|
||||||
Seasons = series_soup.find_all('span', class_="season-name")
|
|
||||||
i = 0
|
|
||||||
for item in Seasons:
|
|
||||||
season_text = item.text.strip()
|
|
||||||
if season in season_text and "SUB" not in season_text:
|
|
||||||
actual_season = i
|
|
||||||
return url, tid, actual_season
|
|
||||||
else:
|
|
||||||
i = i + 1
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
actual_season = None
|
|
||||||
return url, tid, actual_season
|
|
||||||
else:
|
|
||||||
print("")
|
|
||||||
|
|
||||||
def get_episode_link(actual_season,episode,tid,url):
|
|
||||||
#Get the link from where we have to obtain mixdrop link
|
|
||||||
tlink = f'{url}?show_video=true&post_id={tid}&season_id={actual_season}&episode_id={episode-1}'
|
|
||||||
return tlink
|
|
||||||
|
|
||||||
|
|
||||||
def get_film(url):
|
|
||||||
#Get the link from where we have to obtain mixdrop link
|
|
||||||
tlink = url + "?show_video=true"
|
|
||||||
return tlink
|
|
||||||
|
|
||||||
async def get_real_link(tlink,client):
|
|
||||||
#Some basic code to get the mixdrop link
|
|
||||||
page = await client.get(tlink, headers=headers, allow_redirects=True)
|
|
||||||
soup = BeautifulSoup(page.content, features="lxml",parse_only=SoupStrainer('iframe'))
|
|
||||||
iframe_src = soup.find('iframe')['src']
|
|
||||||
iframe_page = await client.get(iframe_src, headers=headers, allow_redirects=True, timeout = 30)
|
|
||||||
iframe_soup = BeautifulSoup(iframe_page.content, features="lxml")
|
|
||||||
|
|
||||||
mega_button = iframe_soup.find('div', attrs={'class': 'megaButton', 'rel': 'nofollow'}, string='MIXDROP')
|
|
||||||
if mega_button:
|
|
||||||
real_link = mega_button.get('meta-link')
|
|
||||||
return real_link
|
|
||||||
|
|
||||||
async def get_true_link(real_link,client):
|
|
||||||
response = await client.get(real_link, headers=headers, allow_redirects=True,timeout = 30)
|
|
||||||
[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
|
|
||||||
return s
|
|
||||||
|
|
||||||
async def filmpertutti(imdb,client):
|
|
||||||
general = is_movie(imdb)
|
|
||||||
ismovie = general[0]
|
|
||||||
imdb_id = general[1]
|
|
||||||
type = "Filmpertutti"
|
|
||||||
if ismovie == 0 :
|
|
||||||
season = general[2]
|
|
||||||
episode = int(general[3])
|
|
||||||
if "tt" in imdb:
|
|
||||||
if ismovie == 0:
|
|
||||||
#Get showname and date
|
|
||||||
showname,date = await get_info_imdb(imdb_id,ismovie,type,client)
|
|
||||||
else:
|
|
||||||
#THIS IS needed cause the only way to get all releases dates is by giving a tmdb ID not a IMDB
|
|
||||||
showname,date = await get_info_imdb(imdb_id,ismovie,type, client)
|
|
||||||
season = None
|
|
||||||
|
|
||||||
elif "tmdb" in imdb:
|
|
||||||
#Get showname and date
|
|
||||||
tmdba = imdb_id.replace("tmdb:","")
|
|
||||||
showname,date = get_info_tmdb(tmdba,ismovie,type)
|
|
||||||
showname = showname.replace(" ", "+").replace("–", "+").replace("—","+")
|
|
||||||
showname = urllib.parse.quote_plus(showname)
|
|
||||||
#Build the query
|
|
||||||
query = f'https://filmpertutti.{FT_DOMAIN}/wp-json/wp/v2/posts?search={showname}&page=1&_fields=link,id'
|
|
||||||
try:
|
|
||||||
url,tid,actual_season = await search(query,date,client,season,ismovie)
|
|
||||||
except:
|
|
||||||
print("MammaMia: No results found for Filmpertutti")
|
|
||||||
return None
|
|
||||||
if ismovie == 0:
|
|
||||||
episode_link = get_episode_link(actual_season,episode,tid,url)
|
|
||||||
#Let's get mixdrop link
|
|
||||||
real_link = await get_real_link(episode_link,client)
|
|
||||||
#let's get delivery link, streaming link
|
|
||||||
streaming_link = await get_true_link(real_link,client)
|
|
||||||
print(streaming_link)
|
|
||||||
return streaming_link
|
|
||||||
elif ismovie == 1:
|
|
||||||
film_link = get_film(url)
|
|
||||||
#Let's get mixdrop link
|
|
||||||
real_link = await get_real_link(film_link,client)
|
|
||||||
#let's get delivery link, streaming link
|
|
||||||
streaming_link = await get_true_link(real_link,client)
|
|
||||||
return streaming_link
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
async def test_animeworld():
|
|
||||||
from curl_cffi.requests import AsyncSession
|
|
||||||
async with AsyncSession() as client:
|
|
||||||
# Replace with actual id, for example 'anime_id:episode' format
|
|
||||||
test_id = "tt4655480:1:1" # This is an example ID format
|
|
||||||
results = await filmpertutti(test_id, client)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import asyncio
|
|
||||||
asyncio.run(test_animeworld())
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
series_response = await client.get(link, headers=headers, follow_redirects=True)
|
|
||||||
series_soup = BeautifulSoup(series_response.text, 'lxml')
|
|
||||||
release_span = series_soup.find('span', class_='released')
|
|
||||||
if release_span:
|
|
||||||
if release_span.text != "Data di uscita: N/A":
|
|
||||||
date_string = release_span.text.split(': ')[-1] # Get the date part
|
|
||||||
for eng, ita in month_mapping.items():
|
|
||||||
date_string = re.sub(rf'\b{eng}\b', ita, date_string)
|
|
||||||
|
|
||||||
# Swap to YY-MM-DD formatting using dateparser
|
|
||||||
release_date = dateparser.parse(date_string, languages=['it']).strftime("%Y-%m-%d")
|
|
||||||
'''
|
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
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
|
||||||
|
import json
|
||||||
|
import random
|
||||||
|
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'
|
||||||
|
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)
|
||||||
|
if response.status_code != 200:
|
||||||
|
logger.warning(f"Guardaflix Failed to fetch search results: {response.status_code}")
|
||||||
|
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
|
||||||
|
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': []},"tt4045450",client,"0",['test','test'])
|
||||||
|
print(results)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_guardaflix())
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
from Src.Utilities.info import is_movie
|
||||||
|
from bs4 import BeautifulSoup,SoupStrainer
|
||||||
|
import re
|
||||||
|
import Src.Utilities.config as config
|
||||||
|
from fake_headers import Headers
|
||||||
|
from Src.Utilities.loadenv import load_env
|
||||||
|
from Src.API.extractors.supervideo import supervideo
|
||||||
|
import json, random
|
||||||
|
import logging
|
||||||
|
from Src.Utilities.config import setup_logging
|
||||||
|
level = config.LEVEL
|
||||||
|
logger = setup_logging(level)
|
||||||
|
env_vars = load_env()
|
||||||
|
GH_PROXY = config.GH_PROXY
|
||||||
|
proxies = {}
|
||||||
|
if GH_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
|
||||||
|
}
|
||||||
|
GH_ForwardProxy = config.GH_ForwardProxy
|
||||||
|
if GH_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy = ""
|
||||||
|
GHD_DOMAIN = config.GHD_DOMAIN
|
||||||
|
|
||||||
|
random_headers = Headers()
|
||||||
|
|
||||||
|
|
||||||
|
async def search(clean_id,client):
|
||||||
|
headers = random_headers.generate()
|
||||||
|
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:
|
||||||
|
logger.warning(f"GuardaHD Failed to fetch search results: {response.status_code}")
|
||||||
|
soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('li'))
|
||||||
|
li_tags = soup.find_all('li')
|
||||||
|
for tag in li_tags:
|
||||||
|
if 'supervideo' in tag['data-link']:
|
||||||
|
href = 'https:' + tag['data-link']
|
||||||
|
return href
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def guardahd(streams,id,client):
|
||||||
|
try:
|
||||||
|
general = await is_movie(id)
|
||||||
|
ismovie = general[0]
|
||||||
|
clean_id = general[1]
|
||||||
|
if ismovie == 0:
|
||||||
|
return streams
|
||||||
|
supervideo_link = await search(clean_id,client)
|
||||||
|
streams = await supervideo(supervideo_link, client,streams,"GuardaHD",proxies, ForwardProxy)
|
||||||
|
return streams
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"MammaMia: GuardaHD 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 = "tt12300742" # This is an example ID format
|
||||||
|
results = await guardahd({'streams': []},test_id, client)
|
||||||
|
print(results)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_script())
|
||||||
|
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
from Src.Utilities.info import is_movie
|
||||||
|
from bs4 import BeautifulSoup,SoupStrainer
|
||||||
|
import re
|
||||||
|
import Src.Utilities.config as config
|
||||||
|
from fake_headers import Headers
|
||||||
|
from Src.Utilities.loadenv import load_env
|
||||||
|
import json, random
|
||||||
|
from Src.Utilities.info import get_info_imdb,get_info_tmdb
|
||||||
|
import urllib.parse
|
||||||
|
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()
|
||||||
|
GS_PROXY = config.GS_PROXY
|
||||||
|
proxies = {}
|
||||||
|
if GS_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
|
||||||
|
}
|
||||||
|
GS_ForwardProxy = config.GS_ForwardProxy
|
||||||
|
if GS_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy = ""
|
||||||
|
#Get domain
|
||||||
|
GS_DOMAIN = config.GS_DOMAIN
|
||||||
|
random_headers = Headers()
|
||||||
|
|
||||||
|
async def search_imdb(clean_id,client):
|
||||||
|
try:
|
||||||
|
headers = random_headers.generate()
|
||||||
|
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:
|
||||||
|
logger.warning(f"Guardaserie Failed to fetch search results: {response.status_code}")
|
||||||
|
soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('div',class_="mlnh-2"))
|
||||||
|
div_mlnh2 = soup.select_one('div.mlnh-2:nth-of-type(2)')
|
||||||
|
a_tag = div_mlnh2.find('h2').find('a')
|
||||||
|
href = a_tag['href']
|
||||||
|
return href
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f'GS {e}')
|
||||||
|
return None
|
||||||
|
'''
|
||||||
|
async def search(showname,date,client):
|
||||||
|
try:
|
||||||
|
headers = random_headers.generate()
|
||||||
|
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)
|
||||||
|
if response.status_code != 200:
|
||||||
|
logger.warning(f"Guardaserie Failed to fetch search results: {response.status_code}")
|
||||||
|
soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('div'))
|
||||||
|
div_mlnew = soup.find_all('div', class_='mlnew')
|
||||||
|
for mlnew in div_mlnew:
|
||||||
|
div_date = mlnew.find('div', class_='mlnh-3 hdn').text
|
||||||
|
div_date = div_date[:4]
|
||||||
|
if div_date == date:
|
||||||
|
a_tag = mlnew.find('div', class_='mlnh-2').find('h2').find('a')
|
||||||
|
href = a_tag['href']
|
||||||
|
return href
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return None
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
async def player_url(page_url, season, episode,client):
|
||||||
|
try:
|
||||||
|
headers = random_headers.generate()
|
||||||
|
response = await client.get(ForwardProxy + page_url, allow_redirects=True, headers = headers, proxies = proxies)
|
||||||
|
soup = BeautifulSoup(response.text,'lxml',parse_only=SoupStrainer('a'))
|
||||||
|
a_tag = soup.find('a', id = f"serie-{season}_{episode}")
|
||||||
|
href = a_tag['data-link']
|
||||||
|
return href
|
||||||
|
except Exception as e:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def guardaserie(streams,id,client):
|
||||||
|
try:
|
||||||
|
general = await is_movie(id)
|
||||||
|
ismovie = general[0]
|
||||||
|
clean_id = general[1]
|
||||||
|
if ismovie == 1:
|
||||||
|
return streams
|
||||||
|
if ismovie == 0:
|
||||||
|
season = general[2]
|
||||||
|
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:
|
||||||
|
clean_id = await get_IMDB_id_from_TMDb_id(clean_id,client)
|
||||||
|
print(clean_id)
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
if "tt" in id:
|
||||||
|
showname,date = await get_info_imdb(clean_id,ismovie,type,client)
|
||||||
|
else:
|
||||||
|
showname,date = get_info_tmdb(clean_id,ismovie,type)
|
||||||
|
showname = showname.replace("'"," ")
|
||||||
|
if "Guru" in showname:
|
||||||
|
showname = showname.split("-")[0]
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
page_url = await search(showname,date,client)
|
||||||
|
'''
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
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
|
||||||
|
import json
|
||||||
|
import random
|
||||||
|
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)
|
||||||
|
if response.status_code != 200:
|
||||||
|
logger.warning(f"Guardoserie Failed to fetch search results: {response.status_code}")
|
||||||
|
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
|
||||||
|
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': []},"tt9165438:3:1",client,"1",['test','test'])
|
||||||
|
print(results)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_guardoserie())
|
||||||
@@ -3,6 +3,7 @@ from Src.Utilities.info import get_info_tmdb,is_movie
|
|||||||
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.loadenv import load_env
|
from Src.Utilities.loadenv import load_env
|
||||||
env_vars = load_env()
|
env_vars = load_env()
|
||||||
|
ForwardProxy = env_vars.get('ALTERNATIVE_LINK')
|
||||||
MYSTERIUS_KEY = env_vars.get('MYSTERIUS_KEY')
|
MYSTERIUS_KEY = env_vars.get('MYSTERIUS_KEY')
|
||||||
|
|
||||||
async def get_links(slug,season,episode,ismovie,client):
|
async def get_links(slug,season,episode,ismovie,client):
|
||||||
@@ -10,31 +11,28 @@ async def get_links(slug,season,episode,ismovie,client):
|
|||||||
headers = {
|
headers = {
|
||||||
"x-api-key": MYSTERIUS_KEY
|
"x-api-key": MYSTERIUS_KEY
|
||||||
}
|
}
|
||||||
response = await client.get("https://mammamia-urlo-ulala12431.hf.space/api/cookie", headers=headers)
|
response = await client.get("https://aimammam-ulala12431.hf.space/api/cookie", headers=headers)
|
||||||
Auths = response.json()
|
Auths = response.json()
|
||||||
Bearer = Auths.get('cookie')
|
Bearer = Auths.get('cookie')
|
||||||
ap_session = Auths.get('auth')
|
ap_session = Auths.get('auth')
|
||||||
|
|
||||||
cookies = {'ap_session': ap_session}
|
cookies = {'ap_session': ap_session}
|
||||||
|
print(cookies)
|
||||||
headers = {
|
headers = {
|
||||||
'accept': 'application/json, text/plain, */*',
|
'accept': 'application/json, text/plain, */*',
|
||||||
'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7',
|
'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7',
|
||||||
'authorization': f'Bearer {Bearer}',
|
'authorization': f'Bearer {Bearer}',
|
||||||
'referer': f'https://altadefinizione-originale.com/play/{slug}',
|
'referer': f'https://altadefinizioneapp.com/play/{slug}',
|
||||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 OPR/111.0.0.0',
|
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 OPR/111.0.0.0',
|
||||||
'x-requested-with': 'XMLHttpRequest',
|
'x-requested-with': 'XMLHttpRequest',
|
||||||
}
|
}
|
||||||
if ismovie == 1:
|
if ismovie == 1:
|
||||||
|
|
||||||
response = await client.get(f'https://altadefinizione-originale.com/api/post/urls/stream/{slug}',cookies=cookies,headers=headers)
|
response = await client.get(f'https://altadefinizioneapp.com/api/post/urls/stream/{slug}',cookies=cookies,headers=headers)
|
||||||
elif ismovie == 0:
|
elif ismovie == 0:
|
||||||
print("HERE SEASON",season)
|
request_url =f'https://altadefinizioneapp.com/api/post/urls/stream/{slug}/{season}/{episode}'
|
||||||
print("HERE EPISODE",episode)
|
|
||||||
request_url =f'https://altadefinizione-originale.com/api/post/urls/stream/{slug}/{season}/{episode}'
|
|
||||||
print(request_url)
|
print(request_url)
|
||||||
response = await client.get(request_url,cookies=cookies,headers=headers)
|
response = await client.get(request_url,cookies=cookies,headers=headers)
|
||||||
print(response.text)
|
|
||||||
try:
|
try:
|
||||||
video_data = response.json() # Assuming this is the JSON response containing video streams
|
video_data = response.json() # Assuming this is the JSON response containing video streams
|
||||||
if 'streams' not in video_data:
|
if 'streams' not in video_data:
|
||||||
@@ -82,7 +80,7 @@ async def get_links(slug,season,episode,ismovie,client):
|
|||||||
async def search_imdb(showname,tmdba,client):
|
async def search_imdb(showname,tmdba,client):
|
||||||
showname = showname.replace(" ","%20")
|
showname = showname.replace(" ","%20")
|
||||||
tmdba = str(tmdba)
|
tmdba = str(tmdba)
|
||||||
query = f'https://altadefinizione-originale.com/api/search?search={showname}&page=1'
|
query = f'https://altadefinizioneapp.com/api/search?search={showname}&page=1'
|
||||||
response = await client.get(query,allow_redirects=True, impersonate = "chrome120")
|
response = await client.get(query,allow_redirects=True, impersonate = "chrome120")
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
data = response.json()
|
data = response.json()
|
||||||
@@ -92,7 +90,6 @@ async def search_imdb(showname,tmdba,client):
|
|||||||
tmdb_id = ''.join(char for char in tmdb_id if char.isdigit())
|
tmdb_id = ''.join(char for char in tmdb_id if char.isdigit())
|
||||||
if tmdb_id == tmdba:
|
if tmdb_id == tmdba:
|
||||||
slug = item.get('slug')
|
slug = item.get('slug')
|
||||||
print(slug)
|
|
||||||
return slug
|
return slug
|
||||||
|
|
||||||
|
|
||||||
@@ -100,11 +97,9 @@ async def search_imdb(showname,tmdba,client):
|
|||||||
def parse_links(resolution_links):
|
def parse_links(resolution_links):
|
||||||
results = {}
|
results = {}
|
||||||
if resolution_links:
|
if resolution_links:
|
||||||
print("Video links:")
|
|
||||||
for resolution, link in resolution_links.items():
|
for resolution, link in resolution_links.items():
|
||||||
if "cdn.altadefinizione-originale.com" in link:
|
if "cdn.altadefinizione-originale.com" in link or "cdn.altadefinizioneapp.com" in link:
|
||||||
link = link.replace("cdn.altadefinizione-originale.com","protectlinknt.b-cdn.net")
|
link = link.replace("cdn.altadefinizione-originale.com","protectlinknt.b-cdn.net").replace("cdn.altadefinizioneapp.com","protectlinknt.b-cdn.net")
|
||||||
print(f"{resolution}: {link}")
|
|
||||||
results[resolution] = link
|
results[resolution] = link
|
||||||
return results
|
return results
|
||||||
else:
|
else:
|
||||||
@@ -114,7 +109,7 @@ def parse_links(resolution_links):
|
|||||||
async def cool(imdb,client):
|
async def cool(imdb,client):
|
||||||
try:
|
try:
|
||||||
type = "Cool"
|
type = "Cool"
|
||||||
general = is_movie(imdb)
|
general = await is_movie(imdb)
|
||||||
ismovie = general[0]
|
ismovie = general[0]
|
||||||
imdb_id = general[1]
|
imdb_id = general[1]
|
||||||
if ismovie == 0 :
|
if ismovie == 0 :
|
||||||
@@ -146,7 +141,7 @@ async def cool(imdb,client):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Cool Error",e)
|
print("Cool Error",e)
|
||||||
return None
|
return None
|
||||||
'''
|
|
||||||
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:
|
||||||
@@ -157,4 +152,3 @@ async def test_animeworld():
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import asyncio
|
import asyncio
|
||||||
asyncio.run(test_animeworld())
|
asyncio.run(test_animeworld())
|
||||||
'''
|
|
||||||
@@ -3,16 +3,23 @@ import re
|
|||||||
from bs4 import BeautifulSoup, SoupStrainer
|
from bs4 import BeautifulSoup, SoupStrainer
|
||||||
from Src.Utilities.info import get_info_imdb, is_movie, get_info_tmdb
|
from Src.Utilities.info import get_info_imdb, is_movie, get_info_tmdb
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
import Src.Utilities.config as config
|
||||||
|
|
||||||
|
DDL_DOMAIN = config.DDL_DOMAIN
|
||||||
|
ips4_device_key = config.ips4_device_key
|
||||||
|
ips4_login_key = config.ips4_login_key
|
||||||
|
ips4_member_id = config.ips4_member_id
|
||||||
|
ips4_IPSSessionFront = config.ips4_IPSSessionFront
|
||||||
cookies = {
|
cookies = {
|
||||||
'ips4_device_key': 'b6f084be79c28bb53ecfc556fd7a2a70',
|
'ips4_device_key': ips4_device_key,
|
||||||
'ips4_IPSSessionFront': 'f2b9db91793e084cf2003a07c563e6aa',
|
'ips4_IPSSessionFront': ips4_IPSSessionFront,
|
||||||
'ips4_member_id': '4029711',
|
'ips4_member_id': ips4_member_id,
|
||||||
'ips4_login_key': '41b6a70b16cce2fd39482f5b21a9c35f',
|
'ips4_login_key': ips4_login_key
|
||||||
}
|
}
|
||||||
|
|
||||||
async def search_series(client,id,season,episode,showname):
|
async def search_series(client,id,season,episode,showname):
|
||||||
showname = showname.replace(" ", "%20").replace("–", "+").replace("—","+")
|
showname = showname.replace(" ", "%20").replace("–", "+").replace("—","+")
|
||||||
response = await client.get(f"https://ddlstreamitaly.co/search/?&q={showname}%20{season}%20Streaming&type=videobox_video&quick=1&nodes=11&search_and_or=and&search_in=titles&sortby=relevancy")
|
response = await client.get(f"{DDL_DOMAIN}/search/?&q={showname}%20{season}%20Streaming&type=videobox_video&quick=1&nodes=11,36&search_and_or=and&search_in=titles&sortby=relevancy", cookies = cookies)
|
||||||
soup = BeautifulSoup(response.text, 'lxml',parse_only=SoupStrainer('a'))
|
soup = BeautifulSoup(response.text, 'lxml',parse_only=SoupStrainer('a'))
|
||||||
a_tags = soup.find_all('a', {'data-linktype': 'link'})
|
a_tags = soup.find_all('a', {'data-linktype': 'link'})
|
||||||
for a in a_tags:
|
for a in a_tags:
|
||||||
@@ -48,7 +55,6 @@ async def get_episode(client,link,episode):
|
|||||||
'Sec-Fetch-Site': 'same-origin',
|
'Sec-Fetch-Site': 'same-origin',
|
||||||
'Sec-Fetch-User': '?1',
|
'Sec-Fetch-User': '?1',
|
||||||
'Connection': 'keep-alive',
|
'Connection': 'keep-alive',
|
||||||
# 'Cookie': 'ips4_device_key=b6f084be79c28bb53ecfc556fd7a2a70; ips4_IPSSessionFront=f2b9db91793e084cf2003a07c563e6aa; ips4_ipsTimezone=Europe/Rome; ips4_hasJS=true; ips4_noCache=1; ips4_announcement_3=true; ips4_member_id=4029711; ips4_login_key=41b6a70b16cce2fd39482f5b21a9c35f; ips4_loggedIn=1725985598',
|
|
||||||
'Priority': 'u=1',
|
'Priority': 'u=1',
|
||||||
'Pragma': 'no-cache',
|
'Pragma': 'no-cache',
|
||||||
'Cache-Control': 'no-cache',
|
'Cache-Control': 'no-cache',
|
||||||
@@ -58,11 +64,7 @@ async def get_episode(client,link,episode):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
response = await client.get(link, cookies = cookies, headers = headers, params = params, impersonate="chrome124")
|
||||||
episode = "6"
|
|
||||||
response = await client.get(link, cookies = cookies, headers = headers, params = params, impersonate="chrome120")
|
|
||||||
print(link)
|
|
||||||
|
|
||||||
pattern = rf'<a\s+href="([^"]+)"[^>]*>\s*Part {episode}\s*</a>'
|
pattern = rf'<a\s+href="([^"]+)"[^>]*>\s*Part {episode}\s*</a>'
|
||||||
match = re.search(pattern, response.text)
|
match = re.search(pattern, response.text)
|
||||||
mp4_link = match.group(1)
|
mp4_link = match.group(1)
|
||||||
@@ -71,9 +73,9 @@ async def get_episode(client,link,episode):
|
|||||||
return mp4_link
|
return mp4_link
|
||||||
|
|
||||||
async def search_movie(client,showname,id):
|
async def search_movie(client,showname,id):
|
||||||
showname = showname.replace(" ", "%20").replace("–", "+").replace("—","+")
|
showname = showname.replace("–", "+").replace("—","+")
|
||||||
showname = urllib.parse.quote_plus(showname)
|
showname = urllib.parse.quote(showname)
|
||||||
link = f"https://ddlstreamitaly.co/search/?&q={showname}%20Streaming&quick=1&nodes=11&search_and_or=and&search_in=titles&sortby=relevancy"
|
link = f"{DDL_DOMAIN}/search/?&q={showname}%20Streaming&quick=1&nodes=11&search_and_or=and&search_in=titles&sortby=relevancy"
|
||||||
response = await client.get(link,impersonate = "chrome120")
|
response = await client.get(link,impersonate = "chrome120")
|
||||||
soup = BeautifulSoup(response.text, 'lxml',parse_only=SoupStrainer('a'))
|
soup = BeautifulSoup(response.text, 'lxml',parse_only=SoupStrainer('a'))
|
||||||
a_tags = soup.find_all('a', {'data-linktype': 'link'})
|
a_tags = soup.find_all('a', {'data-linktype': 'link'})
|
||||||
@@ -116,13 +118,12 @@ async def get_mp4(client,link):
|
|||||||
|
|
||||||
async def ddlstream(imdb,client):
|
async def ddlstream(imdb,client):
|
||||||
try:
|
try:
|
||||||
general = is_movie(imdb)
|
general = await is_movie(imdb)
|
||||||
ismovie = general[0]
|
ismovie = general[0]
|
||||||
id = general[1]
|
id = general[1]
|
||||||
type = "DDLStream"
|
type = "DDLStream"
|
||||||
if "tt" in imdb:
|
if "tt" in imdb:
|
||||||
showname = await get_info_imdb(id,ismovie,type,client)
|
showname = await get_info_imdb(id,ismovie,type,client)
|
||||||
print(showname)
|
|
||||||
else:
|
else:
|
||||||
showname = get_info_tmdb(id,ismovie,type)
|
showname = get_info_tmdb(id,ismovie,type)
|
||||||
if ismovie == 0:
|
if ismovie == 0:
|
||||||
@@ -131,24 +132,22 @@ async def ddlstream(imdb,client):
|
|||||||
page_link = await search_series(client,id,season,episode,showname)
|
page_link = await search_series(client,id,season,episode,showname)
|
||||||
mp4_link = await get_episode(client,page_link,episode)
|
mp4_link = await get_episode(client,page_link,episode)
|
||||||
final_url = await get_mp4(client,mp4_link)
|
final_url = await get_mp4(client,mp4_link)
|
||||||
print(final_url)
|
|
||||||
return final_url
|
return final_url
|
||||||
else:
|
else:
|
||||||
page_link = await search_movie(client,showname,id)
|
page_link = await search_movie(client,showname,id)
|
||||||
mp4_link = page_link + "?area=online"
|
mp4_link = page_link + "?area=online"
|
||||||
final_url = await get_mp4(client,mp4_link)
|
final_url = await get_mp4(client,mp4_link)
|
||||||
print(final_url)
|
|
||||||
return final_url
|
return final_url
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"MammaMia: DDLStream Failed {e}")
|
print(f"MammaMia: DDLStream Failed {e}")
|
||||||
return None,None
|
return None
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
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:
|
||||||
test_id = "tt6263850" # This is an example ID format
|
test_id = "tt3148266:3:4" # This is an example ID format
|
||||||
results = await ddlstream(test_id, client)
|
results = await ddlstream(test_id, client)
|
||||||
print(results)
|
print(results)
|
||||||
|
|
||||||
@@ -158,4 +157,3 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
|
|
||||||
#python3 -m Src.API.ddlstream
|
#python3 -m Src.API.ddlstream
|
||||||
'''
|
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
|
||||||
|
from tmdbv3api import TMDb, Movie, TV
|
||||||
|
from bs4 import BeautifulSoup,SoupStrainer
|
||||||
|
import string
|
||||||
|
import re
|
||||||
|
import dateparser
|
||||||
|
from Src.Utilities.convert import get_TMDb_id_from_IMDb_id, get_IMDB_id_from_TMDb_id
|
||||||
|
from Src.Utilities.info import get_info_tmdb, is_movie, get_info_imdb
|
||||||
|
from Src.Utilities.convert_date import convert_US_date
|
||||||
|
import Src.Utilities.config as config
|
||||||
|
FT_DOMAIN = config.FT_DOMAIN
|
||||||
|
import urllib.parse
|
||||||
|
#Some basic headers
|
||||||
|
headers = {
|
||||||
|
'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',
|
||||||
|
'Accept-Language': 'en-US,en;q=0.5'
|
||||||
|
}
|
||||||
|
#Map months to check if date = date
|
||||||
|
month_mapping = {
|
||||||
|
'Jan': 'Gennaio', 'Feb': 'Febbraio', 'Mar': 'Marzo', 'Apr': 'Aprile',
|
||||||
|
'May': 'Maggio', 'Jun': 'Giugno', 'Jul': 'Luglio', 'Aug': 'Agosto',
|
||||||
|
'Sep': 'Settembre', 'Oct': 'Ottobre', 'Nov': 'Novembre', 'Dec': 'Dicembre'
|
||||||
|
}
|
||||||
|
async def get_streamtape(link,client):
|
||||||
|
headers = {
|
||||||
|
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
|
||||||
|
}
|
||||||
|
response = await client.get(link, headers=headers, impersonate = "chrome124")
|
||||||
|
regex = r"id=.*?(?=')"
|
||||||
|
matches = re.findall(regex, response.text)
|
||||||
|
i = 0
|
||||||
|
final_url = next((f"https://streamtape.com/get_video?{matches[i + 1]}" for i in range(len(matches) - 1) if matches[i] == matches[i + 1]), None)
|
||||||
|
return final_url
|
||||||
|
|
||||||
|
|
||||||
|
async def search(query,imdb_id,client,season,ismovie):
|
||||||
|
response = await client.get(query)
|
||||||
|
response = response.json()
|
||||||
|
#Get link tid of every item and then open the link to see if the date = date
|
||||||
|
for json in response:
|
||||||
|
link = json['link']
|
||||||
|
tid = json['id']
|
||||||
|
series_response = await client.get(link, headers=headers, allow_redirects=True, timeout = 30)
|
||||||
|
series_soup = BeautifulSoup(series_response.text, 'lxml')
|
||||||
|
imdb_pattern = r"'imdb_id':\s*'([^']+)'"
|
||||||
|
imdb_match = re.search(imdb_pattern, series_response.text)
|
||||||
|
if imdb_match:
|
||||||
|
id = imdb_match.group(1)
|
||||||
|
print(id)
|
||||||
|
if id == imdb_id:
|
||||||
|
url = link
|
||||||
|
tid = tid
|
||||||
|
if ismovie == 0:
|
||||||
|
Seasons = series_soup.find_all('span', class_="season-name")
|
||||||
|
i = 0
|
||||||
|
for item in Seasons:
|
||||||
|
season_text = item.text.strip()
|
||||||
|
if season in season_text and "SUB" not in season_text:
|
||||||
|
actual_season = i
|
||||||
|
return url, tid, actual_season
|
||||||
|
else:
|
||||||
|
i = i + 1
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
actual_season = None
|
||||||
|
return url, tid, actual_season
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("There's no IMDB_ID")
|
||||||
|
|
||||||
|
def get_episode_link(actual_season,episode,tid,url):
|
||||||
|
#Get the link from where we have to obtain mixdrop link
|
||||||
|
tlink = f'{url}?show_video=true&post_id={tid}&season_id={actual_season}&episode_id={episode-1}'
|
||||||
|
return tlink
|
||||||
|
|
||||||
|
|
||||||
|
def get_film(url):
|
||||||
|
#Get the link from where we have to obtain mixdrop link
|
||||||
|
tlink = url + "?show_video=true"
|
||||||
|
return tlink
|
||||||
|
|
||||||
|
async def get_real_link(tlink,client):
|
||||||
|
try:
|
||||||
|
print(tlink)
|
||||||
|
#Some basic code to get the mixdrop link
|
||||||
|
page = await client.get(tlink, headers=headers, allow_redirects=True)
|
||||||
|
soup = BeautifulSoup(page.content, features="lxml",parse_only=SoupStrainer('iframe'))
|
||||||
|
iframe_src = soup.find('iframe')['src']
|
||||||
|
iframe_page = await client.get(iframe_src, headers=headers, allow_redirects=True, timeout = 30)
|
||||||
|
iframe_soup = BeautifulSoup(iframe_page.content, features="lxml", parse_only=SoupStrainer('div',class_="megaButton"))
|
||||||
|
|
||||||
|
mega_button = iframe_soup.find('div', attrs={'class': 'megaButton', 'rel': 'nofollow'}, string='MIXDROP')
|
||||||
|
if mega_button:
|
||||||
|
real_link = mega_button.get('meta-link')
|
||||||
|
return real_link
|
||||||
|
else:
|
||||||
|
mega_button = iframe_soup.find('div', attrs={'class': 'megaButton', 'rel': 'nofollow'}, string='STREAMTAPE')
|
||||||
|
real_link = mega_button.get('meta-link')
|
||||||
|
return real_link
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
return None
|
||||||
|
async def get_true_link(real_link,client):
|
||||||
|
response = await client.get(real_link, headers=headers, allow_redirects=True,timeout = 30)
|
||||||
|
[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
|
||||||
|
return s
|
||||||
|
|
||||||
|
async def filmpertutti(imdb,client,MFP):
|
||||||
|
try:
|
||||||
|
general = await is_movie(imdb)
|
||||||
|
ismovie = general[0]
|
||||||
|
imdb_id = general[1]
|
||||||
|
type = "Filmpertutti"
|
||||||
|
if ismovie == 0 :
|
||||||
|
season = general[2]
|
||||||
|
episode = int(general[3])
|
||||||
|
else:
|
||||||
|
season = None
|
||||||
|
episode = None
|
||||||
|
if "tt" in imdb:
|
||||||
|
showname = await get_info_imdb(imdb_id,ismovie,type,client)
|
||||||
|
elif "tmdb" in imdb:
|
||||||
|
#Get showname and date
|
||||||
|
tmdba = imdb_id.replace("tmdb:","")
|
||||||
|
imdb_id = await get_IMDB_id_from_TMDb_id(tmdba,client)
|
||||||
|
showname = get_info_tmdb(tmdba,ismovie,type)
|
||||||
|
showname = showname.replace(" ", "+").replace("–", "+").replace("—","+")
|
||||||
|
showname = urllib.parse.quote_plus(showname)
|
||||||
|
# Build the query
|
||||||
|
query = f'{FT_DOMAIN}/wp-json/wp/v2/posts?search={showname}&page=1&_fields=link,id'
|
||||||
|
try:
|
||||||
|
url,tid,actual_season = await search(query,imdb_id,client,season,ismovie)
|
||||||
|
except:
|
||||||
|
print("MammaMia: No results found for Filmpertutti")
|
||||||
|
return None,None
|
||||||
|
if ismovie == 0:
|
||||||
|
episode_link = get_episode_link(actual_season,episode,tid,url)
|
||||||
|
#Let's get mixdrop link
|
||||||
|
real_link = await get_real_link(episode_link,client)
|
||||||
|
if MFP == "1":
|
||||||
|
if "mixdrop" in real_link:
|
||||||
|
Host = "Mixdrop"
|
||||||
|
elif "streamtape" in real_link:
|
||||||
|
Host = "Streamtape"
|
||||||
|
return real_link, Host
|
||||||
|
#let's get delivery link, streaming link
|
||||||
|
if "mixdrop" in real_link:
|
||||||
|
streaming_link = await get_true_link(real_link,client)
|
||||||
|
elif "streamtape" in real_link:
|
||||||
|
streaming_link = await get_streamtape(real_link,client)
|
||||||
|
Host = None
|
||||||
|
return streaming_link, Host
|
||||||
|
elif ismovie == 1:
|
||||||
|
film_link = get_film(url)
|
||||||
|
#Let's get mixdrop link
|
||||||
|
real_link = await get_real_link(film_link,client)
|
||||||
|
if MFP == "1":
|
||||||
|
if "mixdrop" in real_link:
|
||||||
|
Host = "Mixdrop"
|
||||||
|
elif "streamtape" in real_link:
|
||||||
|
Host = "Streamtape"
|
||||||
|
return real_link, Host
|
||||||
|
if "mixdrop" in real_link:
|
||||||
|
streaming_link = await get_true_link(real_link,client)
|
||||||
|
elif "streamtape" in real_link:
|
||||||
|
streaming_link = await get_streamtape(real_link,client)
|
||||||
|
#let's get delivery link, streaming link
|
||||||
|
Host = None
|
||||||
|
return streaming_link, Host
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Filmpertutti failed: {e}")
|
||||||
|
return None,None
|
||||||
|
|
||||||
|
async def test_animeworld():
|
||||||
|
from curl_cffi.requests import AsyncSession
|
||||||
|
async with AsyncSession() as client:
|
||||||
|
MFP = "1"
|
||||||
|
# Replace with actual id, for example 'anime_id:episode' format
|
||||||
|
test_id = "tt1190634:1:1" # This is an example ID format
|
||||||
|
results = await filmpertutti(test_id, client,MFP)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_animeworld())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
series_response = await client.get(link, headers=headers, follow_redirects=True)
|
||||||
|
series_soup = BeautifulSoup(series_response.text, 'lxml')
|
||||||
|
release_span = series_soup.find('span', class_='released')
|
||||||
|
if release_span:
|
||||||
|
if release_span.text != "Data di uscita: N/A":
|
||||||
|
date_string = release_span.text.split(': ')[-1] # Get the date part
|
||||||
|
for eng, ita in month_mapping.items():
|
||||||
|
date_string = re.sub(rf'\b{eng}\b', ita, date_string)
|
||||||
|
|
||||||
|
# Swap to YY-MM-DD formatting using dateparser
|
||||||
|
release_date = dateparser.parse(date_string, languages=['it']).strftime("%Y-%m-%d")
|
||||||
|
'''
|
||||||
@@ -12,11 +12,11 @@ async def search(showname,date,season,episode,ismovie,client):
|
|||||||
}
|
}
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
'authority': f'lordchannel.{LC_DOMAIN}',
|
'authority': f'{LC_DOMAIN}',
|
||||||
'accept': '*/*',
|
'accept': '*/*',
|
||||||
'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7',
|
'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7',
|
||||||
# 'cookie': 'csrftoken=7lvc502CZe8Zbx7iSX1xkZOBA1NbDxJZ',
|
# 'cookie': 'csrftoken=7lvc502CZe8Zbx7iSX1xkZOBA1NbDxJZ',
|
||||||
'referer': f'https://lordchannel.{LC_DOMAIN}/anime/anime-ita/',
|
'referer': f'{LC_DOMAIN}/anime/anime-ita/',
|
||||||
'sec-ch-ua': '"Not-A.Brand";v="99", "Chromium";v="124"',
|
'sec-ch-ua': '"Not-A.Brand";v="99", "Chromium";v="124"',
|
||||||
'sec-ch-ua-mobile': '?0',
|
'sec-ch-ua-mobile': '?0',
|
||||||
'sec-ch-ua-platform': '"Android"',
|
'sec-ch-ua-platform': '"Android"',
|
||||||
@@ -31,13 +31,13 @@ async def search(showname,date,season,episode,ismovie,client):
|
|||||||
'media': showname,
|
'media': showname,
|
||||||
'_': '1724421723999',
|
'_': '1724421723999',
|
||||||
}
|
}
|
||||||
response = await client.get(f'https://lordchannel.{LC_DOMAIN}/live_search/', params=params, cookies=cookies, headers=headers, allow_redirects=True, impersonate = "chrome120")
|
response = await client.get(f'{LC_DOMAIN}/live_search/', params=params, cookies=cookies, headers=headers, allow_redirects=True, impersonate = "chrome124")
|
||||||
data = json.loads(response.text)
|
data = json.loads(response.text)
|
||||||
for entry in data['data']:
|
for entry in data['data']:
|
||||||
if entry is not None: # check if the a_tag exists
|
if entry is not None: # check if the a_tag exists
|
||||||
href = entry['url']
|
href = entry['url']
|
||||||
quality = entry['qualit\u00e0_video']
|
quality = entry['qualit\u00e0_video']
|
||||||
link = f'https://lordchannel.{LC_DOMAIN}{href}'
|
link = f'{LC_DOMAIN}{href}'
|
||||||
response = await client.get(link, allow_redirects=True, impersonate = "chrome120")
|
response = await client.get(link, allow_redirects=True, impersonate = "chrome120")
|
||||||
soup2 = BeautifulSoup(response.text,'lxml')
|
soup2 = BeautifulSoup(response.text,'lxml')
|
||||||
li_tag = soup2.select_one("ul.card__meta li:nth-of-type(2)")
|
li_tag = soup2.select_one("ul.card__meta li:nth-of-type(2)")
|
||||||
@@ -62,16 +62,15 @@ async def search(showname,date,season,episode,ismovie,client):
|
|||||||
|
|
||||||
async def get_m3u8(video_url,client):
|
async def get_m3u8(video_url,client):
|
||||||
response = await client.get(video_url, allow_redirects=True, impersonate = "chrome120")
|
response = await client.get(video_url, allow_redirects=True, impersonate = "chrome120")
|
||||||
pattern = r'const\s+videoData\s*=\s*\[(.*?)\];'
|
pattern = r'https?://[^\s]+\.m3u8'
|
||||||
match = re.search(pattern, response.text)
|
match = re.search(pattern, response.text)
|
||||||
if match:
|
if match:
|
||||||
video_data = match.group(1).strip().split(', ')
|
url = match.group(0)
|
||||||
url = video_data[0]
|
|
||||||
return url
|
return url
|
||||||
|
|
||||||
async def lordchannel(imdb,client):
|
async def lordchannel(imdb,client):
|
||||||
try:
|
try:
|
||||||
general = is_movie(imdb)
|
general = await is_movie(imdb)
|
||||||
ismovie = general[0]
|
ismovie = general[0]
|
||||||
imdb_id = general[1]
|
imdb_id = general[1]
|
||||||
type = "LordChannel"
|
type = "LordChannel"
|
||||||
@@ -99,8 +98,6 @@ async def lordchannel(imdb,client):
|
|||||||
print("MammaMia: Lordchannel Failed",e)
|
print("MammaMia: Lordchannel Failed",e)
|
||||||
return None,None
|
return None,None
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
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:
|
||||||
@@ -110,4 +107,4 @@ async def test_animeworld():
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import asyncio
|
import asyncio
|
||||||
asyncio.run(test_animeworld())
|
asyncio.run(test_animeworld())
|
||||||
'''
|
#python3 -m Src.API.lordchannel
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
from urllib.parse import urlparse, parse_qs,unquote,quote
|
||||||
|
from fastapi import APIRouter, HTTPException, Response, Request
|
||||||
|
from curl_cffi.requests import AsyncSession
|
||||||
|
import Src.Utilities.config as config
|
||||||
|
from Src.Utilities.loadenv import load_env
|
||||||
|
env_vars = load_env()
|
||||||
|
SC_PROXY = config.SC_PROXY
|
||||||
|
VX_PROXY = config.VX_PROXY
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
|
||||||
|
import random
|
||||||
|
proxies = {}
|
||||||
|
proxies2 = {}
|
||||||
|
if VX_PROXY == "1":
|
||||||
|
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
|
||||||
|
proxy_list = json.loads(PROXY_CREDENTIALS)
|
||||||
|
proxy = random.choice(proxy_list)
|
||||||
|
if proxy == "":
|
||||||
|
proxies2 = {}
|
||||||
|
else:
|
||||||
|
proxies2 = {
|
||||||
|
"http": proxy,
|
||||||
|
"https": proxy
|
||||||
|
}
|
||||||
|
if SC_PROXY == "1":
|
||||||
|
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
|
||||||
|
proxy_list = json.loads(PROXY_CREDENTIALS)
|
||||||
|
proxy = random.choice(proxy_list)
|
||||||
|
if proxy == "":
|
||||||
|
proxies = {}
|
||||||
|
else:
|
||||||
|
proxies = {
|
||||||
|
"http": proxy,
|
||||||
|
"https": proxy
|
||||||
|
}
|
||||||
|
if VX_PROXY == "1":
|
||||||
|
proxies2 = proxies
|
||||||
|
SC_ForwardProxy = config.SC_ForwardProxy
|
||||||
|
VX_ForwardProxy = config.VX_ForwardProxy
|
||||||
|
if SC_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy = ""
|
||||||
|
|
||||||
|
if VX_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy = ""
|
||||||
|
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
User_Agent= "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0"
|
||||||
|
async def fetch_m3u8(url):
|
||||||
|
"""Fetch the M3U8 file from the URL and store it in memory."""
|
||||||
|
async with AsyncSession() as client:
|
||||||
|
response = await client.get(ForwardProxy + url,headers = {"User-Agent": User_Agent, "user-agent": User_Agent}, proxies = proxies2)
|
||||||
|
response.raise_for_status() # Raise an error for bad responses
|
||||||
|
return response.text
|
||||||
|
|
||||||
|
@router.get("/clone/manifest.m3u8")
|
||||||
|
async def clone_m3u8(d: str = None):
|
||||||
|
if d:
|
||||||
|
try:
|
||||||
|
d = unquote(d)
|
||||||
|
m3u8_content = await fetch_m3u8(d)
|
||||||
|
return Response(content=m3u8_content, media_type='application/vnd.apple.mpegurl')
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to fetch M3U8 file: {e}")
|
||||||
|
raise HTTPException(status_code=404, detail="M3U8 content not found")
|
||||||
|
#This is just for testing, ignore that endpoint and the func
|
||||||
|
|
||||||
|
|
||||||
|
@router.api_route("/vixcloud/manifest.m3u8", methods=["GET", "HEAD"])
|
||||||
|
async def clone2_m3u8(d:str,token:str,expires:str,h:str = None, b:str = None, request: Request = None):
|
||||||
|
try:
|
||||||
|
m3u8 = f'{d}?token={token}&expires={expires}'
|
||||||
|
if h:
|
||||||
|
m3u8 = m3u8 + f'&h={h}'
|
||||||
|
if b:
|
||||||
|
m3u8 = m3u8 + f'&b={b}'
|
||||||
|
forwarded_proto = request.headers.get("x-forwarded-proto")
|
||||||
|
scheme = forwarded_proto if forwarded_proto else request.url.scheme
|
||||||
|
instance_url = f"{scheme}://{request.url.netloc}"
|
||||||
|
m3u8_content = await fetch_m3u8(m3u8)
|
||||||
|
modified_playlist = m3u8_content.replace("https://vixcloud.co/playlist/", f"{instance_url}/clony/")
|
||||||
|
|
||||||
|
return Response(content=modified_playlist, media_type='application/vnd.apple.mpegurl')
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to fetch M3U8 file: {e}")
|
||||||
|
raise HTTPException(status_code=404, detail="M3U8 content not found")
|
||||||
|
|
||||||
|
@router.api_route("/clony/{segment:path}", methods=["GET", "HEAD"])
|
||||||
|
async def clony_m3u8(segment: str, request: Request):
|
||||||
|
base_url = "https://vixcloud.co/playlist/"
|
||||||
|
full_url = f"{base_url}{segment}?{request.query_params}"
|
||||||
|
print(full_url, "A",request.query_params)
|
||||||
|
if "rendition=1080p" in full_url or "type=subtitle" in full_url:
|
||||||
|
print(full_url)
|
||||||
|
raise HTTPException(status_code=404, detail="Requested variant not available.")
|
||||||
|
m3u8_content = await fetch_m3u8(full_url)
|
||||||
|
if "sc-u12" not in m3u8_content:
|
||||||
|
m3u8_content = re.sub(r"https://sc-[a-zA-Z0-9]+-\d+.scws-content.net", "https://sc-u12-01.scws-content.net", m3u8_content)
|
||||||
|
return Response(content=m3u8_content, media_type='application/vnd.apple.mpegurl')
|
||||||
|
|
||||||
|
@router.api_route('/storage/enc.key')
|
||||||
|
async def get_key():
|
||||||
|
async with AsyncSession(timeout = 20) as client:
|
||||||
|
response = await client.get(ForwardProxy + 'https://vixcloud.co/storage/enc.key', headers = {"User-Agent": User_Agent, "user-agent": User_Agent}, proxies = proxies2)
|
||||||
|
|
||||||
|
response_headers = {
|
||||||
|
'date': response.headers['date'],
|
||||||
|
'content-length': response.headers['content-length'],
|
||||||
|
'content-type': 'application/octet-stream',
|
||||||
|
'access-control-allow-origin': '*'
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response(
|
||||||
|
response.content,
|
||||||
|
response.status_code,
|
||||||
|
response_headers
|
||||||
|
)
|
||||||
|
#r"https://sc-b1-([0-2][0-9]|30).scws-content.net", "https://sc-u9-01.scws-content.net", m3u8_content)
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
forwarded_proto = request.headers.get("x-forwarded-proto")
|
||||||
|
scheme = forwarded_proto if forwarded_proto else request.url.scheme
|
||||||
|
instance_url = f"{scheme}://{request.url.netloc}"
|
||||||
|
url_streaming_community = url_streaming_community.replace("?","&")
|
||||||
|
url_streaming_community = instance_url + "/vixcloud/manifest.m3u8?d=" + url_streaming_community
|
||||||
|
'''
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
from bs4 import BeautifulSoup
|
||||||
|
import json
|
||||||
|
from Src.Utilities.dictionaries import okru
|
||||||
|
User_Agent= "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0"
|
||||||
|
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0',
|
||||||
|
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
|
||||||
|
'Accept-Language': 'en-US,en;q=0.5',
|
||||||
|
'DNT': '1',
|
||||||
|
'Sec-GPC': '1',
|
||||||
|
'Connection': 'keep-alive',
|
||||||
|
'Upgrade-Insecure-Requests': '1',
|
||||||
|
'Sec-Fetch-Dest': 'document',
|
||||||
|
'Sec-Fetch-Mode': 'navigate',
|
||||||
|
'Sec-Fetch-Site': 'none',
|
||||||
|
'Sec-Fetch-User': '?1',
|
||||||
|
'Priority': 'u=1',
|
||||||
|
'Pragma': 'no-cache',
|
||||||
|
'Cache-Control': 'no-cache',
|
||||||
|
}
|
||||||
|
|
||||||
|
async def okru_get_url(id,client):
|
||||||
|
try:
|
||||||
|
embed_link = okru[id]
|
||||||
|
response = await client.get(embed_link, allow_redirects=True, headers = headers, impersonate = "chrome124")
|
||||||
|
soup = BeautifulSoup(response.text, 'lxml')
|
||||||
|
div = soup.find('div', {'data-module': 'OKVideo'})
|
||||||
|
data_options = div.get('data-options')
|
||||||
|
data = json.loads(data_options)
|
||||||
|
metadata = json.loads(data['flashvars']['metadata'])
|
||||||
|
m3u8_link = metadata['hlsMasterPlaylistUrl']
|
||||||
|
print("MammaMia: Found results for Okru")
|
||||||
|
return m3u8_link
|
||||||
|
except Exception as e:
|
||||||
|
print("MammaMia: No results found for Okru")
|
||||||
|
return None
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
from Src.Utilities.info import get_info_imdb, is_movie, get_info_tmdb
|
||||||
|
from bs4 import BeautifulSoup,SoupStrainer
|
||||||
|
import Src.Utilities.config as config
|
||||||
|
from fake_headers import Headers
|
||||||
|
from Src.Utilities.loadenv import load_env
|
||||||
|
import json, random
|
||||||
|
import re
|
||||||
|
from Src.Utilities.eval import eval_solver
|
||||||
|
import urllib.parse
|
||||||
|
OST_DOMAIN = config.OST_DOMAIN
|
||||||
|
OST_PROXY = config.OST_PROXY
|
||||||
|
env_vars = load_env()
|
||||||
|
proxies = {}
|
||||||
|
if OST_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
|
||||||
|
}
|
||||||
|
OST_ForwardProxy = config.OST_ForwardProxy
|
||||||
|
if OST_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy = ""
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (Linux; Android 12) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.71 Mobile Safari/537.36',
|
||||||
|
'Accept': '*/*',
|
||||||
|
'Accept-Language': 'en-US,en;q=0.5',
|
||||||
|
# 'Accept-Encoding': 'gzip, deflate, br, zstd',
|
||||||
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
|
'DNT': '1',
|
||||||
|
'Sec-GPC': '1',
|
||||||
|
'Connection': 'keep-alive',
|
||||||
|
'Referer': f'https://onlineserietv.{OST_DOMAIN}/',
|
||||||
|
# 'Cookie': 'player_opt=fx',
|
||||||
|
'Sec-Fetch-Dest': 'empty',
|
||||||
|
'Sec-Fetch-Mode': 'cors',
|
||||||
|
'Sec-Fetch-Site': 'same-origin',
|
||||||
|
'Pragma': 'no-cache',
|
||||||
|
'Cache-Control': 'no-cache',
|
||||||
|
}
|
||||||
|
|
||||||
|
async def search(showname,date,client,ismovie,episode,season):
|
||||||
|
cookies = {
|
||||||
|
'player_opt': 'fx',
|
||||||
|
}
|
||||||
|
params = {
|
||||||
|
's': showname,
|
||||||
|
'action': 'searchwp_live_search',
|
||||||
|
'swpengine': 'default',
|
||||||
|
'swpquery': showname,
|
||||||
|
'origin_id': '50141',
|
||||||
|
'searchwp_live_search_client_nonce': 'undefined',
|
||||||
|
}
|
||||||
|
response = await client.get(ForwardProxy + f"https://onlineserietv.{OST_DOMAIN}/wp-admin/admin-ajax.php?s={urllib.parse.quote(showname)}&action=searchwp_live_search&swpengine=default&swpquery={urllib.parse.quote(showname)}&origin_id=50141&searchwp_live_search_client_nonce=undefined", headers=headers, cookies=cookies, impersonate = "chrome124", proxies = proxies)
|
||||||
|
if response.status_code != 200:
|
||||||
|
print("IP Blocked by OnlineserieTV",response)
|
||||||
|
soup = BeautifulSoup(response.text, 'lxml', parse_only=SoupStrainer('a'))
|
||||||
|
a_tags_with_href = soup.find_all("a", href=True)
|
||||||
|
for a_tag in a_tags_with_href:
|
||||||
|
href = a_tag.get("href")
|
||||||
|
if ismovie == 1:
|
||||||
|
if "film" in href:
|
||||||
|
response = await client.get(ForwardProxy + href, headers=headers, impersonate = "chrome124", proxies = proxies)
|
||||||
|
if response.status_code != 200:
|
||||||
|
print("IP Blocked by OnlineserieTV",response)
|
||||||
|
year_match = re.search(r'Anno: <i>(\d{4})</i>', response.text)
|
||||||
|
year = year_match.group(1) if year_match else None
|
||||||
|
if year == date:
|
||||||
|
pattern = r'https://uprot\.net/fxf/[^\s"<>]+'
|
||||||
|
match = re.search(pattern, response.text)
|
||||||
|
if match:
|
||||||
|
name = a_tag.text.replace("\t","").replace("\n","")
|
||||||
|
flexy_link = match.group()
|
||||||
|
return flexy_link,name
|
||||||
|
else:
|
||||||
|
print("No flexy link found.")
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
elif ismovie == 0:
|
||||||
|
if "serietv" in href:
|
||||||
|
response = await client.get(ForwardProxy + href, headers=headers, impersonate = "chrome124", proxies = proxies)
|
||||||
|
if response.status_code != 200:
|
||||||
|
print("IP Blocked by OnlineserieTV",response)
|
||||||
|
year_match = re.search(r'Anno: <i>(\d{4})</i>', response.text)
|
||||||
|
year = year_match.group(1) if year_match else None
|
||||||
|
if year == date:
|
||||||
|
season = season.zfill(2)
|
||||||
|
episode = episode.zfill(2)
|
||||||
|
if season == "0000000000000":
|
||||||
|
print(True,season,episode)
|
||||||
|
#pattern = rf'{season}x{episode}.*?<a href=[\'"](https://uprot\.net/fxf/[^\'"]+)|0{episode}.*?<a href=[\'"](https://uprot\.net/fxf/[^\'"]+)'
|
||||||
|
pattern = rf'0{episode}.*?<a href=[\'"](https://uprot\.net/fxf/[^\'"]+)'
|
||||||
|
match1 = re.findall(pattern, response.text)
|
||||||
|
match = re.search(pattern, response.text)
|
||||||
|
print(match)
|
||||||
|
else:
|
||||||
|
pattern = rf'{season}x{episode}.*?<a href=[\'"](https://uprot\.net/fxf/[^\'"]+)'
|
||||||
|
match = re.search(pattern, response.text, re.DOTALL)
|
||||||
|
if match:
|
||||||
|
name = a_tag.text.replace("\t","").replace("\n","")
|
||||||
|
flexy_link = match.group(1)
|
||||||
|
print(match,flexy_link)
|
||||||
|
return flexy_link,name
|
||||||
|
else:
|
||||||
|
print("No flexy link found.")
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def onlineserietv(id,client):
|
||||||
|
try:
|
||||||
|
general = await is_movie(id)
|
||||||
|
ismovie = general[0]
|
||||||
|
clean_id = general[1]
|
||||||
|
if ismovie == 0:
|
||||||
|
season = general[2]
|
||||||
|
episode = general[3]
|
||||||
|
elif ismovie == 1:
|
||||||
|
season = None
|
||||||
|
episode = None
|
||||||
|
type = "Onlineserietv"
|
||||||
|
if "tt" in id:
|
||||||
|
showname,date = await get_info_imdb(clean_id,ismovie,type,client)
|
||||||
|
else:
|
||||||
|
showname,date = get_info_tmdb(clean_id,ismovie,type)
|
||||||
|
showname = showname.replace("'"," ")
|
||||||
|
flexy_link,name = await search(showname,date,client,ismovie,episode,season)
|
||||||
|
flexy_link = flexy_link.replace("fxf","fxe")
|
||||||
|
real_url = await client.head(ForwardProxy + flexy_link, headers=headers, impersonate = "chrome124", proxies = proxies)
|
||||||
|
real_url = real_url.url
|
||||||
|
final_url = await eval_solver(real_url,proxies, ForwardProxy, client)
|
||||||
|
return final_url,name
|
||||||
|
except Exception as e:
|
||||||
|
print("MammaMia: Onlineserietv Failed",e)
|
||||||
|
return None,None
|
||||||
|
|
||||||
|
|
||||||
|
async def test_animeworld():
|
||||||
|
from curl_cffi.requests import AsyncSession
|
||||||
|
async with AsyncSession() as client:
|
||||||
|
test_id = "tt0206516:2:1" # This is an example ID format
|
||||||
|
results = await onlineserietv(test_id, client)
|
||||||
|
print(results)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_animeworld())
|
||||||
|
|
||||||
|
# Guru Guru tt0330592 Uomo tigre tt0206516
|
||||||
|
#python3 -m Src.API.onlineserietv
|
||||||
@@ -0,0 +1,341 @@
|
|||||||
|
from bs4 import BeautifulSoup,SoupStrainer
|
||||||
|
from Src.Utilities.convert import get_TMDb_id_from_IMDb_id
|
||||||
|
from Src.Utilities.info import get_info_tmdb, is_movie, get_info_imdb
|
||||||
|
import Src.Utilities.config as config
|
||||||
|
import json
|
||||||
|
import random
|
||||||
|
import re
|
||||||
|
from urllib.parse import urlparse, parse_qs
|
||||||
|
from fake_headers import Headers
|
||||||
|
from Src.Utilities.loadenv import load_env
|
||||||
|
from Src.API.extractors.vixcloud import vixcloud
|
||||||
|
import urllib.parse
|
||||||
|
User_Agent= "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0"
|
||||||
|
|
||||||
|
env_vars = load_env()
|
||||||
|
SC_PROXY = config.SC_PROXY
|
||||||
|
VX_PROXY = config.VX_PROXY
|
||||||
|
proxies = {}
|
||||||
|
proxies2 = {}
|
||||||
|
if VX_PROXY == "1":
|
||||||
|
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
|
||||||
|
proxy_list = json.loads(PROXY_CREDENTIALS)
|
||||||
|
proxy = random.choice(proxy_list)
|
||||||
|
if proxy == "":
|
||||||
|
proxies2 = {}
|
||||||
|
else:
|
||||||
|
proxies2 = {
|
||||||
|
"http": proxy,
|
||||||
|
"https": proxy
|
||||||
|
}
|
||||||
|
if SC_PROXY == "1":
|
||||||
|
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
|
||||||
|
proxy_list = json.loads(PROXY_CREDENTIALS)
|
||||||
|
proxy = random.choice(proxy_list)
|
||||||
|
if proxy == "":
|
||||||
|
proxies = {}
|
||||||
|
else:
|
||||||
|
proxies = {
|
||||||
|
"http": proxy,
|
||||||
|
"https": proxy
|
||||||
|
}
|
||||||
|
if VX_PROXY == "1":
|
||||||
|
proxies2 = proxies
|
||||||
|
|
||||||
|
SC_ForwardProxy = config.SC_ForwardProxy
|
||||||
|
VX_ForwardProxy = config.VX_ForwardProxy
|
||||||
|
if SC_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
elif VX_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy = ""
|
||||||
|
#Get domain
|
||||||
|
SC_DOMAIN = config.SC_DOMAIN
|
||||||
|
Public_Instance = config.Public_Instance
|
||||||
|
Alternative_Link = env_vars.get('ALTERNATIVE_LINK')
|
||||||
|
headers = Headers()
|
||||||
|
#GET VERSION OF STREAMING COMMUNITY:
|
||||||
|
async def get_version(client):
|
||||||
|
#Extract the version from the main page of the site
|
||||||
|
#You can extract it from any page of the site but I chose one of the lightiest
|
||||||
|
|
||||||
|
try:
|
||||||
|
random_headers = headers.generate()
|
||||||
|
random_headers['Referer'] = f"{SC_DOMAIN}/"
|
||||||
|
random_headers['Origin'] = f"{SC_DOMAIN}"
|
||||||
|
base_url = f'{SC_DOMAIN}/richiedi-un-titolo'
|
||||||
|
response = await client.get(ForwardProxy + base_url, headers=random_headers, allow_redirects = True, impersonate="chrome124", proxies = proxies)
|
||||||
|
#Soup the response
|
||||||
|
soup = BeautifulSoup(response.text, "lxml")
|
||||||
|
|
||||||
|
# Extract version
|
||||||
|
version = json.loads(soup.find("div", {"id": "app"}).get("data-page"))['version']
|
||||||
|
return version
|
||||||
|
except Exception as e:
|
||||||
|
print("Couldn't find the version",e)
|
||||||
|
version = "65e52dcf34d64173542cd2dc6b8bb75b"
|
||||||
|
return version
|
||||||
|
|
||||||
|
async def search(query,date,ismovie, client,SC_FAST_SEARCH,movie_id):
|
||||||
|
'''
|
||||||
|
This function is used to search for a movie or a show in the Streaming Community website using the API
|
||||||
|
After it checks if the imdb id given is the same as the one in the website
|
||||||
|
We need to convert imdb id to tmdb id because often imdb ids are missing
|
||||||
|
'''
|
||||||
|
random_headers = headers.generate()
|
||||||
|
random_headers['Referer'] = f"{SC_DOMAIN}/"
|
||||||
|
random_headers['Origin'] = f"{SC_DOMAIN}"
|
||||||
|
random_headers['Accept'] = 'application/json' # Assuming the API returns JSON
|
||||||
|
random_headers['Content-Type'] = 'application/json'
|
||||||
|
#Do a request to get the ID of serie/move and it's slug in the URL
|
||||||
|
response = await client.get(ForwardProxy + query, headers = random_headers, allow_redirects=True, impersonate = "chrome124", proxies = proxies)
|
||||||
|
print(response)
|
||||||
|
response = response.json()
|
||||||
|
for item in response['data']:
|
||||||
|
tid = item['id']
|
||||||
|
slug = item['slug']
|
||||||
|
type = item['type']
|
||||||
|
if type == "tv":
|
||||||
|
type = 0
|
||||||
|
elif type == "movie":
|
||||||
|
type = 1
|
||||||
|
if type == ismovie:
|
||||||
|
#Added a Check to see if the result is what it is supposed to be
|
||||||
|
if SC_FAST_SEARCH == "0":
|
||||||
|
random_headers = headers.generate()
|
||||||
|
random_headers['Referer'] = f"{SC_DOMAIN}/"
|
||||||
|
random_headers['Origin'] = f"{SC_DOMAIN}"
|
||||||
|
response = await client.get ( ForwardProxy + f'{SC_DOMAIN}/it/titles/{tid}-{slug}', headers = random_headers, allow_redirects=True,impersonate = "chrome124", proxies = proxies)
|
||||||
|
soup = BeautifulSoup(response.text, "lxml")
|
||||||
|
data = json.loads(soup.find("div", {"id": "app"}).get("data-page"))
|
||||||
|
version = data['version']
|
||||||
|
if "tt" in movie_id:
|
||||||
|
movie_id = str(await get_TMDb_id_from_IMDb_id(movie_id,client))
|
||||||
|
print(movie_id)
|
||||||
|
#Here we need to convert because the IMDB ID is often bugged
|
||||||
|
tmdb_id = str(data['props']['title']['tmdb_id'])
|
||||||
|
if tmdb_id == movie_id:
|
||||||
|
return tid,slug,version
|
||||||
|
elif SC_FAST_SEARCH == "1":
|
||||||
|
version = await get_version(client)
|
||||||
|
return tid,slug,version
|
||||||
|
else:
|
||||||
|
print("Couldn't find anything")
|
||||||
|
|
||||||
|
|
||||||
|
async def get_film(tid,version,client,MFP):
|
||||||
|
''''
|
||||||
|
This function is used to get the link of the m3u8 from the Streaming Community player,vixcloud
|
||||||
|
'''
|
||||||
|
random_headers = headers.generate()
|
||||||
|
random_headers['Referer'] = f"{SC_DOMAIN}/"
|
||||||
|
random_headers['Origin'] = f"{SC_DOMAIN}"
|
||||||
|
random_headers['x-inertia'] = "true"
|
||||||
|
random_headers['x-inertia-version'] = version
|
||||||
|
random_headers['User-Agent'] = User_Agent
|
||||||
|
random_headers['user-agent'] = User_Agent
|
||||||
|
#Access the iframe
|
||||||
|
url = f'{SC_DOMAIN}/it/iframe/{tid}'
|
||||||
|
if MFP == "1":
|
||||||
|
url = f'{SC_DOMAIN}/it/iframe/{tid}'
|
||||||
|
quality = "Unknown"
|
||||||
|
return url,quality
|
||||||
|
response = await client.get(ForwardProxy + url, headers=random_headers, allow_redirects=True,impersonate = "chrome124", proxies = proxies)
|
||||||
|
iframe = BeautifulSoup(response.text, 'lxml')
|
||||||
|
#Get the link of iframe
|
||||||
|
iframe = iframe.find('iframe').get("src")
|
||||||
|
#Get the ID containted in the src of iframe
|
||||||
|
vixid = iframe.split("/embed/")[1].split("?")[0]
|
||||||
|
parsed_url = urlparse(iframe)
|
||||||
|
query_params = parse_qs(parsed_url.query)
|
||||||
|
random_headers = headers.generate()
|
||||||
|
random_headers['Referer'] = f"{SC_DOMAIN}/"
|
||||||
|
random_headers['Origin'] = f"{SC_DOMAIN}"
|
||||||
|
random_headers['x-inertia'] = "true"
|
||||||
|
random_headers['x-inertia-version'] = version
|
||||||
|
random_headers['User-Agent'] = User_Agent
|
||||||
|
random_headers['user-agent'] = User_Agent
|
||||||
|
#Get real token and expires by looking at the page in the iframe, vixcloud/embed
|
||||||
|
resp = await client.get(ForwardProxy + iframe, headers = random_headers, allow_redirects=True,impersonate= "chrome124", proxies = proxies2)
|
||||||
|
soup= BeautifulSoup(resp.text, "lxml")
|
||||||
|
script = soup.find("body").find("script").text
|
||||||
|
token = re.search(r"'token':\s*'(\w+)'", script).group(1)
|
||||||
|
expires = re.search(r"'expires':\s*'(\d+)'", script).group(1)
|
||||||
|
quality = re.search(r'"quality":(\d+)', script).group(1)
|
||||||
|
base_url = re.search(r"url:\s*'(https?://[^']+)'", script).group(1)
|
||||||
|
#Example url https://vixcloud.co/playlist/231315?b=1&token=bce060eec3dc9d1965a5d258dc78c964&expires=1728995040&rendition=1080p
|
||||||
|
url = f'https://vixcloud.co/playlist/{vixid}.m3u8?token={token}&expires={expires}'
|
||||||
|
if 'canPlayFHD' in query_params:
|
||||||
|
canPlayFHD = 'h=1'
|
||||||
|
url += "&h=1"
|
||||||
|
if 'b=1' in base_url:
|
||||||
|
url += "&b=1"
|
||||||
|
'''
|
||||||
|
if 'b' in query_params:
|
||||||
|
b = 'b=1'
|
||||||
|
url += "&b=1"
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
if quality == "1080":
|
||||||
|
if "&h" in url:
|
||||||
|
url = url
|
||||||
|
elif "&b" in url and quality == "1080":
|
||||||
|
url = url.replace("&b=1","&h=1")
|
||||||
|
elif quality == "1080" and "&b" and "&h" not in url:
|
||||||
|
url = url + "&h=1"
|
||||||
|
else:
|
||||||
|
url = url + f"&token={token}"
|
||||||
|
'''
|
||||||
|
return url,quality
|
||||||
|
|
||||||
|
async def get_season_episode_id(tid,slug,season,episode,version,client):
|
||||||
|
'''
|
||||||
|
This function is used to get the ID of the episode in the Streaming Community website
|
||||||
|
'''
|
||||||
|
random_headers = headers.generate()
|
||||||
|
random_headers['Referer'] = f"{SC_DOMAIN}/"
|
||||||
|
random_headers['Origin'] = f"{SC_DOMAIN}"
|
||||||
|
random_headers['x-inertia'] = "true"
|
||||||
|
random_headers['x-inertia-version'] = version
|
||||||
|
random_headers['accept'] = 'text/html, application/xhtml+xml'
|
||||||
|
random_headers['accept-language'] = 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7'
|
||||||
|
|
||||||
|
#Set some basic headers for the request
|
||||||
|
#Get episode ID
|
||||||
|
response = await client.get(ForwardProxy + f'{SC_DOMAIN}/it/titles/{tid}-{slug}/season-{season}', headers=random_headers, allow_redirects=True, impersonate = "chrome124", proxies = proxies)
|
||||||
|
# Print the json got
|
||||||
|
json_response = response.json().get('props', {}).get('loadedSeason', {}).get('episodes', [])
|
||||||
|
for dict_episode in json_response:
|
||||||
|
if dict_episode['number'] == episode:
|
||||||
|
return dict_episode['id']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def get_episode_link(episode_id,tid,version,client,MFP):
|
||||||
|
''''
|
||||||
|
This function is used to get the link of the m3u8 from the Streaming Community player,vixcloud
|
||||||
|
'''
|
||||||
|
#The parameters for the request
|
||||||
|
random_headers = headers.generate()
|
||||||
|
random_headers['Referer'] = f"{SC_DOMAIN}/"
|
||||||
|
random_headers['Origin'] = f"{SC_DOMAIN}"
|
||||||
|
random_headers['User-Agent'] = User_Agent
|
||||||
|
random_headers['user-agent'] = User_Agent
|
||||||
|
params = {
|
||||||
|
'episode_id': episode_id,
|
||||||
|
'next_episode': '1'
|
||||||
|
}
|
||||||
|
#Let's try to get the link from iframe source
|
||||||
|
# Make a request to get iframe source
|
||||||
|
if MFP == "1":
|
||||||
|
url = f'{SC_DOMAIN}/it/iframe/{tid}?episode_id={episode_id}&next_episode=1'
|
||||||
|
quality = "Unknown"
|
||||||
|
return url,quality
|
||||||
|
response = await client.get(ForwardProxy + f"{SC_DOMAIN}/it/iframe/{tid}", params=params, headers = random_headers, allow_redirects=True, impersonate = "chrome124", proxies = proxies)
|
||||||
|
|
||||||
|
# Parse response with BeautifulSoup to get iframe source
|
||||||
|
soup = BeautifulSoup(response.text, "lxml")
|
||||||
|
iframe = soup.find("iframe").get("src")
|
||||||
|
vixid = iframe.split("/embed/")[1].split("?")[0]
|
||||||
|
random_headers = headers.generate()
|
||||||
|
random_headers['Referer'] = f"{SC_DOMAIN}/"
|
||||||
|
random_headers['Origin'] = f"{SC_DOMAIN}"
|
||||||
|
random_headers['x-inertia'] = "true"
|
||||||
|
random_headers['x-inertia-version'] = version
|
||||||
|
random_headers['User-Agent'] = User_Agent
|
||||||
|
random_headers['user-agent'] = User_Agent
|
||||||
|
parsed_url = urlparse(iframe)
|
||||||
|
query_params = parse_qs(parsed_url.query)
|
||||||
|
#Get real token and expires by looking at the page in the iframe, vixcloud/embed
|
||||||
|
resp = await client.get(ForwardProxy + iframe, headers = random_headers, allow_redirects=True, impersonate = "chrome124", proxies = proxies2)
|
||||||
|
soup= BeautifulSoup(resp.text, "lxml")
|
||||||
|
script = soup.find("body").find("script").text
|
||||||
|
token = re.search(r"'token':\s*'(\w+)'", script).group(1)
|
||||||
|
expires = re.search(r"'expires':\s*'(\d+)'", script).group(1)
|
||||||
|
quality = re.search(r'"quality":(\d+)', script).group(1)
|
||||||
|
base_url = re.search(r"url:\s*'(https?://[^']+)'", script).group(1)
|
||||||
|
|
||||||
|
#Example url https://vixcloud.co/playlist/231315?b=1&token=bce060eec3dc9d1965a5d258dc78c964&expires=1728995040&rendition=1080p
|
||||||
|
url = f'https://vixcloud.co/playlist/{vixid}.m3u8?token={token}&expires={expires}'
|
||||||
|
if 'canPlayFHD' in query_params:
|
||||||
|
canPlayFHD = 'h=1'
|
||||||
|
url += "&h=1"
|
||||||
|
if 'b=1' in base_url:
|
||||||
|
b = 'b=1'
|
||||||
|
url += "&b=1"
|
||||||
|
'''
|
||||||
|
if quality == "1080":
|
||||||
|
if "&h" in url:
|
||||||
|
url = url
|
||||||
|
elif "&b" in url and quality == "1080":
|
||||||
|
url = url.replace("&b=1","&h=1")
|
||||||
|
elif quality == "1080" and "&b" and "&h" not in url:
|
||||||
|
url = url + "&h=1"
|
||||||
|
else:
|
||||||
|
url = url + f"&token={token}"
|
||||||
|
'''
|
||||||
|
return url,quality
|
||||||
|
|
||||||
|
|
||||||
|
async def streamingcommunity_site(imdb,client,SC_FAST_SEARCH,MFP):
|
||||||
|
general = await is_movie(imdb)
|
||||||
|
ismovie = general[0]
|
||||||
|
imdb_id = general[1]
|
||||||
|
if ismovie == 0 :
|
||||||
|
season = int(general[2])
|
||||||
|
episode = int(general[3])
|
||||||
|
#Check if fast search is enabled or disabled
|
||||||
|
if SC_FAST_SEARCH == "1":
|
||||||
|
type = "StreamingCommunityFS"
|
||||||
|
if "tt" in imdb:
|
||||||
|
#Get showname
|
||||||
|
showname = await get_info_imdb(imdb_id,ismovie,type,client)
|
||||||
|
date = None
|
||||||
|
else:
|
||||||
|
#I just set n season to None to avoid bugs, but it is not needed if Fast search is enabled
|
||||||
|
date = None
|
||||||
|
#else just equals them
|
||||||
|
tmdba = imdb_id.replace("tmdb:","")
|
||||||
|
showname = get_info_tmdb(tmdba,ismovie,type)
|
||||||
|
elif SC_FAST_SEARCH == "0":
|
||||||
|
type = "StreamingCommunity"
|
||||||
|
if "tt" in imdb:
|
||||||
|
tmdba = await get_TMDb_id_from_IMDb_id(imdb_id,client)
|
||||||
|
showname,date = get_info_tmdb(tmdba,ismovie,type)
|
||||||
|
#HERE THE CASE IF IT IS A MOVIE
|
||||||
|
else:
|
||||||
|
if SC_FAST_SEARCH == "1":
|
||||||
|
type = "StreamingCommunityFS"
|
||||||
|
if "tt" in imdb:
|
||||||
|
#Get showname
|
||||||
|
date = None
|
||||||
|
showname = await get_info_imdb(imdb_id,ismovie,type,client)
|
||||||
|
else:
|
||||||
|
date = None
|
||||||
|
tmdba = imdb_id.replace("tmdb:","")
|
||||||
|
showname = get_info_tmdb(tmdba,ismovie,type)
|
||||||
|
elif SC_FAST_SEARCH == "0":
|
||||||
|
type = "StreamingCommunity"
|
||||||
|
if "tt" in imdb:
|
||||||
|
#Get showname
|
||||||
|
showname,date = await get_info_imdb(imdb_id,ismovie,type,client)
|
||||||
|
else:
|
||||||
|
tmdba = imdb_id.replace("tmdb:","")
|
||||||
|
showname,date = get_info_tmdb(tmdba,ismovie,type)
|
||||||
|
showname = showname.replace(" ", "+").replace("–", "+").replace("—","+")
|
||||||
|
showname = urllib.parse.quote_plus(showname)
|
||||||
|
query = f'{SC_DOMAIN}/api/search?q={showname}'
|
||||||
|
tid,slug,version = await search(query,date,ismovie,client,SC_FAST_SEARCH,imdb_id)
|
||||||
|
if ismovie == 1:
|
||||||
|
#TID means temporaly ID
|
||||||
|
url,quality = await get_film(tid,version,client,MFP)
|
||||||
|
print("MammaMia found results for StreamingCommunity")
|
||||||
|
return url,quality,slug
|
||||||
|
if ismovie == 0:
|
||||||
|
#Uid = URL ID
|
||||||
|
episode_id = await get_season_episode_id(tid,slug,season,episode,version,client)
|
||||||
|
url,quality = await get_episode_link(episode_id,tid,version,client,MFP)
|
||||||
|
return url,quality,slug
|
||||||
@@ -4,10 +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
|
||||||
import urllib.parse
|
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"https://www.streamingwatch.{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]
|
||||||
@@ -16,15 +43,15 @@ async def wponce_get(client):
|
|||||||
async def search(showname,season,episode,date,ismovie,client):
|
async def search(showname,season,episode,date,ismovie,client):
|
||||||
if ismovie == 1:
|
if ismovie == 1:
|
||||||
wponce = await wponce_get(client)
|
wponce = await wponce_get(client)
|
||||||
query = f'https://www.streamingwatch.{SW_DOMAIN}/wp-admin/admin-ajax.php'
|
query = f'{SW_DOMAIN}/wp-admin/admin-ajax.php'
|
||||||
headers = {
|
headers = {
|
||||||
'authority': f'www.streamingwatch.{SW_DOMAIN}',
|
'authority': f'{SW_DOMAIN}',
|
||||||
'accept': '*/*',
|
'accept': '*/*',
|
||||||
'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7',
|
'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7',
|
||||||
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||||
# 'cookie': 'wordpress_test_cookie=WP%20Cookie%20check',
|
# 'cookie': 'wordpress_test_cookie=WP%20Cookie%20check',
|
||||||
'origin': f'https://www.streamingwatch.{SW_DOMAIN}',
|
'origin': f'{SW_DOMAIN}',
|
||||||
'referer': f'https://www.streamingwatch.{SW_DOMAIN}',
|
'referer': f'{SW_DOMAIN}/',
|
||||||
'sec-ch-ua': '"Not-A.Brand";v="99", "Chromium";v="124"',
|
'sec-ch-ua': '"Not-A.Brand";v="99", "Chromium";v="124"',
|
||||||
'sec-ch-ua-mobile': '?0',
|
'sec-ch-ua-mobile': '?0',
|
||||||
'sec-ch-ua-platform': '"Android"',
|
'sec-ch-ua-platform': '"Android"',
|
||||||
@@ -42,12 +69,16 @@ 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')
|
||||||
page_date = soup.find(id = 'search-cat-year').text.strip()
|
all_page_dates = soup.find_all(id = 'search-cat-year')
|
||||||
if page_date == date:
|
all_hrefs = soup.find_all('a')
|
||||||
|
for temp_data,temp_href in zip(all_page_dates,all_hrefs):
|
||||||
|
page_date = temp_data.text.strip()
|
||||||
|
if date == page_date:
|
||||||
|
href = temp_href['href']
|
||||||
href = soup.find('a')['href']
|
href = soup.find('a')['href']
|
||||||
response = await client.get(href, allow_redirects=True, impersonate = "chrome120")
|
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')
|
||||||
@@ -55,15 +86,16 @@ 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'https://streamingwatch.{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'https://streamingwatch.{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:
|
||||||
if f"stagione-{season}-episodio-{episode}" in entry["slug"] and f"stagione-{season}-episodio-{episode}0" not in entry["slug"]:
|
if f"stagione-{season}-episodio-{episode}" in entry["slug"] or f"stagione-{season}-episode-{episode}" in entry["slug"]:
|
||||||
|
if f"stagione-{season}-episodio-{episode}0" not in entry["slug"]:
|
||||||
content = entry["content"]["rendered"]
|
content = entry["content"]["rendered"]
|
||||||
#"content":{
|
#"content":{
|
||||||
# "rendered":"<p><!--baslik:PRO--><iframe loading=\"lazy\" src=\"https:\/\/hdplayer.gives\/embed\/YErLVq64uNTZRNz\" frameborder=\"0\" width=\"700\" height=\"400\" allowfullscreen><\/iframe><\/p>\n","protected":false}
|
# "rendered":"<p><!--baslik:PRO--><iframe loading=\"lazy\" src=\"https:\/\/hdplayer.gives\/embed\/YErLVq64uNTZRNz\" frameborder=\"0\" width=\"700\" height=\"400\" allowfullscreen><\/iframe><\/p>\n","protected":false}
|
||||||
@@ -71,14 +103,10 @@ 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")
|
async def streamingwatch(streams,imdb,client):
|
||||||
match = re.search(r'sources:\s*\[\s*\{\s*file\s*:\s*"([^"]*)"', response.text)
|
|
||||||
url = match.group(1)
|
|
||||||
return url
|
|
||||||
async def streamingwatch(imdb,client):
|
|
||||||
try:
|
try:
|
||||||
general = is_movie(imdb)
|
general = await is_movie(imdb)
|
||||||
ismovie = general[0]
|
ismovie = general[0]
|
||||||
imdb_id = general[1]
|
imdb_id = general[1]
|
||||||
type = "StreamingWatch"
|
type = "StreamingWatch"
|
||||||
@@ -97,24 +125,23 @@ async def streamingwatch(imdb,client):
|
|||||||
else:
|
else:
|
||||||
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("—","+")
|
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)
|
||||||
print(f"MammaMia: StreamingWatch found results for {showname}")
|
return streams
|
||||||
return url
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("MammaMia: StreamingWatch Failed",e)
|
logger.warning(f"MammaMia: StreamingWatch Failed {e}")
|
||||||
return 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 = "tt16426418" # 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
|
||||||
asyncio.run(test_animeworld())
|
asyncio.run(test_animeworld())
|
||||||
'''
|
|
||||||
@@ -4,21 +4,26 @@ import time
|
|||||||
from Src.Utilities.info import is_movie,get_info_imdb,get_info_tmdb
|
from Src.Utilities.info import is_movie,get_info_imdb,get_info_tmdb
|
||||||
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
|
||||||
HF = config.HF
|
|
||||||
env_vars = load_env()
|
env_vars = load_env()
|
||||||
|
TF_PROXY = config.TF_PROXY
|
||||||
|
if TF_PROXY == "1":
|
||||||
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
|
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
|
||||||
|
TF_FORWARDPROXY = config.TF_ForwardProxy
|
||||||
|
if TF_FORWARDPROXY == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy = ""
|
||||||
TF_DOMAIN = config.TF_DOMAIN
|
TF_DOMAIN = config.TF_DOMAIN
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
async def search(showname,ismovie,date,client):
|
async def search(showname,ismovie,date,client):
|
||||||
showname = showname.replace(" ","%20")
|
showname = showname.replace(" ","+")
|
||||||
showname = urllib.parse.quote_plus(showname)
|
url = f'{TF_DOMAIN}/ajax/posts?q={showname}'
|
||||||
url = f'https://www.tanti.bond/ajax/posts?q={showname}'
|
response = await client.get(url, allow_redirects=True)
|
||||||
response = await client.post(url, allow_redirects=True, impersonate = "chrome120")
|
|
||||||
response = response.json()['data']
|
response = response.json()['data']
|
||||||
if ismovie == 1:
|
if ismovie == 1:
|
||||||
for link in response:
|
for link in response:
|
||||||
url = link['url']
|
url = link['url']
|
||||||
response = client.get(url, allow_redirects=True, impersonate = "chrome120")
|
response = await client.get(url, allow_redirects=True, impersonate = "chrome120")
|
||||||
pattern = r'Data di rilascio\s*</div>\s*<div class="text">\s*(\d{4})\s*</div>'
|
pattern = r'Data di rilascio\s*</div>\s*<div class="text">\s*(\d{4})\s*</div>'
|
||||||
found_date = re.search(pattern, response.text)
|
found_date = re.search(pattern, response.text)
|
||||||
release_date = str(found_date.group(1))
|
release_date = str(found_date.group(1))
|
||||||
@@ -45,7 +50,7 @@ async def search(showname,ismovie,date,client):
|
|||||||
|
|
||||||
async def fast_search(showname,ismovie,client):
|
async def fast_search(showname,ismovie,client):
|
||||||
showname = showname.replace(" ","%20")
|
showname = showname.replace(" ","%20")
|
||||||
url = f'https://www.tanti.{TF_DOMAIN}/search/{showname}'
|
url = f'{TF_DOMAIN}/search/{showname}'
|
||||||
response = await client.get(url, allow_redirects=True, impersonate = "chrome120")
|
response = await client.get(url, allow_redirects=True, impersonate = "chrome120")
|
||||||
soup = BeautifulSoup(response.text, "lxml")
|
soup = BeautifulSoup(response.text, "lxml")
|
||||||
if ismovie == 1:
|
if ismovie == 1:
|
||||||
@@ -86,7 +91,7 @@ async def get_protect_link(id,url,client):
|
|||||||
data = {
|
data = {
|
||||||
'id': embed_id
|
'id': embed_id
|
||||||
}
|
}
|
||||||
ajax_url = f"https://www.tanti.{TF_DOMAIN}/ajax/embed"
|
ajax_url = f"{TF_DOMAIN}/ajax/embed"
|
||||||
response = await client.post(ajax_url, headers=headers, data=data)
|
response = await client.post(ajax_url, headers=headers, data=data)
|
||||||
hdplayer = response.text[43:-27]
|
hdplayer = response.text[43:-27]
|
||||||
response = await client.get(hdplayer, allow_redirects=True, impersonate = "chrome120")
|
response = await client.get(hdplayer, allow_redirects=True, impersonate = "chrome120")
|
||||||
@@ -105,7 +110,7 @@ async def get_protect_link(id,url,client):
|
|||||||
soup = BeautifulSoup(response.text, "lxml", parse_only=SoupStrainer('iframe'))
|
soup = BeautifulSoup(response.text, "lxml", parse_only=SoupStrainer('iframe'))
|
||||||
protect_link = soup.iframe['src']
|
protect_link = soup.iframe['src']
|
||||||
if "protect" in protect_link:
|
if "protect" in protect_link:
|
||||||
url = true_url(protect_link)
|
url = await true_url(protect_link,client)
|
||||||
links_dict[title] = url
|
links_dict[title] = url
|
||||||
return links_dict
|
return links_dict
|
||||||
# Get the value of the href attribute
|
# Get the value of the href attribute
|
||||||
@@ -120,7 +125,7 @@ async def get_nuovo_indirizzo_and_protect_link(url,embed_id,season,episode,clien
|
|||||||
data = {
|
data = {
|
||||||
'id': embed_id
|
'id': embed_id
|
||||||
}
|
}
|
||||||
ajax_url = f"https://www.tanti.{TF_DOMAIN}/ajax/embed"
|
ajax_url = f"{TF_DOMAIN}/ajax/embed"
|
||||||
response = await client.post(ajax_url, headers=headers, data=data)
|
response = await client.post(ajax_url, headers=headers, data=data)
|
||||||
nuovo_indirizzo = response.text[43:-27]
|
nuovo_indirizzo = response.text[43:-27]
|
||||||
response = await client.get(nuovo_indirizzo, allow_redirects=True, impersonate = "chrome120")
|
response = await client.get(nuovo_indirizzo, allow_redirects=True, impersonate = "chrome120")
|
||||||
@@ -157,19 +162,27 @@ async def true_url(protect_link,client):
|
|||||||
"Range": "bytes=0-",
|
"Range": "bytes=0-",
|
||||||
"Referer": "https://d000d.com/",
|
"Referer": "https://d000d.com/",
|
||||||
}
|
}
|
||||||
if HF == "1":
|
doodstream_url = protect_link
|
||||||
|
proxies = {}
|
||||||
|
|
||||||
|
if TF_PROXY == "1":
|
||||||
import random
|
import random
|
||||||
import json
|
import json
|
||||||
|
print(PROXY_CREDENTIALS)
|
||||||
proxy_list = json.loads(PROXY_CREDENTIALS)
|
proxy_list = json.loads(PROXY_CREDENTIALS)
|
||||||
proxy = random.choice(proxy_list)
|
proxy = random.choice(proxy_list)
|
||||||
|
if proxy == "":
|
||||||
|
proxies = {}
|
||||||
|
else:
|
||||||
proxies = {
|
proxies = {
|
||||||
"http": proxy,
|
"http": proxy,
|
||||||
"https": proxy
|
"https": proxy
|
||||||
}
|
}
|
||||||
response = await client.get(protect_link, proxies=proxies, allow_redirects=True, impersonate = "chrome120")
|
|
||||||
else:
|
|
||||||
response = await client.get(protect_link, allow_redirects=True, impersonate = "chrome120")
|
|
||||||
|
|
||||||
|
elif TF_FORWARDPROXY == "1":
|
||||||
|
response = await client.head(protect_link, allow_redirects=True, impersonate = "chrome120", proxies = proxies)
|
||||||
|
doodstream_url = response.url
|
||||||
|
response = await client.get(ForwardProxy + doodstream_url, allow_redirects=True, impersonate = "chrome120", proxies = proxies)
|
||||||
|
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
# Get unique timestamp for the request
|
# Get unique timestamp for the request
|
||||||
@@ -185,15 +198,13 @@ async def true_url(protect_link,client):
|
|||||||
if match:
|
if match:
|
||||||
# Create real link (match[0] includes all matched elements)
|
# Create real link (match[0] includes all matched elements)
|
||||||
url =f'https://d000d.com{match[1]}'
|
url =f'https://d000d.com{match[1]}'
|
||||||
if "HF" == "1" :
|
rebobo = await client.get(ForwardProxy + url, headers=headers, allow_redirects=True, impersonate = "chrome120",proxies= proxies)
|
||||||
rebobo = await client.get(url, headers=headers, allow_redirects=True, impersonate = "chrome120",proxies= proxies)
|
if len(rebobo.text)> 2:
|
||||||
else:
|
|
||||||
rebobo = await client.get(url, headers=headers, allow_redirects=True, impersonate = "chrome120")
|
|
||||||
real_url = f'{rebobo.text}123456789{match[2]}{real_time}'
|
real_url = f'{rebobo.text}123456789{match[2]}{real_time}'
|
||||||
print("MammaMia: Found results for Tantifilm")
|
print("MammaMia: Found results for Tantifilm")
|
||||||
return real_url
|
return real_url
|
||||||
else:
|
else:
|
||||||
print("No match found in the text.")
|
print("Tantifilm: No match found in the text. Please be sure you are using a local instance")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
print("Error: Could not get the response.")
|
print("Error: Could not get the response.")
|
||||||
@@ -205,7 +216,7 @@ async def true_url(protect_link,client):
|
|||||||
async def tantifilm(imdb,client,TF_FAST_SEARCH):
|
async def tantifilm(imdb,client,TF_FAST_SEARCH):
|
||||||
urls = None
|
urls = None
|
||||||
try:
|
try:
|
||||||
general = is_movie(imdb)
|
general = await is_movie(imdb)
|
||||||
ismovie = general[0]
|
ismovie = general[0]
|
||||||
imdb_id = general[1]
|
imdb_id = general[1]
|
||||||
if ismovie == 0 :
|
if ismovie == 0 :
|
||||||
@@ -272,17 +283,19 @@ async def tantifilm(imdb,client,TF_FAST_SEARCH):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
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 = "tt6468322:1:1" # This is an example ID format
|
test_id = "tt3148266:1:1" # This is an example ID format
|
||||||
results = await tantifilm(test_id, client,"0")
|
results = await tantifilm(test_id, client,"0")
|
||||||
|
print(results)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import asyncio
|
import asyncio
|
||||||
asyncio.run(test_animeworld())
|
asyncio.run(test_animeworld())
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
import random
|
||||||
|
from bs4 import BeautifulSoup,SoupStrainer
|
||||||
|
import Src.Utilities.config as config
|
||||||
|
from Src.Utilities.dictionaries import webru_vary,webru_dlhd,skystreaming
|
||||||
|
from Src.Utilities.loadenv import load_env
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
import re
|
||||||
|
TF_DOMAIN = config.TF_DOMAIN
|
||||||
|
DLHD_DOMAIN = config.DLHD_DOMAIN
|
||||||
|
env_vars = load_env()
|
||||||
|
MEDIAFLOW_PASS = env_vars.get('MEDIAFLOW_PASS')
|
||||||
|
Referer = "https://ilovetoplay.xyz/"
|
||||||
|
Origin = "https://ilovetoplay.xyz"
|
||||||
|
key_url = "https%3A%2F%2Fkey2.keylocking.ru%2F"
|
||||||
|
headers = {
|
||||||
|
"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",
|
||||||
|
"Accept-Encoding": "gzip, deflate, br, zstd",
|
||||||
|
"Origin": Origin,
|
||||||
|
"DNT": "1",
|
||||||
|
"Sec-GPC": "1",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Referer": Referer,
|
||||||
|
"Sec-Fetch-Dest": "empty",
|
||||||
|
"Sec-Fetch-Mode": "cors",
|
||||||
|
"Sec-Fetch-Site": "cross-site",
|
||||||
|
"Pragma": "no-cache",
|
||||||
|
"Cache-Control": "no-cache",
|
||||||
|
}
|
||||||
|
|
||||||
|
async def get_stream_link(id,site,client):
|
||||||
|
try:
|
||||||
|
if site == "dlhd":
|
||||||
|
dlhd_id = webru_dlhd[id]
|
||||||
|
response = await client.get(f"{DLHD_DOMAIN}/embed/stream-853.php", impersonate = "chrome124", headers = headers)
|
||||||
|
soup = BeautifulSoup(response.text, 'lxml', parse_only=SoupStrainer('iframe'))
|
||||||
|
iframe = soup.find('iframe', id='thatframe')
|
||||||
|
real_link = iframe.get('src')
|
||||||
|
parent_site_domain = real_link.split('/premiumtv')[0]
|
||||||
|
server_key_link = (f'{parent_site_domain}/server_lookup.php?channel_id={dlhd_id}')
|
||||||
|
response = await client.get(server_key_link, allow_redirects = False)
|
||||||
|
server_key = response.json()['server_key']
|
||||||
|
'''
|
||||||
|
response = await client.get(real_link, allow_redirects = False)
|
||||||
|
print(response.text)
|
||||||
|
pattern = r"source:\s*'([^']*\.m3u8)'"
|
||||||
|
match = re.search(pattern, response.text)
|
||||||
|
if match:
|
||||||
|
m3u8_url = match.group(1) # The URL is captured in the first capturing group
|
||||||
|
parsed_url = urlparse(m3u8_url)
|
||||||
|
domain = parsed_url.netloc
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("No .m3u8 URL found.")
|
||||||
|
'''
|
||||||
|
stream_url = f"https://{server_key}new.iosplayer.ru/{server_key}/{dlhd_id}" + "/mono.m3u8"
|
||||||
|
return stream_url,Referer,Origin
|
||||||
|
elif site == "vary":
|
||||||
|
response = await client.get("https://calcio.monster/streaming-gratis-calcio-1.php", impersonate = "chrome124", headers = headers)
|
||||||
|
soup = BeautifulSoup(response.text, 'lxml', parse_only=SoupStrainer('div', class_='ticket_btn'))
|
||||||
|
href = soup.find('a').get('href')
|
||||||
|
response = await client.get(href)
|
||||||
|
soup = BeautifulSoup(response.text, 'lxml', parse_only=SoupStrainer('button'))
|
||||||
|
webru_iframe = soup.find_all('button', {"data-type": "embed"})
|
||||||
|
for i in webru_iframe:
|
||||||
|
webru_iframe = i.get('data-url')
|
||||||
|
if "php" not in webru_iframe:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
webru_iframe = "https://" + webru_iframe.split("/")[2]
|
||||||
|
vary_id = webru_vary[id]
|
||||||
|
vary_link = f"{webru_iframe}/server_lookup.php?channel_id={vary_id}"
|
||||||
|
response = await client.get(vary_link, headers=headers, allow_redirects=True, impersonate = "chrome124")
|
||||||
|
server_key = response.json()['server_key']
|
||||||
|
stream_url = f"https://{server_key}new.iosplayer.ru/{server_key}/{vary_id}" + "/mono.m3u8"
|
||||||
|
return stream_url,Referer,Origin
|
||||||
|
except Exception as e:
|
||||||
|
print("WebRu failed",e)
|
||||||
|
return None,None,None
|
||||||
|
async def webru(id,site,client):
|
||||||
|
try:
|
||||||
|
new_stream_url,Referer,Origin = await get_stream_link(id,site,client)
|
||||||
|
if new_stream_url == None:
|
||||||
|
raise Exception("No stream URL found")
|
||||||
|
return new_stream_url,Referer,Origin
|
||||||
|
except Exception as e:
|
||||||
|
print("WebRu failed",e)
|
||||||
|
return None,None,None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def get_skystreaming(id,client):
|
||||||
|
try:
|
||||||
|
skystreaming_link = skystreaming[id]
|
||||||
|
if type(skystreaming_link) == list:
|
||||||
|
|
||||||
|
for link in skystreaming_link:
|
||||||
|
m3u8_url,Host,Origin = await get_skystreaming_url(link,client)
|
||||||
|
else:
|
||||||
|
m3u8_url,Host,Origin = await get_skystreaming_url(skystreaming_link,client)
|
||||||
|
return m3u8_url,Host,Origin
|
||||||
|
except Exception as e:
|
||||||
|
print("SkyStreaming failed",e)
|
||||||
|
return None,None,None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def get_skystreaming_url(skystreaming_link,client):
|
||||||
|
try:
|
||||||
|
if "hls" in skystreaming_link:
|
||||||
|
m3u8_url = skystreaming_link
|
||||||
|
Host = m3u8_url.replace("https://","").split("/")[0]
|
||||||
|
response = await client.get(skystreaming_link, headers=headers, allow_redirects=True, impersonate = "chrome120")
|
||||||
|
Origin = response.url.split('/embed')[0]
|
||||||
|
return m3u8_url,Host,Origin
|
||||||
|
response = await client.get(skystreaming_link, headers=headers, allow_redirects=True, impersonate = "chrome120")
|
||||||
|
Origin = response.url.split('/embed')[0]
|
||||||
|
soup = BeautifulSoup(response.text, 'lxml', parse_only=SoupStrainer('source'))
|
||||||
|
source_tag = soup.find('source')
|
||||||
|
m3u8_url = source_tag.get('src')
|
||||||
|
Host = m3u8_url.replace("https://","").split("/")[0]
|
||||||
|
return m3u8_url,Host,Origin
|
||||||
|
except Exception as e:
|
||||||
|
print("SkyStreaming failed",e)
|
||||||
|
return None,None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
async def webru(id,site,client,MFP_CREDENTIALS):
|
||||||
|
try:
|
||||||
|
stream_url, Referer,Origin = await get_stream_link(id,site,client)
|
||||||
|
mfp_url = MFP_CREDENTIALS[0]
|
||||||
|
mfp_pass = MFP_CREDENTIALS[1]
|
||||||
|
new_stream_url = f'{mfp_url}/proxy/hls/manifest.m3u8?api_password={mfp_pass}&d={stream_url}&h_Referer={Referer}&h_Origin={Origin}&h_User-Agent=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F58.0.3029.110%20Safari%2F537.3'
|
||||||
|
return new_stream_url
|
||||||
|
except Exception as e:
|
||||||
|
print("WebRu failed",e)
|
||||||
|
return None
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
async def webru2(id,site,client):
|
||||||
|
try:
|
||||||
|
print(id)
|
||||||
|
if site == "vary":
|
||||||
|
print("1")
|
||||||
|
url = await get_stream_link(id,site)
|
||||||
|
if any(keyword in id for keyword in ["cinema", "arte", "nature", "investigation", "sky-uno", "sky-serie"]):
|
||||||
|
print("2")
|
||||||
|
url = await get_stream_link(id,site)
|
||||||
|
else:
|
||||||
|
print("3")
|
||||||
|
response = await client.get(f"https://848b3516657c-worldwide-sports-tv.baby-beamup.club/stream/tv/wwstv-it-{id}.json", impersonate = "chrome120", headers = headers)
|
||||||
|
data = response.json()
|
||||||
|
url = data['streams'][0]['url']
|
||||||
|
print(url)
|
||||||
|
return url
|
||||||
|
except Exception as e:
|
||||||
|
print("WorldSport failed",e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
if id in skystreaming:
|
||||||
|
i = i+1
|
||||||
|
url,Host = await get_skystreaming(id,client)
|
||||||
|
streams['streams'].append({'title': f'{HF}Server {i}', '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": "https://skystreaming.guru", "DNT": "1", "Sec-GPC": "1", "Connection": "keep-alive", "Referer": "https://skystreaming.guru/", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "cross-site", "Pragma": "no-cache", "Cache-Control": "no-cache", "TE": "trailers","Host": Host}}}})
|
||||||
|
|
||||||
|
'''
|
||||||
|
async def test_webru():
|
||||||
|
from curl_cffi.requests import AsyncSession
|
||||||
|
async with AsyncSession() as client:
|
||||||
|
# Replace with actual id, for example 'anime_id:episode' format
|
||||||
|
test_id = "sky-sport-uno" # This is an example ID format
|
||||||
|
results = await get_skystreaming(test_id,client)
|
||||||
|
print(results)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_webru())
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
from Src.Utilities.info import is_movie,get_info_imdb,get_info_tmdb
|
from Src.Utilities.info import is_movie,get_info_imdb,get_info_tmdb
|
||||||
import json
|
import json
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
#This doesn't work anymore.
|
||||||
headers = {
|
headers = {
|
||||||
'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',
|
||||||
'Accept': '*/*',
|
'Accept': '*/*',
|
||||||
@@ -76,6 +76,7 @@ async def whvx(id,client):
|
|||||||
showname = urllib.parse.quote_plus(showname)
|
showname = urllib.parse.quote_plus(showname)
|
||||||
response = await client.get(f'https://api.whvx.net/search', params = params, headers=headers, impersonate = "chrome120")
|
response = await client.get(f'https://api.whvx.net/search', params = params, headers=headers, impersonate = "chrome120")
|
||||||
data = json.loads(response.text)
|
data = json.loads(response.text)
|
||||||
|
print(data)
|
||||||
url = data['url']
|
url = data['url']
|
||||||
print(data)
|
print(data)
|
||||||
params = {
|
params = {
|
||||||
@@ -110,7 +111,7 @@ async def whvx(id,client):
|
|||||||
print(resolution_links)
|
print(resolution_links)
|
||||||
return resolution_links
|
return resolution_links
|
||||||
|
|
||||||
'''
|
|
||||||
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:
|
||||||
@@ -123,4 +124,3 @@ if __name__ == "__main__":
|
|||||||
asyncio.run(test_animeworld())
|
asyncio.run(test_animeworld())
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
from bs4 import BeautifulSoup
|
|
||||||
import json
|
|
||||||
from Src.Utilities.dictionaries import okru
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def okru_get_url(id,client):
|
|
||||||
try:
|
|
||||||
embed_link = okru[id]
|
|
||||||
print(embed_link)
|
|
||||||
response = await client.get(embed_link, allow_redirects=True, impersonate = "chrome120")
|
|
||||||
soup = BeautifulSoup(response.text, 'lxml')
|
|
||||||
div = soup.find('div', {'data-module': 'OKVideo'})
|
|
||||||
data_options = div.get('data-options')
|
|
||||||
data = json.loads(data_options)
|
|
||||||
metadata = json.loads(data['flashvars']['metadata'])
|
|
||||||
m3u8_link = metadata['hlsMasterPlaylistUrl']
|
|
||||||
print("MammaMia: Found results for Okru")
|
|
||||||
print(m3u8_link)
|
|
||||||
return m3u8_link
|
|
||||||
except Exception as e:
|
|
||||||
print("MammaMia: No results found for Okru")
|
|
||||||
return None
|
|
||||||
@@ -0,0 +1,298 @@
|
|||||||
|
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
|
||||||
|
import logging
|
||||||
|
from Src.Utilities.config import setup_logging
|
||||||
|
level = config.LEVEL
|
||||||
|
import random
|
||||||
|
Icon = config.Icon
|
||||||
|
Name = config.Name
|
||||||
|
logger = setup_logging(level)
|
||||||
|
env_vars = load_env()
|
||||||
|
random_headers = Headers()
|
||||||
|
RT_PROXY = config.RT_PROXY
|
||||||
|
proxies = {}
|
||||||
|
if RT_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
|
||||||
|
}
|
||||||
|
RT_ForwardProxy = config.RT_ForwardProxy
|
||||||
|
if RT_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy = ""
|
||||||
|
|
||||||
|
|
||||||
|
endpoints = {
|
||||||
|
'it' : 'https://public.aurora.enhanced.live',
|
||||||
|
'dplay' : 'https://eu1-prod.disco-api.com'
|
||||||
|
}
|
||||||
|
async def search(showname,date,client):
|
||||||
|
showname = showname.split('-')[0]
|
||||||
|
showname = quote(showname)
|
||||||
|
response = await client.get(ForwardProxy + f'https://public.aurora.enhanced.live/site/search/page/?include=default&filter[environment]=realtime&v=2&q={showname}&page[number]=1&page[size]=20', proxies = proxies)
|
||||||
|
data = response.json()
|
||||||
|
for item in data['data']:
|
||||||
|
return item['slug']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def program_info(slug,season,episode,client):
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:143.0) Gecko/20100101 Firefox/143.0',
|
||||||
|
'Accept': '*/*',
|
||||||
|
'Accept-Language': 'en-US,en;q=0.5',
|
||||||
|
'Referer': 'https://realtime.it/',
|
||||||
|
'Origin': 'https://realtime.it',
|
||||||
|
'Sec-GPC': '1',
|
||||||
|
'Connection': 'keep-alive',
|
||||||
|
'Sec-Fetch-Dest': 'empty',
|
||||||
|
'Sec-Fetch-Mode': 'cors',
|
||||||
|
'Sec-Fetch-Site': 'cross-site',
|
||||||
|
'DNT': '1',
|
||||||
|
'Priority': 'u=4',
|
||||||
|
}
|
||||||
|
link = f'https://public.aurora.enhanced.live/site/page/{slug}/?include=default&filter[environment]=realtime&v=2&parent_slug=programmi-real-time'
|
||||||
|
|
||||||
|
response = await client.get(ForwardProxy + link,headers = headers, proxies = proxies)
|
||||||
|
data = response.json()
|
||||||
|
for item in reversed(data['blocks'][1]['items']):
|
||||||
|
if season == item['seasonNumber'] and episode == item['episodeNumber']:
|
||||||
|
if 'aurora' in data['blocks'][0]['item']['poster']['src']:
|
||||||
|
platform = 'IT'
|
||||||
|
elif 'eu1-prod' in data['blocks'][0]['item']['poster']['src']:
|
||||||
|
platform = 'DPLAY'
|
||||||
|
x_realm_it = ''
|
||||||
|
x_realm_dplay = ''
|
||||||
|
if 'X-REALM-IT' in data['userMeta']['realm']:
|
||||||
|
x_realm_it = data['userMeta']['realm']['X-REALM-IT']
|
||||||
|
if 'X-REALM-DPLAY' in data['userMeta']['realm']:
|
||||||
|
x_realm_dplay = data['userMeta']['realm']['X-REALM-DPLAY']
|
||||||
|
return item['id'],x_realm_it,x_realm_dplay, platform
|
||||||
|
return None,None,None,None
|
||||||
|
|
||||||
|
async def get_token(client):
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:143.0) Gecko/20100101 Firefox/143.0',
|
||||||
|
'Accept': '*/*',
|
||||||
|
'Accept-Language': 'en-US,en;q=0.5',
|
||||||
|
'Referer': 'https://realtime.it/',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-disco-client': 'WEB:UNKNOWN:wbdatv:2.1.9',
|
||||||
|
'X-disco-params': 'realm=dplay',
|
||||||
|
'X-Device-Info': 'STONEJS/1 (Unknown/Unknown; Linux/undefined; Unknown)',
|
||||||
|
'Origin': 'https://realtime.it',
|
||||||
|
'Sec-GPC': '1',
|
||||||
|
'Connection': 'keep-alive',
|
||||||
|
'Sec-Fetch-Dest': 'empty',
|
||||||
|
'Sec-Fetch-Mode': 'cors',
|
||||||
|
'Sec-Fetch-Site': 'cross-site',
|
||||||
|
'DNT': '1',
|
||||||
|
'Priority': 'u=4',
|
||||||
|
}
|
||||||
|
response = await client.get(ForwardProxy + 'https://public.aurora.enhanced.live/site/page/casa-a-prima-vista/?include=default&filter[environment]=realtime&v=2&parent_slug=programmi-real-time', headers = headers, proxies = proxies)
|
||||||
|
data = response.json()
|
||||||
|
x_realm_it = data['userMeta']['realm']['X-REALM-IT']
|
||||||
|
x_realm_dplay = data['userMeta']['realm']['X-REALM-DPLAY']
|
||||||
|
return x_realm_it,x_realm_dplay
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def get_url(id, endpoint, x_realm_it,x_realm_dplay,streams,client):
|
||||||
|
if 'IT' in endpoint:
|
||||||
|
base_url = endpoints['it']
|
||||||
|
token = x_realm_it
|
||||||
|
elif 'DPLAY' in endpoint:
|
||||||
|
base_url = endpoints['dplay']
|
||||||
|
token = x_realm_dplay
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:143.0) Gecko/20100101 Firefox/143.0',
|
||||||
|
'Accept': '*/*',
|
||||||
|
'Accept-Language': 'en-US,en;q=0.5',
|
||||||
|
'Referer': 'https://realtime.it/',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-disco-client': 'WEB:UNKNOWN:wbdatv:2.1.9',
|
||||||
|
'X-disco-params': 'realm=dplay',
|
||||||
|
'X-Device-Info': 'STONEJS/1 (Unknown/Unknown; Linux/undefined; Unknown)',
|
||||||
|
'Authorization': f'Bearer {token}',
|
||||||
|
'Origin': 'https://realtime.it',
|
||||||
|
'Sec-GPC': '1',
|
||||||
|
'Connection': 'keep-alive',
|
||||||
|
'Sec-Fetch-Dest': 'empty',
|
||||||
|
'Sec-Fetch-Mode': 'cors',
|
||||||
|
'Sec-Fetch-Site': 'cross-site',
|
||||||
|
'DNT': '1',
|
||||||
|
'Priority': 'u=4',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
json_data = {
|
||||||
|
'deviceInfo': {
|
||||||
|
'adBlocker': False,
|
||||||
|
'drmSupported': True,
|
||||||
|
'hdrCapabilities': [
|
||||||
|
'SDR',
|
||||||
|
],
|
||||||
|
'hwDecodingCapabilities': [],
|
||||||
|
'soundCapabilities': [
|
||||||
|
'STEREO',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'wisteriaProperties': {},
|
||||||
|
'videoId': id,
|
||||||
|
}
|
||||||
|
response = await client.post(ForwardProxy + f'{base_url}/playback/v3/videoPlaybackInfo', headers=headers, json=json_data, proxies = proxies)
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
for item in data['data']['attributes']['streaming']:
|
||||||
|
if item['type'] == 'hls':
|
||||||
|
m3u8 = item['url']
|
||||||
|
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}▶️ Realtime\n HLS', 'url': m3u8, 'behaviorHints': {'bingeGroup': f'realtimehls'}})
|
||||||
|
|
||||||
|
elif item['type'] == 'dash':
|
||||||
|
mpd = item['url']
|
||||||
|
streams['streams'].append({'name': f"{Name}",'title': f'{Icon}▶️ Realtime\n MPD', 'url': mpd, 'behaviorHints': {'bingeGroup': f'realtimempd'}})
|
||||||
|
|
||||||
|
return streams
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def search_catalog(query,catalog,client):
|
||||||
|
showname = quote(query)
|
||||||
|
response = await client.get(f'https://public.aurora.enhanced.live/site/search/page/?include=default&filter[environment]=realtime&v=2&q={showname}&page[number]=1&page[size]=20')
|
||||||
|
data = response.json()
|
||||||
|
for item in data['data']:
|
||||||
|
title = item['title']
|
||||||
|
description = item['subtitle']
|
||||||
|
date = item['datePublished'].split('-')[0]
|
||||||
|
id = item['slug']
|
||||||
|
image = item['image']['url']
|
||||||
|
typeof = item['type']
|
||||||
|
catalog['metas'].append({'id': f'realtime{typeof}:'+id, 'type': "series",'name': f'{title}', 'description': description, 'releaseInfo': date, 'background': image, 'poster': image })
|
||||||
|
return catalog
|
||||||
|
|
||||||
|
async def meta_catalog(id,catalog,client):
|
||||||
|
try:
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:143.0) Gecko/20100101 Firefox/143.0',
|
||||||
|
'Accept': '*/*',
|
||||||
|
'Accept-Language': 'en-US,en;q=0.5',
|
||||||
|
'Referer': 'https://realtime.it/',
|
||||||
|
'Origin': 'https://realtime.it',
|
||||||
|
'Sec-GPC': '1',
|
||||||
|
'Connection': 'keep-alive',
|
||||||
|
'Sec-Fetch-Dest': 'empty',
|
||||||
|
'Sec-Fetch-Mode': 'cors',
|
||||||
|
'Sec-Fetch-Site': 'cross-site',
|
||||||
|
'DNT': '1',
|
||||||
|
'Priority': 'u=4',
|
||||||
|
}
|
||||||
|
parts = id.split(':')
|
||||||
|
slug = parts[1]
|
||||||
|
parts2 = parts[0].split('realtime')
|
||||||
|
typeof= parts2[1]
|
||||||
|
if typeof == 'showpage':
|
||||||
|
link = f'https://public.aurora.enhanced.live/site/page/{slug}/?include=default&filter[environment]=realtime&v=2&parent_slug=programmi-real-time'
|
||||||
|
elif typeof == 'article':
|
||||||
|
link = f'https://public.aurora.enhanced.live/site/page/{slug}/?include=default&filter[environment]=realtime&v=2'
|
||||||
|
|
||||||
|
response = await client.get(ForwardProxy + link,headers = headers, proxies = proxies)
|
||||||
|
data = response.json()
|
||||||
|
title = data['title']
|
||||||
|
subtitle = data['subtitle']
|
||||||
|
|
||||||
|
if data['type'] == 'articlepage':
|
||||||
|
if data['blocks'][1]['sonicOverrideEnabled'] == True:
|
||||||
|
platform = 'IT'
|
||||||
|
else:
|
||||||
|
platform = 'DPLAY'
|
||||||
|
elif data['type'] == 'showpage':
|
||||||
|
if 'aurora' in data['blocks'][0]['item']['poster']['src']:
|
||||||
|
platform = 'IT'
|
||||||
|
elif 'eu1-prod' in data['blocks'][0]['item']['poster']['src']:
|
||||||
|
platform = 'DPLAY'
|
||||||
|
if typeof == 'showpage':
|
||||||
|
for item in reversed(data['blocks'][1]['items']):
|
||||||
|
id = item['id']
|
||||||
|
description = item['description']
|
||||||
|
episode = item['episodeNumber']
|
||||||
|
season = item['seasonNumber']
|
||||||
|
poster = item['poster']
|
||||||
|
date = item['publishStart']
|
||||||
|
catalog['meta']['videos'].append({'title': f'S{season}'+ f'E{episode}','season': season, 'episode': episode,'firstAired':date,'overview': description, 'thumbnail': poster['src'], 'id': f'realtime{platform}:id:'+id})
|
||||||
|
elif typeof == 'article':
|
||||||
|
item = data['blocks'][1]['item']
|
||||||
|
id = item['id']
|
||||||
|
description = item['description']
|
||||||
|
episode = item['episodeNumber']
|
||||||
|
season = item['seasonNumber']
|
||||||
|
poster = item['poster']
|
||||||
|
date = item['publishStart']
|
||||||
|
catalog['meta']['videos'].append({'title': f'{title}','season': season, 'episode': episode,'firstAired':date,'overview': description, 'thumbnail': poster['src'], 'id': f'realtime{platform}:id:'+id})
|
||||||
|
|
||||||
|
catalog['meta']['name'] = title
|
||||||
|
catalog['meta']['description'] = subtitle
|
||||||
|
catalog['meta']['releaseInfo'] = '-' + data['datePublished'].split('-')[0]
|
||||||
|
catalog['meta']['background'] = data['metaMedia'][0]['media']['url']
|
||||||
|
return catalog
|
||||||
|
except Exception as e:
|
||||||
|
catalog['meta']['name'] = title
|
||||||
|
catalog['meta']['description'] = subtitle
|
||||||
|
catalog['meta']['releaseInfo'] = '-' + data['datePublished'].split('-')[0]
|
||||||
|
catalog['meta']['background'] = data['metaMedia'][0]['media']['url']
|
||||||
|
return catalog
|
||||||
|
async def realtime(streams,id,client):
|
||||||
|
try:
|
||||||
|
if 'realtime' in id:
|
||||||
|
parts = id.split('id:')
|
||||||
|
id = parts[1]
|
||||||
|
endpoint = parts[0]
|
||||||
|
x_realm_it,x_realm_dplay = await get_token(client)
|
||||||
|
streams = await get_url(id, endpoint, x_realm_it,x_realm_dplay,streams,client)
|
||||||
|
else:
|
||||||
|
general = await is_movie(id)
|
||||||
|
ismovie = general[0]
|
||||||
|
clean_id = general[1]
|
||||||
|
type = "Realtime"
|
||||||
|
if ismovie == 0 :
|
||||||
|
season = int(general[2])
|
||||||
|
episode = int(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'RT {showname}')
|
||||||
|
slug = await search(showname,date,client)
|
||||||
|
id,x_realm_it,x_realm_dplay,platform = await program_info(slug,season,episode,client)
|
||||||
|
streams = await get_url(id,platform,x_realm_it,x_realm_dplay,streams,client)
|
||||||
|
return streams
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f'RT {e}')
|
||||||
|
return streams
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def test_realtime():
|
||||||
|
from curl_cffi.requests import AsyncSession
|
||||||
|
async with AsyncSession() as client:
|
||||||
|
results = await realtime({'streams': []},"tt5684368:13:10",client)
|
||||||
|
print(results)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_realtime())
|
||||||
+81
-241
@@ -1,264 +1,104 @@
|
|||||||
from bs4 import BeautifulSoup
|
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"
|
||||||
|
|
||||||
env_vars = load_env()
|
env_vars = load_env()
|
||||||
|
SC_PROXY = config.SC_PROXY
|
||||||
|
VX_PROXY = config.VX_PROXY
|
||||||
|
proxies = {}
|
||||||
|
proxies2 = {}
|
||||||
|
if VX_PROXY == "1":
|
||||||
|
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
|
||||||
|
proxy_list = json.loads(PROXY_CREDENTIALS)
|
||||||
|
proxy = random.choice(proxy_list)
|
||||||
|
if proxy == "":
|
||||||
|
proxies2 = {}
|
||||||
|
else:
|
||||||
|
proxies2 = {
|
||||||
|
"http": proxy,
|
||||||
|
"https": proxy
|
||||||
|
}
|
||||||
|
if SC_PROXY == "1":
|
||||||
|
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
|
||||||
|
proxy_list = json.loads(PROXY_CREDENTIALS)
|
||||||
|
proxy = random.choice(proxy_list)
|
||||||
|
if proxy == "":
|
||||||
|
proxies = {}
|
||||||
|
else:
|
||||||
|
proxies = {
|
||||||
|
"http": proxy,
|
||||||
|
"https": proxy
|
||||||
|
}
|
||||||
|
if VX_PROXY == "1":
|
||||||
|
proxies2 = proxies
|
||||||
|
|
||||||
|
SC_ForwardProxy = config.SC_ForwardProxy
|
||||||
|
VX_ForwardProxy = config.VX_ForwardProxy
|
||||||
|
if SC_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
elif VX_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy = ""
|
||||||
#Get domain
|
#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
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
random_headers = headers.generate()
|
|
||||||
random_headers['Referer'] = f"https://streamingcommunity.{SC_DOMAIN}/"
|
|
||||||
random_headers['Origin'] = f"https://streamingcommunity.{SC_DOMAIN}"
|
|
||||||
base_url = f'https://streamingcommunity.{SC_DOMAIN}/richiedi-un-titolo'
|
|
||||||
response = await client.get(base_url, headers=random_headers, allow_redirects = True, impersonate="chrome120")
|
|
||||||
#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):
|
|
||||||
random_headers = headers.generate()
|
|
||||||
random_headers['Referer'] = "https://streamingcommunity.buzz/"
|
|
||||||
random_headers['Origin'] = "https://streamingcommunity.buzz"
|
|
||||||
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(query, headers = random_headers, allow_redirects=True)
|
|
||||||
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'] = "https://streamingcommunity.buzz/"
|
|
||||||
random_headers['Origin'] = "https://streamingcommunity.buzz"
|
|
||||||
response = await client.get ( f'https://streamingcommunity.{SC_DOMAIN}/titles/{tid}-{slug}', headers = random_headers, allow_redirects=True,impersonate = "chrome120")
|
|
||||||
pattern = r'<div[^>]*class="features"[^>]*>.*?<span[^>]*>(.*?)<\/span>'
|
|
||||||
match = re.search(pattern, response.text)
|
|
||||||
print(match.group(1).split("-")[0])
|
|
||||||
first_air_year = match.group(1).split("-")[0]
|
|
||||||
date = int(date)
|
|
||||||
first_air_year = int(first_air_year)
|
|
||||||
if first_air_year == date:
|
|
||||||
return tid,slug
|
|
||||||
elif SC_FAST_SEARCH == "1":
|
|
||||||
return tid,slug
|
|
||||||
else:
|
|
||||||
print("Couldn't find anything")
|
|
||||||
|
|
||||||
|
|
||||||
async def get_film(tid,version,client):
|
|
||||||
random_headers = headers.generate()
|
|
||||||
random_headers['Referer'] = "https://streamingcommunity.buzz/"
|
|
||||||
random_headers['Origin'] = "https://streamingcommunity.buzz"
|
|
||||||
random_headers['x-inertia'] = "true"
|
|
||||||
random_headers['x-inertia-version'] = version
|
|
||||||
#Access the iframe
|
|
||||||
url = f'https://streamingcommunity.{SC_DOMAIN}/iframe/{tid}'
|
|
||||||
response = await client.get(url, headers=random_headers, allow_redirects=True,impersonate = "chrome120")
|
|
||||||
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'] = "https://streamingcommunity.buzz/"
|
|
||||||
random_headers['Origin'] = "https://streamingcommunity.buzz"
|
|
||||||
random_headers['x-inertia'] = "true"
|
|
||||||
random_headers['x-inertia-version'] = version
|
|
||||||
#Get real token and expires by looking at the page in the iframe, vixcloud/embed
|
|
||||||
resp = await client.get(iframe, headers = random_headers, allow_redirects=True,impersonate= "chrome120")
|
|
||||||
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)
|
|
||||||
#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' in query_params:
|
|
||||||
b = 'b=1'
|
|
||||||
url += "&b=1"
|
|
||||||
url720 = f'https://vixcloud.co/playlist/{vixid}.m3u8'
|
|
||||||
return url,url720,quality,
|
|
||||||
|
|
||||||
async def get_season_episode_id(tid,slug,season,episode,version,client):
|
|
||||||
random_headers = headers.generate()
|
|
||||||
random_headers['Referer'] = "https://streamingcommunity.buzz/"
|
|
||||||
random_headers['Origin'] = "https://streamingcommunity.buzz"
|
|
||||||
random_headers['x-inertia'] = "true"
|
|
||||||
random_headers['x-inertia-version'] = version
|
|
||||||
#Set some basic headers for the request
|
|
||||||
#Get episode ID
|
|
||||||
response = await client.get(f'https://streamingcommunity.{SC_DOMAIN}/titles/{tid}-{slug}/stagione-{season}', headers=random_headers, allow_redirects=True, impersonate = "chrome120")
|
|
||||||
# Print the json got
|
|
||||||
json_response = response.json().get('props', {}).get('loadedSeason', {}).get('episodes', [])
|
|
||||||
for dict_episode in json_response:
|
|
||||||
if dict_episode['number'] == episode:
|
|
||||||
return dict_episode['id']
|
|
||||||
|
|
||||||
async def get_episode_link(episode_id,tid,version,client):
|
|
||||||
#The parameters for the request
|
|
||||||
random_headers = headers.generate()
|
|
||||||
random_headers['Referer'] = "https://streamingcommunity.buzz/"
|
|
||||||
random_headers['Origin'] = "https://streamingcommunity.buzz"
|
|
||||||
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
|
|
||||||
response = await client.get(f"https://streamingcommunity.{SC_DOMAIN}/iframe/{tid}", params=params, headers = random_headers, allow_redirects=True, impersonate = "chrome120")
|
|
||||||
|
|
||||||
# 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'] = "https://streamingcommunity.buzz/"
|
|
||||||
random_headers['Origin'] = "https://streamingcommunity.buzz"
|
|
||||||
random_headers['x-inertia'] = "true"
|
|
||||||
random_headers['x-inertia-version'] = version
|
|
||||||
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(iframe, headers = random_headers, allow_redirects=True, impersonate = "chrome120")
|
|
||||||
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)
|
|
||||||
#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' in query_params:
|
|
||||||
b = 'b=1'
|
|
||||||
url += "&b=1"
|
|
||||||
url720 = f'https://vixcloud.co/playlist/{vixid}.m3u8'
|
|
||||||
return url,url720,quality
|
|
||||||
|
|
||||||
|
|
||||||
async def streaming_community(imdb,client,SC_FAST_SEARCH):
|
|
||||||
try:
|
|
||||||
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
|
|
||||||
general = 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"
|
|
||||||
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)
|
async def streaming_community(streams,id,client,MFP,MFP_CREDENTIALS):
|
||||||
query = f'https://streamingcommunity.{SC_DOMAIN}/api/search?q={showname}'
|
try:
|
||||||
version = await get_version(client)
|
if "vixsrc" in SC_DOMAIN:
|
||||||
tid,slug = await search(query,date,ismovie,client,SC_FAST_SEARCH)
|
streams = await vixsrc(streams,id,client,MFP,MFP_CREDENTIALS)
|
||||||
if ismovie == 1:
|
return streams
|
||||||
#TID means temporaly ID
|
|
||||||
url,url720,quality = await get_film(tid,version,client)
|
|
||||||
print("MammaMia found results for StreamingCommunity")
|
|
||||||
return url,url720,quality
|
|
||||||
if ismovie == 0:
|
|
||||||
#Uid = URL ID
|
|
||||||
episode_id = await get_season_episode_id(tid,slug,season,episode,version,client)
|
|
||||||
url,url720,quality = await get_episode_link(episode_id,tid,version,client)
|
|
||||||
print("MammaMia found results for StreamingCommunity")
|
|
||||||
return url,url720,quality
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("MammaMia: 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
|
||||||
test_id = "tt12930350" # This is an example ID format
|
test_id = "tt6468322:1:1" # This is an example ID format
|
||||||
results = await streaming_community(test_id, client,"0")
|
results = await streaming_community({'streams': []},test_id, client,"0",['test','welp'])
|
||||||
|
print(results)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import asyncio
|
import asyncio
|
||||||
asyncio.run(test_animeworld())
|
asyncio.run(test_vixsrc())
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
from fake_headers import Headers
|
||||||
|
|
||||||
|
random_headers = Headers()
|
||||||
|
|
||||||
|
import Src.Utilities.config as config
|
||||||
|
|
||||||
|
from Src.Utilities.info import get_info_imdb,get_info_tmdb
|
||||||
|
from urllib.parse import quote
|
||||||
|
from Src.Utilities.convert import get_IMDB_id_from_TMDb_id
|
||||||
|
from Src.Utilities.info import get_info_tmdb, is_movie, get_info_imdb
|
||||||
|
from Src.API.extractors.voe import voe
|
||||||
|
from Src.API.extractors.maxstream import maxstream
|
||||||
|
import logging
|
||||||
|
from Src.Utilities.config import setup_logging
|
||||||
|
level = config.LEVEL
|
||||||
|
import re
|
||||||
|
|
||||||
|
import random
|
||||||
|
logger = setup_logging(level)
|
||||||
|
from Src.Utilities.loadenv import load_env
|
||||||
|
env_vars = load_env()
|
||||||
|
TI_DOMAIN = config.TI_DOMAIN
|
||||||
|
|
||||||
|
TI_PROXY = config.TI_PROXY
|
||||||
|
proxies = {}
|
||||||
|
if TI_PROXY == "1":
|
||||||
|
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
|
||||||
|
proxy_list = json.loads(PROXY_CREDENTIALS)
|
||||||
|
proxy = random.choice(proxy_list)
|
||||||
|
if proxy == "":
|
||||||
|
proxies = {}
|
||||||
|
else:
|
||||||
|
proxies = {
|
||||||
|
"http": proxy,
|
||||||
|
"https": proxy
|
||||||
|
}
|
||||||
|
TI_ForwardProxy = config.TI_ForwardProxy
|
||||||
|
if TI_ForwardProxy == "1":
|
||||||
|
ForwardProxy = env_vars.get('ForwardProxy')
|
||||||
|
else:
|
||||||
|
ForwardProxy = ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def search(showname,date,season,episode,MFP,MFP_CREDENTIALS,ismovie,client,streams):
|
||||||
|
headers = random_headers.generate()
|
||||||
|
response = await client.get(ForwardProxy + f'{TI_DOMAIN}/wp-json/wp/v2/search?search={quote(showname)}',headers=headers, proxies = proxies)
|
||||||
|
data = response.json()
|
||||||
|
for item in data:
|
||||||
|
response = await client.get(ForwardProxy + item['_links']['self'][0]['href'],headers=headers, proxies = proxies)
|
||||||
|
info = response.json()
|
||||||
|
html = info['content']['rendered']
|
||||||
|
if 'Stagione' in html and ismovie == 1:
|
||||||
|
continue
|
||||||
|
if 'Stagione' not in html and ismovie == 0:
|
||||||
|
continue
|
||||||
|
if ismovie == 0:
|
||||||
|
episode = episode.zfill(2)
|
||||||
|
pattern = rf'{season}×{episode}.*?<a[^>]*href="([^"]*)'
|
||||||
|
if ismovie == 1:
|
||||||
|
pattern = r'Link.*href="([^"]*)(?=.*VOE)'
|
||||||
|
match = re.search(pattern,html)
|
||||||
|
if match:
|
||||||
|
url = match.group(1)
|
||||||
|
if 'maxstream' in url:
|
||||||
|
parts = url.split('.video/')
|
||||||
|
url = 'https://maxstream.video/emvvv/' + parts[1]
|
||||||
|
streams = await maxstream(url,client,streams,'ToonItalia','',proxies,ForwardProxy)
|
||||||
|
else:
|
||||||
|
streams = await voe(url,streams,'ToonItalia',MFP,MFP_CREDENTIALS,proxies,ForwardProxy,client)
|
||||||
|
return streams
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def toonitalia(streams,id,client,MFP,MFP_CREDENTIALS):
|
||||||
|
try:
|
||||||
|
general = await is_movie(id)
|
||||||
|
ismovie = general[0]
|
||||||
|
clean_id = general[1]
|
||||||
|
type = "Toonitalia"
|
||||||
|
if ismovie == 0 :
|
||||||
|
season = str(general[2])
|
||||||
|
episode = str(general[3])
|
||||||
|
elif ismovie == 1:
|
||||||
|
season = None
|
||||||
|
episode = None
|
||||||
|
if "tmdb" in id:
|
||||||
|
showname,date = get_info_tmdb(clean_id,ismovie,type)
|
||||||
|
else:
|
||||||
|
showname,date = await get_info_imdb(clean_id,ismovie,type,client)
|
||||||
|
streams = await search(showname,date, season,episode,MFP,MFP_CREDENTIALS,ismovie,client,streams)
|
||||||
|
return streams
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return streams
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def test_toonitalia():
|
||||||
|
from curl_cffi.requests import AsyncSession
|
||||||
|
async with AsyncSession() as client:
|
||||||
|
results = await toonitalia({'streams': []},"tt1466074:1:1",client,"0",['test','test'])
|
||||||
|
print(results)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_toonitalia())
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
import random
|
|
||||||
from bs4 import BeautifulSoup,SoupStrainer
|
|
||||||
import Src.Utilities.config as config
|
|
||||||
from Src.Utilities.dictionaries import webru_vary,webru_dlhd,skystreaming
|
|
||||||
from Src.Utilities.loadenv import load_env
|
|
||||||
env_vars = load_env()
|
|
||||||
MEDIAFLOW_PASS = env_vars.get('MEDIAFLOW_PASS')
|
|
||||||
Referer = "https://ilovetoplay.xyz/"
|
|
||||||
Origin = "https://ilovetoplay.xyz"
|
|
||||||
key_url = "https%3A%2F%2Fkey2.keylocking.ru%2F"
|
|
||||||
headers = {
|
|
||||||
"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",
|
|
||||||
"Accept-Encoding": "gzip, deflate, br, zstd",
|
|
||||||
"Origin": Origin,
|
|
||||||
"DNT": "1",
|
|
||||||
"Sec-GPC": "1",
|
|
||||||
"Connection": "keep-alive",
|
|
||||||
"Referer": Referer,
|
|
||||||
"Sec-Fetch-Dest": "empty",
|
|
||||||
"Sec-Fetch-Mode": "cors",
|
|
||||||
"Sec-Fetch-Site": "cross-site",
|
|
||||||
"Pragma": "no-cache",
|
|
||||||
"Cache-Control": "no-cache",
|
|
||||||
}
|
|
||||||
|
|
||||||
medialink = config.MediaProxy
|
|
||||||
async def get_stream_link(id,site,client):
|
|
||||||
try:
|
|
||||||
if site == "dlhd":
|
|
||||||
stream_url = "https://xyzdddd.mizhls.ru/lb/" + webru_dlhd[id] + "/index.m3u8"
|
|
||||||
elif site == "vary":
|
|
||||||
stream_url = "https://webuit.mizhls.ru/lb/"+ webru_vary[id] + "/index.m3u8"
|
|
||||||
return stream_url,Referer,Origin
|
|
||||||
except Exception as e:
|
|
||||||
return None
|
|
||||||
async def webru(id,site,client):
|
|
||||||
try:
|
|
||||||
stream_url, Referer,Origin = await get_stream_link(id,site,client)
|
|
||||||
mediaproxy = config.MediaProxy
|
|
||||||
medialink = random.choice(mediaproxy)
|
|
||||||
new_stream_url = f'{medialink}proxy/hls/manifest.m3u8?api_password={MEDIAFLOW_PASS}&d={stream_url}&h_Referer={Referer}&h_Origin={Origin}&h_User-Agent=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F58.0.3029.110%20Safari%2F537.3'
|
|
||||||
return new_stream_url
|
|
||||||
except Exception as e:
|
|
||||||
print("WebRu failed",e)
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def get_skystreaming(id,client):
|
|
||||||
try:
|
|
||||||
skystreaming_link = skystreaming[id]
|
|
||||||
m3u8_urls = {}
|
|
||||||
if type(skystreaming_link) == list:
|
|
||||||
|
|
||||||
for link in skystreaming_link:
|
|
||||||
m3u8_url,Host = await get_skystreaming_url(link,client)
|
|
||||||
m3u8_urls[m3u8_url] = Host
|
|
||||||
print(m3u8_urls)
|
|
||||||
else:
|
|
||||||
m3u8_url,Host = await get_skystreaming_url(skystreaming_link,client)
|
|
||||||
m3u8_urls[m3u8_url] = Host
|
|
||||||
return m3u8_urls
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print("SkyStreaming failed",e)
|
|
||||||
return None,None
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def get_skystreaming_url(skystreaming_link,client):
|
|
||||||
try:
|
|
||||||
if "hls" in skystreaming_link:
|
|
||||||
m3u8_url = skystreaming_link
|
|
||||||
Host = m3u8_url.replace("https://","").split("/")[0]
|
|
||||||
return m3u8_url,Host
|
|
||||||
response = await client.get(skystreaming_link, headers=headers, allow_redirects=True, impersonate = "chrome120")
|
|
||||||
soup = BeautifulSoup(response.text, 'lxml', parse_only=SoupStrainer('source'))
|
|
||||||
source_tag = soup.find('source')
|
|
||||||
m3u8_url = source_tag.get('src')
|
|
||||||
Host = m3u8_url.replace("https://","").split("/")[0]
|
|
||||||
print(Host)
|
|
||||||
return m3u8_url,Host
|
|
||||||
except Exception as e:
|
|
||||||
print("SkyStreaming failed",e)
|
|
||||||
return None,None
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
async def webru(id,site,client):
|
|
||||||
try:
|
|
||||||
stream_url, Referer,Origin = await get_stream_link(id,site,client)
|
|
||||||
mediaproxy = config.MediaProxy
|
|
||||||
medialink = random.choice(mediaproxy)
|
|
||||||
new_stream_url = f'{medialink}proxy/hls/manifest.m3u8?api_password={MEDIAFLOW_PASS}&d={stream_url}&h_Referer={Referer}&h_Origin={Origin}&h_User-Agent=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F58.0.3029.110%20Safari%2F537.3'
|
|
||||||
return new_stream_url
|
|
||||||
except Exception as e:
|
|
||||||
print("WebRu failed",e)
|
|
||||||
return None
|
|
||||||
'''
|
|
||||||
+62
-14
@@ -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,21 +8,69 @@ with open('config.json') as f:
|
|||||||
|
|
||||||
# Accessing SC_DOMAIN
|
# Accessing SC_DOMAIN
|
||||||
SITE = config["Siti"]
|
SITE = config["Siti"]
|
||||||
FT_DOMAIN = SITE["Filmpertutti"]['domain']
|
SC_DOMAIN = SITE["StreamingCommunity"]['url']
|
||||||
SC_DOMAIN = SITE["StreamingCommunity"]['domain']
|
AW_DOMAIN = SITE['AnimeWorld']['url']
|
||||||
TF_DOMAIN = SITE["Tantifilm"]['domain']
|
CB_DOMAIN = SITE['CB01']['url']
|
||||||
LC_DOMAIN = SITE["LordChannel"]['domain']
|
GS_DOMAIN = SITE['Guardaserie']['url']
|
||||||
SW_DOMAIN = SITE["StreamingWatch"]['domain']
|
GHD_DOMAIN = SITE['GuardaHD']['url']
|
||||||
AW_DOMAIN = SITE['AnimeWorld']['domain']
|
ES_DOMAIN = SITE['Eurostreaming']['url']
|
||||||
SKY_DOMAIN = SITE['SkyStreaming']['domain']
|
GF_DOMAIN = SITE['Guardaflix']['url']
|
||||||
MYSTERIUS = SITE['Mysterius']['enabled']
|
GO_DOMAIN = SITE['Guardoserie']['url']
|
||||||
DLHD = SITE['DaddyLiveHD']['enabled']
|
RT_DOMAIN = SITE['Realtime']['url']
|
||||||
|
TI_DOMAIN = SITE['Toonitalia']['url']
|
||||||
|
SC = SITE['StreamingCommunity']['enabled']
|
||||||
|
AW = SITE['AnimeWorld']['enabled']
|
||||||
|
CB = SITE['CB01']['enabled']
|
||||||
|
GS = SITE['Guardaserie']['enabled']
|
||||||
|
GHD = SITE['GuardaHD']['enabled']
|
||||||
|
ES= SITE['Eurostreaming']['enabled']
|
||||||
|
GF = SITE['Guardaflix']['enabled']
|
||||||
|
GO = SITE['Guardoserie']['enabled']
|
||||||
|
RT = SITE['Realtime']['enabled']
|
||||||
|
TI = SITE['Toonitalia']['enabled']
|
||||||
|
SC_ForwardProxy = SITE['StreamingCommunity']["SC_ForwardProxy"]
|
||||||
|
GS_ForwardProxy = SITE['Guardaserie']["GS_ForwardProxy"]
|
||||||
|
GH_ForwardProxy = SITE['GuardaHD']["GH_ForwardProxy"]
|
||||||
|
VX_ForwardProxy = SITE['StreamingCommunity']["VX_ForwardProxy"]
|
||||||
|
AW_ForwardProxy = SITE['AnimeWorld']["AW_ForwardProxy"]
|
||||||
|
MX_ForwardProxy = SITE['CB01']["MX_ForwardProxy"]
|
||||||
|
CB_ForwardProxy = SITE['CB01']["CB_ForwardProxy"]
|
||||||
|
ES_ForwardProxy = SITE['Eurostreaming']['ES_ForwardProxy']
|
||||||
|
GF_ForwardProxy = SITE['Guardaflix']['GF_ForwardProxy']
|
||||||
|
GO_ForwardProxy = SITE['Guardoserie']['GO_ForwardProxy']
|
||||||
|
RT_ForwardProxy = SITE['Realtime']['RT_ForwardProxy']
|
||||||
|
|
||||||
|
TI_ForwardProxy = SITE['Toonitalia']['TI_ForwardProxy']
|
||||||
|
GS_PROXY = SITE['Guardaserie']["GS_PROXY"]
|
||||||
|
GH_PROXY = SITE['GuardaHD']["GH_PROXY"]
|
||||||
|
CB_PROXY = SITE['CB01']["CB_PROXY"]
|
||||||
|
SC_PROXY = SITE['StreamingCommunity']["SC_PROXY"]
|
||||||
|
VX_PROXY = SITE['StreamingCommunity']["VX_PROXY"]
|
||||||
|
AW_PROXY = SITE['AnimeWorld']["AW_PROXY"]
|
||||||
|
MX_PROXY = SITE['CB01']["MX_PROXY"]
|
||||||
|
ES_PROXY = SITE['Eurostreaming']['ES_PROXY']
|
||||||
|
GF_PROXY = SITE['Guardaflix']['GF_PROXY']
|
||||||
|
GO_PROXY = SITE['Guardoserie']['GO_PROXY']
|
||||||
|
RT_PROXY = SITE['Realtime']['RT_PROXY']
|
||||||
|
TI_PROXY = SITE['Toonitalia']['TI_PROXY']
|
||||||
|
#Captcha
|
||||||
|
CAPTCHA = config['Captcha']
|
||||||
|
UT_ForwardProxy = CAPTCHA['Uprot']['UT_ForwardProxy']
|
||||||
|
UT_PROXY = CAPTCHA['Uprot']['UT_PROXY']
|
||||||
|
|
||||||
#General
|
#General
|
||||||
GENERAL = config['General']
|
GENERAL = config['General']
|
||||||
dotenv = GENERAL["load_env"]
|
dotenv = GENERAL["load_env"]
|
||||||
HOST = GENERAL["HOST"]
|
HOST = GENERAL["HOST"]
|
||||||
PORT = GENERAL["PORT"]
|
PORT = GENERAL["PORT"]
|
||||||
HF = GENERAL["HF"]
|
Icon = GENERAL["Icon"]
|
||||||
Public_Instance = GENERAL["Public_Instance"]
|
Name = GENERAL["Name"]
|
||||||
MediaProxy = GENERAL["MediaProxy"]
|
LEVEL = GENERAL["level"]
|
||||||
ForwardProxy = GENERAL["ForwardProxy"]
|
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
|
||||||
@@ -12,3 +12,14 @@ async def get_TMDb_id_from_IMDb_id(imdb_id,client):
|
|||||||
return tmbda['tv_results'][0]['id']
|
return tmbda['tv_results'][0]['id']
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
async def get_IMDB_id_from_TMDb_id(tmdb_id,client):
|
||||||
|
url = f"https://api.themoviedb.org/3/movie/{tmdb_id}?api_key={TMDB_KEY}"
|
||||||
|
response = await client.get(url)
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
imdb_id = data.get('imdb_id')
|
||||||
|
if imdb_id:
|
||||||
|
return imdb_id
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+61
-497
@@ -1,15 +1,4 @@
|
|||||||
okru = {
|
import Src.Utilities.config as config
|
||||||
"rai-1": "https://ok.ru/videoembed/7868570672752?nochat=1",
|
|
||||||
"rai-2": "https://ok.ru/videoembed/7805618364016?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/7681651777136?nochat=1",
|
|
||||||
"rsi-la-2": "https://ok.ru/videoembed/7681648107120?nochat=1",
|
|
||||||
"mediaset-extra": "https://ok.ru/videoembed/7363152715376?nochat=1",
|
|
||||||
"mediaset-infinity": "https://ok.ru/videoembed/6323249159792%3Fnochat=1"
|
|
||||||
}
|
|
||||||
|
|
||||||
STREAM = {
|
STREAM = {
|
||||||
"channels": [
|
"channels": [
|
||||||
@@ -19,39 +8,39 @@ STREAM = {
|
|||||||
"name": "HD/FHD",
|
"name": "HD/FHD",
|
||||||
"genres": ["La7"],
|
"genres": ["La7"],
|
||||||
"poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/LA7_-_Logo_2011.svg/1280px-LA7_-_Logo_2011.svg.png",
|
"poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/LA7_-_Logo_2011.svg/1280px-LA7_-_Logo_2011.svg.png",
|
||||||
"url": "https://d3749synfikwkv.cloudfront.net/v1/master/3722c60a815c199d9c0ef36c5b73da68a62b09d1/cc-74ylxpgd78bpb/Live.m3u8"
|
"url": "https://d1chghleocc9sm.cloudfront.net/v1/master/3722c60a815c199d9c0ef36c5b73da68a62b09d1/cc-evfku205gqrtf/Live.m3u8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "rai-1",
|
"id": "rai-1",
|
||||||
"title": "Rai 1",
|
"title": "Rai 1",
|
||||||
"name": "Full HD Http",
|
"name": "Full HD ",
|
||||||
"genres": ["Rai"],
|
"genres": ["Rai"],
|
||||||
"poster": "https://i.imgur.com/OPV9jJD.png",
|
"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",
|
||||||
"title": "Rai 2",
|
"title": "Rai 2",
|
||||||
"name": "Full HD Http",
|
"name": "Full HD ",
|
||||||
"genres": ["Rai"],
|
"genres": ["Rai"],
|
||||||
"poster": "https://i.imgur.com/uHtYy8w.png",
|
"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",
|
||||||
"title": "Rai 3",
|
"title": "Rai 3",
|
||||||
"name": "Full HD Http",
|
"name": "Full HD ",
|
||||||
"genres": ["Rai"],
|
"genres": ["Rai"],
|
||||||
"poster": "https://i.imgur.com/iXst6me.png",
|
"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",
|
||||||
"title": "Rai 4",
|
"title": "Rai 4",
|
||||||
"name": "Full HD Http",
|
"name": "Full HD ",
|
||||||
"genres": ["Rai"],
|
"genres": ["Rai"],
|
||||||
"poster": "https://i.imgur.com/KGg3hvr.png",
|
"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",
|
||||||
@@ -59,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",
|
||||||
@@ -76,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",
|
||||||
@@ -84,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",
|
||||||
@@ -92,15 +81,15 @@ 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",
|
||||||
"title": "Rete 4",
|
"title": "Rete 4",
|
||||||
"name": "Full HD Http",
|
"name": "Full HD",
|
||||||
"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",
|
||||||
@@ -108,23 +97,22 @@ STREAM = {
|
|||||||
"name": "720p",
|
"name": "720p",
|
||||||
"genres": ["Euronews"],
|
"genres": ["Euronews"],
|
||||||
"poster": "https://yt3.googleusercontent.com/t3slq37NYJRuP2UoEZDoPKyMClKyQULG8-j2DEfzL1XXcBvFpR6z6HD7rtc0wDn8Mqt0OtpU=s900-c-k-c0x00ffffff-no-rj",
|
"poster": "https://yt3.googleusercontent.com/t3slq37NYJRuP2UoEZDoPKyMClKyQULG8-j2DEfzL1XXcBvFpR6z6HD7rtc0wDn8Mqt0OtpU=s900-c-k-c0x00ffffff-no-rj",
|
||||||
"url": "https://rakuten-euronews-3-it.samsung.wurl.tv/manifest/playlist.m3u8"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "canale-5",
|
"id": "canale-5",
|
||||||
"title": "Canale 5",
|
"title": "Canale 5",
|
||||||
"name": "Full HD Http",
|
"name": "Full HD",
|
||||||
"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",
|
||||||
"title": "Italia 1",
|
"title": "Italia 1",
|
||||||
"name": "Full HD Http",
|
"name": "Full HD",
|
||||||
"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",
|
||||||
@@ -173,13 +161,6 @@ STREAM = {
|
|||||||
"genres": ["A+E"],
|
"genres": ["A+E"],
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/history_c.png"
|
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/history_c.png"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "comedy-central",
|
|
||||||
"title": "Comedy Central",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Paramount"],
|
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/comedy-central_c.png"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "sky-tg-24",
|
"id": "sky-tg-24",
|
||||||
"title": "Sky TG24",
|
"title": "Sky TG24",
|
||||||
@@ -204,308 +185,13 @@ STREAM = {
|
|||||||
"poster": "https://static.sky.it/static_clientlibs/skycielo/clientlibs/clientlib-site/resources/images/facebook.jpg",
|
"poster": "https://static.sky.it/static_clientlibs/skycielo/clientlibs/clientlib-site/resources/images/facebook.jpg",
|
||||||
"url": "https://hlslive-web-gcdn-skycdn-it.akamaized.net/TACT/11219/cieloweb/master.m3u8?hdnea=st=1701861650~exp=1765449000~acl=/*~hmac=84c9f3f71e57b13c3a67afa8b29a8591ea9ed84bf786524399545d94be1ec04d"
|
"url": "https://hlslive-web-gcdn-skycdn-it.akamaized.net/TACT/11219/cieloweb/master.m3u8?hdnea=st=1701861650~exp=1765449000~acl=/*~hmac=84c9f3f71e57b13c3a67afa8b29a8591ea9ed84bf786524399545d94be1ec04d"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "sky-cinema-action",
|
|
||||||
"title": "Sky Cinema Action",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/sky-cinema-action_c.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-arte",
|
|
||||||
"title": "Sky Arte",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://www.davinciface.com/wp-content/uploads/2022/07/sky_arte_logo-270x270.jpg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-atlantic",
|
|
||||||
"title": "Sky Atlantic",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/sky-atlantic_c.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-cinema-collection",
|
|
||||||
"title": "Sky Cinema Collection",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/sky-cinema-collection_c.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-cinema-comedy",
|
|
||||||
"title": "Sky Cinema Comedy",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/sky-cinema-comedy_c.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-cinema-drama",
|
|
||||||
"title": "Sky Cinema Drama",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster":"https://i.imgur.com/Z8hr5aR.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-cinema-due",
|
|
||||||
"title": "Sky Cinema Due",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://i.imgur.com/xfbZiXs.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-cinema-family",
|
|
||||||
"title": "Sky Cinema Family",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/sky-cinema-family_c.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-cinema-romance",
|
|
||||||
"title": "Sky Cinema Romance",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/sky-cinema-romance_c.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-cinema-suspence",
|
|
||||||
"title": "Sky Cinema Suspence",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://i.imgur.com/vS97bNg.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-cinema-uno",
|
|
||||||
"title": "Sky Cinema Uno",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/sky-cinema-1_c.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-crime",
|
|
||||||
"title": "Sky Crime",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://i.imgur.com/j2JdQaH.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-documentaries",
|
|
||||||
"title": "Sky Documentaries",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://artworks.thetvdb.com/banners/posters/117551-3.jpg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-investigation",
|
|
||||||
"title": "Sky Investigation",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/sky-investigation_c.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-nature",
|
|
||||||
"title": "Sky Nature",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster":"https://search.bus-hit.me/image_proxy?url=https%3A%2F%2Fstatic.wikia.nocookie.net%2Flogosfake%2Fimages%2Fa%2Fad%2FSky_Nature_Generic_ID_2020.png%2Frevision%2Flatest%2Fscale-to-width-down%2F1200%3Fcb%3D20200725184630&h=71ab69ffa3abfe2ce6c20912b44f862adff4f10b9d4d761c18d292b7ffa3e9a9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-serie",
|
|
||||||
"title": "Sky Serie",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://i.imgur.com/FYvSq5T.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-uno",
|
|
||||||
"title": "Sky Uno",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://www.miotvonline.com/wp-content/uploads/2020/09/sky-uno-straming-live-miotv.jpg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-24",
|
|
||||||
"title": "Sky Sport 24",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://img2.sport-tv-guide.live/images/tv-station-sky-sport24-it-356.png"
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-golf",
|
|
||||||
"title": "Sky Sport Golf",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://search.bus-hit.me/image_proxy?url=https%3A%2F%2Fencrypted-tbn0.gstatic.com%2Fimages%3Fq%3Dtbn%3AANd9GcRQoDZOK798-OYz0E_NAahzde_JW-hLcHK-PjLm0rCXyVVcj_Y%26s&h=4b1b7a276442b52778daf26f745d06f57ff6c0cf401f4d7f3e371a566247f3ef"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-251",
|
|
||||||
"title": "Sky Sport 251",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://logodownload.org/wp-content/uploads/2020/06/sky-sports-logo-0-1.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-252",
|
|
||||||
"title": "Sky Sport 252",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://logodownload.org/wp-content/uploads/2020/06/sky-sports-logo-0-1.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-253",
|
|
||||||
"title": "Sky Sport 253",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://logodownload.org/wp-content/uploads/2020/06/sky-sports-logo-0-1.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-254",
|
|
||||||
"title": "Sky Sport 254",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://logodownload.org/wp-content/uploads/2020/06/sky-sports-logo-0-1.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-255",
|
|
||||||
"title": "Sky Sport 255",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://logodownload.org/wp-content/uploads/2020/06/sky-sports-logo-0-1.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-256",
|
|
||||||
"title": "Sky Sport 256",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://logodownload.org/wp-content/uploads/2020/06/sky-sports-logo-0-1.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-257",
|
|
||||||
"title": "Sky Sport 257",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://logodownload.org/wp-content/uploads/2020/06/sky-sports-logo-0-1.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-258",
|
|
||||||
"title": "Sky Sport 258",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://logodownload.org/wp-content/uploads/2020/06/sky-sports-logo-0-1.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-259",
|
|
||||||
"title": "Sky Sport 259",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://logodownload.org/wp-content/uploads/2020/06/sky-sports-logo-0-1.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-260",
|
|
||||||
"title": "Sky Sport 260",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://logodownload.org/wp-content/uploads/2020/06/sky-sports-logo-0-1.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-261",
|
|
||||||
"title": "Sky Sport 261",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://logodownload.org/wp-content/uploads/2020/06/sky-sports-logo-0-1.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-max",
|
|
||||||
"title": "Sky Sport Max",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://i.imgur.com/TWl58VI.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-uno",
|
|
||||||
"title": "Sky Sport Uno",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/sky-sport-1_c.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-f1",
|
|
||||||
"title": "Sky Sport F1",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://i1.wp.com/cache.pressmailing.net/thumbnail/story_hires/395b1e2f-a1c6-4cf6-9869-02155da4021f/Sky_F1_Logo.jpg.jpg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-motogp",
|
|
||||||
"title": "Sky Sport MotoGP",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://img2.sport-tv-guide.live/images/tv-station-sky-sport-motogp-360.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-calcio",
|
|
||||||
"title": "Sky Sport Calcio",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/sky-sport-2_c.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-arena",
|
|
||||||
"title": "Sky Sport Arena",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://img2.sport-tv-guide.live/images/tv-station-sky-sport-arena-354.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-tennis",
|
|
||||||
"title": "Sky Sport Tennis",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://pbs.twimg.com/profile_images/1752313472325431296/jr-YrkR6_400x400.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sky-sport-nba",
|
|
||||||
"title": "Sky Sport NBA",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sky"],
|
|
||||||
"poster": "https://www.nbareligion.com/wp-content/uploads/2019/09/sky-sport-nba.jpg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "dazn-zona-a",
|
|
||||||
"title": "DAZN Zona A",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["DAZN"],
|
|
||||||
"poster": "https://i.ytimg.com/vi/0cEfGLq-tz4/maxresdefault.jpg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "dazn-1",
|
|
||||||
"title": "DAZN 1",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["DAZN"],
|
|
||||||
"poster": "https://i.ytimg.com/vi/0cEfGLq-tz4/maxresdefault.jpg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "eurosport-1",
|
|
||||||
"title": "Eurosport 1",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Warner Bros"],
|
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/eurosport-1_c.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "eurosport-2",
|
|
||||||
"title": "Eurosport 2",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Warner Bros"],
|
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/eurosport-2_c.png"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "dmax",
|
"id": "dmax",
|
||||||
"title": "DMAX",
|
"title": "DMAX",
|
||||||
"name": "",
|
"name": "",
|
||||||
"genres": ["Warner Bros"],
|
"genres": ["Warner Bros"],
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/d-max_c.png",
|
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/d-max_c.png",
|
||||||
"url": "https://amg16146-wbdi-amg16146c8-samsung-it-1841.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-dmax-samsungit/playlist.m3u8"
|
"url": "https://d2j2nqgg7bzth.cloudfront.net/v1/master/3722c60a815c199d9c0ef36c5b73da68a62b09d1/cc-02k1gv1j0ufwn/DMAX_IT.m3u8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "foodnetwork",
|
"id": "foodnetwork",
|
||||||
@@ -513,7 +199,7 @@ STREAM = {
|
|||||||
"name": "",
|
"name": "",
|
||||||
"genres": ["Warner Bros"],
|
"genres": ["Warner Bros"],
|
||||||
"poster":"https://upload.wikimedia.org/wikipedia/commons/thumb/0/06/Food_Network_logo.svg/1024px-Food_Network_logo.svg.png",
|
"poster":"https://upload.wikimedia.org/wikipedia/commons/thumb/0/06/Food_Network_logo.svg/1024px-Food_Network_logo.svg.png",
|
||||||
"url": "https://amg16146-wbdi-amg16146c3-samsung-it-1836.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-foodnetwork-samsungit/playlist.m3u8"
|
"url": "https://dk3okdd5036kz.cloudfront.net/v1/master/3722c60a815c199d9c0ef36c5b73da68a62b09d1/cc-o4pw0nc02sthz/Foodnetwork_IT.m3u8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "frisbee",
|
"id": "frisbee",
|
||||||
@@ -521,7 +207,7 @@ STREAM = {
|
|||||||
"name": "",
|
"name": "",
|
||||||
"genres": ["Warner Bros"],
|
"genres": ["Warner Bros"],
|
||||||
"poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/FRISBEE_LOGO_2015.png/1280px-FRISBEE_LOGO_2015.png",
|
"poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/FRISBEE_LOGO_2015.png/1280px-FRISBEE_LOGO_2015.png",
|
||||||
"url": "https://amg16146-wbdi-amg16146c7-samsung-it-1840.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-frisbee-samsungit/playlist.m3u8"
|
"url": "https://d6m7lubks416z.cloudfront.net/v1/manifest/3722c60a815c199d9c0ef36c5b73da68a62b09d1/cc-zmbstsedxme9s/2fbb852d-6778-4a74-955b-59164269c705/0.m3u8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "giallo",
|
"id": "giallo",
|
||||||
@@ -529,7 +215,7 @@ STREAM = {
|
|||||||
"name": "",
|
"name": "",
|
||||||
"genres": ["Warner Bros"],
|
"genres": ["Warner Bros"],
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/giallo_c.png",
|
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/giallo_c.png",
|
||||||
"url": "https://amg16146-wbdi-amg16146c5-samsung-it-1838.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-giallo-samsungit/playlist.m3u8"
|
"url": "https://d9fqo6nfqlv2h.cloudfront.net/v1/master/3722c60a815c199d9c0ef36c5b73da68a62b09d1/cc-ulukbrgm1n3yb/Giallo_IT.m3u8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "hgtv",
|
"id": "hgtv",
|
||||||
@@ -537,7 +223,7 @@ STREAM = {
|
|||||||
"name": "",
|
"name": "",
|
||||||
"genres": ["Warner Bros"],
|
"genres": ["Warner Bros"],
|
||||||
"poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/HGTV_2010.svg/1920px-HGTV_2010.svg.png",
|
"poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/HGTV_2010.svg/1920px-HGTV_2010.svg.png",
|
||||||
"url": "https://amg16146-wbdi-amg16146c9-samsung-it-1842.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-hgtv-samsungit/playlist.m3u8"
|
"url": "https://timlivetu0.cb.ticdn.it/Content/DASH/Live/channel(hgtvhd)/manifest.mpd"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "k2",
|
"id": "k2",
|
||||||
@@ -545,7 +231,7 @@ STREAM = {
|
|||||||
"name": "",
|
"name": "",
|
||||||
"genres": ["Warner Bros"],
|
"genres": ["Warner Bros"],
|
||||||
"poster": "https://upload.wikimedia.org/wikipedia/it/thumb/7/70/K2_logo_%282013%29.svg/800px-K2_logo_%282013%29.svg.png",
|
"poster": "https://upload.wikimedia.org/wikipedia/it/thumb/7/70/K2_logo_%282013%29.svg/800px-K2_logo_%282013%29.svg.png",
|
||||||
"url": "https://amg16146-wbdi-amg16146c6-samsung-it-1839.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-k2-samsungit/playlist.m3u8"
|
"url": "https://d1pmpe0hs35ka5.cloudfront.net/v1/master/3722c60a815c199d9c0ef36c5b73da68a62b09d1/cc-39hsskpppgf72/K2_IT.m3u8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "nove",
|
"id": "nove",
|
||||||
@@ -553,7 +239,7 @@ STREAM = {
|
|||||||
"name": "",
|
"name": "",
|
||||||
"genres": ["Warner Bros"],
|
"genres": ["Warner Bros"],
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/nove_c.png",
|
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/nove_c.png",
|
||||||
"url": "https://amg16146-wbdi-amg16146c1-samsung-it-1831.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-nove-samsungit/playlist.m3u8"
|
"url": "https://d31mw7o1gs0dap.cloudfront.net/v1/master/3722c60a815c199d9c0ef36c5b73da68a62b09d1/cc-y5pbi2sq9r609/NOVE_IT.m3u8"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -562,7 +248,7 @@ STREAM = {
|
|||||||
"name": "",
|
"name": "",
|
||||||
"genres": ["Warner Bros"],
|
"genres": ["Warner Bros"],
|
||||||
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/real-time_c.png",
|
"poster": "https://www.sorrisi.com/guidatv/bundles/tvscnewsite/css/images/loghi/real-time_c.png",
|
||||||
"url": "https://amg16146-wbdi-amg16146c2-samsung-it-1835.playouts.now.amagi.tv/playlist/amg16146-warnerbrosdiscoveryitalia-realtime-samsungit/playlist.m3u8"
|
"url": "https://d3562mgijzx0zq.cloudfront.net/v1/master/3722c60a815c199d9c0ef36c5b73da68a62b09d1/cc-kizqtzpvvl3i8/Realtime_IT.m3u8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "supertennis",
|
"id": "supertennis",
|
||||||
@@ -570,7 +256,7 @@ STREAM = {
|
|||||||
"name": "",
|
"name": "",
|
||||||
"genres": ["FIT"],
|
"genres": ["FIT"],
|
||||||
"poster": "https://upload.wikimedia.org/wikipedia/commons/0/02/SUPERTENNIS_HD.png",
|
"poster": "https://upload.wikimedia.org/wikipedia/commons/0/02/SUPERTENNIS_HD.png",
|
||||||
"url": "https://live-embed.supertennix.hiway.media/restreamer/supertennix_client/gpu-a-c0-16/restreamer/rtmp/hls/h24_supertennix/manifest.m3u8"
|
"url": "https://live-embed.supertennix.hiway.media/restreamer/supertennix_client/gpu-a-c0-16/restreamer/outgest/aa3673f1-e178-44a9-a947-ef41db73211a/manifest.m3u8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "solocalcio",
|
"id": "solocalcio",
|
||||||
@@ -586,22 +272,15 @@ STREAM = {
|
|||||||
"name": "",
|
"name": "",
|
||||||
"genres": ["Sportitalia"],
|
"genres": ["Sportitalia"],
|
||||||
"poster": "https://upload.wikimedia.org/wikipedia/en/5/55/Sportitalia.jpg",
|
"poster": "https://upload.wikimedia.org/wikipedia/en/5/55/Sportitalia.jpg",
|
||||||
"url": "https://di-kzbhv8pw.vo.lswcdn.net/sportitalia/sihd/playlist.m3u8"
|
"url": "https://origin.streamup.eu/sportitaliain/sisolocalcio/playlist.m3u8"
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "sportitalia24",
|
|
||||||
"title": "Sportitalia 24",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Sportitalia"],
|
|
||||||
"poster": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/SI_Live_24_logo_%282019%29.svg/1280px-SI_Live_24_logo_%282019%29.svg.png",
|
|
||||||
"url": "https://di-kzbhv8pw.vo.lswcdn.net/sportitalia/sihd/playlist.m3u8"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "rsi-la-2",
|
"id": "rsi-la-2",
|
||||||
"title": "RSI LA 2",
|
"title": "RSI LA 2",
|
||||||
"name": "",
|
"name": "",
|
||||||
"genres": ["RSI"],
|
"genres": ["RSI"],
|
||||||
"poster": "https://livehere.one/img/rsi.png"
|
"poster": "https://livehere.one/img/rsi.png",
|
||||||
|
"url": "https://viamotionhsi.netplus.ch/live/eds/rsila2hd/browser-HLS8/rsila2hd.m3u8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "baby-shark-tv",
|
"id": "baby-shark-tv",
|
||||||
@@ -611,21 +290,13 @@ STREAM = {
|
|||||||
"poster": "https://flxt.tmsimg.com/assets/p19459897_b_v13_aa.jpg",
|
"poster": "https://flxt.tmsimg.com/assets/p19459897_b_v13_aa.jpg",
|
||||||
"url": "https://c0c65b821b3542c3a4dca92702f59944.mediatailor.us-east-1.amazonaws.com/v1/master/04fd913bb278d8775298c26fdca9d9841f37601f/RakutenTV-eu_BabySharkTV/playlist.m3u8?ads.content_classification=6&ads.device_lmt=1&ads.device_make=&ads.device_model=&ads.device_type=web&ads.device_year=&ads.env=prod&ads.gdpr_consent=&ads.market=it&ads.player_height=&ads.player_width=&ads.pod_type=playerpage_midroll&ads.ppid=&ads.rtv_content_id=3623&ads.rtv_content_language=eng&ads.rtvid=271861&ads.streaming_id=17ded124-30eb-47bc-ab57-ddfce3a16599&ads.user_type=visitor&ads.wurl_channel=696"
|
"url": "https://c0c65b821b3542c3a4dca92702f59944.mediatailor.us-east-1.amazonaws.com/v1/master/04fd913bb278d8775298c26fdca9d9841f37601f/RakutenTV-eu_BabySharkTV/playlist.m3u8?ads.content_classification=6&ads.device_lmt=1&ads.device_make=&ads.device_model=&ads.device_type=web&ads.device_year=&ads.env=prod&ads.gdpr_consent=&ads.market=it&ads.player_height=&ads.player_width=&ads.pod_type=playerpage_midroll&ads.ppid=&ads.rtv_content_id=3623&ads.rtv_content_language=eng&ads.rtvid=271861&ads.streaming_id=17ded124-30eb-47bc-ab57-ddfce3a16599&ads.user_type=visitor&ads.wurl_channel=696"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "adrenaline-movies",
|
|
||||||
"title": "Rakuten Adrenaline Movies",
|
|
||||||
"name": "",
|
|
||||||
"genres": ["Rakuten"],
|
|
||||||
"poster": "https://tvpnlogopeu.samsungcloud.tv/platform/image/sourcelogo/vc/00/02/34/ITBC11000050E_20231213T033148SQUARE.png_20231213033148.png",
|
|
||||||
"url": "https://minerva-fullmoon-1-eu.plex.wurl.tv/4300.m3u8"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "bizzarro-movies",
|
"id": "bizzarro-movies",
|
||||||
"title": "Bizzarro Movies",
|
"title": "Bizzarro Movies",
|
||||||
"name": "",
|
"name": "",
|
||||||
"genres": ["Rakuten"],
|
"genres": ["Rakuten"],
|
||||||
"poster": "https://tvpnlogopeu.samsungcloud.tv/platform/image/sourcelogo/vc/00/02/34/ITBA3300024IU_20240214T034959SQUARE.png_20240214034959.png",
|
"poster": "https://tvpnlogopeu.samsungcloud.tv/platform/image/sourcelogo/vc/00/02/34/ITBA3300024IU_20240214T034959SQUARE.png_20240214034959.png",
|
||||||
"url": "https://minerva-bizzarromovies-1-eu.plex.wurl.tv/4300.m3u8"
|
"url": "https://797fbe152cbe418697be037aef3a708f.mediatailor.us-east-1.amazonaws.com/v1/master/44f73ba4d03e9607dcd9bebdcb8494d86964f1d8/Samsung-it_BizzarroMovies/playlist.m3u8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "cinema-italiano",
|
"id": "cinema-italiano",
|
||||||
@@ -633,7 +304,7 @@ STREAM = {
|
|||||||
"name": "",
|
"name": "",
|
||||||
"genres": ["Rakuten"],
|
"genres": ["Rakuten"],
|
||||||
"poster": "https://tvpnlogopeu.samsungcloud.tv/platform/image/sourcelogo/vc/00/02/34/ITBA33000238E_20240313T074122SQUARE.png",
|
"poster": "https://tvpnlogopeu.samsungcloud.tv/platform/image/sourcelogo/vc/00/02/34/ITBA33000238E_20240313T074122SQUARE.png",
|
||||||
"url": "https://minerva-cinemasegreto-1-eu.plex.wurl.tv/4300.m3u8"
|
"url": "http://stitcher-ipv4.pluto.tv/v1/stitch/embed/hls/channel/608aa512d67fd900072323db/master.m3u8?deviceType=samsung-tvplus&deviceMake=samsung&deviceModel=samsung&deviceVersion=unknown&appVersion=unknown&deviceLat=0&deviceLon=0&deviceDNT=%7BTARGETOPT%7D&deviceId=%7BPSID%7D&advertisingId=%7BPSID%7D&us_privacy=1YNY&samsung_app_domain=%7BAPP_DOMAIN%7D&samsung_app_name=%7BAPP_NAME%7D&profileFloor=&profileLimit=&embedPartner=samsung-tvplus"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "le-vite-degli-altri",
|
"id": "le-vite-degli-altri",
|
||||||
@@ -743,94 +414,17 @@ STREAM = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
REALTIME = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
webru_vary = {
|
|
||||||
"sky-cinema-action": "calcioXac",
|
|
||||||
"comedy-central": "calcioXcomedycentral",
|
|
||||||
"history": "calcioXhistory",
|
|
||||||
"sky-arte": "calcioXskyarte",
|
|
||||||
"sky-atlantic": "calcioXskyatlantic",
|
|
||||||
"sky-cinema-collection": "calcioXskycinemacollection",
|
|
||||||
"sky-cinema-comedy": "calcioXskycinemacomedy",
|
|
||||||
"sky-cinema-drama": "calcioXskycinemadrama",
|
|
||||||
"sky-cinema-due": "calcioXskycinemadue",
|
|
||||||
"sky-cinema-family": "calcioXskycinemafamily",
|
|
||||||
"sky-cinema-romance": "calcioXskycinemaromance",
|
|
||||||
"sky-cinema-suspence": "calcioXskycinemasuspence",
|
|
||||||
"sky-cinema-uno": "calcioXskycinemauno",
|
|
||||||
"sky-crime": "calcioXskycrime",
|
|
||||||
"sky-documentaries": "calcioXskydocumentaries",
|
|
||||||
"sky-investigation": "calcioXskyinvestigation",
|
|
||||||
"sky-nature": "calcioXskynature",
|
|
||||||
"sky-serie": "calcioXskyserie",
|
|
||||||
"sky-uno": "calcioXskyuno",
|
|
||||||
"sky-sport-24": "calcioXskysport24",
|
|
||||||
}
|
|
||||||
'''
|
|
||||||
"sky-sport-golf": "https://webuit.mizhls.ru/lb/calcioXskysportgolf/index.m3u8",
|
|
||||||
"sky-sport-251": "https://webuit.mizhls.ru/lb/calcioXskysport251/index.m3u8",
|
|
||||||
"sky-sport-253": "https://webuit.mizhls.ru/lb/calcioXskysport253/index.m3u8",
|
|
||||||
"sky-sport-max": "https://webuit.mizhls.ru/lb/calcioXskysportmax/index.m3u8",
|
|
||||||
"sky-sport-255": "https://webuit.mizhls.ru/lb/calcioXskysport255/index.m3u8",
|
|
||||||
"sky-sport-259": "https://webuit.mizhls.ru/lb/calcioXsky259/index.m3u8",
|
|
||||||
"sky-sport-252": "https://webuit.mizhls.ru/lb/calcioXskysport252/index.m3u8",
|
|
||||||
"sky-sport-254": "https://webuit.mizhls.ru/lb/calcioXskysport254/index.m3u8",
|
|
||||||
"sky-sport-256": "https://webuit.mizhls.ru/lb/calcioXskysport256/index.m3u8",
|
|
||||||
"sky-sport-257": "https://webuit.mizhls.ru/lb/calcioXskysport257/index.m3u8",
|
|
||||||
"sky-sport-258": "https://webuit.mizhls.ru/lb/calcioXsky258/index.m3u8",
|
|
||||||
"sky-sport-259": "https://webuit.mizhls.ru/lb/calcioXsky259/index.m3u8",
|
|
||||||
"sky-sport-260": "https://webuit.mizhls.ru/lb/calcioXsky260/index.m3u8",
|
|
||||||
"sky-sport-261": "https://webuit.mizhls.ru/lb/calcioXsky261/index.m3u8",
|
|
||||||
"eurosport-1": "https://webuit.mizhls.ru/lb/calcioXeurosport1/index.m3u8",
|
|
||||||
"eurosport-2": "https://webuit.mizhls.ru/lb/calcioXeurosport2/index.m3u8",
|
|
||||||
"sky-sport-uno": "https://webuit.mizhls.ru/lb/calcioXskysportuno/index.m3u8",
|
|
||||||
"sky-sport-f1": "https://webuit.mizhls.ru/lb/calcioXskysportf1/index.m3u8",
|
|
||||||
"sky-sport-motogp": "https://webuit.mizhls.ru/lb/calcioXskysportmotogp/index.m3u8",
|
|
||||||
"sky-sport-calcio": "https://webuit.mizhls.ru/lb/calcioXskysportcalcio/index.m3u8",
|
|
||||||
"sky-sport-arena": "https://webuit.mizhls.ru/lb/calcioXskysportarena/index.m3u8",
|
|
||||||
"sky-sport-tennis": "https://webuit.mizhls.ru/lb/calcioXskysporttennis/index.m3u8",
|
|
||||||
"sky-sport-nba": "https://webuit.mizhls.ru/lb/calcioXskysportnba/index.m3u8",
|
|
||||||
'''
|
|
||||||
#"dazn-zona-a": "https://webuit.mizhls.ru/lb/calcioXzona/index.m3u8"
|
|
||||||
webru_dlhd = {
|
|
||||||
"sky-sport-tennis": "premium576",
|
|
||||||
"sky-sport-uno": "premium461",
|
|
||||||
"sky-cinema-collection": "premium859",
|
|
||||||
"sky-cinema-romance": "premium864",
|
|
||||||
"sky-sport-24": "premium869",
|
|
||||||
"sky-sport-254": "premium874",
|
|
||||||
"sky-sport-f1": "premium577",
|
|
||||||
"sky-sport-arena": "premium462",
|
|
||||||
"sky-cinema-uno": "premium860",
|
|
||||||
"sky-cinema-family": "premium865",
|
|
||||||
"sky-sport-calcio": "premium870",
|
|
||||||
"sky-sport-255": "premium875",
|
|
||||||
"sky-cinema-action": "premium861",
|
|
||||||
"sky-cinema-due": "premium866",
|
|
||||||
"sky-sport-251": "premium871",
|
|
||||||
"sky-sport-256": "premium876",
|
|
||||||
"sky-sport-golf": "premium574",
|
|
||||||
"sky-uno": "premium881",
|
|
||||||
"sky-cinema-comedy": "premium862",
|
|
||||||
"sky-cinema-drama": "premium867",
|
|
||||||
"sky-sport-252": "premium872",
|
|
||||||
"sky-sport-257": "premium877",
|
|
||||||
"sky-sport-motogp": "premium575",
|
|
||||||
"sky-sport-football": "premium460",
|
|
||||||
"sky-cinema-uno-24": "premium863",
|
|
||||||
"sky-cinema-suspence": "premium868",
|
|
||||||
"sky-sport-253": "premium873",
|
|
||||||
"sky-serie": "premium880",
|
|
||||||
"dazn-1": "premium877"
|
|
||||||
}
|
|
||||||
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"],
|
||||||
@@ -843,56 +437,26 @@ extra_sources = {
|
|||||||
"dmax": ["https://tvit.leicaflorianrobert.dev/discovery/dmax/stream.m3u8"],
|
"dmax": ["https://tvit.leicaflorianrobert.dev/discovery/dmax/stream.m3u8"],
|
||||||
"nove": ["https://tvit.leicaflorianrobert.dev/discovery/nove/stream.m3u8"],
|
"nove": ["https://tvit.leicaflorianrobert.dev/discovery/nove/stream.m3u8"],
|
||||||
"euronews": ["https://amg00882-amg00882c4-wedotv-eu-4536.playouts.now.amagi.tv/playlist/amg00882-euronewsfast-euronewsita-wedotveu/playlist.m3u8?app_bundle=&app_name=wedotv&app_store_url=https://wedotv.com&url=https://wedotv.com&gdpr=1&channel_name=Euronews - Italiano&content_custom_1_param=Euronews - Italiano"],
|
"euronews": ["https://amg00882-amg00882c4-wedotv-eu-4536.playouts.now.amagi.tv/playlist/amg00882-euronewsfast-euronewsita-wedotveu/playlist.m3u8?app_bundle=&app_name=wedotv&app_store_url=https://wedotv.com&url=https://wedotv.com&gdpr=1&channel_name=Euronews - Italiano&content_custom_1_param=Euronews - Italiano"],
|
||||||
"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"]
|
||||||
skystreaming ={
|
|
||||||
"sky-sport-tennis": "https://skystreaming.guru/embed/MKCKP",
|
|
||||||
"sky-sport-24": "https://skystreaming.guru/embed/GB7zq",
|
|
||||||
"sky-sport-251": "https://skystreaming.guru/embed/drHbM",
|
|
||||||
"sky-sport-252": "https://skystreaming.guru/embed/m5kfg",
|
|
||||||
"sky-sport-253": "https://skystreaming.guru/embed/YprHf",
|
|
||||||
"sky-sport-254": "https://skystreaming.guru/embed/wroRV",
|
|
||||||
"sky-sport-255": "https://skystreaming.guru/embed/0TixN",
|
|
||||||
"sky-sport-256": "https://skystreaming.guru/embed/8g8bh",
|
|
||||||
"sky-sport-257": "https://skystreaming.guru/embed/ri859",
|
|
||||||
"sky-sport-258": "https://skystreaming.guru/embed/UoJuW",
|
|
||||||
"sky-sport-259": "https://skystreaming.guru/embed/squCy",
|
|
||||||
"sky-sport-260": "https://skystreaming.guru/embed/Z5h2e",
|
|
||||||
"sky-sport-261": "https://skystreaming.guru/embed/Hz9FW",
|
|
||||||
"sky-sport-uno": "https://skystreaming.guru/embed/tb1np",
|
|
||||||
"sky-sport-f1": "https://skystreaming.guru/embed/MLkym",
|
|
||||||
"sky-sport-motogp": "https://skystreaming.guru/embed/ARFFv",
|
|
||||||
"sky-sport-calcio": "https://skystreaming.guru/embed/STOZT",
|
|
||||||
"sky-sport-arena": "https://skystreaming.guru/embed/NkEda",
|
|
||||||
"sky-sport-max": "https://skystreaming.guru/embed/4QzWz",
|
|
||||||
"sky-sport-nba": "https://skystreaming.guru/embed/saR8j",
|
|
||||||
"sky-sport-golf": "https://skystreaming.guru/embed/s9L5f",
|
|
||||||
"eurosport-1": "https://skystreaming.guru/embed/Vyv99",
|
|
||||||
"eurosport-2": "https://skystreaming.guru/embed/um8E5",
|
|
||||||
"dazn-zona-a": ["https://hls.psz.pm/hls/serie/index.m3u8","https://hls.cls.autos/hls/serie/index.m3u8"],
|
|
||||||
"sportitalia": "https://hls.cls.autos/hls/sportitalia/index.m3u8",
|
|
||||||
}
|
|
||||||
huhu = {
|
|
||||||
"canale-5": "1101559666",
|
|
||||||
"sky-sport-motogp": "2090703806",
|
|
||||||
"rai-1": "1225653759",
|
|
||||||
"sky-cinema-drama": "1235530177",
|
|
||||||
"sky-cinema-action": "3812796171",
|
|
||||||
"Dazn": "2745635299",
|
|
||||||
"sky-sport-uno": "3192996672",
|
|
||||||
"canale-5": "1534161807",
|
|
||||||
"mediaset-extra": "477466531",
|
|
||||||
"Dazn-1": "1376440573",
|
|
||||||
"sky-sport-24": "2775802255",
|
|
||||||
"sky-sport-24": "3445562519",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
provider_map = {
|
provider_map = {
|
||||||
'SC': 'STREAMINGCOMMUNITY',
|
'SC': 'STREAMINGCOMMUNITY',
|
||||||
'SC_FS': 'SC_FAST_SEARCH',
|
'SC_MFP': 'SC_MFP',
|
||||||
'LC': 'LORDCHANNEL',
|
'LC': 'LORDCHANNEL',
|
||||||
'SW': 'STREAMINGWATCH',
|
|
||||||
'TF_FS': 'TF_FAST_SEARCH',
|
'TF_FS': 'TF_FAST_SEARCH',
|
||||||
'TF': 'TANTIFILM', # Assuming 'TF' should also be handled
|
'TF': 'TANTIFILM', # Assuming 'TF' should also be handled
|
||||||
'FT': 'FILMPERTUTTI',
|
'FT': 'FILMPERTUTTI',
|
||||||
'AW': 'ANIMEWORLD'
|
'AW': 'ANIMEWORLD',
|
||||||
|
'DDL': 'DDLSTREAM',
|
||||||
|
'CB': 'CB01',
|
||||||
|
"GS": "GUARDASERIE",
|
||||||
|
"GHD": "GUARDAHD",
|
||||||
|
"OST": "ONLINESERIETV",
|
||||||
|
"ES": "EUROSTREAMING",
|
||||||
|
"GO": "GUARDOSERIE",
|
||||||
|
"RT": "REALTIME",
|
||||||
|
"TI": "TOONITALIA",
|
||||||
|
"GF": "GUARDAFLIX"
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
#Adapted for use in MammaMia from:
|
||||||
|
#https://github.com/einars/js-beautify/blob/master/python/jsbeautifier/unpackers/packer.py
|
||||||
|
# Unpacker for Dean Edward's p.a.c.k.e.r, a part of javascript beautifier
|
||||||
|
# by Einar Lielmanis <[email protected]>
|
||||||
|
#
|
||||||
|
# written by Stefano Sanfilippo <[email protected]>
|
||||||
|
#
|
||||||
|
# usage:
|
||||||
|
#
|
||||||
|
# if detect(some_string):
|
||||||
|
# unpacked = unpack(some_string)
|
||||||
|
#
|
||||||
|
from fake_headers import Headers
|
||||||
|
"""Unpacker for Dean Edward's p.a.c.k.e.r"""
|
||||||
|
import re
|
||||||
|
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):
|
||||||
|
if "eval(function(p,a,c,k,e,d)" in source:
|
||||||
|
mystr = "smth"
|
||||||
|
return mystr is not None
|
||||||
|
|
||||||
|
|
||||||
|
def unpack(source):
|
||||||
|
"""Unpacks P.A.C.K.E.R. packed js code."""
|
||||||
|
payload, symtab, radix, count = _filterargs(source)
|
||||||
|
|
||||||
|
if count != len(symtab):
|
||||||
|
raise UnpackingError("Malformed p.a.c.k.e.r. symtab.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
unbase = Unbaser(radix)
|
||||||
|
except TypeError:
|
||||||
|
raise UnpackingError("Unknown p.a.c.k.e.r. encoding.")
|
||||||
|
|
||||||
|
def lookup(match):
|
||||||
|
"""Look up symbols in the synthetic symtab."""
|
||||||
|
word = match.group(0)
|
||||||
|
return symtab[unbase(word)] or word
|
||||||
|
|
||||||
|
payload = payload.replace("\\\\", "\\").replace("\\'", "'")
|
||||||
|
source = re.sub(r"\b\w+\b", lookup, payload)
|
||||||
|
return _replacestrings(source)
|
||||||
|
|
||||||
|
|
||||||
|
def _filterargs(source):
|
||||||
|
"""Juice from a source file the four args needed by decoder."""
|
||||||
|
juicers = [
|
||||||
|
(r"}\('(.*)', *(\d+|\[\]), *(\d+), *'(.*)'\.split\('\|'\), *(\d+), *(.*)\)\)"),
|
||||||
|
(r"}\('(.*)', *(\d+|\[\]), *(\d+), *'(.*)'\.split\('\|'\)"),
|
||||||
|
]
|
||||||
|
for juicer in juicers:
|
||||||
|
args = re.search(juicer, source, re.DOTALL)
|
||||||
|
if args:
|
||||||
|
a = args.groups()
|
||||||
|
if a[1] == "[]":
|
||||||
|
a = list(a)
|
||||||
|
a[1] = 62
|
||||||
|
a = tuple(a)
|
||||||
|
try:
|
||||||
|
return a[0], a[3].split("|"), int(a[1]), int(a[2])
|
||||||
|
except ValueError:
|
||||||
|
raise UnpackingError("Corrupted p.a.c.k.e.r. data.")
|
||||||
|
|
||||||
|
# could not find a satisfying regex
|
||||||
|
raise UnpackingError(
|
||||||
|
"Could not make sense of p.a.c.k.e.r data (unexpected code structure)"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _replacestrings(source):
|
||||||
|
"""Strip string lookup table (list) and replace values in source."""
|
||||||
|
match = re.search(r'var *(_\w+)\=\["(.*?)"\];', source, re.DOTALL)
|
||||||
|
|
||||||
|
if match:
|
||||||
|
varname, strings = match.groups()
|
||||||
|
startpoint = len(match.group(0))
|
||||||
|
lookup = strings.split('","')
|
||||||
|
variable = "%s[%%d]" % varname
|
||||||
|
for index, value in enumerate(lookup):
|
||||||
|
source = source.replace(variable % index, '"%s"' % value)
|
||||||
|
return source[startpoint:]
|
||||||
|
return source
|
||||||
|
|
||||||
|
|
||||||
|
class Unbaser(object):
|
||||||
|
"""Functor for a given base. Will efficiently convert
|
||||||
|
strings to natural numbers."""
|
||||||
|
|
||||||
|
ALPHABET = {
|
||||||
|
62: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||||
|
95: (
|
||||||
|
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, base):
|
||||||
|
self.base = base
|
||||||
|
|
||||||
|
# fill elements 37...61, if necessary
|
||||||
|
if 36 < base < 62:
|
||||||
|
if not hasattr(self.ALPHABET, self.ALPHABET[62][:base]):
|
||||||
|
self.ALPHABET[base] = self.ALPHABET[62][:base]
|
||||||
|
# attrs = self.ALPHABET
|
||||||
|
# print ', '.join("%s: %s" % item for item in attrs.items())
|
||||||
|
# If base can be handled by int() builtin, let it do it for us
|
||||||
|
if 2 <= base <= 36:
|
||||||
|
self.unbase = lambda string: int(string, base)
|
||||||
|
else:
|
||||||
|
# Build conversion dictionary cache
|
||||||
|
try:
|
||||||
|
self.dictionary = dict(
|
||||||
|
(cipher, index) for index, cipher in enumerate(self.ALPHABET[base])
|
||||||
|
)
|
||||||
|
except KeyError:
|
||||||
|
raise TypeError("Unsupported base encoding.")
|
||||||
|
|
||||||
|
self.unbase = self._dictunbaser
|
||||||
|
|
||||||
|
def __call__(self, string):
|
||||||
|
return self.unbase(string)
|
||||||
|
|
||||||
|
def _dictunbaser(self, string):
|
||||||
|
"""Decodes a value to an integer."""
|
||||||
|
ret = 0
|
||||||
|
for index, cipher in enumerate(string[::-1]):
|
||||||
|
ret += (self.base**index) * self.dictionary[cipher]
|
||||||
|
return ret
|
||||||
|
class UnpackingError(Exception):
|
||||||
|
"""Badly packed source or general error. Argument is a
|
||||||
|
meaningful description."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
random_headers = Headers()
|
||||||
|
|
||||||
|
|
||||||
|
async def eval_solver(stream_link,proxies, ForwardProxy, client):
|
||||||
|
try:
|
||||||
|
headers = random_headers.generate()
|
||||||
|
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'
|
||||||
|
response = await client.get( ForwardProxy + stream_link, allow_redirects=True, timeout=30, headers = headers, proxies = proxies, impersonate = "chrome124")
|
||||||
|
logger.debug("Eval:",response.status_code)
|
||||||
|
soup = BeautifulSoup(response.text, "lxml",parse_only=SoupStrainer("script"))
|
||||||
|
script_all = soup.find_all("script")
|
||||||
|
for i in script_all:
|
||||||
|
if detect(i.text):
|
||||||
|
unpacked_code = unpack(i.text)
|
||||||
|
if "xdrop" in stream_link:
|
||||||
|
pattern = r'MDCore.wurl ?= ?"(.*?)"'
|
||||||
|
|
||||||
|
else:
|
||||||
|
pattern = r'file:"(.*?)"'
|
||||||
|
match = re.search(pattern, unpacked_code)
|
||||||
|
if match:
|
||||||
|
m3u8_url = match.group(1)
|
||||||
|
return m3u8_url
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug("Eval solver error\n",e)
|
||||||
|
raise Exception("Error in eval_solver")
|
||||||
|
|
||||||
|
|
||||||
|
#Testing
|
||||||
|
async def test_animeworld():
|
||||||
|
from curl_cffi.requests import AsyncSession
|
||||||
|
async with AsyncSession() as client:
|
||||||
|
results = await eval_solver("https://mixdrop.cv/e/l6kqxrm4t4l4or",{},"",client)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
asyncio.run(test_animeworld())
|
||||||
|
#python3 -m Src.Utilities.eval
|
||||||
+87
-27
@@ -16,21 +16,16 @@ def get_info_tmdb(tmbda,ismovie,type):
|
|||||||
show= tv.details(tmbda)
|
show= tv.details(tmbda)
|
||||||
showname = show.name
|
showname = show.name
|
||||||
if type == "Filmpertutti":
|
if type == "Filmpertutti":
|
||||||
date= show.first_air_date
|
return showname
|
||||||
date = date.split("-")[0]
|
|
||||||
print("Real date",date)
|
|
||||||
return showname,date
|
|
||||||
elif type == "StreamingCommunity":
|
elif type == "StreamingCommunity":
|
||||||
full_date = show.first_air_date
|
full_date = show.first_air_date
|
||||||
date = full_date.split("-")[0]
|
date = full_date.split("-")[0]
|
||||||
print(date)
|
|
||||||
return showname,date
|
return showname,date
|
||||||
elif type == "StreamingCommunityFS":
|
elif type == "StreamingCommunityFS":
|
||||||
return showname
|
return showname
|
||||||
elif type == "Tantifilm":
|
elif type == "Tantifilm":
|
||||||
date = show.first_air_date
|
date = show.first_air_date
|
||||||
date = date.split("-")[0]
|
date = date.split("-")[0]
|
||||||
print("Real date",date)
|
|
||||||
return showname,date
|
return showname,date
|
||||||
elif type == "TantifilmFS":
|
elif type == "TantifilmFS":
|
||||||
return showname
|
return showname
|
||||||
@@ -39,12 +34,10 @@ def get_info_tmdb(tmbda,ismovie,type):
|
|||||||
elif type == "LordChannel":
|
elif type == "LordChannel":
|
||||||
date = show.first_air_date
|
date = show.first_air_date
|
||||||
date = date.split("-")[0]
|
date = date.split("-")[0]
|
||||||
print("Real date",date)
|
|
||||||
return showname,date
|
return showname,date
|
||||||
elif type == "StreamingWatch":
|
elif type == "StreamingWatch":
|
||||||
date = show.first_air_date
|
date = show.first_air_date
|
||||||
date = date.split("-")[0]
|
date = date.split("-")[0]
|
||||||
print("Real date",date)
|
|
||||||
return showname,date
|
return showname,date
|
||||||
elif type == "DDLStream":
|
elif type == "DDLStream":
|
||||||
return showname
|
return showname
|
||||||
@@ -56,6 +49,25 @@ 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 == "Guardaserie":
|
||||||
|
date = show.first_air_date
|
||||||
|
date = date.split("-")[0]
|
||||||
|
return showname,date
|
||||||
|
elif type == "Eurostreaming":
|
||||||
|
date = show.first_air_date
|
||||||
|
date = date.split("-")[0]
|
||||||
|
return showname,date
|
||||||
|
elif type == "Guardoserie":
|
||||||
|
date = show.first_air_date
|
||||||
|
date = date.split("-")[0]
|
||||||
|
return showname,date
|
||||||
|
elif type == 'Realtime':
|
||||||
|
date = show.first_air_date
|
||||||
|
return showname,date
|
||||||
|
elif type == 'Toonitalia':
|
||||||
|
date = show.first_air_date
|
||||||
|
date = date.split("-")[0]
|
||||||
|
return showname,date
|
||||||
|
|
||||||
elif ismovie == 1:
|
elif ismovie == 1:
|
||||||
movie = Movie()
|
movie = Movie()
|
||||||
@@ -63,20 +75,16 @@ def get_info_tmdb(tmbda,ismovie,type):
|
|||||||
showname= show.title
|
showname= show.title
|
||||||
#Get all release dates
|
#Get all release dates
|
||||||
if type == "Filmpertutti":
|
if type == "Filmpertutti":
|
||||||
date = show.release_dates
|
|
||||||
date = date.split("-")[0]
|
|
||||||
#GET US RELEASE DATE because filmpertutti somewhy uses US release date
|
|
||||||
return showname,date
|
|
||||||
elif type == "StreamingCommunity":
|
|
||||||
date = show.release_dates
|
|
||||||
date = date.split("-")[0]
|
|
||||||
return showname
|
return showname
|
||||||
|
elif type == "StreamingCommunity":
|
||||||
|
date = show.release_date
|
||||||
|
date = date.split("-")[0]
|
||||||
|
return showname,date
|
||||||
elif type == "StreamingCommunityFS":
|
elif type == "StreamingCommunityFS":
|
||||||
return showname
|
return showname
|
||||||
elif type == "Tantifilm":
|
elif type == "Tantifilm":
|
||||||
date = show.release_date
|
date = show.release_date
|
||||||
date = date.split("-")[0]
|
date = date.split("-")[0]
|
||||||
print("Real date",date)
|
|
||||||
return showname,date
|
return showname,date
|
||||||
elif type == "TantifilmFS":
|
elif type == "TantifilmFS":
|
||||||
return showname
|
return showname
|
||||||
@@ -85,12 +93,10 @@ def get_info_tmdb(tmbda,ismovie,type):
|
|||||||
elif type == "LordChannel":
|
elif type == "LordChannel":
|
||||||
date = show.release_date
|
date = show.release_date
|
||||||
date = date.split("-")[0]
|
date = date.split("-")[0]
|
||||||
print("Real date",date)
|
|
||||||
return showname,date
|
return showname,date
|
||||||
elif type == "StreamingWatch":
|
elif type == "StreamingWatch":
|
||||||
date = show.release_date
|
date = show.release_date
|
||||||
date = date.split("-")[0]
|
date = date.split("-")[0]
|
||||||
print("Real date",date)
|
|
||||||
return showname,date
|
return showname,date
|
||||||
elif type == "DDLStream":
|
elif type == "DDLStream":
|
||||||
return showname
|
return showname
|
||||||
@@ -102,17 +108,28 @@ 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
|
||||||
|
elif type == 'Realtime':
|
||||||
|
date = show.release_date
|
||||||
|
return showname,date
|
||||||
|
elif type == "Toonitalia":
|
||||||
|
date = show.release_date
|
||||||
|
date = date.split("-")[0]
|
||||||
|
return showname,date
|
||||||
async def get_info_imdb(imdb_id, ismovie, type,client):
|
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')
|
||||||
data = resp.json()
|
data = resp.json()
|
||||||
if ismovie == 0:
|
if ismovie == 0:
|
||||||
showname = data['tv_results'][0]['name']
|
showname = data['tv_results'][0]['name']
|
||||||
if type == "Filmpertutti":
|
if type == "Filmpertutti":
|
||||||
date= data['tv_results'][0]['first_air_date']
|
return showname
|
||||||
date = date.split("-")[0]
|
|
||||||
print("Real date",date)
|
|
||||||
return showname, date
|
|
||||||
elif type == "StreamingCommunity":
|
elif type == "StreamingCommunity":
|
||||||
date = data['tv_results'][0]['first_air_date']
|
date = data['tv_results'][0]['first_air_date']
|
||||||
date = date.split("-")[0]
|
date = date.split("-")[0]
|
||||||
@@ -137,13 +154,33 @@ 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 == "Onlineserietv":
|
||||||
|
date = data['tv_results'][0]['first_air_date']
|
||||||
|
date = date.split("-")[0]
|
||||||
|
return showname,date
|
||||||
|
elif type == "Guardaserie":
|
||||||
|
date = data['tv_results'][0]['first_air_date']
|
||||||
|
date = date.split("-")[0]
|
||||||
|
return showname,date
|
||||||
|
elif type == "Eurostreaming":
|
||||||
|
date = data['tv_results'][0]['first_air_date']
|
||||||
|
date = date.split("-")[0]
|
||||||
|
return showname,date
|
||||||
|
elif type == "Guardoserie":
|
||||||
|
date = data['tv_results'][0]['first_air_date']
|
||||||
|
date = date.split("-")[0]
|
||||||
|
return showname,date
|
||||||
|
elif type == 'Realtime':
|
||||||
|
return showname,data['tv_results'][0]['first_air_date']
|
||||||
|
elif type == "Toonitalia":
|
||||||
|
date = data['tv_results'][0]['first_air_date']
|
||||||
|
date = date.split("-")[0]
|
||||||
|
return showname,date
|
||||||
|
|
||||||
elif ismovie == 1:
|
elif ismovie == 1:
|
||||||
showname= data['movie_results'][0]['title']
|
showname= data['movie_results'][0]['title']
|
||||||
if type == "Filmpertutti":
|
if type == "Filmpertutti":
|
||||||
date = data['movie_results'][0]['release_date']
|
return showname
|
||||||
date = date.split("-")[0]
|
|
||||||
return showname,date
|
|
||||||
elif type == "StreamingCommunity":
|
elif type == "StreamingCommunity":
|
||||||
date = data['movie_results'][0]['release_date']
|
date = data['movie_results'][0]['release_date']
|
||||||
date = date.split("-")[0]
|
date = date.split("-")[0]
|
||||||
@@ -166,12 +203,35 @@ 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 == "Onlineserietv":
|
||||||
|
date = data['movie_results'][0]['release_date']
|
||||||
|
date = date.split("-")[0]
|
||||||
|
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
|
||||||
|
elif type == 'Realtime':
|
||||||
|
date = data['movie_results'][0]['release_date']
|
||||||
|
return showname,date
|
||||||
|
elif type == 'Toonitalia':
|
||||||
|
date = data['movie_results'][0]['release_date']
|
||||||
|
date = date.split("-")[0]
|
||||||
|
return showname,date
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def get_info_kitsu(kitsu_id,client):
|
async def get_info_kitsu(kitsu_id,client):
|
||||||
api_url = f'https://kitsu.io/api/edge/anime/{kitsu_id}'
|
api_url = f'https://kitsu.io/api/edge/anime/{kitsu_id}'
|
||||||
response = await client.get(api_url)
|
response = await client.get(api_url)
|
||||||
data = json.loads(response.text)
|
data = json.loads(response.text)
|
||||||
|
try:
|
||||||
|
showname = data['data']['attributes']['titles']['en']
|
||||||
|
except Exception as e:
|
||||||
showname = data['data']['attributes']['canonicalTitle']
|
showname = data['data']['attributes']['canonicalTitle']
|
||||||
date = data['data']['attributes']['startDate']
|
date = data['data']['attributes']['startDate']
|
||||||
return showname,date
|
return showname,date
|
||||||
@@ -179,7 +239,7 @@ async def get_info_kitsu(kitsu_id,client):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def is_movie(imdb_id):
|
async def is_movie(imdb_id):
|
||||||
if "tmdb:" in imdb_id:
|
if "tmdb:" in imdb_id:
|
||||||
imdb_id = imdb_id.replace("tmdb:","")
|
imdb_id = imdb_id.replace("tmdb:","")
|
||||||
if ":" in imdb_id:
|
if ":" in imdb_id:
|
||||||
|
|||||||
@@ -1,9 +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
|
||||||
HF = config.HF
|
|
||||||
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
|
||||||
@@ -13,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')
|
||||||
env_vars['MEDIAFLOW_PASS'] = os.getenv('MEDIAFLOW_PASS')
|
env_vars['ForwardProxy'] = os.getenv('FORWARDPROXY')
|
||||||
if Public_Instance == "1":
|
env_vars['PORT_ENV'] = os.getenv('PORT')
|
||||||
env_vars['ALTERNATIVE_LINK'] = os.getenv('ALTERNATIVE_LINK')
|
|
||||||
return env_vars
|
return env_vars
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"projectName": "mammamia",
|
||||||
|
"lastCommit": "58af5b8"
|
||||||
|
}
|
||||||
+65
-23
@@ -1,41 +1,83 @@
|
|||||||
{
|
{
|
||||||
"Siti": {
|
"Siti": {
|
||||||
"StreamingCommunity": {
|
"StreamingCommunity": {
|
||||||
"domain": "buzz"
|
"url": "https://vixsrc.to",
|
||||||
|
"SC_ForwardProxy": "0",
|
||||||
|
"SC_PROXY": "0",
|
||||||
|
"VX_ForwardProxy": "0",
|
||||||
|
"VX_PROXY": "0",
|
||||||
|
"enabled": "1"
|
||||||
},
|
},
|
||||||
"Filmpertutti": {
|
"CB01":{
|
||||||
"domain": "diy"
|
"url": "https://cb01.uno",
|
||||||
|
"CB_PROXY":"0",
|
||||||
|
"CB_ForwardProxy":"0",
|
||||||
|
"MX_ForwardProxy":"0",
|
||||||
|
"MX_PROXY":"0",
|
||||||
|
"enabled":"1"
|
||||||
},
|
},
|
||||||
"Tantifilm":{
|
"Guardaserie":{
|
||||||
"domain": "bond"
|
"url": "https://guardaserietv.asia",
|
||||||
|
"enabled":"1",
|
||||||
|
"GS_ForwardProxy":"0",
|
||||||
|
"GS_PROXY":"0"
|
||||||
},
|
},
|
||||||
"Mysterius":{
|
"GuardaHD":{
|
||||||
"enabled": "0"
|
"url": "https://mostraguarda.stream",
|
||||||
|
"enabled":"1",
|
||||||
|
"GH_ForwardProxy":"0",
|
||||||
|
"GH_PROXY":"0"
|
||||||
},
|
},
|
||||||
"LordChannel":{
|
"Eurostreaming":{
|
||||||
"domain":"com"
|
"url": "https://eurostreamings.life",
|
||||||
|
"enabled": "1",
|
||||||
|
"ES_ForwardProxy": "0",
|
||||||
|
"ES_PROXY": "0"
|
||||||
},
|
},
|
||||||
"StreamingWatch":{
|
"Guardaflix":{
|
||||||
"domain":"org"
|
"url": "https://guardaplay.blog",
|
||||||
|
"enabled": "1",
|
||||||
|
"GF_ForwardProxy": "0",
|
||||||
|
"GF_PROXY": "0"
|
||||||
|
},
|
||||||
|
"Guardoserie":{
|
||||||
|
"url": "https://guardoserie.blog",
|
||||||
|
"enabled": "1",
|
||||||
|
"GO_ForwardProxy": "0",
|
||||||
|
"GO_PROXY": "0"
|
||||||
},
|
},
|
||||||
"AnimeWorld":{
|
"AnimeWorld":{
|
||||||
"domain":"so"
|
"url": "https://www.animeworld.ac",
|
||||||
|
"enabled":"1",
|
||||||
|
"AW_ForwardProxy":"0",
|
||||||
|
"AW_PROXY":"0"
|
||||||
},
|
},
|
||||||
"SkyStreaming":{
|
"Realtime": {
|
||||||
"domain":"guru"
|
"url": "https://realtime.it",
|
||||||
|
"enabled": "1",
|
||||||
|
"RT_ForwardProxy": "0",
|
||||||
|
"RT_PROXY": "0"
|
||||||
},
|
},
|
||||||
"DaddyLiveHD":{
|
"Toonitalia": {
|
||||||
"enabled":"1"
|
"url": "https://toonitalia.xyz",
|
||||||
|
"enabled": "1",
|
||||||
|
"TI_ForwardProxy": "0",
|
||||||
|
"TI_PROXY": "0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Captcha":{
|
||||||
|
"Uprot": {
|
||||||
|
"UT_ForwardProxy": "0",
|
||||||
|
"UT_PROXY": "0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"General":{
|
"General":{
|
||||||
"load_env": "0",
|
"load_env": "1",
|
||||||
"HOST": "0.0.0.0",
|
"HOST": "0.0.0.0",
|
||||||
"PORT": "8080",
|
"PORT": 8080,
|
||||||
"HF": "1",
|
"Name": "MammaMia",
|
||||||
"Public_Instance": "0",
|
"Icon": "🍕",
|
||||||
"MediaProxy": ["Test"],
|
"level": "info",
|
||||||
"ForwardProxy": ["Test"],
|
"Global_Proxy": "0"
|
||||||
"Proxy": []
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -1,3 +1,7 @@
|
|||||||
|
# This env variable is mandatory
|
||||||
|
# Questa variabile è obbligatoria
|
||||||
TMDB_KEY= "INSERT YOUR API KEY HERE"
|
TMDB_KEY= "INSERT YOUR API KEY HERE"
|
||||||
MEDIAFLOW_PASS = "INSERT YOUR MEDIAFLOW PASS HERE"
|
# Those env variable are not mandatory
|
||||||
|
# Queste variabili non sono obbligatoria
|
||||||
|
PROXY = ["PROXY1","PROXY2"]
|
||||||
|
FORWARDPROXY = "YOURFORWARDPROXY/"
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
services:
|
||||||
|
- type: web
|
||||||
|
name: MammaMia
|
||||||
|
runtime: python
|
||||||
|
buildCommand: pip install -r requirements.txt
|
||||||
|
startCommand: python3 run.py
|
||||||
|
plan: free
|
||||||
|
region: frankfurt
|
||||||
|
envVars:
|
||||||
|
# Sets a hardcoded value
|
||||||
|
# (DO NOT hardcode secrets in your Blueprint file!)
|
||||||
|
- key: PORT
|
||||||
|
value: 8080
|
||||||
|
# Prompts for a value in the Render Dashboard on creation
|
||||||
|
# (useful for secrets)
|
||||||
|
- key: TMDB_KEY
|
||||||
|
sync: false
|
||||||
@@ -9,3 +9,6 @@ lxml
|
|||||||
slowapi
|
slowapi
|
||||||
curl_cffi
|
curl_cffi
|
||||||
fake-headers
|
fake-headers
|
||||||
|
pycryptodome
|
||||||
|
rich
|
||||||
|
python-multipart
|
||||||
@@ -1,48 +1,83 @@
|
|||||||
from fastapi import FastAPI, HTTPException,Request
|
from fastapi import FastAPI, HTTPException,Request, Form,Cookie
|
||||||
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
|
|
||||||
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 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
|
||||||
# Configure logging
|
from static.configure import CONFIGURE
|
||||||
MYSTERIUS = config.MYSTERIUS
|
from fastapi.templating import Jinja2Templates
|
||||||
DLHD = config.DLHD
|
from Src.API.streamingcommunity import streaming_community
|
||||||
|
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.API.toonitalia import toonitalia
|
||||||
|
from Src.API.realtime import search_catalog as realtime
|
||||||
|
from Src.API.realtime import meta_catalog as meta_catalog_realtime
|
||||||
|
from Src.API.realtime import realtime as streams_realtime
|
||||||
|
from Src.Utilities.dictionaries import STREAM,extra_sources,provider_map
|
||||||
|
from Src.API.epg import tivu, tivu_get,epg_guide,convert_bho_1,convert_bho_2,convert_bho_3
|
||||||
|
from Src.API.extractors.uprot import get_uprot_numbers,generate_uprot_txt
|
||||||
|
import logging
|
||||||
|
from urllib.parse import unquote
|
||||||
|
from curl_cffi.requests import AsyncSession
|
||||||
|
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
|
||||||
|
Global_Proxy = config.Global_Proxy
|
||||||
|
if Global_Proxy == "1":
|
||||||
|
PROXY_CREDENTIALS = env_vars.get('PROXY_CREDENTIALS')
|
||||||
|
|
||||||
|
proxies = {
|
||||||
|
"http": PROXY_CREDENTIALS,
|
||||||
|
"https": PROXY_CREDENTIALS
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
proxies = {}
|
||||||
|
# Configure config
|
||||||
|
SC = config.SC
|
||||||
|
SC_DOMAIN = config.SC_DOMAIN
|
||||||
|
AW = config.AW
|
||||||
|
CB = config.CB
|
||||||
|
GS = config.GS
|
||||||
|
GHD = config.GHD
|
||||||
|
ES = config.ES
|
||||||
|
GF = config.GF
|
||||||
|
GO = config.GO
|
||||||
|
RT = config.RT
|
||||||
|
TI = config.TI
|
||||||
HOST = config.HOST
|
HOST = config.HOST
|
||||||
PORT = int(config.PORT)
|
PORT = int(config.PORT)
|
||||||
HF = config.HF
|
if env_vars.get('PORT_ENV'):
|
||||||
if HF == "1":
|
PORT = int(env_vars.get('PORT_ENV'))
|
||||||
HF = "🤗️"
|
Icon = config.Icon
|
||||||
|
Name = config.Name
|
||||||
#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.
|
||||||
else:
|
|
||||||
HF = ""
|
|
||||||
if MYSTERIUS == "1":
|
|
||||||
from Src.API.cool import cool
|
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
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"
|
||||||
|
#Tells Where to look for static files
|
||||||
|
static = Jinja2Templates(directory="static")
|
||||||
|
|
||||||
MANIFEST = {
|
MANIFEST = {
|
||||||
"id": "org.stremio.mammamia",
|
"id": "org.stremio.mammamia",
|
||||||
"version": "1.1.0",
|
"version": "2.0.0",
|
||||||
"catalogs": [
|
"catalogs": [
|
||||||
{
|
{
|
||||||
"type": "tv",
|
"type": "tv",
|
||||||
"id": "tv_channels",
|
"id": "tv_channels",
|
||||||
"name": "TV Channels",
|
"name": "MammaMia",
|
||||||
"behaviorHints": {
|
"behaviorHints": {
|
||||||
"configurable": True,
|
"configurable": True,
|
||||||
"configurationRequired": True
|
"configurationRequired": True
|
||||||
@@ -54,11 +89,22 @@ MANIFEST = {
|
|||||||
"options": ["Rai", "Mediaset", "Sky", "Euronews", "La7", "Warner Bros", "FIT", "Sportitalia","RSI","DAZN", "Rakuten", "Pluto", "A+E", "Paramount", "Chill"]
|
"options": ["Rai", "Mediaset", "Sky", "Euronews", "La7", "Warner Bros", "FIT", "Sportitalia","RSI","DAZN", "Rakuten", "Pluto", "A+E", "Paramount", "Chill"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'realtime',
|
||||||
|
'type': "series",
|
||||||
|
"name": "realtime",
|
||||||
|
'extra' :[
|
||||||
|
{
|
||||||
|
"name": "search",
|
||||||
|
"isRequired": True
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"resources": ["stream", "catalog", "meta"],
|
"resources": ["stream", "catalog", "meta"],
|
||||||
"types": ["movie", "series", "tv"],
|
"types": ["movie", "series", "tv"],
|
||||||
"name": "Mamma Mia",
|
"name": Name,
|
||||||
"description": "Addon providing HTTPS Streams for Italian Movies, Series, and Live TV! Note that you need to have Kitsu Addon installed in order to watch Anime",
|
"description": "Addon providing HTTPS Streams for Italian Movies, Series, and Live TV! Note that you need to have Kitsu Addon installed in order to watch Anime",
|
||||||
"logo": "https://creazilla-store.fra1.digitaloceanspaces.com/emojis/49647/pizza-emoji-clipart-md.png"
|
"logo": "https://creazilla-store.fra1.digitaloceanspaces.com/emojis/49647/pizza-emoji-clipart-md.png"
|
||||||
}
|
}
|
||||||
@@ -70,15 +116,38 @@ def respond_with(data):
|
|||||||
resp.headers['Access-Control-Allow-Headers'] = '*'
|
resp.headers['Access-Control-Allow-Headers'] = '*'
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
@app.get('/config')
|
|
||||||
def config():
|
|
||||||
return RedirectResponse(url="/")
|
@app.get('/configure',response_class=HTMLResponse)
|
||||||
@app.get('/{config}/manifest.json')
|
def config(request: Request):
|
||||||
def addon_manifest():
|
forwarded_proto = request.headers.get("x-forwarded-proto")
|
||||||
return respond_with(MANIFEST)
|
scheme = forwarded_proto if forwarded_proto else request.url.scheme
|
||||||
|
instance_url = f"{scheme}://{request.url.netloc}"
|
||||||
|
html_content = CONFIGURE.replace("{instance_url}", instance_url)
|
||||||
|
return html_content
|
||||||
|
@app.get('/{config:path}/manifest.json')
|
||||||
|
def addon_manifest(config: str):
|
||||||
|
manifest_copy = MANIFEST.copy()
|
||||||
|
config = base64.b64decode(config).decode('utf-8')
|
||||||
|
if "LIVETV" not in config:
|
||||||
|
if "catalog" in manifest_copy["resources"]:
|
||||||
|
for item in manifest_copy['catalogs']:
|
||||||
|
if item['id'] == 'tv_channels':
|
||||||
|
manifest_copy['catalogs'].remove(item)
|
||||||
|
if not any(manifest_copy['catalogs']):
|
||||||
|
manifest_copy["resources"].remove('catalog')
|
||||||
|
if 'RT' not in config or RT == '0':
|
||||||
|
if "catalog" in manifest_copy["resources"]:
|
||||||
|
for item in manifest_copy['catalogs']:
|
||||||
|
if item['id'] == 'realtime':
|
||||||
|
manifest_copy['catalogs'].remove(item)
|
||||||
|
if not any(manifest_copy['catalogs']):
|
||||||
|
manifest_copy["resources"].remove('catalog')
|
||||||
|
return respond_with(manifest_copy)
|
||||||
|
|
||||||
@app.get('/manifest.json')
|
@app.get('/manifest.json')
|
||||||
def manifest():
|
def manifest():
|
||||||
return RedirectResponse(url="/|SC|LC|SW|/manifest.json")
|
return RedirectResponse(url="/|SC|LC|/manifest.json")
|
||||||
|
|
||||||
@app.get('/', response_class=HTMLResponse)
|
@app.get('/', response_class=HTMLResponse)
|
||||||
def root(request: Request):
|
def root(request: Request):
|
||||||
@@ -88,7 +157,6 @@ def root(request: Request):
|
|||||||
html_content = HTML.replace("{instance_url}", instance_url)
|
html_content = HTML.replace("{instance_url}", instance_url)
|
||||||
return html_content
|
return html_content
|
||||||
async def addon_catalog(type: str, id: str, genre: str = None):
|
async def addon_catalog(type: str, id: str, genre: str = None):
|
||||||
print(f"Received genre parameter: {genre}")
|
|
||||||
if type != "tv":
|
if type != "tv":
|
||||||
raise HTTPException(status_code=404)
|
raise HTTPException(status_code=404)
|
||||||
|
|
||||||
@@ -109,18 +177,26 @@ async def addon_catalog(type: str, id: str, genre: str = None):
|
|||||||
})
|
})
|
||||||
|
|
||||||
return catalogs
|
return catalogs
|
||||||
@app.get('/{config}/catalog/{type}/{id}.json')
|
@app.get('/{config:path}/catalog/{type}/{id}.json')
|
||||||
@limiter.limit("5/second")
|
@limiter.limit("5/second")
|
||||||
async def first_catalog(request: Request,type: str, id: str, genre: str = None):
|
async def first_catalog(request: Request,type: str, id: str, genre: str = None):
|
||||||
catalogs = await addon_catalog(type, id,genre)
|
catalogs = await addon_catalog(type, id,genre)
|
||||||
return respond_with(catalogs)
|
return respond_with(catalogs)
|
||||||
|
|
||||||
@app.get('/{config}/catalog/{type}/{id}/genre={genre}.json')
|
@app.get('/{config:path}/catalog/{type}/{id}/genre={genre}.json')
|
||||||
async def first_catalog(type: str, id: str, genre: str = None):
|
async def first_catalog(type: str, id: str, genre: str = None):
|
||||||
catalogs = await addon_catalog(type, id,genre)
|
catalogs = await addon_catalog(type, id,genre)
|
||||||
return respond_with(catalogs)
|
return respond_with(catalogs)
|
||||||
|
|
||||||
@app.get('/{config}/meta/tv/{id}.json')
|
@app.get('/{config:path}/catalog/{type}/{id}/search={query}.json')
|
||||||
|
async def realtime_catalog(type:str,id:str,query: str = None):
|
||||||
|
if type != 'series':
|
||||||
|
raise HTTPException(status_code=404)
|
||||||
|
catalogs = {"query": query,'cacheMaxAge': 86400,"metas": []}
|
||||||
|
async with AsyncSession(proxies = proxies) as client:
|
||||||
|
catalogs = await realtime(query, catalogs,client)
|
||||||
|
return respond_with(catalogs)
|
||||||
|
@app.get('/{config:path}/meta/tv/{id}.json')
|
||||||
@limiter.limit("20/second")
|
@limiter.limit("20/second")
|
||||||
async def addon_meta(request: Request,id: str):
|
async def addon_meta(request: Request,id: str):
|
||||||
# Find the channel by ID
|
# Find the channel by ID
|
||||||
@@ -128,12 +204,11 @@ async def addon_meta(request: Request,id: str):
|
|||||||
|
|
||||||
if not channel:
|
if not channel:
|
||||||
raise HTTPException(status_code=404, detail="Channel not found")
|
raise HTTPException(status_code=404, detail="Channel not found")
|
||||||
async with AsyncSession() as client:
|
async with AsyncSession(proxies = proxies) as client:
|
||||||
if channel["id"] in convert_bho_1 or channel["id"] in convert_bho_2 or channel["id"] in convert_bho_3:
|
if channel["id"] in convert_bho_1 or channel["id"] in convert_bho_2 or channel["id"] in convert_bho_3:
|
||||||
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"]}'
|
||||||
@@ -156,132 +231,120 @@ async def addon_meta(request: Request,id: str):
|
|||||||
meta['meta']['url'] = channel['url'] # Using the stream URL as a website link
|
meta['meta']['url'] = channel['url'] # Using the stream URL as a website link
|
||||||
return respond_with(meta)
|
return respond_with(meta)
|
||||||
|
|
||||||
|
@app.get('/{config:path}/meta/series/{id}.json')
|
||||||
@app.get('/{config}/stream/{type}/{id}.json')
|
async def addon_meta(request: Request,id: str):
|
||||||
|
meta = {'meta': {'videos':[], 'status': 'Continuing', 'type': 'series', 'id': id}}
|
||||||
|
async with AsyncSession(proxies = proxies) as client:
|
||||||
|
if 'realtime' not in id:
|
||||||
|
raise HTTPException(status_code=404)
|
||||||
|
meta = await meta_catalog_realtime(id,meta,client)
|
||||||
|
return respond_with(meta)
|
||||||
|
@app.get('/{config:path}/stream/{type}/{id}.json')
|
||||||
@limiter.limit("5/second")
|
@limiter.limit("5/second")
|
||||||
async def addon_stream(request: Request,config, type, id,):
|
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:
|
||||||
config_providers = config.split('|')
|
config_providers = config.split('|')
|
||||||
|
elif "%7C" in config:
|
||||||
|
config_providers = config.split('%7C')
|
||||||
provider_maps = {name: "0" for name in provider_map.values()}
|
provider_maps = {name: "0" for name in provider_map.values()}
|
||||||
for provider in config_providers:
|
for provider in config_providers:
|
||||||
if provider in provider_map:
|
if provider in provider_map:
|
||||||
provider_name = provider_map[provider]
|
provider_name = provider_map[provider]
|
||||||
provider_maps[provider_name] = "1"
|
provider_maps[provider_name] = "1"
|
||||||
|
if "MFP[" in config:
|
||||||
|
# Extract proxy data between "MFP(" and ")"
|
||||||
|
mfp_data = config.split("MFP[")[1].split(")")[0]
|
||||||
|
# Split the data by comma to get proxy URL and password
|
||||||
|
MFP_url, MFP_password = mfp_data.split(",")
|
||||||
|
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
|
||||||
|
MFP_CREDENTIALS = [MFP_url, MFP_password]
|
||||||
|
if MFP_url and MFP_password:
|
||||||
|
MFP = "1"
|
||||||
|
|
||||||
async with AsyncSession() as client:
|
else:
|
||||||
|
MFP = "0"
|
||||||
|
MFP_CREDENTIALS = ['','']
|
||||||
|
async with AsyncSession(proxies = proxies) as client:
|
||||||
if type == "tv":
|
if type == "tv":
|
||||||
for channel in STREAM["channels"]:
|
for channel in STREAM["channels"]:
|
||||||
if channel["id"] == id:
|
if channel["id"] == 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"{HF}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"{HF}Server {i} " + channel['title'] + " OKRU",
|
|
||||||
'url': channel_url
|
|
||||||
})
|
|
||||||
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
|
||||||
streams['streams'].append({'title':f"{HF}Server {i} " + channel['title'],'url': item})
|
streams['streams'].append({'title':f"{Icon}Server {i} " + channel['title'],'url': item})
|
||||||
if id in skystreaming:
|
|
||||||
|
|
||||||
urls = await get_skystreaming(id,client)
|
|
||||||
for url in urls:
|
|
||||||
i = i+1
|
|
||||||
Host = urls[url]
|
|
||||||
print(url,Host)
|
|
||||||
streams['streams'].append({'title': f'{HF}Server {i}', '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": "https://skystreaming.guru", "DNT": "1", "Sec-GPC": "1", "Connection": "keep-alive", "Referer": "https://skystreaming.guru/", "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 = await webru(id,"vary",client)
|
|
||||||
streams['streams'].append({'title': f"{HF}Server {i} " + channel['title'],'url': webru_url})
|
|
||||||
if id in webru_dlhd:
|
|
||||||
if DLHD == "1":
|
|
||||||
i = i+1
|
|
||||||
webru_url_2 = await webru(id,"dlhd",client)
|
|
||||||
streams['streams'].append({'title': f"{HF}Server {i} " + channel['title'],'url': webru_url_2})
|
|
||||||
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 "realtime" in id and RT == '1':
|
||||||
|
streams = await streams_realtime(streams,id,client)
|
||||||
|
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:
|
||||||
print(f"Handling movie or series: {id}")
|
logger.info(f"Handling movie or series: {id}")
|
||||||
if "kitsu" in id:
|
if "kitsu" in id:
|
||||||
if provider_maps['ANIMEWORLD'] == "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'{HF}Animeworld {title}', 'url': url})
|
|
||||||
i+=1
|
|
||||||
else:
|
else:
|
||||||
if MYSTERIUS == "1":
|
if provider_maps['STREAMINGCOMMUNITY'] == "1" and SC == "1":
|
||||||
results = await cool(id,client)
|
if provider_maps['SC_MFP'] != "0":
|
||||||
if results:
|
SC_MFP = "1"
|
||||||
print(f"Mysterius Found Results for {id}")
|
|
||||||
for resolution, link in results.items():
|
|
||||||
streams['streams'].append({'title': f'{HF}Mysterious {resolution}', 'url': link})
|
|
||||||
print(provider_maps['STREAMINGCOMMUNITY'])
|
|
||||||
if provider_maps['STREAMINGCOMMUNITY'] == "1":
|
|
||||||
SC_FAST_SEARCH = provider_maps['SC_FAST_SEARCH']
|
|
||||||
url_streaming_community,url_720_streaming_community,quality_sc = await streaming_community(id,client,SC_FAST_SEARCH)
|
|
||||||
if url_streaming_community is not None:
|
|
||||||
print(f"StreamingCommunity Found Results for {id}")
|
|
||||||
if quality_sc == "1080":
|
|
||||||
streams['streams'].append({'title': f'{HF}StreamingCommunity 1080p Max', 'url': url_streaming_community})
|
|
||||||
streams['streams'].append({'title': f'{HF}StreamingCommunity 720p Max', 'url': url_720_streaming_community})
|
|
||||||
else:
|
else:
|
||||||
streams['streams'].append({'title': f'{HF}StreamingCommunity 720p Max', 'url': url_streaming_community})
|
SC_MFP = '0'
|
||||||
if provider_maps['LORDCHANNEL'] == "1":
|
streams = await streaming_community(streams,id,client,SC_MFP,MFP_CREDENTIALS)
|
||||||
url_lordchannel,quality_lordchannel = await lordchannel(id,client)
|
if provider_maps['CB01'] == "1" and CB == "1":
|
||||||
if quality_lordchannel == "FULL HD" and url_lordchannel != None:
|
streams = await cb01(streams,id,MFP,MFP_CREDENTIALS,client)
|
||||||
print(f"LordChannel Found Results for {id}")
|
if provider_maps['GUARDASERIE'] == "1" and GS == "1":
|
||||||
streams['streams'].append({'title': f'{HF}LordChannel 1080p', 'url': url_lordchannel})
|
streams = await guardaserie(streams,id,client)
|
||||||
elif url_lordchannel != None:
|
if provider_maps['GUARDAHD'] == "1" and GHD == "1":
|
||||||
print(f"LordChannel Found Results for {id}")
|
streams = await guardahd(streams,id,client)
|
||||||
streams['streams'].append({'title': f'{HF}LordChannel 720p', 'url': url_lordchannel})
|
if provider_maps['EUROSTREAMING'] == "1" and ES == "1":
|
||||||
if provider_maps['FILMPERTUTTI'] == "1":
|
streams = await eurostreaming(streams,id,client,MFP,MFP_CREDENTIALS)
|
||||||
url_filmpertutti = await filmpertutti(id,client)
|
if provider_maps['GUARDAFLIX'] == "1" and GF == "1":
|
||||||
if url_filmpertutti is not None:
|
streams = await guardaflix(streams,id,client,MFP,MFP_CREDENTIALS)
|
||||||
print(f"Filmpertutti Found Results for {id}")
|
if provider_maps['GUARDOSERIE'] == "1" and GO == "1":
|
||||||
streams['streams'].append({'title': 'Filmpertutti', 'url': url_filmpertutti})
|
streams = await guardoserie(streams,id,client,MFP,MFP_CREDENTIALS)
|
||||||
if provider_maps['TANTIFILM'] == "1":
|
if provider_maps['REALTIME'] == '1' and RT == '1':
|
||||||
TF_FAST_SEARCH = provider_maps['TF_FAST_SEARCH']
|
streams = await streams_realtime(streams,id,client)
|
||||||
url_tantifilm = await tantifilm(id,client,TF_FAST_SEARCH)
|
if provider_maps['TOONITALIA'] == '1' and TI == '1':
|
||||||
if url_tantifilm:
|
streams = await toonitalia(streams,id,client,MFP,MFP_CREDENTIALS)
|
||||||
print(f"TantiFilm Found Results for {id}")
|
return respond_with(streams)
|
||||||
if not isinstance(url_tantifilm, str):
|
|
||||||
for title, url in url_tantifilm.items():
|
|
||||||
streams['streams'].append({'title': f'{HF}Tantifilm {title}', 'url': url, 'behaviorHints': {'proxyHeaders': {"request": {"Referer": "https://d000d.com/"}}, 'notWebReady': True}})
|
|
||||||
else:
|
|
||||||
streams['streams'].append({'title': f'{HF}Tantifilm', 'url': url_tantifilm, 'behaviorHints': {'proxyHeaders': {"request": {"Referer": "https://d000d.com/"}}, 'notWebReady': True}})
|
|
||||||
if provider_maps['STREAMINGWATCH'] == "1":
|
|
||||||
url_streamingwatch = await streamingwatch(id,client)
|
|
||||||
if url_streamingwatch:
|
|
||||||
print(f"Streaming Watch Found Results for {id}")
|
|
||||||
streams['streams'].append({'title': f'{HF}StreamingWatch 720p', 'url': url_streamingwatch})
|
|
||||||
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)
|
||||||
|
|
||||||
|
@app.get('/uprot')
|
||||||
|
async def uprot(request: Request):
|
||||||
|
async with AsyncSession(proxies = proxies) as client:
|
||||||
|
image, cookies = await get_uprot_numbers(client)
|
||||||
|
response = static.TemplateResponse('uprot.html',{'request':request,"image_url": image})
|
||||||
|
response.set_cookie(key='PHPSESSID', value=cookies['PHPSESSID'],httponly=True)
|
||||||
|
|
||||||
|
return response
|
||||||
|
@app.post("/uprot")
|
||||||
|
async def execute_uprot(request: Request,user_input = Form(...),PHPSESSID: str = Cookie(None)):
|
||||||
|
async with AsyncSession(proxies = proxies) as client:
|
||||||
|
cookies = {
|
||||||
|
'PHPSESSID': PHPSESSID
|
||||||
|
}
|
||||||
|
status = await generate_uprot_txt(user_input,cookies,client)
|
||||||
|
if status == True:
|
||||||
|
response = static.TemplateResponse('uprot.html',{'request':request,"image_url": 'https://tinyurl.com/doneokdone'})
|
||||||
|
elif status == False:
|
||||||
|
return static.TemplateResponse('uprot.html',{'request':request,"image_url": 'https://tinyurl.com/tryagaindumb'})
|
||||||
|
|
||||||
if __name__ == '__main__':
|
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)
|
||||||
@@ -0,0 +1,336 @@
|
|||||||
|
# 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;
|
||||||
|
}
|
||||||
|
.provider-group input[type="checkbox"][id$="_mfp"] {
|
||||||
|
margin-left: 2.2vh;
|
||||||
|
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; /* Initially hidden */
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre-wrap; /* Preserves whitespace and wraps text */
|
||||||
|
overflow-wrap: break-word; /* Breaks long words to prevent overflow */
|
||||||
|
word-wrap: break-word; /* For older browsers */
|
||||||
|
max-width: 100%; /* Ensures it doesn't exceed the container width */
|
||||||
|
border: 1px solid #ccc; /* Optional: Add a border for visibility */
|
||||||
|
}
|
||||||
|
#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">v2.1.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 <br>Select the box with this icon if you want to enable MFP for that source<br></p>
|
||||||
|
<h3 class="gives">Select Providers:</h3>
|
||||||
|
<form class="pure-form" id="provider-form">
|
||||||
|
<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 🕵️♂️
|
||||||
|
<input type="checkbox" id="streamingcommunity_mfp" checked> 🕵️♂️
|
||||||
|
</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="realtime" class="provider-label">
|
||||||
|
<input type="checkbox" id="toonitalia"> Toonitalia
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="provider-group">
|
||||||
|
<label for="realtime" class="provider-label">
|
||||||
|
<input type="checkbox" id="realtime"> Realtime
|
||||||
|
</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",
|
||||||
|
"animeworld": "AW",
|
||||||
|
"livetv": "LIVETV",
|
||||||
|
"cb01": "CB",
|
||||||
|
"guardaserie": "GS",
|
||||||
|
"guardahd": "GHD",
|
||||||
|
"guardoserie": "GO",
|
||||||
|
"guardaflix": "GF",
|
||||||
|
"eurostreaming": "ES",
|
||||||
|
"realtime": "RT",
|
||||||
|
"toonitalia": "TI",
|
||||||
|
"streamingcommunity_mfp": "SC_MFP",
|
||||||
|
"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>
|
||||||
|
"""
|
||||||
+120
-57
@@ -20,7 +20,7 @@ HTML = """
|
|||||||
font-size: 2.2vh;
|
font-size: 2.2vh;
|
||||||
font-family: 'Open Sans', Arial, sans-serif;
|
font-family: 'Open Sans', Arial, sans-serif;
|
||||||
color: white;
|
color: white;
|
||||||
background: url('https://i.postimg.cc/m2ZqvpZj/italian-seamless-free-vector-pattern3.png') center center repeat;
|
background: url('https://i.postimg.cc/ry3p76HY/italian-seamless-free-vector-pattern3.png') center center repeat;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
@@ -75,6 +75,7 @@ HTML = """
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
}
|
}
|
||||||
.provider-group label {
|
.provider-group label {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -85,21 +86,16 @@ 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;
|
||||||
height: 4vh;
|
height: 4vh;
|
||||||
}
|
}
|
||||||
|
.provider-group input[type="checkbox"][id$="_mfp"] {
|
||||||
|
margin-left: 2.2vh;
|
||||||
|
width: 4vh;
|
||||||
|
height: 4vh;
|
||||||
|
}
|
||||||
.parent-container {
|
.parent-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -146,9 +142,13 @@ HTML = """
|
|||||||
padding: 2vh;
|
padding: 2vh;
|
||||||
background: rgba(255, 255, 255, 0.2);
|
background: rgba(255, 255, 255, 0.2);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
display: none;
|
display: none; /* Initially hidden */
|
||||||
text-align: left;
|
text-align: left;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap; /* Preserves whitespace and wraps text */
|
||||||
|
overflow-wrap: break-word; /* Breaks long words to prevent overflow */
|
||||||
|
word-wrap: break-word; /* For older browsers */
|
||||||
|
max-width: 100%; /* Ensures it doesn't exceed the container width */
|
||||||
|
border: 1px solid #ccc; /* Optional: Add a border for visibility */
|
||||||
}
|
}
|
||||||
#generateManifestButton {
|
#generateManifestButton {
|
||||||
background: #4CAF50;
|
background: #4CAF50;
|
||||||
@@ -180,46 +180,21 @@ HTML = """
|
|||||||
<img src="https://creazilla-store.fra1.digitaloceanspaces.com/emojis/49647/pizza-emoji-clipart-md.png" alt="Logo">
|
<img src="https://creazilla-store.fra1.digitaloceanspaces.com/emojis/49647/pizza-emoji-clipart-md.png" alt="Logo">
|
||||||
</div>
|
</div>
|
||||||
<h1 class="name">Mamma Mia</h1>
|
<h1 class="name">Mamma Mia</h1>
|
||||||
<h2 class="version">v1.1.0</h2>
|
<h2 class="version">v2.1.0</h2>
|
||||||
<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. <br> Filmpertutti and Tantifilm won't work if you are not using a local (on your PC) instance.</p>
|
<p class="description">🕵️♂️ = Mediaflowproxy might be needed <br>Select the box with this icon if you want to enable MFP for that source<br></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="streamingcommunity" class="provider-label">
|
<label for="guardoserie" class="provider-label">
|
||||||
<input type="checkbox" id="streamingcommunity"> StreamingCommunity
|
<input type="checkbox" id="guardoserie"> Guardoserie
|
||||||
</label>
|
|
||||||
<span class="fast-search">
|
|
||||||
<label for="fast_search_sc">
|
|
||||||
<input type="checkbox" id="fast_search_sc"> Fast Search
|
|
||||||
</label>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="provider-group">
|
|
||||||
<label for="lordchannel" class="provider-label">
|
|
||||||
<input type="checkbox" id="lordchannel"> LordChannel
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="provider-group">
|
<div class="provider-group">
|
||||||
<label for="streamingwatch" class="provider-label">
|
<label for="guardaflix" class="provider-label">
|
||||||
<input type="checkbox" id="streamingwatch"> StreamingWatch
|
<input type="checkbox" id="guardaflix"> Guardaflix
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="provider-group">
|
|
||||||
<label for="tantifilm" class="provider-label">
|
|
||||||
<input type="checkbox" id="tantifilm"> Tantifilm
|
|
||||||
</label>
|
|
||||||
<span class="fast-search">
|
|
||||||
<label for="fast_search_tf">
|
|
||||||
<input type="checkbox" id="fast_search_tf"> Fast Search
|
|
||||||
</label>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="provider-group">
|
|
||||||
<label for="filmpertutti" class="provider-label">
|
|
||||||
<input type="checkbox" id="filmpertutti"> Filmpertutti
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="provider-group">
|
<div class="provider-group">
|
||||||
@@ -227,39 +202,127 @@ HTML = """
|
|||||||
<input type="checkbox" id="animeworld"> Animeworld
|
<input type="checkbox" id="animeworld"> Animeworld
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</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 🕵️♂️
|
||||||
|
<input type="checkbox" id="streamingcommunity_mfp" checked> 🕵️♂️
|
||||||
|
</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="realtime" class="provider-label">
|
||||||
|
<input type="checkbox" id="toonitalia"> Toonitalia
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="provider-group">
|
||||||
|
<label for="realtime" class="provider-label">
|
||||||
|
<input type="checkbox" id="realtime"> Realtime
|
||||||
|
</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>
|
</form>
|
||||||
<button id="generateManifestButton">Generate Link</button>
|
<button id="generateManifestButton">Generate Manifest</button>
|
||||||
<button id="installButton">INSTALL</button>
|
|
||||||
<div id="manifestBox"></div>
|
<div id="manifestBox"></div>
|
||||||
|
<button id="installButton">Install in Stremio</button>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<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() {
|
function generateManifest() {
|
||||||
let manifest = "|";
|
let manifest = "|";
|
||||||
const providers = {
|
const providers = {
|
||||||
"streamingcommunity": "SC",
|
"streamingcommunity": "SC",
|
||||||
"fast_search_sc": "SC_FS",
|
"animeworld": "AW",
|
||||||
"lordchannel": "LC",
|
"livetv": "LIVETV",
|
||||||
"streamingwatch": "SW",
|
"cb01": "CB",
|
||||||
"tantifilm": "TF",
|
"guardaserie": "GS",
|
||||||
"fast_search_tf": "TF_FS",
|
"guardahd": "GHD",
|
||||||
"filmpertutti": "FT",
|
"guardoserie": "GO",
|
||||||
"animeworld": "AW"
|
"guardaflix": "GF",
|
||||||
|
"eurostreaming": "ES",
|
||||||
|
"realtime": "RT",
|
||||||
|
"toonitalia": "TI",
|
||||||
|
"streamingcommunity_mfp": "SC_MFP",
|
||||||
|
"mediaflowproxy": "MFP"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Loop through providers and add selected ones to the manifest
|
||||||
for (const id in providers) {
|
for (const id in providers) {
|
||||||
if (document.getElementById(id).checked) {
|
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] + "|";
|
manifest += providers[id] + "|";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const instanceUrl = "{instance_url}"; // Keep http in the URL
|
}
|
||||||
const manifestUrl = instanceUrl + "/" + manifest + "/" + "manifest.json";
|
const encodedProviders = btoa(manifest);
|
||||||
|
const instanceUrl = "{instance_url}"; // Replace with your instance URL
|
||||||
|
const manifestUrl = instanceUrl + "/" + encodedProviders + "/" + "manifest.json";
|
||||||
return manifestUrl;
|
return manifestUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate manifest URL and display it
|
||||||
document.getElementById('generateManifestButton').addEventListener('click', function() {
|
document.getElementById('generateManifestButton').addEventListener('click', function() {
|
||||||
const manifestUrl = generateManifest();
|
const manifestUrl = generateManifest();
|
||||||
document.getElementById("manifestBox").style.display = "block";
|
const manifestBox = document.getElementById("manifestBox");
|
||||||
document.getElementById("manifestBox").innerText = manifestUrl;
|
manifestBox.style.display = "block";
|
||||||
|
manifestBox.innerText = manifestUrl;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Install the manifest in Stremio
|
||||||
document.getElementById('installButton').addEventListener('click', function() {
|
document.getElementById('installButton').addEventListener('click', function() {
|
||||||
let manifestUrl = generateManifest();
|
let manifestUrl = generateManifest();
|
||||||
manifestUrl = manifestUrl.replace("http://", "");
|
manifestUrl = manifestUrl.replace("http://", "");
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
|
||||||
|
<!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;
|
||||||
|
}
|
||||||
|
#captcha {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
.captchaimg img {
|
||||||
|
width: 80%;
|
||||||
|
height: auto;
|
||||||
|
object-fit: contain;
|
||||||
|
display: block;
|
||||||
|
margin: 0 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;
|
||||||
|
}
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
form {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
form:hover {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="captcha">
|
||||||
|
<div class="logo">
|
||||||
|
<img src="https://creazilla-store.fra1.digitaloceanspaces.com/emojis/49647/pizza-emoji-clipart-md.png" alt="Logo">
|
||||||
|
</div>
|
||||||
|
<h1 class="name">Uprot Captcha</h1>
|
||||||
|
<h2 class="version">Per abilitare MaxStream</h2>
|
||||||
|
<div id="additionalText">
|
||||||
|
<h2>Inserire i numeri in foto per abilitare la fonte MaxStream per la durata di un giorno<br> https://github.com/UrloMythus/MammaMia/</h2>
|
||||||
|
<div class="captchaimg">
|
||||||
|
<img src="{{ image_url }}" alt="captcha1">
|
||||||
|
</div>
|
||||||
|
<form id = 'form' action="/uprot" method="post">
|
||||||
|
<input type="text" name="user_input" required>
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Merge remote URLs into local config.json, replacing ONLY the "url" lines.
|
||||||
|
- Scarica config.json remoto (raw GitHub).
|
||||||
|
- Per ogni sito in "Siti", segue i redirect e trova l'URL finale.
|
||||||
|
- Apre il config.json locale come testo, trova le righe "url" relative ai siti
|
||||||
|
e sostituisce SOLO il valore dentro le virgolette, preservando tutto il resto.
|
||||||
|
- Crea un backup del config.json locale prima di sovrascriverlo.
|
||||||
|
"""
|
||||||
|
from pathlib import Path
|
||||||
|
from datetime import datetime
|
||||||
|
import shutil
|
||||||
|
import re
|
||||||
|
import requests
|
||||||
|
import urllib3
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
|
# --- CONFIGURAZIONE ---
|
||||||
|
REMOTE_RAW_URL = "https://raw.githubusercontent.com/UrloMythus/MammaMia/main/config.json"
|
||||||
|
LOCAL_CONFIG_PATH = Path("config.json")
|
||||||
|
HEADERS = {"User-Agent": "Mozilla/5.0 (compatible; DomainMerger/1.0)"}
|
||||||
|
REQUEST_TIMEOUT = 12
|
||||||
|
# -----------------------
|
||||||
|
|
||||||
|
def backup_file(path: Path) -> Path | None:
|
||||||
|
if not path.exists():
|
||||||
|
return None
|
||||||
|
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
bak = path.with_name(f"{path.name}.bak_{ts}")
|
||||||
|
shutil.copy2(path, bak)
|
||||||
|
return bak
|
||||||
|
|
||||||
|
def normalize_url(u: str) -> str:
|
||||||
|
parsed = urlparse(u)
|
||||||
|
scheme = parsed.scheme if parsed.scheme else "https"
|
||||||
|
netloc = parsed.netloc or parsed.path
|
||||||
|
return f"{scheme}://{netloc}"
|
||||||
|
|
||||||
|
def follow_redirect(url: str) -> str | None:
|
||||||
|
if not url.startswith(("http://", "https://")):
|
||||||
|
test = "http://" + url
|
||||||
|
else:
|
||||||
|
test = url
|
||||||
|
try:
|
||||||
|
r = requests.get(test, allow_redirects=True, headers=HEADERS,
|
||||||
|
timeout=REQUEST_TIMEOUT, verify=False)
|
||||||
|
return normalize_url(r.url)
|
||||||
|
except requests.RequestException as e:
|
||||||
|
print(f"⚠️ Redirect fallito per '{url}': {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def load_remote_urls(remote_raw_url: str) -> dict:
|
||||||
|
"""Scarica il JSON remoto e ritorna mappa site_key -> url (o None se mancante)."""
|
||||||
|
try:
|
||||||
|
r = requests.get(remote_raw_url, headers=HEADERS, timeout=REQUEST_TIMEOUT)
|
||||||
|
r.raise_for_status()
|
||||||
|
remote_json = r.json()
|
||||||
|
except Exception as e:
|
||||||
|
raise RuntimeError(f"Impossibile scaricare/parsing remote config: {e}")
|
||||||
|
|
||||||
|
siti = remote_json.get("Siti", {})
|
||||||
|
result = {}
|
||||||
|
for site_key, site_info in siti.items():
|
||||||
|
url = site_info.get("url")
|
||||||
|
if url:
|
||||||
|
result[site_key] = url
|
||||||
|
return result
|
||||||
|
|
||||||
|
def merge_remote_into_local(remote_map: dict, local_path: Path):
|
||||||
|
if not local_path.exists():
|
||||||
|
raise FileNotFoundError(f"File locale non trovato: {local_path}")
|
||||||
|
|
||||||
|
# backup
|
||||||
|
bak = backup_file(local_path)
|
||||||
|
if bak:
|
||||||
|
print(f"📦 Backup creato: {bak.name}")
|
||||||
|
|
||||||
|
text = local_path.read_text(encoding="utf-8")
|
||||||
|
lines = text.splitlines()
|
||||||
|
|
||||||
|
# regex: match apertura blocco sito es. "CB01":{
|
||||||
|
site_open_re = re.compile(r'^\s*"(?P<site>[^"]+)"\s*:\s*\{\s*$')
|
||||||
|
|
||||||
|
# regex per trovare esattamente la riga "url": "valore" preservando indentazione e virgola finale
|
||||||
|
url_line_re = re.compile(r'^(\s*)"url"\s*:\s*"([^"]*)"( *)(,?)\s*$')
|
||||||
|
|
||||||
|
current_site = None
|
||||||
|
updated_lines = []
|
||||||
|
changes = []
|
||||||
|
|
||||||
|
for idx, line in enumerate(lines):
|
||||||
|
site_match = site_open_re.match(line)
|
||||||
|
if site_match:
|
||||||
|
current_site = site_match.group("site")
|
||||||
|
updated_lines.append(line)
|
||||||
|
continue
|
||||||
|
|
||||||
|
url_match = url_line_re.match(line)
|
||||||
|
if url_match:
|
||||||
|
indent = url_match.group(1)
|
||||||
|
old_value = url_match.group(2)
|
||||||
|
trailing_space = url_match.group(3) or ""
|
||||||
|
trailing_comma = url_match.group(4) or ""
|
||||||
|
site_key = current_site or "unknown"
|
||||||
|
|
||||||
|
# se il sito esiste nella mappa remota, proviamo ad aggiornare
|
||||||
|
remote_url = remote_map.get(site_key)
|
||||||
|
if remote_url:
|
||||||
|
final_url = follow_redirect(remote_url)
|
||||||
|
if final_url and final_url != normalize_url(old_value):
|
||||||
|
# sostituisco solo la parte tra virgolette
|
||||||
|
new_line = f'{indent}"url": "{final_url}"{trailing_space}{trailing_comma}'
|
||||||
|
updated_lines.append(new_line)
|
||||||
|
changes.append((site_key, old_value, final_url))
|
||||||
|
print(f"✅ {site_key}: {old_value} → {final_url}")
|
||||||
|
else:
|
||||||
|
# nessuna modifica (redirect fallito o identico)
|
||||||
|
updated_lines.append(line)
|
||||||
|
print(f"ℹ️ {site_key}: nessuna modifica per '{old_value}'")
|
||||||
|
else:
|
||||||
|
# il sito non è nella lista remota: non tocchiamo la riga
|
||||||
|
updated_lines.append(line)
|
||||||
|
print(f"ℹ️ {site_key}: nessun URL remoto per questo sito, riga lasciata invariata")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# linea normale
|
||||||
|
updated_lines.append(line)
|
||||||
|
|
||||||
|
# Scrivo solo se ci sono cambiamenti (ma anche se non ci sono, sovrascrivo per coerenza)
|
||||||
|
new_text = "\n".join(updated_lines)
|
||||||
|
# preserva newline finale se il file originale ce l'aveva
|
||||||
|
if text.endswith("\n") and not new_text.endswith("\n"):
|
||||||
|
new_text += "\n"
|
||||||
|
|
||||||
|
local_path.write_text(new_text, encoding="utf-8")
|
||||||
|
print("💾 Merge completato: solo le righe 'url' del file locale sono state eventualmente aggiornate.")
|
||||||
|
if not changes:
|
||||||
|
print("🔎 Nessun cambiamento effettuato.")
|
||||||
|
else:
|
||||||
|
print("📄 Riepilogo modifiche:")
|
||||||
|
for s, old, new in changes:
|
||||||
|
print(f" - {s}: {old} → {new}")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
remote_map = load_remote_urls(REMOTE_RAW_URL)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Errore: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
merge_remote_into_local(remote_map, LOCAL_CONFIG_PATH)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Errore durante il merge: {e}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"devCommand": "uvicorn run:app --host 0.0.0.0 --port 8080",
|
||||||
|
"builds": [
|
||||||
|
{
|
||||||
|
"src": "run.py",
|
||||||
|
"use": "@vercel/python"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"src": "/(.*)",
|
||||||
|
"dest": "run.py"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user