mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-09 03:37:45 +03:00
Merge pull request #1439 from hydralauncher/feature/torbox-integration
feat: torbox integration
This commit is contained in:
commit
a22be44086
@ -11,11 +11,12 @@ class HttpDownloader:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def start_download(self, url: str, save_path: str, header: str):
|
def start_download(self, url: str, save_path: str, header: str, out: str = None):
|
||||||
if self.download:
|
if self.download:
|
||||||
self.aria2.resume([self.download])
|
self.aria2.resume([self.download])
|
||||||
else:
|
else:
|
||||||
downloads = self.aria2.add(url, options={"header": header, "dir": save_path})
|
downloads = self.aria2.add(url, options={"header": header, "dir": save_path, "out": out})
|
||||||
|
|
||||||
self.download = downloads[0]
|
self.download = downloads[0]
|
||||||
|
|
||||||
def pause_download(self):
|
def pause_download(self):
|
||||||
|
@ -28,14 +28,14 @@ if start_download_payload:
|
|||||||
torrent_downloader = TorrentDownloader(torrent_session)
|
torrent_downloader = TorrentDownloader(torrent_session)
|
||||||
downloads[initial_download['game_id']] = torrent_downloader
|
downloads[initial_download['game_id']] = torrent_downloader
|
||||||
try:
|
try:
|
||||||
torrent_downloader.start_download(initial_download['url'], initial_download['save_path'], "")
|
torrent_downloader.start_download(initial_download['url'], initial_download['save_path'])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Error starting torrent download", e)
|
print("Error starting torrent download", e)
|
||||||
else:
|
else:
|
||||||
http_downloader = HttpDownloader()
|
http_downloader = HttpDownloader()
|
||||||
downloads[initial_download['game_id']] = http_downloader
|
downloads[initial_download['game_id']] = http_downloader
|
||||||
try:
|
try:
|
||||||
http_downloader.start_download(initial_download['url'], initial_download['save_path'], initial_download.get('header'))
|
http_downloader.start_download(initial_download['url'], initial_download['save_path'], initial_download.get('header'), initial_download.get("out"))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Error starting http download", e)
|
print("Error starting http download", e)
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ if start_seeding_payload:
|
|||||||
torrent_downloader = TorrentDownloader(torrent_session, lt.torrent_flags.upload_mode)
|
torrent_downloader = TorrentDownloader(torrent_session, lt.torrent_flags.upload_mode)
|
||||||
downloads[seed['game_id']] = torrent_downloader
|
downloads[seed['game_id']] = torrent_downloader
|
||||||
try:
|
try:
|
||||||
torrent_downloader.start_download(seed['url'], seed['save_path'], "")
|
torrent_downloader.start_download(seed['url'], seed['save_path'])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Error starting seeding", e)
|
print("Error starting seeding", e)
|
||||||
|
|
||||||
@ -140,18 +140,18 @@ def action():
|
|||||||
|
|
||||||
if url.startswith('magnet'):
|
if url.startswith('magnet'):
|
||||||
if existing_downloader and isinstance(existing_downloader, TorrentDownloader):
|
if existing_downloader and isinstance(existing_downloader, TorrentDownloader):
|
||||||
existing_downloader.start_download(url, data['save_path'], "")
|
existing_downloader.start_download(url, data['save_path'])
|
||||||
else:
|
else:
|
||||||
torrent_downloader = TorrentDownloader(torrent_session)
|
torrent_downloader = TorrentDownloader(torrent_session)
|
||||||
downloads[game_id] = torrent_downloader
|
downloads[game_id] = torrent_downloader
|
||||||
torrent_downloader.start_download(url, data['save_path'], "")
|
torrent_downloader.start_download(url, data['save_path'])
|
||||||
else:
|
else:
|
||||||
if existing_downloader and isinstance(existing_downloader, HttpDownloader):
|
if existing_downloader and isinstance(existing_downloader, HttpDownloader):
|
||||||
existing_downloader.start_download(url, data['save_path'], data.get('header'))
|
existing_downloader.start_download(url, data['save_path'], data.get('header'), data.get('out'))
|
||||||
else:
|
else:
|
||||||
http_downloader = HttpDownloader()
|
http_downloader = HttpDownloader()
|
||||||
downloads[game_id] = http_downloader
|
downloads[game_id] = http_downloader
|
||||||
http_downloader.start_download(url, data['save_path'], data.get('header'))
|
http_downloader.start_download(url, data['save_path'], data.get('header'), data.get('out'))
|
||||||
|
|
||||||
downloading_game_id = game_id
|
downloading_game_id = game_id
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ def action():
|
|||||||
elif action == 'resume_seeding':
|
elif action == 'resume_seeding':
|
||||||
torrent_downloader = TorrentDownloader(torrent_session, lt.torrent_flags.upload_mode)
|
torrent_downloader = TorrentDownloader(torrent_session, lt.torrent_flags.upload_mode)
|
||||||
downloads[game_id] = torrent_downloader
|
downloads[game_id] = torrent_downloader
|
||||||
torrent_downloader.start_download(data['url'], data['save_path'], "")
|
torrent_downloader.start_download(data['url'], data['save_path'])
|
||||||
elif action == 'pause_seeding':
|
elif action == 'pause_seeding':
|
||||||
downloader = downloads.get(game_id)
|
downloader = downloads.get(game_id)
|
||||||
if downloader:
|
if downloader:
|
||||||
|
@ -102,7 +102,7 @@ class TorrentDownloader:
|
|||||||
"http://bvarf.tracker.sh:2086/announce",
|
"http://bvarf.tracker.sh:2086/announce",
|
||||||
]
|
]
|
||||||
|
|
||||||
def start_download(self, magnet: str, save_path: str, header: str):
|
def start_download(self, magnet: str, save_path: str):
|
||||||
params = {'url': magnet, 'save_path': save_path, 'trackers': self.trackers, 'flags': self.flags}
|
params = {'url': magnet, 'save_path': save_path, 'trackers': self.trackers, 'flags': self.flags}
|
||||||
self.torrent_handle = self.session.add_torrent(params)
|
self.torrent_handle = self.session.add_torrent(params)
|
||||||
self.torrent_handle.resume()
|
self.torrent_handle.resume()
|
||||||
|
@ -236,13 +236,13 @@
|
|||||||
"behavior": "السلوك",
|
"behavior": "السلوك",
|
||||||
"download_sources": "مصادر التنزيل",
|
"download_sources": "مصادر التنزيل",
|
||||||
"language": "اللغة",
|
"language": "اللغة",
|
||||||
"real_debrid_api_token": "رمز API",
|
"api_token": "رمز API",
|
||||||
"enable_real_debrid": "تفعيل Real-Debrid",
|
"enable_real_debrid": "تفعيل Real-Debrid",
|
||||||
"real_debrid_description": "Real-Debrid هو أداة تنزيل غير مقيدة تتيح لك تنزيل الملفات بسرعة، مقيدة فقط بسرعة الإنترنت لديك.",
|
"real_debrid_description": "Real-Debrid هو أداة تنزيل غير مقيدة تتيح لك تنزيل الملفات بسرعة، مقيدة فقط بسرعة الإنترنت لديك.",
|
||||||
"real_debrid_invalid_token": "رمز API غير صالح",
|
"debrid_invalid_token": "رمز API غير صالح",
|
||||||
"real_debrid_api_token_hint": "يمكنك الحصول على رمز API الخاص بك <0>هنا</0>",
|
"debrid_api_token_hint": "يمكنك الحصول على رمز API الخاص بك <0>هنا</0>",
|
||||||
"real_debrid_free_account_error": "الحساب \"{{username}}\" هو حساب مجاني. يرجى الاشتراك في Real-Debrid",
|
"real_debrid_free_account_error": "الحساب \"{{username}}\" هو حساب مجاني. يرجى الاشتراك في Real-Debrid",
|
||||||
"real_debrid_linked_message": "تم ربط الحساب \"{{username}}\"",
|
"debrid_linked_message": "تم ربط الحساب \"{{username}}\"",
|
||||||
"save_changes": "حفظ التغييرات",
|
"save_changes": "حفظ التغييرات",
|
||||||
"changes_saved": "تم حفظ التغييرات بنجاح",
|
"changes_saved": "تم حفظ التغييرات بنجاح",
|
||||||
"download_sources_description": "سيقوم Hydra بجلب روابط التنزيل من هذه المصادر. يجب أن يكون عنوان URL المصدر رابطًا مباشرًا لملف .json يحتوي على روابط التنزيل.",
|
"download_sources_description": "سيقوم Hydra بجلب روابط التنزيل من هذه المصادر. يجب أن يكون عنوان URL المصدر رابطًا مباشرًا لملف .json يحتوي على روابط التنزيل.",
|
||||||
|
@ -230,13 +230,13 @@
|
|||||||
"behavior": "Поведение",
|
"behavior": "Поведение",
|
||||||
"download_sources": "Източници за изтегляне",
|
"download_sources": "Източници за изтегляне",
|
||||||
"language": "Език",
|
"language": "Език",
|
||||||
"real_debrid_api_token": "API Токен",
|
"api_token": "API Токен",
|
||||||
"enable_real_debrid": "Включи Real-Debrid",
|
"enable_real_debrid": "Включи Real-Debrid",
|
||||||
"real_debrid_description": "Real-Debrid е неограничен даунлоудър, който ви позволява бързо да изтегляте файлове, ограничени само от скоростта на интернет..",
|
"real_debrid_description": "Real-Debrid е неограничен даунлоудър, който ви позволява бързо да изтегляте файлове, ограничени само от скоростта на интернет..",
|
||||||
"real_debrid_invalid_token": "Невалиден API токен",
|
"debrid_invalid_token": "Невалиден API токен",
|
||||||
"real_debrid_api_token_hint": "Вземете своя API токен <0>тук</0>",
|
"debrid_api_token_hint": "Вземете своя API токен <0>тук</0>",
|
||||||
"real_debrid_free_account_error": "Акаунтът \"{{username}}\" е безплатен акаунт. Моля абонирай се за Real-Debrid",
|
"real_debrid_free_account_error": "Акаунтът \"{{username}}\" е безплатен акаунт. Моля абонирай се за Real-Debrid",
|
||||||
"real_debrid_linked_message": "Акаунтът \"{{username}}\" е свързан",
|
"debrid_linked_message": "Акаунтът \"{{username}}\" е свързан",
|
||||||
"save_changes": "Запази промените",
|
"save_changes": "Запази промените",
|
||||||
"changes_saved": "Промените са успешно запазни",
|
"changes_saved": "Промените са успешно запазни",
|
||||||
"download_sources_description": "Hydra ще извлича връзките за изтегляне от тези източници. URL адресът на източника трябва да е директна връзка към .json файл, съдържащ връзките за изтегляне.",
|
"download_sources_description": "Hydra ще извлича връзките за изтегляне от тези източници. URL адресът на източника трябва да е директна връзка към .json файл, съдържащ връзките за изтегляне.",
|
||||||
|
@ -161,13 +161,13 @@
|
|||||||
"behavior": "Comportament",
|
"behavior": "Comportament",
|
||||||
"download_sources": "Fonts de descàrrega",
|
"download_sources": "Fonts de descàrrega",
|
||||||
"language": "Idioma",
|
"language": "Idioma",
|
||||||
"real_debrid_api_token": "Testimoni API",
|
"api_token": "Testimoni API",
|
||||||
"enable_real_debrid": "Activa el Real Debrid",
|
"enable_real_debrid": "Activa el Real Debrid",
|
||||||
"real_debrid_description": "Real-Debrid és un programa de descàrrega sense restriccions que us permet descarregar fitxers a l'instant i al màxim de la vostra velocitat d'Internet.",
|
"real_debrid_description": "Real-Debrid és un programa de descàrrega sense restriccions que us permet descarregar fitxers a l'instant i al màxim de la vostra velocitat d'Internet.",
|
||||||
"real_debrid_invalid_token": "Invalida el testimoni de l'API",
|
"debrid_invalid_token": "Invalida el testimoni de l'API",
|
||||||
"real_debrid_api_token_hint": "Pots obtenir la teva clau de l'API <0>aquí</0>.",
|
"debrid_api_token_hint": "Pots obtenir la teva clau de l'API <0>aquí</0>.",
|
||||||
"real_debrid_free_account_error": "L'usuari \"{{username}}\" és un compte gratuït. Si us plau subscriu-te a Real-Debrid",
|
"real_debrid_free_account_error": "L'usuari \"{{username}}\" és un compte gratuït. Si us plau subscriu-te a Real-Debrid",
|
||||||
"real_debrid_linked_message": "Compte \"{{username}}\" vinculat",
|
"debrid_linked_message": "Compte \"{{username}}\" vinculat",
|
||||||
"save_changes": "Desa els canvis",
|
"save_changes": "Desa els canvis",
|
||||||
"changes_saved": "Els canvis s'han desat correctament",
|
"changes_saved": "Els canvis s'han desat correctament",
|
||||||
"download_sources_description": "Hydra buscarà els enllaços de descàrrega d'aquestes fonts. L'URL d'origen ha de ser un enllaç directe a un fitxer .json que contingui els enllaços de descàrrega.",
|
"download_sources_description": "Hydra buscarà els enllaços de descàrrega d'aquestes fonts. L'URL d'origen ha de ser un enllaç directe a un fitxer .json que contingui els enllaços de descàrrega.",
|
||||||
|
@ -214,13 +214,13 @@
|
|||||||
"behavior": "Chování",
|
"behavior": "Chování",
|
||||||
"download_sources": "Zdroje stahování",
|
"download_sources": "Zdroje stahování",
|
||||||
"language": "Jazyk",
|
"language": "Jazyk",
|
||||||
"real_debrid_api_token": "API Token",
|
"api_token": "API Token",
|
||||||
"enable_real_debrid": "Povolit Real-Debrid",
|
"enable_real_debrid": "Povolit Real-Debrid",
|
||||||
"real_debrid_description": "Real-Debrid je neomezený správce stahování, který umožňuje stahovat soubory v nejvyšší rychlosti vašeho internetu.",
|
"real_debrid_description": "Real-Debrid je neomezený správce stahování, který umožňuje stahovat soubory v nejvyšší rychlosti vašeho internetu.",
|
||||||
"real_debrid_invalid_token": "Neplatný API token",
|
"debrid_invalid_token": "Neplatný API token",
|
||||||
"real_debrid_api_token_hint": "API token můžeš sehnat <0>zde</0>",
|
"debrid_api_token_hint": "API token můžeš sehnat <0>zde</0>",
|
||||||
"real_debrid_free_account_error": "Účet \"{{username}}\" má základní úroveň. Prosím předplaťte si Real-Debrid",
|
"real_debrid_free_account_error": "Účet \"{{username}}\" má základní úroveň. Prosím předplaťte si Real-Debrid",
|
||||||
"real_debrid_linked_message": "Účet \"{{username}}\" je propojen",
|
"debrid_linked_message": "Účet \"{{username}}\" je propojen",
|
||||||
"save_changes": "Uložit změny",
|
"save_changes": "Uložit změny",
|
||||||
"changes_saved": "Změny úspěšně uloženy",
|
"changes_saved": "Změny úspěšně uloženy",
|
||||||
"download_sources_description": "Hydra bude odsud sbírat soubory. Zdrojový odkaz musí být .json soubor obsahující odkazy na soubory.",
|
"download_sources_description": "Hydra bude odsud sbírat soubory. Zdrojový odkaz musí být .json soubor obsahující odkazy na soubory.",
|
||||||
|
@ -177,13 +177,13 @@
|
|||||||
"behavior": "Opførsel",
|
"behavior": "Opførsel",
|
||||||
"download_sources": "Download kilder",
|
"download_sources": "Download kilder",
|
||||||
"language": "Sprog",
|
"language": "Sprog",
|
||||||
"real_debrid_api_token": "API nøgle",
|
"api_token": "API nøgle",
|
||||||
"enable_real_debrid": "Slå Real-Debrid til",
|
"enable_real_debrid": "Slå Real-Debrid til",
|
||||||
"real_debrid_description": "Real-Debrid er en ubegrænset downloader der gør det muligt for dig at downloade filer med det samme og med den bedste udnyttelse af din internet hastighed.",
|
"real_debrid_description": "Real-Debrid er en ubegrænset downloader der gør det muligt for dig at downloade filer med det samme og med den bedste udnyttelse af din internet hastighed.",
|
||||||
"real_debrid_invalid_token": "Ugyldig API nøgle",
|
"debrid_invalid_token": "Ugyldig API nøgle",
|
||||||
"real_debrid_api_token_hint": "Du kan få din API nøgle <0>her</0>",
|
"debrid_api_token_hint": "Du kan få din API nøgle <0>her</0>",
|
||||||
"real_debrid_free_account_error": "Brugeren \"{{username}}\" er en gratis bruger. Venligst abbonér på Real-Debrid",
|
"real_debrid_free_account_error": "Brugeren \"{{username}}\" er en gratis bruger. Venligst abbonér på Real-Debrid",
|
||||||
"real_debrid_linked_message": "Brugeren \"{{username}}\" er forbundet",
|
"debrid_linked_message": "Brugeren \"{{username}}\" er forbundet",
|
||||||
"save_changes": "Gem ændringer",
|
"save_changes": "Gem ændringer",
|
||||||
"changes_saved": "Ændringer gemt successfuldt",
|
"changes_saved": "Ændringer gemt successfuldt",
|
||||||
"download_sources_description": "Hydra vil hente download links fra disse kilder. Kilde URLen skal være et direkte link til en .json fil der indeholder download linkene.",
|
"download_sources_description": "Hydra vil hente download links fra disse kilder. Kilde URLen skal være et direkte link til en .json fil der indeholder download linkene.",
|
||||||
|
@ -161,13 +161,13 @@
|
|||||||
"behavior": "Verhalten",
|
"behavior": "Verhalten",
|
||||||
"download_sources": "Download-Quellen",
|
"download_sources": "Download-Quellen",
|
||||||
"language": "Sprache",
|
"language": "Sprache",
|
||||||
"real_debrid_api_token": "API Token",
|
"api_token": "API Token",
|
||||||
"enable_real_debrid": "Real-Debrid aktivieren",
|
"enable_real_debrid": "Real-Debrid aktivieren",
|
||||||
"real_debrid_description": "Real-Debrid ist ein unrestriktiver Downloader, der es dir ermöglicht Dateien sofort und mit deiner maximalen Internetgeschwindigkeit herunterzuladen.",
|
"real_debrid_description": "Real-Debrid ist ein unrestriktiver Downloader, der es dir ermöglicht Dateien sofort und mit deiner maximalen Internetgeschwindigkeit herunterzuladen.",
|
||||||
"real_debrid_invalid_token": "API token nicht gültig",
|
"debrid_invalid_token": "API token nicht gültig",
|
||||||
"real_debrid_api_token_hint": "<0>Hier</0> kannst du dir deinen API Token holen",
|
"debrid_api_token_hint": "<0>Hier</0> kannst du dir deinen API Token holen",
|
||||||
"real_debrid_free_account_error": "Das Konto \"{{username}}\" ist ein gratis account. Bitte abonniere Real-Debrid",
|
"real_debrid_free_account_error": "Das Konto \"{{username}}\" ist ein gratis account. Bitte abonniere Real-Debrid",
|
||||||
"real_debrid_linked_message": "Konto \"{{username}}\" verknüpft",
|
"debrid_linked_message": "Konto \"{{username}}\" verknüpft",
|
||||||
"save_changes": "Änderungen speichern",
|
"save_changes": "Änderungen speichern",
|
||||||
"changes_saved": "Änderungen erfolgreich gespeichert",
|
"changes_saved": "Änderungen erfolgreich gespeichert",
|
||||||
"download_sources_description": "Hydra wird die Download-Links von diesen Quellen abrufen. Die Quell-URL muss ein direkter Link zu einer .json Datei, welche die Download-Links enthält, sein.",
|
"download_sources_description": "Hydra wird die Download-Links von diesen Quellen abrufen. Die Quell-URL muss ein direkter Link zu einer .json Datei, welche die Download-Links enthält, sein.",
|
||||||
|
@ -240,13 +240,13 @@
|
|||||||
"behavior": "Behavior",
|
"behavior": "Behavior",
|
||||||
"download_sources": "Download sources",
|
"download_sources": "Download sources",
|
||||||
"language": "Language",
|
"language": "Language",
|
||||||
"real_debrid_api_token": "API Token",
|
"api_token": "API Token",
|
||||||
"enable_real_debrid": "Enable Real-Debrid",
|
"enable_real_debrid": "Enable Real-Debrid",
|
||||||
"real_debrid_description": "Real-Debrid is an unrestricted downloader that allows you to quickly download files, only limited by your internet speed.",
|
"real_debrid_description": "Real-Debrid is an unrestricted downloader that allows you to quickly download files, only limited by your internet speed.",
|
||||||
"real_debrid_invalid_token": "Invalid API token",
|
"debrid_invalid_token": "Invalid API token",
|
||||||
"real_debrid_api_token_hint": "You can get your API token <0>here</0>",
|
"debrid_api_token_hint": "You can get your API token <0>here</0>",
|
||||||
"real_debrid_free_account_error": "The account \"{{username}}\" is a free account. Please subscribe to Real-Debrid",
|
"real_debrid_free_account_error": "The account \"{{username}}\" is a free account. Please subscribe to Real-Debrid",
|
||||||
"real_debrid_linked_message": "Account \"{{username}}\" linked",
|
"debrid_linked_message": "Account \"{{username}}\" linked",
|
||||||
"save_changes": "Save changes",
|
"save_changes": "Save changes",
|
||||||
"changes_saved": "Changes successfully saved",
|
"changes_saved": "Changes successfully saved",
|
||||||
"download_sources_description": "Hydra will fetch the download links from these sources. The source URL must be a direct link to a .json file containing the download links.",
|
"download_sources_description": "Hydra will fetch the download links from these sources. The source URL must be a direct link to a .json file containing the download links.",
|
||||||
@ -300,7 +300,11 @@
|
|||||||
"become_subscriber": "Be Hydra Cloud",
|
"become_subscriber": "Be Hydra Cloud",
|
||||||
"subscription_renew_cancelled": "Automatic renewal is disabled",
|
"subscription_renew_cancelled": "Automatic renewal is disabled",
|
||||||
"subscription_renews_on": "Your subscription renews on {{date}}",
|
"subscription_renews_on": "Your subscription renews on {{date}}",
|
||||||
"bill_sent_until": "Your next bill will be sent until this day"
|
"bill_sent_until": "Your next bill will be sent until this day",
|
||||||
|
"enable_torbox": "Enable Torbox",
|
||||||
|
"torbox_description": "TorBox is your premium seedbox service rivaling even the best servers on the market.",
|
||||||
|
"torbox_account_linked": "TorBox account linked",
|
||||||
|
"real_debrid_account_linked": "Real-Debrid account linked"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"download_complete": "Download complete",
|
"download_complete": "Download complete",
|
||||||
|
@ -236,13 +236,13 @@
|
|||||||
"behavior": "Otros",
|
"behavior": "Otros",
|
||||||
"download_sources": "Fuentes de descarga",
|
"download_sources": "Fuentes de descarga",
|
||||||
"language": "Idioma",
|
"language": "Idioma",
|
||||||
"real_debrid_api_token": "Token API",
|
"api_token": "Token API",
|
||||||
"enable_real_debrid": "Activar Real-Debrid",
|
"enable_real_debrid": "Activar Real-Debrid",
|
||||||
"real_debrid_description": "Real-Debrid es una forma de descargar sin restricciones archivos instantáneamente con la máxima velocidad de tu internet.",
|
"real_debrid_description": "Real-Debrid es una forma de descargar sin restricciones archivos instantáneamente con la máxima velocidad de tu internet.",
|
||||||
"real_debrid_invalid_token": "Token de API inválido",
|
"debrid_invalid_token": "Token de API inválido",
|
||||||
"real_debrid_api_token_hint": "Puedes obtener tu clave de API <0>aquí</0>",
|
"debrid_api_token_hint": "Puedes obtener tu clave de API <0>aquí</0>",
|
||||||
"real_debrid_free_account_error": "La cuenta \"{{username}}\" es una cuenta gratuita. Por favor, suscríbete a Real-Debrid",
|
"real_debrid_free_account_error": "La cuenta \"{{username}}\" es una cuenta gratuita. Por favor, suscríbete a Real-Debrid",
|
||||||
"real_debrid_linked_message": "Cuenta \"{{username}}\" vinculada",
|
"debrid_linked_message": "Cuenta \"{{username}}\" vinculada",
|
||||||
"save_changes": "Guardar cambios",
|
"save_changes": "Guardar cambios",
|
||||||
"changes_saved": "Ajustes guardados exitosamente",
|
"changes_saved": "Ajustes guardados exitosamente",
|
||||||
"download_sources_description": "Hydra buscará los enlaces de descarga de estas fuentes. La URL de origen debe ser un enlace directo a un archivo .json que contenga los enlaces de descarga",
|
"download_sources_description": "Hydra buscará los enlaces de descarga de estas fuentes. La URL de origen debe ser un enlace directo a un archivo .json que contenga los enlaces de descarga",
|
||||||
|
@ -213,13 +213,13 @@
|
|||||||
"behavior": "Käitumine",
|
"behavior": "Käitumine",
|
||||||
"download_sources": "Allalaadimise allikad",
|
"download_sources": "Allalaadimise allikad",
|
||||||
"language": "Keel",
|
"language": "Keel",
|
||||||
"real_debrid_api_token": "API Võti",
|
"api_token": "API Võti",
|
||||||
"enable_real_debrid": "Luba Real-Debrid",
|
"enable_real_debrid": "Luba Real-Debrid",
|
||||||
"real_debrid_description": "Real-Debrid on piiranguteta allalaadija, mis võimaldab sul faile alla laadida koheselt ja sinu internetiühenduse parima kiirusega.",
|
"real_debrid_description": "Real-Debrid on piiranguteta allalaadija, mis võimaldab sul faile alla laadida koheselt ja sinu internetiühenduse parima kiirusega.",
|
||||||
"real_debrid_invalid_token": "Vigane API võti",
|
"debrid_invalid_token": "Vigane API võti",
|
||||||
"real_debrid_api_token_hint": "Sa saad oma API võtme <0>siit</0>",
|
"debrid_api_token_hint": "Sa saad oma API võtme <0>siit</0>",
|
||||||
"real_debrid_free_account_error": "Konto \"{{username}}\" on tasuta konto. Palun telli Real-Debrid",
|
"real_debrid_free_account_error": "Konto \"{{username}}\" on tasuta konto. Palun telli Real-Debrid",
|
||||||
"real_debrid_linked_message": "Konto \"{{username}}\" ühendatud",
|
"debrid_linked_message": "Konto \"{{username}}\" ühendatud",
|
||||||
"save_changes": "Salvesta muudatused",
|
"save_changes": "Salvesta muudatused",
|
||||||
"changes_saved": "Muudatused edukalt salvestatud",
|
"changes_saved": "Muudatused edukalt salvestatud",
|
||||||
"download_sources_description": "Hydra laeb allalaadimise lingid nendest allikatest. Allika URL peab olema otsene link .json failile, mis sisaldab allalaadimise linke.",
|
"download_sources_description": "Hydra laeb allalaadimise lingid nendest allikatest. Allika URL peab olema otsene link .json failile, mis sisaldab allalaadimise linke.",
|
||||||
|
@ -110,7 +110,7 @@
|
|||||||
"general": "کلی",
|
"general": "کلی",
|
||||||
"behavior": "رفتار",
|
"behavior": "رفتار",
|
||||||
"enable_real_debrid": "فعالسازی Real-Debrid",
|
"enable_real_debrid": "فعالسازی Real-Debrid",
|
||||||
"real_debrid_api_token_hint": "کلید API خود را از <ب0>اینجا</0> بگیرید.",
|
"debrid_api_token_hint": "کلید API خود را از <ب0>اینجا</0> بگیرید.",
|
||||||
"save_changes": "ذخیره تغییرات"
|
"save_changes": "ذخیره تغییرات"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
|
@ -161,13 +161,13 @@
|
|||||||
"behavior": "Perilaku",
|
"behavior": "Perilaku",
|
||||||
"download_sources": "Sumber unduhan",
|
"download_sources": "Sumber unduhan",
|
||||||
"language": "Bahasa",
|
"language": "Bahasa",
|
||||||
"real_debrid_api_token": "Token API",
|
"api_token": "Token API",
|
||||||
"enable_real_debrid": "Aktifkan Real-Debrid",
|
"enable_real_debrid": "Aktifkan Real-Debrid",
|
||||||
"real_debrid_description": "Real-Debrid adalah downloader tanpa batas yang memungkinkan kamu untuk mengunduh file dengan cepat dan pada kecepatan terbaik dari Internet kamu.",
|
"real_debrid_description": "Real-Debrid adalah downloader tanpa batas yang memungkinkan kamu untuk mengunduh file dengan cepat dan pada kecepatan terbaik dari Internet kamu.",
|
||||||
"real_debrid_invalid_token": "Token API tidak valid",
|
"debrid_invalid_token": "Token API tidak valid",
|
||||||
"real_debrid_api_token_hint": "Kamu bisa dapatkan token API di <0>sini</0>",
|
"debrid_api_token_hint": "Kamu bisa dapatkan token API di <0>sini</0>",
|
||||||
"real_debrid_free_account_error": "Akun \"{{username}}\" adalah akun gratis. Silakan berlangganan Real-Debrid",
|
"real_debrid_free_account_error": "Akun \"{{username}}\" adalah akun gratis. Silakan berlangganan Real-Debrid",
|
||||||
"real_debrid_linked_message": "Akun \"{{username}}\" terhubung",
|
"debrid_linked_message": "Akun \"{{username}}\" terhubung",
|
||||||
"save_changes": "Simpan perubahan",
|
"save_changes": "Simpan perubahan",
|
||||||
"changes_saved": "Perubahan disimpan berhasil",
|
"changes_saved": "Perubahan disimpan berhasil",
|
||||||
"download_sources_description": "Hydra akan mencari link unduhan dari sini. URL harus menuju file .json dengan link unduhan.",
|
"download_sources_description": "Hydra akan mencari link unduhan dari sini. URL harus menuju file .json dengan link unduhan.",
|
||||||
|
@ -118,7 +118,7 @@
|
|||||||
"general": "Generale",
|
"general": "Generale",
|
||||||
"behavior": "Comportamento",
|
"behavior": "Comportamento",
|
||||||
"enable_real_debrid": "Abilita Real Debrid",
|
"enable_real_debrid": "Abilita Real Debrid",
|
||||||
"real_debrid_api_token_hint": "Puoi trovare la tua chiave API <0>here</0>",
|
"debrid_api_token_hint": "Puoi trovare la tua chiave API <0>here</0>",
|
||||||
"save_changes": "Salva modifiche"
|
"save_changes": "Salva modifiche"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
|
@ -159,13 +159,13 @@
|
|||||||
"behavior": "Мінез-құлық",
|
"behavior": "Мінез-құлық",
|
||||||
"download_sources": "Жүктеу көздері",
|
"download_sources": "Жүктеу көздері",
|
||||||
"language": "Тіл",
|
"language": "Тіл",
|
||||||
"real_debrid_api_token": "API Кілті",
|
"api_token": "API Кілті",
|
||||||
"enable_real_debrid": "Real-Debrid-ті қосу",
|
"enable_real_debrid": "Real-Debrid-ті қосу",
|
||||||
"real_debrid_description": "Real-Debrid - бұл шектеусіз жүктеуші, ол интернетте орналастырылған файлдарды тез жүктеуге немесе жеке желі арқылы кез келген блоктарды айналып өтіп, оларды бірден плеерге беруге мүмкіндік береді.",
|
"real_debrid_description": "Real-Debrid - бұл шектеусіз жүктеуші, ол интернетте орналастырылған файлдарды тез жүктеуге немесе жеке желі арқылы кез келген блоктарды айналып өтіп, оларды бірден плеерге беруге мүмкіндік береді.",
|
||||||
"real_debrid_invalid_token": "Қате API кілті",
|
"debrid_invalid_token": "Қате API кілті",
|
||||||
"real_debrid_api_token_hint": "API кілтін <0>осы жерден</0> алуға болады",
|
"debrid_api_token_hint": "API кілтін <0>осы жерден</0> алуға болады",
|
||||||
"real_debrid_free_account_error": "\"{{username}}\" аккаунты жазылымға ие емес. Real-Debrid жазылымын алыңыз",
|
"real_debrid_free_account_error": "\"{{username}}\" аккаунты жазылымға ие емес. Real-Debrid жазылымын алыңыз",
|
||||||
"real_debrid_linked_message": "\"{{username}}\" аккаунты байланған",
|
"debrid_linked_message": "\"{{username}}\" аккаунты байланған",
|
||||||
"save_changes": "Өзгерістерді сақтау",
|
"save_changes": "Өзгерістерді сақтау",
|
||||||
"changes_saved": "Өзгерістер сәтті сақталды",
|
"changes_saved": "Өзгерістер сәтті сақталды",
|
||||||
"download_sources_description": "Hydra осы көздерден жүктеу сілтемелерін алады. URL-да жүктеу сілтемелері бар .json файлына тікелей сілтеме болуы керек.",
|
"download_sources_description": "Hydra осы көздерден жүктеу сілтемелерін алады. URL-да жүктеу сілтемелері бар .json файлына тікелей сілтеме болуы керек.",
|
||||||
|
@ -110,7 +110,7 @@
|
|||||||
"general": "일반",
|
"general": "일반",
|
||||||
"behavior": "행동",
|
"behavior": "행동",
|
||||||
"enable_real_debrid": "Real-Debrid 활성화",
|
"enable_real_debrid": "Real-Debrid 활성화",
|
||||||
"real_debrid_api_token_hint": "API 키를 <0>이곳</0>에서 얻으세요.",
|
"debrid_api_token_hint": "API 키를 <0>이곳</0>에서 얻으세요.",
|
||||||
"save_changes": "변경 사항 저장"
|
"save_changes": "변경 사항 저장"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
|
@ -177,13 +177,13 @@
|
|||||||
"behavior": "Oppførsel",
|
"behavior": "Oppførsel",
|
||||||
"download_sources": "Nedlastingskilder",
|
"download_sources": "Nedlastingskilder",
|
||||||
"language": "Språk",
|
"language": "Språk",
|
||||||
"real_debrid_api_token": "API nøkkel",
|
"api_token": "API nøkkel",
|
||||||
"enable_real_debrid": "Slå på Real-Debrid",
|
"enable_real_debrid": "Slå på Real-Debrid",
|
||||||
"real_debrid_description": "Real-Debrid er en ubegrenset nedlaster som gør det mulig for deg å laste ned filer med en gang og med den beste utnyttelsen av internethastigheten din.",
|
"real_debrid_description": "Real-Debrid er en ubegrenset nedlaster som gør det mulig for deg å laste ned filer med en gang og med den beste utnyttelsen av internethastigheten din.",
|
||||||
"real_debrid_invalid_token": "Ugyldig API nøkkel",
|
"debrid_invalid_token": "Ugyldig API nøkkel",
|
||||||
"real_debrid_api_token_hint": "Du kan få API nøkkelen din <0>her</0>",
|
"debrid_api_token_hint": "Du kan få API nøkkelen din <0>her</0>",
|
||||||
"real_debrid_free_account_error": "Brukeren \"{{username}}\" er en gratis bruker. Vennligst abboner på Real-Debrid",
|
"real_debrid_free_account_error": "Brukeren \"{{username}}\" er en gratis bruker. Vennligst abboner på Real-Debrid",
|
||||||
"real_debrid_linked_message": "Brukeren \"{{username}}\" er forbunnet",
|
"debrid_linked_message": "Brukeren \"{{username}}\" er forbunnet",
|
||||||
"save_changes": "Lagre endringer",
|
"save_changes": "Lagre endringer",
|
||||||
"changes_saved": "Lagring av endringer vellykket",
|
"changes_saved": "Lagring av endringer vellykket",
|
||||||
"download_sources_description": "Hydra vil hente nedlastingslenker fra disse kildene. Kilde URLen skal være en direkte lenke til en .json fil som inneholder nedlastingslenkene.",
|
"download_sources_description": "Hydra vil hente nedlastingslenker fra disse kildene. Kilde URLen skal være en direkte lenke til en .json fil som inneholder nedlastingslenkene.",
|
||||||
|
@ -111,7 +111,7 @@
|
|||||||
"general": "Algemeen",
|
"general": "Algemeen",
|
||||||
"behavior": "Gedrag",
|
"behavior": "Gedrag",
|
||||||
"enable_real_debrid": "Enable Real-Debrid",
|
"enable_real_debrid": "Enable Real-Debrid",
|
||||||
"real_debrid_api_token_hint": "U kunt uw API-sleutel <0>hier</0> verkrijgen.",
|
"debrid_api_token_hint": "U kunt uw API-sleutel <0>hier</0> verkrijgen.",
|
||||||
"save_changes": "Wijzigingen opslaan"
|
"save_changes": "Wijzigingen opslaan"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
|
@ -119,7 +119,7 @@
|
|||||||
"behavior": "Zachowania",
|
"behavior": "Zachowania",
|
||||||
"language": "Język",
|
"language": "Język",
|
||||||
"enable_real_debrid": "Włącz Real-Debrid",
|
"enable_real_debrid": "Włącz Real-Debrid",
|
||||||
"real_debrid_api_token_hint": "Możesz uzyskać swój klucz API <0>tutaj</0>",
|
"debrid_api_token_hint": "Możesz uzyskać swój klucz API <0>tutaj</0>",
|
||||||
"save_changes": "Zapisz zmiany"
|
"save_changes": "Zapisz zmiany"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
|
@ -229,13 +229,13 @@
|
|||||||
"behavior": "Comportamento",
|
"behavior": "Comportamento",
|
||||||
"download_sources": "Fontes de download",
|
"download_sources": "Fontes de download",
|
||||||
"language": "Idioma",
|
"language": "Idioma",
|
||||||
"real_debrid_api_token": "Token de API",
|
"api_token": "Token de API",
|
||||||
"enable_real_debrid": "Habilitar Real-Debrid",
|
"enable_real_debrid": "Habilitar Real-Debrid",
|
||||||
"real_debrid_api_token_hint": "Você pode obter seu token de API <0>aqui</0>",
|
"debrid_api_token_hint": "Você pode obter seu token de API <0>aqui</0>",
|
||||||
"real_debrid_description": "O Real-Debrid é um downloader sem restrições que permite baixar arquivos instantaneamente e com a melhor velocidade da sua Internet.",
|
"real_debrid_description": "O Real-Debrid é um downloader sem restrições que permite baixar arquivos instantaneamente e com a melhor velocidade da sua Internet.",
|
||||||
"real_debrid_invalid_token": "Token de API inválido",
|
"debrid_invalid_token": "Token de API inválido",
|
||||||
"real_debrid_free_account_error": "A conta \"{{username}}\" é uma conta gratuita. Por favor, assine a Real-Debrid",
|
"real_debrid_free_account_error": "A conta \"{{username}}\" é uma conta gratuita. Por favor, assine a Real-Debrid",
|
||||||
"real_debrid_linked_message": "Conta \"{{username}}\" vinculada",
|
"debrid_linked_message": "Conta \"{{username}}\" vinculada",
|
||||||
"save_changes": "Salvar mudanças",
|
"save_changes": "Salvar mudanças",
|
||||||
"changes_saved": "Ajustes salvos com sucesso",
|
"changes_saved": "Ajustes salvos com sucesso",
|
||||||
"download_sources_description": "Hydra vai buscar links de download em todas as fontes habilitadas. A URL da fonte deve ser um link direto para um arquivo .json contendo uma lista de links.",
|
"download_sources_description": "Hydra vai buscar links de download em todas as fontes habilitadas. A URL da fonte deve ser um link direto para um arquivo .json contendo uma lista de links.",
|
||||||
@ -289,7 +289,11 @@
|
|||||||
"become_subscriber": "Seja Hydra Cloud",
|
"become_subscriber": "Seja Hydra Cloud",
|
||||||
"subscription_renew_cancelled": "A renovação automática está desativada",
|
"subscription_renew_cancelled": "A renovação automática está desativada",
|
||||||
"subscription_renews_on": "Sua assinatura renova dia {{date}}",
|
"subscription_renews_on": "Sua assinatura renova dia {{date}}",
|
||||||
"bill_sent_until": "Sua próxima cobrança será enviada até esse dia"
|
"bill_sent_until": "Sua próxima cobrança será enviada até esse dia",
|
||||||
|
"enable_torbox": "Habilitar Torbox",
|
||||||
|
"torbox_description": "TorBox é o seu serviço de seedbox premium que rivaliza até com os melhores servidores do mercado.",
|
||||||
|
"torbox_account_linked": "Conta do TorBox vinculada",
|
||||||
|
"real_debrid_account_linked": "Conta Real-Debrid associada"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"download_complete": "Download concluído",
|
"download_complete": "Download concluído",
|
||||||
|
@ -205,13 +205,13 @@
|
|||||||
"behavior": "Comportamento",
|
"behavior": "Comportamento",
|
||||||
"download_sources": "Fontes de transferência",
|
"download_sources": "Fontes de transferência",
|
||||||
"language": "Idioma",
|
"language": "Idioma",
|
||||||
"real_debrid_api_token": "Token de API",
|
"api_token": "Token de API",
|
||||||
"enable_real_debrid": "Ativar Real-Debrid",
|
"enable_real_debrid": "Ativar Real-Debrid",
|
||||||
"real_debrid_api_token_hint": "Podes obter o teu token de API <0>aqui</0>",
|
"debrid_api_token_hint": "Podes obter o teu token de API <0>aqui</0>",
|
||||||
"real_debrid_description": "O Real-Debrid é um downloader sem restrições que permite descarregar ficheiros instantaneamente e com a melhor velocidade da tua Internet.",
|
"real_debrid_description": "O Real-Debrid é um downloader sem restrições que permite descarregar ficheiros instantaneamente e com a melhor velocidade da tua Internet.",
|
||||||
"real_debrid_invalid_token": "Token de API inválido",
|
"debrid_invalid_token": "Token de API inválido",
|
||||||
"real_debrid_free_account_error": "A conta \"{{username}}\" é uma conta gratuita. Por favor, subscreve o Real-Debrid",
|
"real_debrid_free_account_error": "A conta \"{{username}}\" é uma conta gratuita. Por favor, subscreve o Real-Debrid",
|
||||||
"real_debrid_linked_message": "Conta \"{{username}}\" associada",
|
"debrid_linked_message": "Conta \"{{username}}\" associada",
|
||||||
"save_changes": "Guardar alterações",
|
"save_changes": "Guardar alterações",
|
||||||
"changes_saved": "Alterações guardadas com sucesso",
|
"changes_saved": "Alterações guardadas com sucesso",
|
||||||
"download_sources_description": "O Hydra vai procurar links de download em todas as fontes ativadas. O URL da fonte deve ser um link direto para um ficheiro .json que contenha uma lista de links.",
|
"download_sources_description": "O Hydra vai procurar links de download em todas as fontes ativadas. O URL da fonte deve ser um link direto para um ficheiro .json que contenha uma lista de links.",
|
||||||
|
@ -124,13 +124,13 @@
|
|||||||
"general": "General",
|
"general": "General",
|
||||||
"behavior": "Comportament",
|
"behavior": "Comportament",
|
||||||
"language": "Limbă",
|
"language": "Limbă",
|
||||||
"real_debrid_api_token": "Token API",
|
"api_token": "Token API",
|
||||||
"enable_real_debrid": "Activează Real-Debrid",
|
"enable_real_debrid": "Activează Real-Debrid",
|
||||||
"real_debrid_description": "Real-Debrid este un descărcător fără restricții care îți permite să descarci fișiere instantaneu și la cea mai bună viteză a internetului tău.",
|
"real_debrid_description": "Real-Debrid este un descărcător fără restricții care îți permite să descarci fișiere instantaneu și la cea mai bună viteză a internetului tău.",
|
||||||
"real_debrid_invalid_token": "Token API invalid",
|
"debrid_invalid_token": "Token API invalid",
|
||||||
"real_debrid_api_token_hint": "Poți obține token-ul tău API <0>aici</0>",
|
"debrid_api_token_hint": "Poți obține token-ul tău API <0>aici</0>",
|
||||||
"real_debrid_free_account_error": "Contul \"{{username}}\" este un cont gratuit. Te rugăm să te abonezi la Real-Debrid",
|
"real_debrid_free_account_error": "Contul \"{{username}}\" este un cont gratuit. Te rugăm să te abonezi la Real-Debrid",
|
||||||
"real_debrid_linked_message": "Contul \"{{username}}\" a fost legat",
|
"debrid_linked_message": "Contul \"{{username}}\" a fost legat",
|
||||||
"save_changes": "Salvează modificările",
|
"save_changes": "Salvează modificările",
|
||||||
"changes_saved": "Modificările au fost salvate cu succes"
|
"changes_saved": "Modificările au fost salvate cu succes"
|
||||||
},
|
},
|
||||||
|
@ -237,13 +237,13 @@
|
|||||||
"behavior": "Поведение",
|
"behavior": "Поведение",
|
||||||
"download_sources": "Источники загрузки",
|
"download_sources": "Источники загрузки",
|
||||||
"language": "Язык",
|
"language": "Язык",
|
||||||
"real_debrid_api_token": "API Ключ",
|
"api_token": "API Ключ",
|
||||||
"enable_real_debrid": "Включить Real-Debrid",
|
"enable_real_debrid": "Включить Real-Debrid",
|
||||||
"real_debrid_description": "Real-Debrid - это неограниченный загрузчик, который позволяет быстро скачивать файлы, размещенные в Интернете, или мгновенно передавать их в плеер через частную сеть, позволяющую обходить любые блокировки.",
|
"real_debrid_description": "Real-Debrid - это неограниченный загрузчик, который позволяет быстро скачивать файлы, размещенные в Интернете, или мгновенно передавать их в плеер через частную сеть, позволяющую обходить любые блокировки.",
|
||||||
"real_debrid_invalid_token": "Неверный API ключ",
|
"debrid_invalid_token": "Неверный API ключ",
|
||||||
"real_debrid_api_token_hint": "API ключ можно получить <0>здесь</0>",
|
"debrid_api_token_hint": "API ключ можно получить <0>здесь</0>",
|
||||||
"real_debrid_free_account_error": "Аккаунт \"{{username}}\" - не имеет подписки. Пожалуйста, оформите подписку на Real-Debrid",
|
"real_debrid_free_account_error": "Аккаунт \"{{username}}\" - не имеет подписки. Пожалуйста, оформите подписку на Real-Debrid",
|
||||||
"real_debrid_linked_message": "Привязан аккаунт \"{{username}}\"",
|
"debrid_linked_message": "Привязан аккаунт \"{{username}}\"",
|
||||||
"save_changes": "Сохранить изменения",
|
"save_changes": "Сохранить изменения",
|
||||||
"changes_saved": "Изменения успешно сохранены",
|
"changes_saved": "Изменения успешно сохранены",
|
||||||
"download_sources_description": "Hydra будет получать ссылки на загрузки из этих источников. URL должна содержать прямую ссылку на .json-файл с ссылками для загрузок.",
|
"download_sources_description": "Hydra будет получать ссылки на загрузки из этих источников. URL должна содержать прямую ссылку на .json-файл с ссылками для загрузок.",
|
||||||
|
@ -236,13 +236,13 @@
|
|||||||
"behavior": "Davranış",
|
"behavior": "Davranış",
|
||||||
"download_sources": "İndirme kaynakları",
|
"download_sources": "İndirme kaynakları",
|
||||||
"language": "Dil",
|
"language": "Dil",
|
||||||
"real_debrid_api_token": "API Anahtarı",
|
"api_token": "API Anahtarı",
|
||||||
"enable_real_debrid": "Real-Debrid'i Etkinleştir",
|
"enable_real_debrid": "Real-Debrid'i Etkinleştir",
|
||||||
"real_debrid_description": "Real-Debrid, yalnızca internet hızınızla sınırlı olarak hızlı dosya indirmenizi sağlayan sınırsız bir indirici.",
|
"real_debrid_description": "Real-Debrid, yalnızca internet hızınızla sınırlı olarak hızlı dosya indirmenizi sağlayan sınırsız bir indirici.",
|
||||||
"real_debrid_invalid_token": "Geçersiz API anahtarı",
|
"debrid_invalid_token": "Geçersiz API anahtarı",
|
||||||
"real_debrid_api_token_hint": "API anahtarınızı <0>buradan</0> alabilirsiniz",
|
"debrid_api_token_hint": "API anahtarınızı <0>buradan</0> alabilirsiniz",
|
||||||
"real_debrid_free_account_error": "\"{{username}}\" hesabı ücretsiz bir hesaptır. Lütfen Real-Debrid abonesi olun",
|
"real_debrid_free_account_error": "\"{{username}}\" hesabı ücretsiz bir hesaptır. Lütfen Real-Debrid abonesi olun",
|
||||||
"real_debrid_linked_message": "\"{{username}}\" hesabı bağlandı",
|
"debrid_linked_message": "\"{{username}}\" hesabı bağlandı",
|
||||||
"save_changes": "Değişiklikleri Kaydet",
|
"save_changes": "Değişiklikleri Kaydet",
|
||||||
"changes_saved": "Değişiklikler başarıyla kaydedildi",
|
"changes_saved": "Değişiklikler başarıyla kaydedildi",
|
||||||
"download_sources_description": "Hydra, indirme bağlantılarını bu kaynaklardan alacak. Kaynak URL, indirme bağlantılarını içeren bir .json dosyasına doğrudan bir bağlantı olmalıdır.",
|
"download_sources_description": "Hydra, indirme bağlantılarını bu kaynaklardan alacak. Kaynak URL, indirme bağlantılarını içeren bir .json dosyasına doğrudan bir bağlantı olmalıdır.",
|
||||||
|
@ -174,13 +174,13 @@
|
|||||||
"import": "Імпортувати",
|
"import": "Імпортувати",
|
||||||
"insert_valid_json_url": "Вставте дійсний URL JSON-файлу",
|
"insert_valid_json_url": "Вставте дійсний URL JSON-файлу",
|
||||||
"language": "Мова",
|
"language": "Мова",
|
||||||
"real_debrid_api_token": "API-токен",
|
"api_token": "API-токен",
|
||||||
"real_debrid_api_token_hint": "API токен можливо отримати <0>тут</0>",
|
"debrid_api_token_hint": "API токен можливо отримати <0>тут</0>",
|
||||||
"real_debrid_api_token_label": "Real-Debrid API-токен",
|
"real_debrid_api_token_label": "Real-Debrid API-токен",
|
||||||
"real_debrid_description": "Real-Debrid — це необмежений завантажувач, який дозволяє швидко завантажувати файли, розміщені в Інтернеті, або миттєво передавати їх у плеєр через приватну мережу, що дозволяє обходити будь-які блокування.",
|
"real_debrid_description": "Real-Debrid — це необмежений завантажувач, який дозволяє швидко завантажувати файли, розміщені в Інтернеті, або миттєво передавати їх у плеєр через приватну мережу, що дозволяє обходити будь-які блокування.",
|
||||||
"real_debrid_free_account_error": "Акаунт \"{{username}}\" - не має наявної підписки. Будь ласка, оформіть підписку на Real-Debrid",
|
"real_debrid_free_account_error": "Акаунт \"{{username}}\" - не має наявної підписки. Будь ласка, оформіть підписку на Real-Debrid",
|
||||||
"real_debrid_invalid_token": "Невірний API-токен",
|
"debrid_invalid_token": "Невірний API-токен",
|
||||||
"real_debrid_linked_message": "Акаунт \"{{username}}\" привязаний",
|
"debrid_linked_message": "Акаунт \"{{username}}\" привязаний",
|
||||||
"remove_download_source": "Видалити",
|
"remove_download_source": "Видалити",
|
||||||
"removed_download_source": "Джерело завантажень було видалено",
|
"removed_download_source": "Джерело завантажень було видалено",
|
||||||
"save_changes": "Зберегти зміни",
|
"save_changes": "Зберегти зміни",
|
||||||
|
@ -213,13 +213,13 @@
|
|||||||
"behavior": "行为",
|
"behavior": "行为",
|
||||||
"download_sources": "下载源",
|
"download_sources": "下载源",
|
||||||
"language": "语言",
|
"language": "语言",
|
||||||
"real_debrid_api_token": "API 令牌",
|
"api_token": "API 令牌",
|
||||||
"enable_real_debrid": "启用 Real-Debrid",
|
"enable_real_debrid": "启用 Real-Debrid",
|
||||||
"real_debrid_description": "Real-Debrid 是一个无限制的下载器,允许您以最快的互联网速度即时下载文件。",
|
"real_debrid_description": "Real-Debrid 是一个无限制的下载器,允许您以最快的互联网速度即时下载文件。",
|
||||||
"real_debrid_invalid_token": "无效的 API 令牌",
|
"debrid_invalid_token": "无效的 API 令牌",
|
||||||
"real_debrid_api_token_hint": "您可以从<0>这里</0>获取API密钥.",
|
"debrid_api_token_hint": "您可以从<0>这里</0>获取API密钥.",
|
||||||
"real_debrid_free_account_error": "账户 \"{{username}}\" 是免费账户。请订阅 Real-Debrid",
|
"real_debrid_free_account_error": "账户 \"{{username}}\" 是免费账户。请订阅 Real-Debrid",
|
||||||
"real_debrid_linked_message": "账户 \"{{username}}\" 已链接",
|
"debrid_linked_message": "账户 \"{{username}}\" 已链接",
|
||||||
"save_changes": "保存更改",
|
"save_changes": "保存更改",
|
||||||
"changes_saved": "更改已成功保存",
|
"changes_saved": "更改已成功保存",
|
||||||
"download_sources_description": "Hydra 将从这些源获取下载链接。源 URL 必须是直接链接到包含下载链接的 .json 文件。",
|
"download_sources_description": "Hydra 将从这些源获取下载链接。源 URL 必须是直接链接到包含下载链接的 .json 文件。",
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { registerEvent } from "../register-event";
|
import { registerEvent } from "../register-event";
|
||||||
import { DownloadManager, HydraApi, gamesPlaytime } from "@main/services";
|
import { DownloadManager, HydraApi, gamesPlaytime } from "@main/services";
|
||||||
import { PythonRPC } from "@main/services/python-rpc";
|
|
||||||
import { db, downloadsSublevel, gamesSublevel, levelKeys } from "@main/level";
|
import { db, downloadsSublevel, gamesSublevel, levelKeys } from "@main/level";
|
||||||
|
|
||||||
const signOut = async (_event: Electron.IpcMainInvokeEvent) => {
|
const signOut = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||||
@ -25,9 +24,6 @@ const signOut = async (_event: Electron.IpcMainInvokeEvent) => {
|
|||||||
/* Cancels any ongoing downloads */
|
/* Cancels any ongoing downloads */
|
||||||
DownloadManager.cancelDownload();
|
DownloadManager.cancelDownload();
|
||||||
|
|
||||||
/* Disconnects libtorrent */
|
|
||||||
PythonRPC.kill();
|
|
||||||
|
|
||||||
HydraApi.handleSignOut();
|
HydraApi.handleSignOut();
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
|
@ -46,6 +46,7 @@ import "./user-preferences/auto-launch";
|
|||||||
import "./autoupdater/check-for-updates";
|
import "./autoupdater/check-for-updates";
|
||||||
import "./autoupdater/restart-and-install-update";
|
import "./autoupdater/restart-and-install-update";
|
||||||
import "./user-preferences/authenticate-real-debrid";
|
import "./user-preferences/authenticate-real-debrid";
|
||||||
|
import "./user-preferences/authenticate-torbox";
|
||||||
import "./download-sources/put-download-source";
|
import "./download-sources/put-download-source";
|
||||||
import "./auth/sign-out";
|
import "./auth/sign-out";
|
||||||
import "./auth/open-auth-window";
|
import "./auth/open-auth-window";
|
||||||
|
@ -76,10 +76,10 @@ const startGameDownload = async (
|
|||||||
queued: true,
|
queued: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
await downloadsSublevel.put(gameKey, download);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await DownloadManager.startDownload(download);
|
await DownloadManager.startDownload(download).then(() => {
|
||||||
|
return downloadsSublevel.put(gameKey, download);
|
||||||
|
});
|
||||||
|
|
||||||
const updatedGame = await gamesSublevel.get(gameKey);
|
const updatedGame = await gamesSublevel.get(gameKey);
|
||||||
|
|
||||||
@ -113,6 +113,10 @@ const startGameDownload = async (
|
|||||||
error: DownloadError.RealDebridAccountNotAuthorized,
|
error: DownloadError.RealDebridAccountNotAuthorized,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (downloader === Downloader.TorBox) {
|
||||||
|
return { ok: false, error: err.response?.data?.detail };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err instanceof Error) {
|
if (err instanceof Error) {
|
||||||
|
14
src/main/events/user-preferences/authenticate-torbox.ts
Normal file
14
src/main/events/user-preferences/authenticate-torbox.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { registerEvent } from "../register-event";
|
||||||
|
import { TorBoxClient } from "@main/services/download/torbox";
|
||||||
|
|
||||||
|
const authenticateTorBox = async (
|
||||||
|
_event: Electron.IpcMainInvokeEvent,
|
||||||
|
apiToken: string
|
||||||
|
) => {
|
||||||
|
TorBoxClient.authorize(apiToken);
|
||||||
|
|
||||||
|
const user = await TorBoxClient.getUser();
|
||||||
|
return user;
|
||||||
|
};
|
||||||
|
|
||||||
|
registerEvent("authenticateTorBox", authenticateTorBox);
|
@ -15,6 +15,12 @@ const getUserPreferences = async () =>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (userPreferences?.torBoxApiToken) {
|
||||||
|
userPreferences.torBoxApiToken = Crypto.decrypt(
|
||||||
|
userPreferences.torBoxApiToken
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return userPreferences;
|
return userPreferences;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@ const updateUserPreferences = async (
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (preferences.torBoxApiToken) {
|
||||||
|
preferences.torBoxApiToken = Crypto.encrypt(preferences.torBoxApiToken);
|
||||||
|
}
|
||||||
|
|
||||||
if (!preferences.downloadsPath) {
|
if (!preferences.downloadsPath) {
|
||||||
preferences.downloadsPath = null;
|
preferences.downloadsPath = null;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import {
|
|||||||
} from "./level";
|
} from "./level";
|
||||||
import { Auth, User, type UserPreferences } from "@types";
|
import { Auth, User, type UserPreferences } from "@types";
|
||||||
import { knexClient } from "./knex-client";
|
import { knexClient } from "./knex-client";
|
||||||
|
import { TorBoxClient } from "./services/download/torbox";
|
||||||
|
|
||||||
export const loadState = async () => {
|
export const loadState = async () => {
|
||||||
const userPreferences = await migrateFromSqlite().then(async () => {
|
const userPreferences = await migrateFromSqlite().then(async () => {
|
||||||
@ -42,6 +43,10 @@ export const loadState = async () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (userPreferences?.torBoxApiToken) {
|
||||||
|
TorBoxClient.authorize(Crypto.decrypt(userPreferences.torBoxApiToken));
|
||||||
|
}
|
||||||
|
|
||||||
Ludusavi.addManifestToLudusaviConfig();
|
Ludusavi.addManifestToLudusaviConfig();
|
||||||
|
|
||||||
HydraApi.setupApi().then(() => {
|
HydraApi.setupApi().then(() => {
|
||||||
|
@ -15,6 +15,7 @@ import path from "path";
|
|||||||
import { logger } from "../logger";
|
import { logger } from "../logger";
|
||||||
import { db, downloadsSublevel, gamesSublevel, levelKeys } from "@main/level";
|
import { db, downloadsSublevel, gamesSublevel, levelKeys } from "@main/level";
|
||||||
import { sortBy } from "lodash-es";
|
import { sortBy } from "lodash-es";
|
||||||
|
import { TorBoxClient } from "./torbox";
|
||||||
|
|
||||||
export class DownloadManager {
|
export class DownloadManager {
|
||||||
private static downloadingGameId: string | null = null;
|
private static downloadingGameId: string | null = null;
|
||||||
@ -275,6 +276,7 @@ export class DownloadManager {
|
|||||||
}
|
}
|
||||||
case Downloader.PixelDrain: {
|
case Downloader.PixelDrain: {
|
||||||
const id = download.uri.split("/").pop();
|
const id = download.uri.split("/").pop();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
action: "start",
|
action: "start",
|
||||||
game_id: downloadId,
|
game_id: downloadId,
|
||||||
@ -329,6 +331,18 @@ export class DownloadManager {
|
|||||||
save_path: download.downloadPath,
|
save_path: download.downloadPath,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
case Downloader.TorBox: {
|
||||||
|
const { name, url } = await TorBoxClient.getDownloadInfo(download.uri);
|
||||||
|
|
||||||
|
if (!url) return;
|
||||||
|
return {
|
||||||
|
action: "start",
|
||||||
|
game_id: downloadId,
|
||||||
|
url,
|
||||||
|
save_path: download.downloadPath,
|
||||||
|
out: name,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,24 +6,23 @@ import type {
|
|||||||
TorBoxAddTorrentRequest,
|
TorBoxAddTorrentRequest,
|
||||||
TorBoxRequestLinkRequest,
|
TorBoxRequestLinkRequest,
|
||||||
} from "@types";
|
} from "@types";
|
||||||
import { logger } from "../logger";
|
|
||||||
|
|
||||||
export class TorBoxClient {
|
export class TorBoxClient {
|
||||||
private static instance: AxiosInstance;
|
private static instance: AxiosInstance;
|
||||||
private static readonly baseURL = "https://api.torbox.app/v1/api";
|
private static readonly baseURL = "https://api.torbox.app/v1/api";
|
||||||
public static apiToken: string;
|
private static apiToken: string;
|
||||||
|
|
||||||
static authorize(apiToken: string) {
|
static authorize(apiToken: string) {
|
||||||
|
this.apiToken = apiToken;
|
||||||
this.instance = axios.create({
|
this.instance = axios.create({
|
||||||
baseURL: this.baseURL,
|
baseURL: this.baseURL,
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${apiToken}`,
|
Authorization: `Bearer ${apiToken}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
this.apiToken = apiToken;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async addMagnet(magnet: string) {
|
private static async addMagnet(magnet: string) {
|
||||||
const form = new FormData();
|
const form = new FormData();
|
||||||
form.append("magnet", magnet);
|
form.append("magnet", magnet);
|
||||||
|
|
||||||
@ -32,6 +31,10 @@ export class TorBoxClient {
|
|||||||
form
|
form
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!response.data.success) {
|
||||||
|
throw new Error(response.data.detail);
|
||||||
|
}
|
||||||
|
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,22 +58,16 @@ export class TorBoxClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async requestLink(id: number) {
|
static async requestLink(id: number) {
|
||||||
const searchParams = new URLSearchParams({});
|
const searchParams = new URLSearchParams({
|
||||||
|
token: this.apiToken,
|
||||||
searchParams.set("token", this.apiToken);
|
torrent_id: id.toString(),
|
||||||
searchParams.set("torrent_id", id.toString());
|
zip_link: "true",
|
||||||
searchParams.set("zip_link", "true");
|
});
|
||||||
|
|
||||||
const response = await this.instance.get<TorBoxRequestLinkRequest>(
|
const response = await this.instance.get<TorBoxRequestLinkRequest>(
|
||||||
"/torrents/requestdl?" + searchParams.toString()
|
"/torrents/requestdl?" + searchParams.toString()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.status !== 200) {
|
|
||||||
logger.error(response.data.error);
|
|
||||||
logger.error(response.data.detail);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +78,7 @@ export class TorBoxClient {
|
|||||||
return response.data.data;
|
return response.data.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getTorrentId(magnetUri: string) {
|
private static async getTorrentIdAndName(magnetUri: string) {
|
||||||
const userTorrents = await this.getAllTorrentsFromUser();
|
const userTorrents = await this.getAllTorrentsFromUser();
|
||||||
|
|
||||||
const { infoHash } = await parseTorrent(magnetUri);
|
const { infoHash } = await parseTorrent(magnetUri);
|
||||||
@ -89,9 +86,18 @@ export class TorBoxClient {
|
|||||||
(userTorrent) => userTorrent.hash === infoHash
|
(userTorrent) => userTorrent.hash === infoHash
|
||||||
);
|
);
|
||||||
|
|
||||||
if (userTorrent) return userTorrent.id;
|
if (userTorrent) return { id: userTorrent.id, name: userTorrent.name };
|
||||||
|
|
||||||
const torrent = await this.addMagnet(magnetUri);
|
const torrent = await this.addMagnet(magnetUri);
|
||||||
return torrent.torrent_id;
|
return { id: torrent.torrent_id, name: torrent.name };
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getDownloadInfo(uri: string) {
|
||||||
|
const torrentData = await this.getTorrentIdAndName(uri);
|
||||||
|
const url = await this.requestLink(torrentData.id);
|
||||||
|
|
||||||
|
const name = torrentData.name ? `${torrentData.name}.zip` : undefined;
|
||||||
|
|
||||||
|
return { url, name };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,8 @@ contextBridge.exposeInMainWorld("electron", {
|
|||||||
ipcRenderer.invoke("autoLaunch", autoLaunchProps),
|
ipcRenderer.invoke("autoLaunch", autoLaunchProps),
|
||||||
authenticateRealDebrid: (apiToken: string) =>
|
authenticateRealDebrid: (apiToken: string) =>
|
||||||
ipcRenderer.invoke("authenticateRealDebrid", apiToken),
|
ipcRenderer.invoke("authenticateRealDebrid", apiToken),
|
||||||
|
authenticateTorBox: (apiToken: string) =>
|
||||||
|
ipcRenderer.invoke("authenticateTorBox", apiToken),
|
||||||
|
|
||||||
/* Download sources */
|
/* Download sources */
|
||||||
putDownloadSource: (objectIds: string[]) =>
|
putDownloadSource: (objectIds: string[]) =>
|
||||||
|
BIN
src/renderer/src/assets/icons/torbox.webp
Normal file
BIN
src/renderer/src/assets/icons/torbox.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
@ -14,7 +14,7 @@ export const textField = recipe({
|
|||||||
base: {
|
base: {
|
||||||
display: "inline-flex",
|
display: "inline-flex",
|
||||||
transition: "all ease 0.2s",
|
transition: "all ease 0.2s",
|
||||||
width: "100%",
|
flex: 1,
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
border: `solid 1px ${vars.color.border}`,
|
border: `solid 1px ${vars.color.border}`,
|
||||||
|
@ -10,6 +10,7 @@ export const DOWNLOADER_NAME = {
|
|||||||
[Downloader.Qiwi]: "Qiwi",
|
[Downloader.Qiwi]: "Qiwi",
|
||||||
[Downloader.Datanodes]: "Datanodes",
|
[Downloader.Datanodes]: "Datanodes",
|
||||||
[Downloader.Mediafire]: "Mediafire",
|
[Downloader.Mediafire]: "Mediafire",
|
||||||
|
[Downloader.TorBox]: "TorBox",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MAX_MINUTES_TO_SHOW_IN_PLAYTIME = 120;
|
export const MAX_MINUTES_TO_SHOW_IN_PLAYTIME = 120;
|
||||||
|
2
src/renderer/src/declaration.d.ts
vendored
2
src/renderer/src/declaration.d.ts
vendored
@ -28,6 +28,7 @@ import type {
|
|||||||
CatalogueSearchPayload,
|
CatalogueSearchPayload,
|
||||||
LibraryGame,
|
LibraryGame,
|
||||||
GameRunning,
|
GameRunning,
|
||||||
|
TorBoxUser,
|
||||||
} from "@types";
|
} from "@types";
|
||||||
import type { AxiosProgressEvent } from "axios";
|
import type { AxiosProgressEvent } from "axios";
|
||||||
import type disk from "diskusage";
|
import type disk from "diskusage";
|
||||||
@ -144,6 +145,7 @@ declare global {
|
|||||||
minimized: boolean;
|
minimized: boolean;
|
||||||
}) => Promise<void>;
|
}) => Promise<void>;
|
||||||
authenticateRealDebrid: (apiToken: string) => Promise<RealDebridUser>;
|
authenticateRealDebrid: (apiToken: string) => Promise<RealDebridUser>;
|
||||||
|
authenticateTorBox: (apiToken: string) => Promise<TorBoxUser>;
|
||||||
onAchievementUnlocked: (cb: () => void) => () => Electron.IpcRenderer;
|
onAchievementUnlocked: (cb: () => void) => () => Electron.IpcRenderer;
|
||||||
|
|
||||||
/* Download sources */
|
/* Download sources */
|
||||||
|
@ -30,6 +30,9 @@ import {
|
|||||||
XCircleIcon,
|
XCircleIcon,
|
||||||
} from "@primer/octicons-react";
|
} from "@primer/octicons-react";
|
||||||
|
|
||||||
|
import torBoxLogo from "@renderer/assets/icons/torbox.webp";
|
||||||
|
import { SPACING_UNIT, vars } from "@renderer/theme.css";
|
||||||
|
|
||||||
export interface DownloadGroupProps {
|
export interface DownloadGroupProps {
|
||||||
library: LibraryGame[];
|
library: LibraryGame[];
|
||||||
title: string;
|
title: string;
|
||||||
@ -235,12 +238,16 @@ export function DownloadGroup({
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isResumeDisabled =
|
||||||
|
(download?.downloader === Downloader.RealDebrid &&
|
||||||
|
!userPreferences?.realDebridApiToken) ||
|
||||||
|
(download?.downloader === Downloader.TorBox &&
|
||||||
|
!userPreferences?.torBoxApiToken);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: t("resume"),
|
label: t("resume"),
|
||||||
disabled:
|
disabled: isResumeDisabled,
|
||||||
download?.downloader === Downloader.RealDebrid &&
|
|
||||||
!userPreferences?.realDebridApiToken,
|
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
resumeDownload(game.shop, game.objectId);
|
resumeDownload(game.shop, game.objectId);
|
||||||
},
|
},
|
||||||
@ -279,13 +286,30 @@ export function DownloadGroup({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="download-group__cover-content">
|
<div className="download-group__cover-content">
|
||||||
<Badge>
|
{game.download?.downloader === Downloader.TorBox ? (
|
||||||
{
|
<div
|
||||||
DOWNLOADER_NAME[
|
style={{
|
||||||
game?.download?.downloader as Downloader
|
display: "flex",
|
||||||
]
|
alignItems: "center",
|
||||||
}
|
background: "#11141b",
|
||||||
</Badge>
|
padding: `${SPACING_UNIT / 2}px ${SPACING_UNIT}px`,
|
||||||
|
borderRadius: "4px",
|
||||||
|
gap: 4,
|
||||||
|
border: `1px solid ${vars.color.border}`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={torBoxLogo}
|
||||||
|
alt="TorBox"
|
||||||
|
style={{ width: 13 }}
|
||||||
|
/>
|
||||||
|
<span style={{ fontSize: 10 }}>TorBox</span>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<Badge>
|
||||||
|
{DOWNLOADER_NAME[game.download!.downloader]}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -88,14 +88,14 @@ export function DownloadSettingsModal({
|
|||||||
const filteredDownloaders = downloaders.filter((downloader) => {
|
const filteredDownloaders = downloaders.filter((downloader) => {
|
||||||
if (downloader === Downloader.RealDebrid)
|
if (downloader === Downloader.RealDebrid)
|
||||||
return userPreferences?.realDebridApiToken;
|
return userPreferences?.realDebridApiToken;
|
||||||
|
if (downloader === Downloader.TorBox)
|
||||||
|
return userPreferences?.torBoxApiToken;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Gives preference to Real Debrid */
|
/* Gives preference to TorBox */
|
||||||
const selectedDownloader = filteredDownloaders.includes(
|
const selectedDownloader = filteredDownloaders.includes(Downloader.TorBox)
|
||||||
Downloader.RealDebrid
|
? Downloader.TorBox
|
||||||
)
|
|
||||||
? Downloader.RealDebrid
|
|
||||||
: filteredDownloaders[0];
|
: filteredDownloaders[0];
|
||||||
|
|
||||||
setSelectedDownloader(selectedDownloader ?? null);
|
setSelectedDownloader(selectedDownloader ?? null);
|
||||||
|
@ -57,7 +57,8 @@ export function SettingsRealDebrid() {
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
showSuccessToast(
|
showSuccessToast(
|
||||||
t("real_debrid_linked_message", { username: user.username })
|
t("real_debrid_account_linked"),
|
||||||
|
t("debrid_linked_message", { username: user.username })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -68,7 +69,7 @@ export function SettingsRealDebrid() {
|
|||||||
realDebridApiToken: form.useRealDebrid ? form.realDebridApiToken : null,
|
realDebridApiToken: form.useRealDebrid ? form.realDebridApiToken : null,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showErrorToast(t("real_debrid_invalid_token"));
|
showErrorToast(t("debrid_invalid_token"));
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
@ -94,29 +95,30 @@ export function SettingsRealDebrid() {
|
|||||||
|
|
||||||
{form.useRealDebrid && (
|
{form.useRealDebrid && (
|
||||||
<TextField
|
<TextField
|
||||||
label={t("real_debrid_api_token")}
|
label={t("api_token")}
|
||||||
value={form.realDebridApiToken ?? ""}
|
value={form.realDebridApiToken ?? ""}
|
||||||
type="password"
|
type="password"
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setForm({ ...form, realDebridApiToken: event.target.value })
|
setForm({ ...form, realDebridApiToken: event.target.value })
|
||||||
}
|
}
|
||||||
placeholder="API Token"
|
placeholder="API Token"
|
||||||
containerProps={{ style: { marginTop: `${SPACING_UNIT}px` } }}
|
containerProps={{
|
||||||
|
style: {
|
||||||
|
marginTop: `${SPACING_UNIT}px`,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
rightContent={
|
||||||
|
<Button type="submit" disabled={isButtonDisabled}>
|
||||||
|
{t("save_changes")}
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
hint={
|
hint={
|
||||||
<Trans i18nKey="real_debrid_api_token_hint" ns="settings">
|
<Trans i18nKey="debrid_api_token_hint" ns="settings">
|
||||||
<Link to={REAL_DEBRID_API_TOKEN_URL} />
|
<Link to={REAL_DEBRID_API_TOKEN_URL} />
|
||||||
</Trans>
|
</Trans>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Button
|
|
||||||
type="submit"
|
|
||||||
style={{ alignSelf: "flex-end", marginTop: `${SPACING_UNIT * 2}px` }}
|
|
||||||
disabled={isButtonDisabled}
|
|
||||||
>
|
|
||||||
{t("save_changes")}
|
|
||||||
</Button>
|
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
13
src/renderer/src/pages/settings/settings-torbox.css.ts
Normal file
13
src/renderer/src/pages/settings/settings-torbox.css.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { style } from "@vanilla-extract/css";
|
||||||
|
|
||||||
|
import { SPACING_UNIT } from "../../theme.css";
|
||||||
|
|
||||||
|
export const form = style({
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: `${SPACING_UNIT}px`,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const description = style({
|
||||||
|
marginBottom: `${SPACING_UNIT * 2}px`,
|
||||||
|
});
|
116
src/renderer/src/pages/settings/settings-torbox.tsx
Normal file
116
src/renderer/src/pages/settings/settings-torbox.tsx
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import { useContext, useEffect, useState } from "react";
|
||||||
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { Button, CheckboxField, Link, TextField } from "@renderer/components";
|
||||||
|
import * as styles from "./settings-torbox.css";
|
||||||
|
|
||||||
|
import { useAppSelector, useToast } from "@renderer/hooks";
|
||||||
|
|
||||||
|
import { SPACING_UNIT } from "@renderer/theme.css";
|
||||||
|
import { settingsContext } from "@renderer/context";
|
||||||
|
|
||||||
|
const TORBOX_API_TOKEN_URL = "https://torbox.app/settings";
|
||||||
|
|
||||||
|
export function SettingsTorbox() {
|
||||||
|
const userPreferences = useAppSelector(
|
||||||
|
(state) => state.userPreferences.value
|
||||||
|
);
|
||||||
|
|
||||||
|
const { updateUserPreferences } = useContext(settingsContext);
|
||||||
|
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [form, setForm] = useState({
|
||||||
|
useTorBox: false,
|
||||||
|
torBoxApiToken: null as string | null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { showSuccessToast, showErrorToast } = useToast();
|
||||||
|
|
||||||
|
const { t } = useTranslation("settings");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (userPreferences) {
|
||||||
|
setForm({
|
||||||
|
useTorBox: Boolean(userPreferences.torBoxApiToken),
|
||||||
|
torBoxApiToken: userPreferences.torBoxApiToken ?? null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [userPreferences]);
|
||||||
|
|
||||||
|
const handleFormSubmit: React.FormEventHandler<HTMLFormElement> = async (
|
||||||
|
event
|
||||||
|
) => {
|
||||||
|
setIsLoading(true);
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (form.useTorBox) {
|
||||||
|
const user = await window.electron.authenticateTorBox(
|
||||||
|
form.torBoxApiToken!
|
||||||
|
);
|
||||||
|
|
||||||
|
showSuccessToast(
|
||||||
|
t("torbox_account_linked"),
|
||||||
|
t("debrid_linked_message", { username: user.email })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
showSuccessToast(t("changes_saved"));
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUserPreferences({
|
||||||
|
torBoxApiToken: form.useTorBox ? form.torBoxApiToken : null,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
showErrorToast(t("debrid_invalid_token"));
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const isButtonDisabled =
|
||||||
|
(form.useTorBox && !form.torBoxApiToken) || isLoading;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form className={styles.form} onSubmit={handleFormSubmit}>
|
||||||
|
<p className={styles.description}>{t("torbox_description")}</p>
|
||||||
|
|
||||||
|
<CheckboxField
|
||||||
|
label={t("enable_torbox")}
|
||||||
|
checked={form.useTorBox}
|
||||||
|
onChange={() =>
|
||||||
|
setForm((prev) => ({
|
||||||
|
...prev,
|
||||||
|
useTorBox: !form.useTorBox,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{form.useTorBox && (
|
||||||
|
<TextField
|
||||||
|
label={t("api_token")}
|
||||||
|
value={form.torBoxApiToken ?? ""}
|
||||||
|
type="password"
|
||||||
|
onChange={(event) =>
|
||||||
|
setForm({ ...form, torBoxApiToken: event.target.value })
|
||||||
|
}
|
||||||
|
placeholder="API Token"
|
||||||
|
containerProps={{
|
||||||
|
style: {
|
||||||
|
marginTop: `${SPACING_UNIT}px`,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
rightContent={
|
||||||
|
<Button type="submit" disabled={isButtonDisabled}>
|
||||||
|
{t("save_changes")}
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
hint={
|
||||||
|
<Trans i18nKey="debrid_api_token_hint" ns="settings">
|
||||||
|
<Link to={TORBOX_API_TOKEN_URL} />
|
||||||
|
</Trans>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
@ -5,7 +5,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { SettingsRealDebrid } from "./settings-real-debrid";
|
import { SettingsRealDebrid } from "./settings-real-debrid";
|
||||||
import { SettingsGeneral } from "./settings-general";
|
import { SettingsGeneral } from "./settings-general";
|
||||||
import { SettingsBehavior } from "./settings-behavior";
|
import { SettingsBehavior } from "./settings-behavior";
|
||||||
|
import torBoxLogo from "@renderer/assets/icons/torbox.webp";
|
||||||
import { SettingsDownloadSources } from "./settings-download-sources";
|
import { SettingsDownloadSources } from "./settings-download-sources";
|
||||||
import {
|
import {
|
||||||
SettingsContextConsumer,
|
SettingsContextConsumer,
|
||||||
@ -14,6 +14,7 @@ import {
|
|||||||
import { SettingsAccount } from "./settings-account";
|
import { SettingsAccount } from "./settings-account";
|
||||||
import { useUserDetails } from "@renderer/hooks";
|
import { useUserDetails } from "@renderer/hooks";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
|
import { SettingsTorbox } from "./settings-torbox";
|
||||||
|
|
||||||
export default function Settings() {
|
export default function Settings() {
|
||||||
const { t } = useTranslation("settings");
|
const { t } = useTranslation("settings");
|
||||||
@ -22,13 +23,26 @@ export default function Settings() {
|
|||||||
|
|
||||||
const categories = useMemo(() => {
|
const categories = useMemo(() => {
|
||||||
const categories = [
|
const categories = [
|
||||||
t("general"),
|
{ tabLabel: t("general"), contentTitle: t("general") },
|
||||||
t("behavior"),
|
{ tabLabel: t("behavior"), contentTitle: t("behavior") },
|
||||||
t("download_sources"),
|
{ tabLabel: t("download_sources"), contentTitle: t("download_sources") },
|
||||||
"Real-Debrid",
|
{
|
||||||
|
tabLabel: (
|
||||||
|
<>
|
||||||
|
<img src={torBoxLogo} alt="TorBox" style={{ width: 13 }} />
|
||||||
|
Torbox
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
contentTitle: "TorBox",
|
||||||
|
},
|
||||||
|
{ tabLabel: "Real-Debrid", contentTitle: "Real-Debrid" },
|
||||||
];
|
];
|
||||||
|
|
||||||
if (userDetails) return [...categories, t("account")];
|
if (userDetails)
|
||||||
|
return [
|
||||||
|
...categories,
|
||||||
|
{ tabLabel: t("account"), contentTitle: t("account") },
|
||||||
|
];
|
||||||
return categories;
|
return categories;
|
||||||
}, [userDetails, t]);
|
}, [userDetails, t]);
|
||||||
|
|
||||||
@ -50,6 +64,10 @@ export default function Settings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currentCategoryIndex === 3) {
|
if (currentCategoryIndex === 3) {
|
||||||
|
return <SettingsTorbox />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentCategoryIndex === 4) {
|
||||||
return <SettingsRealDebrid />;
|
return <SettingsRealDebrid />;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,18 +80,18 @@ export default function Settings() {
|
|||||||
<section className={styles.settingsCategories}>
|
<section className={styles.settingsCategories}>
|
||||||
{categories.map((category, index) => (
|
{categories.map((category, index) => (
|
||||||
<Button
|
<Button
|
||||||
key={category}
|
key={index}
|
||||||
theme={
|
theme={
|
||||||
currentCategoryIndex === index ? "primary" : "outline"
|
currentCategoryIndex === index ? "primary" : "outline"
|
||||||
}
|
}
|
||||||
onClick={() => setCurrentCategoryIndex(index)}
|
onClick={() => setCurrentCategoryIndex(index)}
|
||||||
>
|
>
|
||||||
{category}
|
{category.tabLabel}
|
||||||
</Button>
|
</Button>
|
||||||
))}
|
))}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<h2>{categories[currentCategoryIndex]}</h2>
|
<h2>{categories[currentCategoryIndex].contentTitle}</h2>
|
||||||
{renderCategory()}
|
{renderCategory()}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -6,6 +6,7 @@ export enum Downloader {
|
|||||||
Qiwi,
|
Qiwi,
|
||||||
Datanodes,
|
Datanodes,
|
||||||
Mediafire,
|
Mediafire,
|
||||||
|
TorBox,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum DownloadSourceStatus {
|
export enum DownloadSourceStatus {
|
||||||
|
@ -95,7 +95,7 @@ export const getDownloadersForUri = (uri: string) => {
|
|||||||
return [Downloader.RealDebrid];
|
return [Downloader.RealDebrid];
|
||||||
|
|
||||||
if (uri.startsWith("magnet:")) {
|
if (uri.startsWith("magnet:")) {
|
||||||
return [Downloader.Torrent, Downloader.RealDebrid];
|
return [Downloader.Torrent, Downloader.TorBox, Downloader.RealDebrid];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
|
@ -69,6 +69,7 @@ export interface UserPreferences {
|
|||||||
downloadsPath?: string | null;
|
downloadsPath?: string | null;
|
||||||
language?: string;
|
language?: string;
|
||||||
realDebridApiToken?: string | null;
|
realDebridApiToken?: string | null;
|
||||||
|
torBoxApiToken?: string | null;
|
||||||
preferQuitInsteadOfHiding?: boolean;
|
preferQuitInsteadOfHiding?: boolean;
|
||||||
runAtStartup?: boolean;
|
runAtStartup?: boolean;
|
||||||
startMinimized?: boolean;
|
startMinimized?: boolean;
|
||||||
|
Loading…
Reference in New Issue
Block a user