Prepare Release, Update docs with new features & Bug fixes (#303)

* Refactor Kodi addon setup to input code after expire

* Use `parse.urljoin` for URL construction

* Add error handling for cache setup and request response

* Fix WebDAV auth configuration and enhance README setup guide

* Update color values for Kodi Setup visibility

* Refactor kodi request cache

* Update README and home page with new features
This commit is contained in:
Mohamed Zumair
2024-09-28 19:45:16 +05:30
committed by GitHub
parent 64773baecb
commit db7fab8b40
17 changed files with 121 additions and 81 deletions
+12 -2
View File
@@ -26,7 +26,7 @@
![Media Fusion Streams](resources/images/ss2.png?raw=true)
- **Scraper Support**:
- **Advanced Scraper Support**:
- 🏎️ **Formula Racing**: Exclusive scraping from TorrentGalaxy for all your racing needs.
- 🥊 **Fighting Sports**: Catch up on all the latest fighting sports content from UFC and WWE.
- 🏈🏀⚾⚽🏒🏉🎾 **American Football, Basketball, Baseball, Football, Hockey, Rugby/AFL, and Other Sports**: Now all scraping through sport-video.org.ua for catchup videos.
@@ -35,8 +35,11 @@
- 🌟 **TamilBlasters**: Dedicated access to an extensive library of regional content.
- 📺 **TamilUltra & NowMeTV**: Get the best of Live TV channels right at your fingertips.
- 🔄 **Prowlarr Integration**: Supercharge your scraping streams with Prowlarr's powerful integration.
- 🔍 **Advanced Prowlarr Integration**: Improved Prowlarr feed scraping for more comprehensive content discovery with latest updates.
- 🌊 **Torrentio/KnightCrawler Streams**: Optional scraping streams directly from Torrentio/KnightCrawler streams for even more variety.
- 🔍 **Zilean DMM Search**: Search for movies and TV shows with [Zilean DMM](https://github.com/iPromKnight/zilean) for a cached debrid contents.
- 🔍 **Zilean DMM Search**: Search for movies and TV shows with [Zilean DMM](https://github.com/iPromKnight/zilean) for cached debrid contents.
- 📺 **MPD DRM Scraping**: Scraping MPD & Support streaming functionality with MediaFlow MPD DRM support.
- **Additional Features**:
- 🔒 **API Security**: Fortify your self-hosted API with a password to prevent unauthorized access.
@@ -48,6 +51,13 @@
-**Manual Scraper Triggering UI**: Manage your scraping sources with a manual trigger UI for a more hands-on approach.
- 🗑️ **Delete Watchlist**: Delete your watchlist from the stremio for quick control over your content.
- 🔍 **Prowlarr Indexer Support**: Use [MediaFusion as an indexer in Prowlarr](/resources/yaml/mediafusion.yaml) for searching movies and TV shows with Radarr and Sonarr.
- 🔞 **Parental Controls**: Filter content based on nudity and certification ratings.
- 🎬 **IMDb Integration**: Display IMDb ratings with the logo for quick quality assessment.
- 🕰️ **Sports Event Timing**: View the time for sports events directly on the poster for better planning.
- 🌐 **MediaFlow Proxy**: Support for MediaFlow Proxy for Debrid and Live streams, enhancing accessibility.
- 🎥 **RPDB Posters**: RPDB posters support with fallback to MediaFusion posters.
- 📥 **Browser Download Support**: Support for downloading video files from debrid services directly in the browser.
- 🚫 **Support DMCA Take Down**: Torrent blocking feature for DMCA compliance.
## 🚀 Installation Guide
+2 -2
View File
@@ -2,7 +2,7 @@ version: '3.8'
services:
mediafusion:
image: mhdzumair/mediafusion:beta
image: mhdzumair/mediafusion:4.0.0
ports:
- "8000:8000"
env_file:
@@ -41,7 +41,7 @@ services:
- "6379:6379"
dramatiq-worker:
image: mhdzumair/mediafusion:beta
image: mhdzumair/mediafusion:4.0.0
command: ["pipenv", "run", "dramatiq", "api.task", "-p", "1", "-t", "1", "--queues", "scrapy"]
env_file:
- .env
+2 -2
View File
@@ -19,7 +19,7 @@ spec:
spec:
containers:
- name: mediafusion
image: mhdzumair/mediafusion:v3.9.15
image: mhdzumair/mediafusion:v4.0.0
ports:
- containerPort: 8000
resources:
@@ -124,7 +124,7 @@ spec:
spec:
containers:
- name: dramatiq-worker
image: mhdzumair/mediafusion:v3.9.15
image: mhdzumair/mediafusion:v4.0.0
command: ["pipenv", "run", "dramatiq", "api.task", "-p", "1", "-t", "1"]
env:
- name: HOST_URL
+10 -4
View File
@@ -57,10 +57,16 @@ Configure MediaFusion:
1. Open MediaFusion config page.
2. Select "qBittorrent - WebDav" as the streaming provider.
3. Fill in WebUI and WebDAV URLs (use local addresses for a local setup).
4. Enter WebDAV credentials if set; leave blank if not.
5. Adjust seeding settings and 'Play Video After Download' percentage.
6. Save and start streaming through Stremio.
3. Get the Docker IP address using following command:
```bash
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container_name>
```
4. Fill in WebUI and WebDAV URLs:
- If running MediaFusion locally (not in Docker): Use `http://localhost:8080`
- If running MediaFusion in Docker: Use `http://<docker_ip>:8080`, where `<docker_ip>` is the IP obtained in step 3.
5. Enter WebDAV credentials if set; leave blank if not.
6. Adjust seeding settings and 'Play Video After Download' percentage.
7. Save and start streaming through Stremio.
Refer to the screenshot below for a visual guide:
![MediaFusion qBittorrent-WebDAV Configuration](/deployment/qbittorrent-webdav/ss.png)
@@ -13,6 +13,6 @@
DAV On
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
# The authentication directives will be added here by the entrypoint script
</Directory>
</VirtualHost>
+3 -1
View File
@@ -29,10 +29,12 @@ HTPASSWD_PATH="/etc/apache2/.htpasswd"
# Check if .htpasswd file exists and configure basic auth for WebDAV accordingly
if [ -f "$HTPASSWD_PATH" ]; then
echo "Basic auth password file found. Configuring WebDAV with basic auth."
sed -i '/<Directory \/downloads>/,/<\/Directory>/{/Require /d}' /etc/apache2/conf.d/000-default.conf
sed -i '/<Directory \/downloads>/,/<\/Directory>/{/AuthType/d;/AuthName/d;/AuthUserFile/d;/Require/d}' /etc/apache2/conf.d/000-default.conf
sed -i '/<Directory \/downloads>/a \\tAuthType Basic\n\tAuthName "WebDAV"\n\tAuthUserFile '"$HTPASSWD_PATH"'\n\tRequire valid-user' /etc/apache2/conf.d/000-default.conf
else
echo "No basic auth password file found. Configuring WebDAV without basic auth."
sed -i '/<Directory \/downloads>/,/<\/Directory>/{/AuthType/d;/AuthName/d;/AuthUserFile/d;/Require/d}' /etc/apache2/conf.d/000-default.conf
sed -i '/<Directory \/downloads>/a \\tRequire all granted' /etc/apache2/conf.d/000-default.conf
fi
# start supervisord
Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 KiB

After

Width:  |  Height:  |  Size: 344 KiB

+1 -1
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.mediafusion" version="3.9.15" name="MediaFusion" provider-name="Mohamed Zumair">
<addon id="plugin.video.mediafusion" version="4.0.0" name="MediaFusion" provider-name="Mohamed Zumair">
<requires>
<import addon="xbmc.python" version="3.0.0"/>
<import addon="xbmc.metadata" version="2.1.0"/>
@@ -104,6 +104,7 @@ class CustomSettingsWindow(xbmcgui.WindowXMLDialog):
response = requests.post(
urljoin(self.base_url, "kodi/generate_setup_code"), json=data
)
response.raise_for_status()
data = response.json()
code = data["code"]
qr_code_url = data["qr_code_url"]
+21 -6
View File
@@ -19,7 +19,7 @@ from .utils import (
def list_categories():
manifest_data = fetch_data(f"{BASE_URL}/{SECRET_STR}/manifest.json")
manifest_data = fetch_data(parse.urljoin(BASE_URL, f"/{SECRET_STR}/manifest.json"))
if not manifest_data:
return
@@ -106,7 +106,10 @@ def process_videos(videos, action, catalog_type, catalog_id):
def list_catalog(params):
log(f"Loading {params['catalog_type']} videos...", xbmc.LOGINFO)
skip = int(params.get("skip", 0))
url = f"{BASE_URL}/{SECRET_STR}/catalog/{params['catalog_type']}/{params['catalog_id']}/skip={skip}.json"
url = parse.urljoin(
BASE_URL,
f"/{SECRET_STR}/catalog/{params['catalog_type']}/{params['catalog_id']}/skip={skip}.json",
)
force_refresh = params.get("force_refresh", False)
response = fetch_data(url, force_refresh)
if not response:
@@ -145,7 +148,10 @@ def search_catalog(params):
if not search_query:
return
url = f"{BASE_URL}/{SECRET_STR}/catalog/{params['catalog_type']}/{params['catalog_id']}/search={search_query}.json"
url = parse.urljoin(
BASE_URL,
f"/{SECRET_STR}/catalog/{params['catalog_type']}/{params['catalog_id']}/search={search_query}.json",
)
force_refresh = params.get("force_refresh", False)
response = fetch_data(url, force_refresh)
if not response:
@@ -169,7 +175,10 @@ def search_catalog(params):
def list_seasons(params):
url = f"{BASE_URL}/{SECRET_STR}/meta/{params['catalog_type']}/{params['video_id']}.json"
url = parse.urljoin(
BASE_URL,
f"/{SECRET_STR}/meta/{params['catalog_type']}/{params['video_id']}.json",
)
force_refresh = params.get("force_refresh", False)
response = fetch_data(url, force_refresh)
if not response:
@@ -233,7 +242,10 @@ def list_seasons(params):
def list_episodes(params):
url = f"{BASE_URL}/{SECRET_STR}/meta/{params['catalog_type']}/{params['video_id']}.json"
url = parse.urljoin(
BASE_URL,
f"/{SECRET_STR}/meta/{params['catalog_type']}/{params['video_id']}.json",
)
force_refresh = params.get("force_refresh", False)
response = fetch_data(url, force_refresh)
if not response:
@@ -299,7 +311,10 @@ def list_episodes(params):
def get_streams(params):
url = f"{BASE_URL}/{SECRET_STR}/stream/{params['catalog_type']}/{params['video_id']}.json"
url = parse.urljoin(
BASE_URL,
f"/{SECRET_STR}/stream/{params['catalog_type']}/{params['video_id']}.json",
)
force_refresh = params.get("force_refresh", False)
response = fetch_data(url, force_refresh)
if not response:
+36 -7
View File
@@ -1,3 +1,4 @@
import sqlite3
import sys
from urllib import parse
@@ -13,13 +14,6 @@ ADDON = xbmcaddon.Addon()
ADDON_PATH = sys.argv[0]
ADDON_ID = ADDON.getAddonInfo("id")
# Initialize requests_cache with CachedSession
cache_file = xbmcvfs.translatePath(
f"special://profile/addon_data/{ADDON_ID}/cache.sqlite"
)
session = requests_cache.CachedSession(
cache_name=cache_file, backend="sqlite", cache_control=True
)
BASE_URL = ADDON.getSetting("base_url")
SECRET_STR = ADDON.getSetting("secret_string")
@@ -37,10 +31,13 @@ if not SECRET_STR:
def remove_cache(url):
session = get_request_session()
session.cache.delete_url(url)
def fetch_data(url, force_refresh=False):
session = get_request_session()
if force_refresh:
with session.cache_disabled():
response = session.get(url)
@@ -120,3 +117,35 @@ def is_elementum_installed_and_enabled():
return True
except Exception:
return False
def get_request_session():
# Initialize requests_cache with CachedSession
cache_file = xbmcvfs.translatePath(
f"special://profile/addon_data/{ADDON_ID}/cache.sqlite"
)
try:
session = requests_cache.CachedSession(
cache_name=cache_file, backend="sqlite", cache_control=True
)
except sqlite3.OperationalError as e:
xbmc.log(f"Failed to setup cache: {e}", xbmc.LOGERROR)
try:
fallback_cache_file = xbmcvfs.translatePath(
f"special://temp/{ADDON_ID}_cache.sqlite"
)
session = requests_cache.CachedSession(
cache_name=fallback_cache_file, backend="sqlite", cache_control=True
)
xbmc.log(
f"Using fallback cache location: {fallback_cache_file}", xbmc.LOGINFO
)
except sqlite3.OperationalError:
xbmc.log("Fallback to in-memory cache", xbmc.LOGWARNING)
session = requests_cache.CachedSession(
cache_name="mediafusion_request", backend="memory", cache_control=True
)
xbmcgui.Dialog().notification(
"MediaFusion", f"Cache setup issue: {str(e)}", xbmcgui.NOTIFICATION_WARNING
)
return session
@@ -33,7 +33,6 @@
<height>50</height>
<font>font60</font>
<label>MediaFusion Settings</label>
<textcolor>FF00FFFF</textcolor>
<align>center</align>
</control>
@@ -44,7 +43,7 @@
<width>50</width>
<height>50</height>
<focusedcolor>FFFFFF00</focusedcolor>
<texturefocus colordiffuse="FF00FFFF">triangle-left.png</texturefocus>
<texturefocus colordiffuse="FF4B0082">triangle-left.png</texturefocus>
<texturenofocus colordiffuse="FF8080FF">triangle-left.png</texturenofocus>
</control>
@@ -108,7 +107,7 @@
<label>Configure Secret</label>
<textcolor>FF000000</textcolor>
<focusedcolor>FFFFFFFF</focusedcolor>
<texturefocus colordiffuse="FF00FFFF">white.png</texturefocus>
<texturefocus colordiffuse="FF4B0082">white.png</texturefocus>
<texturenofocus colordiffuse="FF8080FF">white.png</texturenofocus>
<align>center</align>
<aligny>center</aligny>
@@ -169,7 +168,7 @@
<label>Open Configuration Page</label>
<textcolor>FF000000</textcolor>
<focusedcolor>FFFFFFFF</focusedcolor>
<texturefocus colordiffuse="FF00FFFF">white.png</texturefocus>
<texturefocus colordiffuse="FF4B0082">white.png</texturefocus>
<texturenofocus colordiffuse="FF8080FF">white.png</texturenofocus>
<align>center</align>
<aligny>center</aligny>
+1 -5
View File
@@ -641,7 +641,7 @@
Kodi Addon Setup Guide
</a>
</div>
<input type="text" id="kodiCodeInput" class="form-control" placeholder="Enter 6-digit code" maxlength="6">
<input type="text" id="kodiCodeInput" class="form-control" placeholder="Enter 6-digit code" maxlength="6" value="{{ kodi_code or '' }}">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
@@ -656,10 +656,6 @@
</div>
</div>
<script>
const kodiCode = "{{ kodi_code or '' }}";
</script>
<!-- JS for Bootstrap and form validation -->
<script src="/static/js/jquery-3.6.0.min.js"></script>
<script src="/static/js/popper.min.js"></script>
+22 -33
View File
@@ -5,18 +5,18 @@
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{addon_name}} - Stremio Addon</title>
<title>{{ addon_name }} - Stremio Addon</title>
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/css/styles.css" rel="stylesheet">
<link rel="shortcut icon" href="{{logo_url}}" type="image/x-icon">
<link rel="shortcut icon" href="{{ logo_url }}" type="image/x-icon">
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-10 col-lg-10 col-md-8 col-sm-10 config-container">
<a href="/"><img class="logo" src="{{logo_url}}"></a>
<h3 class="text-center mb-5"><b>{{addon_name}}</b> - {{version}}</h3>
<a href="/"><img class="logo" src="{{ logo_url }}"></a>
<h3 class="text-center mb-5"><b>{{ addon_name }}</b> - {{ version }}</h3>
<h4 class="mt-4">🔎 Advanced Scraping Capabilities</h4>
<p>Tap into a world of content with our enhanced scraping features:</p>
@@ -29,6 +29,8 @@
<li>📺 TamilUltra & NowMeTV: Get the best of Live TV channels right at your fingertips.</li>
<li>🔄 Prowlarr Integration: Supercharge your scraping streams with Prowlarr's powerful integration.</li>
<li>🌊 Torrentio/KnightCrawler Streams: Optional scraping streams directly from Torrentio/KnightCrawler streams for even more variety.</li>
<li>🔍 Advanced Prowlarr Integration: Improved Prowlarr feed scraping for more comprehensive content discovery with latest updates.</li>
<li>📺 MPD DRM Scraping: Scraping MPD & Support streaming functionality with MediaFlow MPD DRM support.</li>
</ul>
<h4 class="mt-4">🎬 Streaming Provider Integration</h4>
@@ -49,35 +51,22 @@
<h4 class="mt-4">🛠️ Enhanced Additional Features</h4>
<p>Our addon comes packed with features designed to elevate your streaming experience:</p>
<ul>
<li>🔒 API Security: Fortify your self-hosted API with a password to prevent unauthorized access.
</li>
<li>🔐 User Data Encryption: Encrypt user data for heightened privacy and security, storing only
encrypted URLs on Stremio.
</li>
<li>📋 Watchlist Catalog Support: Sync your streaming provider's watchlist directly into the
Stremio catalog for a personalized touch.
</li>
<li>⚙️ Stream Filters: Customize your viewing experience with filters that sort streams by file
size, resolution, seeders and much more.
</li>
<li>
🖼️ Poster with Title: Display the poster with the title for a more visually appealing
catalog on sport events.
</li>
<li>
📺 M3U Playlist Import: Import M3U playlists for a more personalized streaming experience.
</li>
<li>
✨ Manual Scraper Triggering UI: Manage your scraping sources with a manual trigger UI for a
more hands-on approach.
</li>
<li>
🗑️ Delete Watchlist: Delete your watchlist from the stremio for quick control over your
content.
</li>
<li>
🔍 Prowlarr Indexer Support: Use MediaFusion as an indexer in Prowlarr for searching movies and TV shows with Radarr and Sonarr.
</li>
<li>🔒 API Security: Fortify your self-hosted API with a password to prevent unauthorized access.</li>
<li>🔐 User Data Encryption: Encrypt user data for heightened privacy and security, storing only encrypted URLs on Stremio.</li>
<li>📋 Watchlist Catalog Support: Sync your streaming provider's watchlist directly into the Stremio catalog for a personalized touch.</li>
<li>⚙️ Stream Filters: Customize your viewing experience with filters that sort streams by file size, resolution, seeders and much more.</li>
<li>🖼️ Poster with Title: Display the poster with the title for a more visually appealing catalog on sport events.</li>
<li>📺 M3U Playlist Import: Import M3U playlists for a more personalized streaming experience.</li>
<li>✨ Manual Scraper Triggering UI: Manage your scraping sources with a manual trigger UI for a more hands-on approach.</li>
<li>🗑️ Delete Watchlist: Delete your watchlist from the stremio for quick control over your content.</li>
<li>🔍 Prowlarr Indexer Support: Use MediaFusion as an indexer in Prowlarr for searching movies and TV shows with Radarr and Sonarr.</li>
<li>🔞 Parental Controls: Filter content based on nudity and certification ratings.</li>
<li>🎬 IMDb Integration: Display IMDb ratings with the logo for quick quality assessment.</li>
<li>🕰️ Sports Event Timing: View the time for sports events directly on the poster for better planning.</li>
<li>🌐 MediaFlow Proxy: Support for MediaFlow Proxy for Debrid and Live streams, enhancing accessibility.</li>
<li>🎥 RPDB Posters: Support for RPDB posters with fallback to MediaFusion posters.</li>
<li>📥 Browser Download Support: Support for downloading video files from debrid services directly in the browser.</li>
<li>🚫 Support DMCA Take Down: Torrent blocking feature for DMCA compliance.</li>
</ul>
<div class="button-container">
-7
View File
@@ -407,16 +407,9 @@ function setupPasswordToggle(passwordInputId, toggleButtonId, toggleIconId) {
}
async function initiateKodiSetup() {
const urlParams = new URLSearchParams(window.location.search);
const kodiCode = urlParams.get('kodi_code');
if (kodiCode) {
await setupKodiAddon(kodiCode);
} else {
// Show modal to input Kodi code
const kodiCodeModal = new bootstrap.Modal(document.getElementById('kodiCodeModal'));
kodiCodeModal.show();
}
}
async function submitKodiCodeAndSetup() {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"id": "stremio.addons",
"version": "3.9.15",
"version": "4.0.0",
"name": "Media Fusion",
"contactEmail": "mhdzumair@gmail.com",
"description": "Universal Stremio Add-on for Movies, Series, Live TV & Sports Events. Source: https://github.com/mhdzumair/MediaFusion",
+1 -1
View File
@@ -184,7 +184,7 @@ async def get_mediaflow_proxy_public_ip(
try:
async with httpx.AsyncClient() as client:
response = await client.get(
mediaflow_proxy_url + "/proxy/ip",
parse.urljoin(mediaflow_proxy_url, "/proxy/ip"),
params={"api_password": api_password},
timeout=10,
)