Skip to content

Commit

Permalink
Feature/alldebrid support (rivenmedia#517)
Browse files Browse the repository at this point in the history
* All Debrid Support (backend)

* Frontend support for alldebrid settings
  • Loading branch information
iPromKnight committed Jul 22, 2024
1 parent 0429ea2 commit 5d14765
Show file tree
Hide file tree
Showing 12 changed files with 760 additions and 34 deletions.
25 changes: 23 additions & 2 deletions backend/program/downloaders/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,23 @@
from .realdebrid import Debrid
from .torbox import TorBoxDownloader
from .realdebrid import RealDebridDownloader
from .alldebrid import AllDebridDownloader
from .torbox import TorBoxDownloader
from program.media.item import MediaItem


class Downloader:
def __init__(self, hash_cache):
self.key = "downloader"
self.initialized = False
services = [
RealDebridDownloader(hash_cache),
TorBoxDownloader(hash_cache),
AllDebridDownloader(hash_cache),
]
self.service = next(service for service in services if service.initialized)
self.initialized = self.validate()

def validate(self):
return self.service is not None

def run(self, item: MediaItem):
yield next(self.service.run(item))
669 changes: 669 additions & 0 deletions backend/program/downloaders/alldebrid.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion backend/program/downloaders/realdebrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
RD_BASE_URL = "https://api.real-debrid.com/rest/1.0"


class Debrid:
class RealDebridDownloader:
"""Real-Debrid API Wrapper"""

def __init__(self, hash_cache):
Expand Down
4 changes: 2 additions & 2 deletions backend/program/downloaders/torbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def validate(self) -> bool:
return False

def run(self, item: MediaItem) -> Generator[MediaItem, None, None]:
"""Download media item from TorBox"""
"""Download media item from TorBox"""
logger.info(f"Downloading {item.log_string} from TorBox")
if self.is_cached(item):
self.download(item)
Expand Down Expand Up @@ -97,4 +97,4 @@ def create_torrent(self, hash) -> int:

def get_torrent_list(self) -> list:
response = get(f"{self.base_url}/torrents/mylist", additional_headers=self.headers, response_type=dict)
return response.data["data"]
return response.data["data"]
14 changes: 3 additions & 11 deletions backend/program/program.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@

from apscheduler.schedulers.background import BackgroundScheduler
from program.content import Listrr, Mdblist, Overseerr, PlexWatchlist, TraktContent
from program.downloaders.realdebrid import Debrid
from program.downloaders.torbox import TorBoxDownloader
from program.downloaders import Downloader
from program.indexers.trakt import TraktIndexer
from program.libraries import SymlinkLibrary
from program.media.item import Episode, MediaItem, Movie, Season, Show
Expand Down Expand Up @@ -71,10 +70,7 @@ def initialize_services(self):
Scraping: Scraping(),
Symlinker: Symlinker(),
Updater: Updater(),
}
self.downloader_services = {
Debrid: Debrid(hash_cache),
TorBoxDownloader: TorBoxDownloader(hash_cache),
Downloader: Downloader(hash_cache),
}
# Depends on Symlinker having created the file structure so needs
# to run after it
Expand All @@ -83,8 +79,6 @@ def initialize_services(self):
}
if not any(s.initialized for s in self.requesting_services.values()):
logger.error("No Requesting service initialized, you must select at least one.")
if not any(s.initialized for s in self.downloader_services.values()):
logger.error("No Downloader service initialized, you must select at least one.")
if not self.processing_services.get(Scraping).initialized:
logger.error("No Scraping service initialized, you must select at least one.")

Expand All @@ -93,7 +87,6 @@ def initialize_services(self):
**self.indexing_services,
**self.requesting_services,
**self.processing_services,
**self.downloader_services,
}

if self.enable_trace:
Expand All @@ -107,7 +100,6 @@ def validate(self) -> bool:
any(s.initialized for s in self.library_services.values()),
any(s.initialized for s in self.indexing_services.values()),
all(s.initialized for s in self.processing_services.values()),
any(s.initialized for s in self.downloader_services.values()),
)
)

Expand Down Expand Up @@ -425,4 +417,4 @@ def clear_queue(self):
self.event_queue.task_done()
except Empty:
break
logger.log("PROGRAM", "Cleared the event queue")
logger.log("PROGRAM", "Cleared the event queue")
13 changes: 10 additions & 3 deletions backend/program/settings/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@ def __setattr__(self, name, value):

# Download Services

class DebridModel(Observable):
class RealDebridModel(Observable):
enabled: bool = False
api_key: str = ""
proxy_enabled: bool = False
proxy_url: str = ""

class AllDebridModel(Observable):
enabled: bool = False
api_key: str = ""
proxy_enabled: bool = False
Expand All @@ -43,7 +49,8 @@ class DownloadersModel(Observable):
movie_filesize_max: int = -1 # MB (-1 is no limit)
episode_filesize_min: int = 40 # MB
episode_filesize_max: int = -1 # MB (-1 is no limit)
real_debrid: DebridModel = DebridModel()
real_debrid: RealDebridModel = RealDebridModel()
all_debrid: AllDebridModel = AllDebridModel()
torbox: TorboxModel = TorboxModel()


Expand Down Expand Up @@ -324,4 +331,4 @@ class AppModel(Observable):
scraping: ScraperModel = ScraperModel()
ranking: RTNSettingsModel = RTNSettingsModel()
indexer: IndexerModel = IndexerModel()
database: DatabaseModel = DatabaseModel()
database: DatabaseModel = DatabaseModel()
5 changes: 2 additions & 3 deletions backend/program/state_transition.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from program.content import Listrr, Mdblist, Overseerr, PlexWatchlist
from program.content.trakt import TraktContent
from program.downloaders.realdebrid import Debrid
from program.downloaders.torbox import TorBoxDownloader
from program.downloaders import Downloader
from program.indexers.trakt import TraktIndexer
from program.libraries import SymlinkLibrary
from program.media import Episode, MediaItem, Movie, Season, Show, States
Expand Down Expand Up @@ -43,7 +42,7 @@ def process_event(existing_item: MediaItem | None, emitted_by: Service, item: Me
items_to_submit = [item] if Scraping.can_we_scrape(item) else []

elif item.state == States.Scraped:
next_service = Debrid or TorBoxDownloader
next_service = Downloader
items_to_submit = [item]

elif item.state == States.Downloaded:
Expand Down
6 changes: 3 additions & 3 deletions backend/program/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Generator, Union

from program.content import Listrr, Mdblist, Overseerr, PlexWatchlist, TraktContent
from program.downloaders import Debrid, TorBoxDownloader
from program.downloaders import RealDebridDownloader, TorBoxDownloader, AllDebridDownloader
from program.libraries import SymlinkLibrary
from program.media.item import MediaItem
from program.scrapers import (
Expand All @@ -22,7 +22,7 @@
# Typehint classes
Scraper = Union[Scraping, Torrentio, Knightcrawler, Mediafusion, Orionoid, Jackett, Annatar, TorBoxScraper, Zilean]
Content = Union[Overseerr, PlexWatchlist, Listrr, Mdblist, TraktContent]
Downloader = Union[Debrid, TorBoxDownloader]
Downloader = Union[RealDebridDownloader, TorBoxDownloader, AllDebridDownloader]
Service = Union[Content, SymlinkLibrary, Scraper, Downloader, Symlinker, Updater]
MediaItemGenerator = Generator[MediaItem, None, MediaItem | None]
ProcessedEvent = (MediaItem, Service, list[MediaItem])
Expand All @@ -31,4 +31,4 @@
@dataclass
class Event:
emitted_by: Service
item: MediaItem
item: MediaItem
16 changes: 8 additions & 8 deletions backend/tests/test_states_processing.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from program.downloaders.realdebrid import Debrid
from program.downloaders.realdebrid import RealDebridDownloader
from program.indexers.trakt import TraktIndexer
from program.media.item import Episode, MediaItem, Movie, Season, Show
from program.media.state import States
Expand Down Expand Up @@ -126,8 +126,8 @@ def test_show_state_transitions(show):
(States.Unknown, Program, TraktIndexer),
# (States.Requested, TraktIndexer, TraktIndexer),
(States.Indexed, TraktIndexer, Scraping),
(States.Scraped, Scraping, Debrid),
(States.Downloaded, Debrid, Symlinker),
(States.Scraped, Scraping, RealDebridDownloader),
(States.Downloaded, RealDebridDownloader, Symlinker),
(States.Symlinked, Symlinker, PlexUpdater),
(States.Completed, PlexUpdater, None)
])
Expand All @@ -150,8 +150,8 @@ def test_process_event_transitions_movie(state, service, next_service, movie):
(States.Unknown, Program, TraktIndexer),
# (States.Requested, TraktIndexer, TraktIndexer),
(States.Indexed, TraktIndexer, Scraping),
(States.Scraped, Scraping, Debrid),
(States.Downloaded, Debrid, Symlinker),
(States.Scraped, Scraping, RealDebridDownloader),
(States.Downloaded, RealDebridDownloader, Symlinker),
(States.Symlinked, Symlinker, PlexUpdater),
(States.Completed, PlexUpdater, None)
])
Expand Down Expand Up @@ -181,8 +181,8 @@ def test_process_event_transition_shows(state, service, next_service, show):
(States.Unknown, Program, TraktIndexer),
# (States.Requested, TraktIndexer, TraktIndexer),
(States.Indexed, TraktIndexer, Scraping),
(States.Scraped, Scraping, Debrid),
(States.Downloaded, Debrid, Symlinker),
(States.Scraped, Scraping, RealDebridDownloader),
(States.Downloaded, RealDebridDownloader, Symlinker),
(States.Symlinked, Symlinker, PlexUpdater),
(States.Completed, PlexUpdater, None)
])
Expand Down Expand Up @@ -225,4 +225,4 @@ def test_process_event_transitions_media_item_movie(state, service, next_service
# if next_service is None:
# assert next_service_result is None, f"Next service should be None for {service}"
# else:
# assert next_service_result == next_service, f"Next service should be {next_service} for {service}"
# assert next_service_result == next_service, f"Next service should be {next_service} for {service}"
2 changes: 2 additions & 0 deletions backend/utils/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,13 @@ def ping(
timeout=10,
additional_headers=None,
proxies=None,
params=None,
specific_rate_limiter: Optional[RateLimiter] = None,
overall_rate_limiter: Optional[RateLimiter] = None):
return get(
url,
additional_headers=additional_headers,
params=params,
timeout=timeout,
proxies=proxies,
specific_rate_limiter=specific_rate_limiter,
Expand Down
22 changes: 22 additions & 0 deletions frontend/src/lib/forms/general-form.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,28 @@
{/if}
{/if}

{#if $formData.alldebrid_enabled}
<div transition:slide>
<TextField {form} name="alldebrid_api_key" {formData} isProtected={true} />
</div>

<div transition:slide>
<CheckboxField
{form}
name="alldebrid_proxy_enabled"
label="All-Debrid Proxy"
{formData}
fieldDescription="Use proxy for All-Debrid API"
/>
</div>

{#if $formData.alldebrid_proxy_enabled}
<div transition:slide>
<TextField {form} name="alldebrid_proxy_url" {formData} />
</div>
{/if}
{/if}

{#if $formData.torbox_enabled}
<div transition:slide>
<TextField {form} name="torbox_api_key" {formData} />
Expand Down
16 changes: 15 additions & 1 deletion frontend/src/lib/forms/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export const generalSettingsSchema = z.object({
realdebrid_api_key: z.string().optional().default(''),
realdebrid_proxy_enabled: z.boolean().default(false),
realdebrid_proxy_url: z.string().optional().default(''),
alldebrid_enabled: z.boolean().default(false),
alldebrid_api_key: z.string().optional().default(''),
alldebrid_proxy_enabled: z.boolean().default(false),
alldebrid_proxy_url: z.string().optional().default(''),
torbox_enabled: z.boolean().default(false),
torbox_api_key: z.string().optional().default('')
});
Expand All @@ -38,8 +42,12 @@ export function generalSettingsToPass(data: any) {
realdebrid_api_key: data.data.downloaders.real_debrid?.api_key || '',
realdebrid_proxy_enabled: data.data.downloaders.real_debrid?.proxy_enabled || false,
realdebrid_proxy_url: data.data.downloaders.real_debrid?.proxy_url || '',
alldebrid_enabled: data.data.downloaders.all_debrid.enabled,
alldebrid_api_key: data.data.downloaders.all_debrid?.api_key || '',
alldebrid_proxy_enabled: data.data.downloaders.all_debrid?.proxy_enabled || false,
alldebrid_proxy_url: data.data.downloaders.all_debrid?.proxy_url || '',
torbox_enabled: data.data.downloaders.torbox.enabled,
torbox_api_key: data.data.downloaders.torbox?.api_key || ''
torbox_api_key: data.data.downloaders.torbox?.api_key || '',
};
}

Expand Down Expand Up @@ -74,6 +82,12 @@ export function generalSettingsToSet(form: SuperValidated<Infer<GeneralSettingsS
proxy_enabled: form.data.realdebrid_proxy_enabled,
proxy_url: form.data.realdebrid_proxy_url
},
all_debrid: {
enabled: form.data.alldebrid_enabled,
api_key: form.data.alldebrid_api_key,
proxy_enabled: form.data.alldebrid_proxy_enabled,
proxy_url: form.data.alldebrid_proxy_url
},
torbox: {
enabled: form.data.torbox_enabled,
api_key: form.data.torbox_api_key
Expand Down

0 comments on commit 5d14765

Please sign in to comment.