Skip to content

Commit

Permalink
Merge pull request #61 from LimeDrive:develop
Browse files Browse the repository at this point in the history
v2.2.0 Add Torbox service
  • Loading branch information
LimeDrive authored Oct 20, 2024
2 parents fde3631 + 3721bbc commit aa6c448
Show file tree
Hide file tree
Showing 42 changed files with 1,884 additions and 776 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<p align="center" style="font-size: 1.5em; font-weight: bold;">Optimisé pour le contenu francophone</p>

<p align="center">
<img src="stream_fusion/static/logo-stream-fusion.png" alt="StreamFusion Logo"/>
<img src="stream_fusion/static/logo_anim_stream-fusion-3.gif" alt="StreamFusion Logo"/>
</p>

<p align="center">
Expand All @@ -20,6 +20,7 @@ StreamFusion est un addon avancé pour Stremio, spécialement conçu pour améli
- **Intégration de Zilean** : Indexe les hashlist de DébridMediaManager pour accéder aux contenus en cache chez les débrideurs.
- **Intégration de Real-Debrid** : Permet la redistribution des liens de streaming en direct et l'ajout de torrents depuis Stremio.
- **Intégration de AllDebrid** : Offre un accès aux liens de streaming et aux torrents via AllDebrid.
- **Intégration de TorBox** : Offre un accès aux liens de streaming et aux torrents avec TorBox.
- **Tri optimisé pour le contenu français** : Offre des résultats ciblés et de qualité, avec reconnaissance des langues et des teams.
- **Sécurité renforcée** : Protège l'application avec une clé API via une interface de gestion.

Expand Down
1 change: 1 addition & 0 deletions docs/en/StreamFusion/streamfusion.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ StreamFusion is an advanced addon for Stremio, specially designed to enhance the
- **Zilean integration**: Indexes DébridMediaManager hashlists to access cached content from debridders.
- **Real-Debrid integration**: Allows direct redistribution of streaming links and torrent addition from Stremio.
- **AllDebrid integration**: Provides access to streaming links and torrents via AllDebrid.
- **TorBox integration**: Provides access to streaming links and torrents via TorBox.
- **Optimized sorting for French content**: Offers targeted and quality results, with language and team recognition.
- **Enhanced security**: Protects the application with an API key via a management interface.

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion docs/fr/StreamFusion/streamfusion.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<p align="center">
<img src="../images/logo-stream-fusion.png" alt="StreamFusion">
<img src="../images/dark_logo_streamfusion.png" alt="StreamFusion">
</p>

<h1 align="center">Présentation de StreamFusion</h1>
Expand All @@ -11,6 +11,7 @@ StreamFusion est un addon avancé pour Stremio, spécialement conçu pour améli
- **Intégration de Zilean** : Indexe les hashlist de DébridMediaManager pour accéder aux contenus en cache chez les débrideurs.
- **Intégration de Real-Debrid** : Permet la redistribution des liens de streaming en direct et l'ajout de torrents depuis Stremio.
- **Intégration de AllDebrid** : Offre un accès aux liens de streaming et aux torrents via AllDebrid.
- **Intégration de TorBox** : Offre un accès aux liens de streaming et aux torrents avec TorBox.
- **Tri optimisé pour le contenu français** : Offre des résultats ciblés et de qualité, avec reconnaissance des langues et des teams.
- **Sécurité renforcée** : Protège l'application avec une clé API via une interface de gestion.

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "stream-fusion"
version = "2.1.0"
version = "2.2.0"
description = "StreamFusion is an advanced plugin for Stremio that significantly enhances its streaming capabilities with debrid service."
authors = ["LimeDrive <[email protected]>"]
readme = "README.md"
Expand Down
7 changes: 0 additions & 7 deletions stream_fusion/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@
NO_CONFIG = {'streams': [{'url': "#", 'title': "No configuration found"}]}
JACKETT_ERROR = {'streams': [{'url': "#", 'title': "An error occured"}]}

# CACHER_URL = "https://stremio-jackett-cacher.elfhosted.com/"

NO_CACHE_HEADERS = {
"Cache-Control": "no-store, no-cache, must-revalidate, max-age=0",
"Pragma": "no-cache",
"Expires": "0",
}

NO_CACHE_VIDEO_URL = "https://github.com/aymene69/stremio-jackett/raw/main/source/videos/nocache.mp4"

EXCLUDED_TRACKERS = ['0day.kiev', '1ptbar', '2 Fast 4 You', '2xFree', '3ChangTrai', '3D Torrents', '3Wmg', '4thD',
'52PT', '720pier', 'Abnormal', 'ABtorrents', 'Acid-Lounge', 'Across The Tasman', 'Aftershock',
'AGSVPT', 'Aidoru!Online', 'Aither (API)', 'AlphaRatio', 'Amigos Share Club', 'AniDUB',
Expand Down Expand Up @@ -122,9 +118,6 @@
"FRENCH": r"\b(?:FRENCH|FR)\b",
}

# REDIS_HOST = 'redis'
# REDIS_PORT = 6379

class CustomException(Exception):
def __init__(self, status_code: int, message: Any):
self.status_code = status_code
Expand Down
95 changes: 35 additions & 60 deletions stream_fusion/services/postgresql/dao/torrentitem_dao.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import List, Optional
from fastapi import Depends, HTTPException
from fastapi import Depends
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
from datetime import datetime, timezone
Expand All @@ -24,23 +24,21 @@ async def create_torrent_item(self, torrent_item: TorrentItem, id: str) -> Torre
await self.session.flush()
await self.session.refresh(new_item)

logger.success(f"Created new TorrentItem: {new_item.id}")
logger.debug(f"TorrentItemDAO: Created new TorrentItem: {new_item.id}")
return new_item
except Exception as e:
logger.error(f"Error creating TorrentItem: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")
logger.error(f"TorrentItemDAO: Error creating TorrentItem: {str(e)}")

async def get_all_torrent_items(self, limit: int, offset: int) -> List[TorrentItemModel]:
async with self.session.begin():
try:
query = select(TorrentItemModel).limit(limit).offset(offset)
result = await self.session.execute(query)
items = result.scalars().all()
logger.info(f"Retrieved {len(items)} TorrentItems")
logger.debug(f"TorrentItemDAO: Retrieved {len(items)} TorrentItems")
return items
except Exception as e:
logger.error(f"Error retrieving TorrentItems: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")
logger.error(f"TorrentItemDAO: Error retrieving TorrentItems: {str(e)}")

async def get_torrent_item_by_id(self, item_id: str) -> Optional[TorrentItemModel]:
async with self.session.begin():
Expand All @@ -49,14 +47,14 @@ async def get_torrent_item_by_id(self, item_id: str) -> Optional[TorrentItemMode
result = await self.session.execute(query)
db_item = result.scalar_one_or_none()
if db_item:
logger.info(f"Retrieved TorrentItem: {item_id}")
logger.debug(f"TorrentItemDAO: Retrieved TorrentItem: {item_id}")
return db_item
else:
logger.info(f"TorrentItem not found: {item_id}")
logger.debug(f"TorrentItemDAO: TorrentItem not found: {item_id}")
return None
except Exception as e:
logger.error(f"Error retrieving TorrentItem {item_id}: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")
logger.error(f"TorrentItemDAO: Error retrieving TorrentItem {item_id}: {str(e)}")
return None

async def update_torrent_item(self, item_id: str, torrent_item: TorrentItem) -> TorrentItemModel:
async with self.session.begin():
Expand All @@ -66,8 +64,8 @@ async def update_torrent_item(self, item_id: str, torrent_item: TorrentItem) ->
db_item = result.scalar_one_or_none()

if not db_item:
logger.warning(f"TorrentItem not found for update: {item_id}")
raise HTTPException(status_code=404, detail="TorrentItem not found")
logger.warning(f"TorrentItemDAO: TorrentItem not found for update: {item_id}")
return None

# Update fields
for key, value in torrent_item.__dict__.items():
Expand All @@ -77,13 +75,11 @@ async def update_torrent_item(self, item_id: str, torrent_item: TorrentItem) ->
await self.session.flush()
await self.session.refresh(db_item)

logger.info(f"Updated TorrentItem: {item_id}")
logger.debug(f"TorrentItemDAO: Updated TorrentItem: {item_id}")
return db_item
except HTTPException:
raise
except Exception as e:
logger.error(f"Error updating TorrentItem {item_id}: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")
logger.error(f"TorrentItemDAO: Error updating TorrentItem {item_id}: {str(e)}")
return None

async def delete_torrent_item(self, item_id: str) -> bool:
async with self.session.begin():
Expand All @@ -94,93 +90,72 @@ async def delete_torrent_item(self, item_id: str) -> bool:

if db_item:
await self.session.delete(db_item)
logger.info(f"Deleted TorrentItem: {item_id}")
logger.debug(f"TorrentItemDAO: Deleted TorrentItem: {item_id}")
return True
else:
logger.warning(f"TorrentItem not found for deletion: {item_id}")
logger.warning(f"TorrentItemDAO: TorrentItem not found for deletion: {item_id}")
return False
except Exception as e:
logger.error(f"Error deleting TorrentItem {item_id}: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")
logger.error(f"TorrentItemDAO: Error deleting TorrentItem {item_id}: {str(e)}")
return False

async def get_torrent_items_by_info_hash(self, info_hash: str) -> List[TorrentItemModel]:
async with self.session.begin():
try:
query = select(TorrentItemModel).where(TorrentItemModel.info_hash == info_hash)
result = await self.session.execute(query)
items = result.scalars().all()
logger.info(f"Retrieved {len(items)} TorrentItems with info_hash: {info_hash}")
logger.debug(f"TorrentItemDAO: Retrieved {len(items)} TorrentItems with info_hash: {info_hash}")
return items
except Exception as e:
logger.error(f"Error retrieving TorrentItems by info_hash {info_hash}: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")

logger.error(f"TorrentItemDAO: Error retrieving TorrentItems by info_hash {info_hash}: {str(e)}")
return None
async def get_torrent_items_by_indexer(self, indexer: str) -> List[TorrentItemModel]:
async with self.session.begin():
try:
query = select(TorrentItemModel).where(TorrentItemModel.indexer == indexer)
result = await self.session.execute(query)
items = result.scalars().all()
logger.info(f"Retrieved {len(items)} TorrentItems from indexer: {indexer}")
logger.debug(f"TorrentItemDAO: Retrieved {len(items)} TorrentItems from indexer: {indexer}")
return items
except Exception as e:
logger.error(f"Error retrieving TorrentItems by indexer {indexer}: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")

logger.error(f"TorrentItemDAO: Error retrieving TorrentItems by indexer {indexer}: {str(e)}")
return None
async def is_torrent_item_cached(self, item_id: str) -> bool:
async with self.session.begin():
try:
query = select(func.count()).where(TorrentItemModel.id == item_id)
result = await self.session.execute(query)
count = result.scalar_one()
is_cached = count > 0
logger.info(f"TorrentItem {item_id} {'is' if is_cached else 'is not'} in cache")
logger.debug(f"TorrentItemDAO: TorrentItem {item_id} {'is' if is_cached else 'is not'} in cache")
return is_cached
except Exception as e:
logger.error(f"Error checking if TorrentItem {item_id} is cached: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")
logger.error(f"TorrentItemDAO: Error checking if TorrentItem {item_id} is cached: {str(e)}")
return None

async def get_torrent_items_by_type(self, item_type: str) -> List[TorrentItemModel]:
async with self.session.begin():
try:
query = select(TorrentItemModel).where(TorrentItemModel.type == item_type)
result = await self.session.execute(query)
items = result.scalars().all()
logger.info(f"Retrieved {len(items)} TorrentItems of type: {item_type}")
logger.debug(f"TorrentItemDAO: Retrieved {len(items)} TorrentItems of type: {item_type}")
return items
except Exception as e:
logger.error(f"Error retrieving TorrentItems by type {item_type}: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")
logger.error(f"TorrentItemDAO: Error retrieving TorrentItems by type {item_type}: {str(e)}")
return None

async def get_torrent_items_by_availability(self, available: bool) -> List[TorrentItemModel]:
async with self.session.begin():
try:
query = select(TorrentItemModel).where(TorrentItemModel.availability == available)
result = await self.session.execute(query)
items = result.scalars().all()
logger.info(f"Retrieved {len(items)} TorrentItems with availability: {available}")
logger.debug(f"TorrentItemDAO: Retrieved {len(items)} TorrentItems with availability: {available}")
return items
except Exception as e:
logger.error(f"Error retrieving TorrentItems by availability {available}: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")

# async def update_torrent_item_availability(self, item_id: str, available: bool) -> bool:
# async with self.session.begin():
# try:
# query = select(TorrentItemModel).where(TorrentItemModel.id == item_id)
# result = await self.session.execute(query)
# db_item = result.scalar_one_or_none()

# if not db_item:
# logger.warning(f"TorrentItem not found for availability update: {item_id}")
# return False

# db_item.availability = available
# db_item.updated_at = int(datetime.now(timezone.utc).timestamp())
# await self.session.flush()

# logger.info(f"Updated availability for TorrentItem {item_id}: {available}")
# return True
# except Exception as e:
# logger.error(f"Error updating availability for TorrentItem {item_id}: {str(e)}")
# raise HTTPException(status_code=500, detail="Internal server error")
logger.error(f"TorrentItemDAO: Error retrieving TorrentItems by availability {available}: {str(e)}")
return None
Loading

0 comments on commit aa6c448

Please sign in to comment.