From ad617847443df67bc34273b9e7b5f8e303a8c238 Mon Sep 17 00:00:00 2001 From: Lukas Pupka-Lipinski Date: Sun, 22 Jun 2025 19:59:48 +0200 Subject: [PATCH] full rework --- errors.log | 786 ------------------ src/AniWorld-Downloader | 1 - src/AniWorldLoader.py | 137 --- src/Loaders/AniWorldLoader.py | 327 ++++++++ src/Loaders/Loader.py | 27 + src/Loaders/Loaders.py | 10 + src/Loaders/Providers.py | 12 + src/Loaders/__init__.py | 0 .../AniWorldLoader.cpython-310.pyc | Bin 0 -> 10757 bytes .../__pycache__/Loader.cpython-310.pyc | Bin 0 -> 1364 bytes .../__pycache__/Loaders.cpython-310.pyc | Bin 0 -> 718 bytes .../__pycache__/Providers.cpython-310.pyc | Bin 0 -> 722 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 133 bytes src/Loaders/provider/Provider.py | 7 + .../__pycache__/Provider.cpython-310.pyc | Bin 0 -> 570 bytes .../provider/__pycache__/voe.cpython-310.pyc | Bin 0 -> 3438 bytes src/Loaders/provider/doodstream.py | 59 ++ src/Loaders/provider/filemoon.py | 51 ++ src/Loaders/provider/hanime.py | 90 ++ src/Loaders/provider/loadx.py | 35 + src/Loaders/provider/luluvdo.py | 39 + src/Loaders/provider/speedfiles.py | 43 + src/Loaders/provider/streamtape.py | 2 + src/Loaders/provider/vidmoly.py | 34 + src/Loaders/provider/vidoza.py | 29 + src/Loaders/provider/voe.py | 101 +++ src/Main.py | 77 +- src/SerieList.py | 21 +- src/SerieScanner.py | 19 +- src/__pycache__/Serie.cpython-310.pyc | Bin 2405 -> 3467 bytes 30 files changed, 928 insertions(+), 979 deletions(-) delete mode 160000 src/AniWorld-Downloader delete mode 100644 src/AniWorldLoader.py create mode 100644 src/Loaders/AniWorldLoader.py create mode 100644 src/Loaders/Loader.py create mode 100644 src/Loaders/Loaders.py create mode 100644 src/Loaders/Providers.py create mode 100644 src/Loaders/__init__.py create mode 100644 src/Loaders/__pycache__/AniWorldLoader.cpython-310.pyc create mode 100644 src/Loaders/__pycache__/Loader.cpython-310.pyc create mode 100644 src/Loaders/__pycache__/Loaders.cpython-310.pyc create mode 100644 src/Loaders/__pycache__/Providers.cpython-310.pyc create mode 100644 src/Loaders/__pycache__/__init__.cpython-310.pyc create mode 100644 src/Loaders/provider/Provider.py create mode 100644 src/Loaders/provider/__pycache__/Provider.cpython-310.pyc create mode 100644 src/Loaders/provider/__pycache__/voe.cpython-310.pyc create mode 100644 src/Loaders/provider/doodstream.py create mode 100644 src/Loaders/provider/filemoon.py create mode 100644 src/Loaders/provider/hanime.py create mode 100644 src/Loaders/provider/loadx.py create mode 100644 src/Loaders/provider/luluvdo.py create mode 100644 src/Loaders/provider/speedfiles.py create mode 100644 src/Loaders/provider/streamtape.py create mode 100644 src/Loaders/provider/vidmoly.py create mode 100644 src/Loaders/provider/vidoza.py create mode 100644 src/Loaders/provider/voe.py diff --git a/errors.log b/errors.log index dd9866d..e69de29 100644 --- a/errors.log +++ b/errors.log @@ -1,786 +0,0 @@ -Unexpected error processing folder 'A.I.C.O. Incarnation (2018)': ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -ConnectionResetError: [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 667, in send - resp = conn.urlopen( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 841, in urlopen - retries = retries.increment( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\retry.py", line 474, in increment - raise reraise(type(error), error, _stacktrace) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\util.py", line 38, in reraise - raise value.with_traceback(tb) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "D:\repo\AniWorld\src\FolderLookup.py", line 31, in __init - missings, site = self.__GetMissingEpisodesAndSeason(serie.key, mp4_files) - File "D:\repo\AniWorld\src\FolderLookup.py", line 136, in __GetMissingEpisodesAndSeason - expected_dict = get_season_episode_count(key) # key season , value count of episodes - File "D:\repo\AniWorld\src\AniWorld-Downloader\src\aniworld\common\common.py", line 245, in get_season_episode_count - response = session.get(base_url, headers=ANIWORLD_HEADERS, timeout=DEFAULT_REQUEST_TIMEOUT) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 602, in get - return self.request("GET", url, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 589, in request - resp = self.send(prep, **send_kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 703, in send - r = adapter.send(request, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 682, in send - raise ConnectionError(err, request=request) -requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -Unexpected error processing folder 'A.I.C.O. Incarnation (2018)': ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -ConnectionResetError: [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 667, in send - resp = conn.urlopen( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 841, in urlopen - retries = retries.increment( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\retry.py", line 474, in increment - raise reraise(type(error), error, _stacktrace) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\util.py", line 38, in reraise - raise value.with_traceback(tb) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "D:\repo\AniWorld\src\FolderLookup.py", line 31, in __init - missings, site = self.__GetMissingEpisodesAndSeason(serie.key, mp4_files) - File "D:\repo\AniWorld\src\FolderLookup.py", line 136, in __GetMissingEpisodesAndSeason - expected_dict = get_season_episode_count(key) # key season , value count of episodes - File "D:\repo\AniWorld\src\AniWorld-Downloader\src\aniworld\common\common.py", line 245, in get_season_episode_count - response = session.get(base_url, headers=ANIWORLD_HEADERS, timeout=DEFAULT_REQUEST_TIMEOUT) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 602, in get - return self.request("GET", url, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 589, in request - resp = self.send(prep, **send_kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 703, in send - r = adapter.send(request, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 682, in send - raise ConnectionError(err, request=request) -requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -Unexpected error processing folder 'A.I.C.O. Incarnation (2018)': argument of type 'types.GenericAlias' is not iterable - Traceback (most recent call last): - File "D:\repo\AniWorld\src\FolderLookup.py", line 34, in __init - if folder not in self.folderDict: -TypeError: argument of type 'types.GenericAlias' is not iterable - -Unexpected error processing folder 'A.I.C.O. Incarnation (2018)': ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -ConnectionResetError: [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 667, in send - resp = conn.urlopen( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 841, in urlopen - retries = retries.increment( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\retry.py", line 474, in increment - raise reraise(type(error), error, _stacktrace) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\util.py", line 38, in reraise - raise value.with_traceback(tb) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "D:\repo\AniWorld\src\FolderLookup.py", line 31, in __init - missings, site = self.__GetMissingEpisodesAndSeason(serie.key, mp4_files) - File "D:\repo\AniWorld\src\FolderLookup.py", line 136, in __GetMissingEpisodesAndSeason - expected_dict = get_season_episode_count(key) # key season , value count of episodes - File "D:\repo\AniWorld\src\AniWorld-Downloader\src\aniworld\common\common.py", line 245, in get_season_episode_count - response = session.get(base_url, headers=ANIWORLD_HEADERS, timeout=DEFAULT_REQUEST_TIMEOUT) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 602, in get - return self.request("GET", url, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 589, in request - resp = self.send(prep, **send_kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 703, in send - r = adapter.send(request, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 682, in send - raise ConnectionError(err, request=request) -requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -Unexpected error processing folder 'Aesthetica of a Rogue Hero (2012)': ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -ConnectionResetError: [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 667, in send - resp = conn.urlopen( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 841, in urlopen - retries = retries.increment( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\retry.py", line 474, in increment - raise reraise(type(error), error, _stacktrace) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\util.py", line 38, in reraise - raise value.with_traceback(tb) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "D:\repo\AniWorld\src\FolderLookup.py", line 31, in __init - missings, site = self.__GetMissingEpisodesAndSeason(serie.key, mp4_files) - File "D:\repo\AniWorld\src\FolderLookup.py", line 136, in __GetMissingEpisodesAndSeason - expected_dict = get_season_episode_count(key) # key season , value count of episodes - File "D:\repo\AniWorld\src\AniWorld-Downloader\src\aniworld\common\common.py", line 245, in get_season_episode_count - response = session.get(base_url, headers=ANIWORLD_HEADERS, timeout=DEFAULT_REQUEST_TIMEOUT) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 602, in get - return self.request("GET", url, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 589, in request - resp = self.send(prep, **send_kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 703, in send - r = adapter.send(request, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 682, in send - raise ConnectionError(err, request=request) -requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -Unexpected error processing folder 'A.I.C.O. Incarnation (2018)': ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response')) - Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 534, in _make_request - response = conn.getresponse() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 516, in getresponse - httplib_response = super().getresponse() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\http\client.py", line 1375, in getresponse - response.begin() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\http\client.py", line 318, in begin - version, status, reason = self._read_status() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\http\client.py", line 287, in _read_status - raise RemoteDisconnected("Remote end closed connection without" -http.client.RemoteDisconnected: Remote end closed connection without response - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 667, in send - resp = conn.urlopen( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 841, in urlopen - retries = retries.increment( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\retry.py", line 474, in increment - raise reraise(type(error), error, _stacktrace) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\util.py", line 38, in reraise - raise value.with_traceback(tb) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 534, in _make_request - response = conn.getresponse() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 516, in getresponse - httplib_response = super().getresponse() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\http\client.py", line 1375, in getresponse - response.begin() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\http\client.py", line 318, in begin - version, status, reason = self._read_status() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\http\client.py", line 287, in _read_status - raise RemoteDisconnected("Remote end closed connection without" -urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response')) - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "D:\repo\AniWorld\src\FolderLookup.py", line 31, in __init - missings, site = self.__GetMissingEpisodesAndSeason(serie.key, mp4_files) - File "D:\repo\AniWorld\src\FolderLookup.py", line 137, in __GetMissingEpisodesAndSeason - expected_dict = get_season_episode_count(key) # key season , value count of episodes - File "D:\repo\AniWorld\src\AniWorld-Downloader\src\aniworld\common\common.py", line 248, in get_season_episode_count - response = session.get(base_url, headers=ANIWORLD_HEADERS, timeout=DEFAULT_REQUEST_TIMEOUT) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 602, in get - return self.request("GET", url, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 589, in request - resp = self.send(prep, **send_kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 703, in send - r = adapter.send(request, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 682, in send - raise ConnectionError(err, request=request) -requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response')) - -Unexpected error processing folder 'Aesthetica of a Rogue Hero (2012)': ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -ConnectionResetError: [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 667, in send - resp = conn.urlopen( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 841, in urlopen - retries = retries.increment( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\retry.py", line 474, in increment - raise reraise(type(error), error, _stacktrace) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\util.py", line 38, in reraise - raise value.with_traceback(tb) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "D:\repo\AniWorld\src\FolderLookup.py", line 31, in __init - missings, site = self.__GetMissingEpisodesAndSeason(serie.key, mp4_files) - File "D:\repo\AniWorld\src\FolderLookup.py", line 137, in __GetMissingEpisodesAndSeason - expected_dict = get_season_episode_count(key) # key season , value count of episodes - File "D:\repo\AniWorld\src\AniWorld-Downloader\src\aniworld\common\common.py", line 248, in get_season_episode_count - response = session.get(base_url, headers=ANIWORLD_HEADERS, timeout=DEFAULT_REQUEST_TIMEOUT) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 602, in get - return self.request("GET", url, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 589, in request - resp = self.send(prep, **send_kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 703, in send - r = adapter.send(request, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 682, in send - raise ConnectionError(err, request=request) -requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -Unexpected error processing folder 'Alya Sometimes Hides Her Feelings in Russian (2024)': ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -ConnectionResetError: [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 667, in send - resp = conn.urlopen( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 841, in urlopen - retries = retries.increment( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\retry.py", line 474, in increment - raise reraise(type(error), error, _stacktrace) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\util.py", line 38, in reraise - raise value.with_traceback(tb) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "D:\repo\AniWorld\src\FolderLookup.py", line 31, in __init - missings, site = self.__GetMissingEpisodesAndSeason(serie.key, mp4_files) - File "D:\repo\AniWorld\src\FolderLookup.py", line 137, in __GetMissingEpisodesAndSeason - expected_dict = get_season_episode_count(key) # key season , value count of episodes - File "D:\repo\AniWorld\src\AniWorld-Downloader\src\aniworld\common\common.py", line 248, in get_season_episode_count - response = session.get(base_url, headers=ANIWORLD_HEADERS, timeout=DEFAULT_REQUEST_TIMEOUT) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 602, in get - return self.request("GET", url, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 589, in request - resp = self.send(prep, **send_kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 703, in send - r = adapter.send(request, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 682, in send - raise ConnectionError(err, request=request) -requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -Unexpected error processing folder 'Angels of Death (2018)': ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -ConnectionResetError: [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 667, in send - resp = conn.urlopen( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 841, in urlopen - retries = retries.increment( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\retry.py", line 474, in increment - raise reraise(type(error), error, _stacktrace) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\util.py", line 38, in reraise - raise value.with_traceback(tb) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "D:\repo\AniWorld\src\FolderLookup.py", line 31, in __init - missings, site = self.__GetMissingEpisodesAndSeason(serie.key, mp4_files) - File "D:\repo\AniWorld\src\FolderLookup.py", line 137, in __GetMissingEpisodesAndSeason - expected_dict = get_season_episode_count(key) # key season , value count of episodes - File "D:\repo\AniWorld\src\AniWorld-Downloader\src\aniworld\common\common.py", line 248, in get_season_episode_count - response = session.get(base_url, headers=ANIWORLD_HEADERS, timeout=DEFAULT_REQUEST_TIMEOUT) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 602, in get - return self.request("GET", url, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 589, in request - resp = self.send(prep, **send_kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 703, in send - r = adapter.send(request, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 682, in send - raise ConnectionError(err, request=request) -requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -Unexpected error processing folder 'Arifureta (2019)': ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -ConnectionResetError: [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 667, in send - resp = conn.urlopen( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 841, in urlopen - retries = retries.increment( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\retry.py", line 474, in increment - raise reraise(type(error), error, _stacktrace) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\util.py", line 38, in reraise - raise value.with_traceback(tb) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "D:\repo\AniWorld\src\FolderLookup.py", line 31, in __init - missings, site = self.__GetMissingEpisodesAndSeason(serie.key, mp4_files) - File "D:\repo\AniWorld\src\FolderLookup.py", line 137, in __GetMissingEpisodesAndSeason - expected_dict = get_season_episode_count(key) # key season , value count of episodes - File "D:\repo\AniWorld\src\AniWorld-Downloader\src\aniworld\common\common.py", line 248, in get_season_episode_count - response = session.get(base_url, headers=ANIWORLD_HEADERS, timeout=DEFAULT_REQUEST_TIMEOUT) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 602, in get - return self.request("GET", url, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 589, in request - resp = self.send(prep, **send_kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 703, in send - r = adapter.send(request, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 682, in send - raise ConnectionError(err, request=request) -requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -Folder: 'A.I.C.O. Incarnation (2018)' - Unexpected error processing folder 'A.I.C.O. Incarnation (2018)': ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -ConnectionResetError: [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 667, in send - resp = conn.urlopen( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 841, in urlopen - retries = retries.increment( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\retry.py", line 474, in increment - raise reraise(type(error), error, _stacktrace) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\util.py", line 38, in reraise - raise value.with_traceback(tb) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen - response = self._make_request( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 488, in _make_request - raise new_e - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 464, in _make_request - self._validate_conn(conn) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connectionpool.py", line 1093, in _validate_conn - conn.connect() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 741, in connect - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\connection.py", line 920, in _ssl_wrap_socket_and_match_hostname - ssl_sock = ssl_wrap_socket( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 480, in ssl_wrap_socket - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\urllib3\util\ssl_.py", line 524, in _ssl_wrap_socket_impl - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 513, in wrap_socket - return self.sslsocket_class._create( - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1104, in _create - self.do_handshake() - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\ssl.py", line 1375, in do_handshake - self._sslobj.do_handshake() -urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "D:\repo\AniWorld\src\FolderLookup.py", line 31, in __init - missings, site = self.__GetMissingEpisodesAndSeason(serie.key, mp4_files) - File "D:\repo\AniWorld\src\FolderLookup.py", line 137, in __GetMissingEpisodesAndSeason - expected_dict = get_season_episode_count(key) # key season , value count of episodes - File "D:\repo\AniWorld\src\AniWorld-Downloader\src\aniworld\common\common.py", line 248, in get_season_episode_count - response = session.get(base_url, headers=ANIWORLD_HEADERS, timeout=DEFAULT_REQUEST_TIMEOUT) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 602, in get - return self.request("GET", url, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 589, in request - resp = self.send(prep, **send_kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\sessions.py", line 703, in send - r = adapter.send(request, **kwargs) - File "C:\Users\lukas\anaconda3\envs\AniWorld\lib\site-packages\requests\adapters.py", line 682, in send - raise ConnectionError(err, request=request) -requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None)) - diff --git a/src/AniWorld-Downloader b/src/AniWorld-Downloader deleted file mode 160000 index a267efa..0000000 --- a/src/AniWorld-Downloader +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a267efa72a12af19df6641ab2ab39e494a1d0ee8 diff --git a/src/AniWorldLoader.py b/src/AniWorldLoader.py deleted file mode 100644 index bab6f36..0000000 --- a/src/AniWorldLoader.py +++ /dev/null @@ -1,137 +0,0 @@ -import os -import re -import subprocess -import logging -import json -import requests -import html -from urllib.parse import quote -from Serie import Serie -from aniworld.models import Anime, Episode, NoMachingLanguage -from aniworld.config import PROVIDER_HEADERS, INVALID_PATH_CHARS, ANIWORLD_TO, session, DEFAULT_REQUEST_TIMEOUT -from aniworld.parser import arguments - - -# Read timeout from environment variable, default to 600 seconds (10 minutes) -timeout = int(os.getenv("DOWNLOAD_TIMEOUT", 600)) - -download_error_logger = logging.getLogger("DownloadErrors") -download_error_handler = logging.FileHandler("../download_errors.log") -download_error_handler.setLevel(logging.ERROR) -download_error_logger.addHandler(download_error_handler) - - -def CreateSerie(searchEntry): - return Serie(searchEntry["link"], searchEntry["name"], "aniworld.to", searchEntry["link"], {}) - -def search_anime(keyword: str = None) -> str: - - search_url = f"{ANIWORLD_TO}/ajax/seriesSearch?keyword={quote(keyword)}" - anime_list = fetch_anime_list(search_url) - - return anime_list - -def fetch_anime_list(url: str) -> list: - response = session.get(url, timeout=DEFAULT_REQUEST_TIMEOUT) - response.raise_for_status() - - clean_text = response.text.strip() - - try: - decoded_data = json.loads(html.unescape(clean_text)) - return decoded_data if isinstance(decoded_data, list) else [] - except json.JSONDecodeError: - try: - # Remove BOM and problematic characters - clean_text = clean_text.encode('utf-8').decode('utf-8-sig') - # Remove problematic characters - clean_text = re.sub(r'[\x00-\x1F\x7F-\x9F]', '', clean_text) - # Parse the new text - decoded_data = json.loads(clean_text) - return decoded_data if isinstance(decoded_data, list) else [] - except (requests.RequestException, json.JSONDecodeError) as exc: - raise ValueError("Could not get valid anime: ") from exc - -def AniWorld_download_episode(directory, folder, season, episode, key): - """Helper function to download an individual episode.""" - try: - folder_path = os.path.join(directory, folder, f"Season {season}") - anime = Anime( - episode_list=[Episode(slug=key, season=season, episode=episode)], - language="German Dub", - output_directory=folder_path - ) - logging.info(f"Downloading anime {key} season {season} episode {episode}") - download(anime) - logging.info(f"Downloading completed anime {key} season {season} episode {episode}") - except KeyError as keye: - download_error_logger.error(f"Language not found for anime: {key} season: {season} episode: {episode}") - except NoMachingLanguage as ee: - download_error_logger.error(f"Language not found for anime: {key} season: {season} episode: {episode}") - except Exception as e: - logging.error(f"Error downloading episode {episode} of season {season} for anime {key}: {e}") - -def download(anime: Anime): # pylint: disable=too-many-branches - for episode in anime: - sanitized_anime_title = ''.join( - char for char in anime.title if char not in INVALID_PATH_CHARS - ) - - if episode.season == 0: - output_file = ( - f"{sanitized_anime_title} - " - f"Movie {episode.episode:02} - " - f"({anime.language}).mp4" - ) - else: - output_file = ( - f"{sanitized_anime_title} - " - f"S{episode.season:02}E{episode.episode:03} - " - f"({anime.language}).mp4" - ) - - output_path = os.path.join(anime.output_directory, output_file) - os.makedirs(os.path.dirname(output_path), exist_ok=True) - command = [ - "yt-dlp", - episode.get_direct_link(anime.provider, anime.language), - "--fragment-retries", "infinite", - #"--concurrent-fragments", "4", - "-o", output_path, - "--quiet", - "--no-warnings", - "--progress" - ] - - if anime.provider in PROVIDER_HEADERS: - for header in PROVIDER_HEADERS[anime.provider]: - command.extend(["--add-header", header]) - - if arguments.only_command: - logging.info( - f"{anime.title} - S{episode.season}E{episode.episode} - ({anime.language}): " - f"{' '.join(str(item) if item is not None else '' for item in command)}" - ) - continue - - try: - subprocess.run(command, check=True, timeout=timeout) - except subprocess.TimeoutExpired: - download_error_logger.error(f"Download timed out after {timeout} seconds: {' '.join(str(item) for item in command)}") - except subprocess.CalledProcessError: - download_error_logger.error(f"Error running command: {' '.join(str(item) for item in command)}") - except KeyboardInterrupt: - logging.warning("Download interrupted by user.") - output_dir = os.path.dirname(output_path) - is_empty = True - - for file_name in os.listdir(output_dir): - if re.search(r'\.(part|ytdl|part-Frag\d+)$', file_name): - os.remove(os.path.join(output_dir, file_name)) - else: - is_empty = False - - if is_empty or not os.listdir(output_dir): - os.rmdir(output_dir) - logging.info(f"Removed empty download directory: {output_dir}") - diff --git a/src/Loaders/AniWorldLoader.py b/src/Loaders/AniWorldLoader.py new file mode 100644 index 0000000..41ca6d0 --- /dev/null +++ b/src/Loaders/AniWorldLoader.py @@ -0,0 +1,327 @@ +import os +import re +import subprocess +import logging +import json +import requests +import html +from urllib.parse import quote + +from bs4 import BeautifulSoup + +from fake_useragent import UserAgent +from requests.adapters import HTTPAdapter +from urllib3.util.retry import Retry + +from src.Loaders.Loader import Loader +from src.Loaders.Providers import Providers +from yt_dlp import YoutubeDL + +# Read timeout from environment variable, default to 600 seconds (10 minutes) +timeout = int(os.getenv("DOWNLOAD_TIMEOUT", 600)) + +download_error_logger = logging.getLogger("DownloadErrors") +download_error_handler = logging.FileHandler("../../download_errors.log") +download_error_handler.setLevel(logging.ERROR) + +noKeyFound_logger = logging.getLogger("NoKeyFound") +noKeyFound_handler = logging.FileHandler("../../NoKeyFound.log") +noKeyFound_handler.setLevel(logging.ERROR) + +class AniworldLoader(Loader): + def __init__(self): + self.SUPPORTED_PROVIDERS = ["VOE", "Doodstream", "Vidmoly", "Vidoza", "SpeedFiles", "Streamtape", "Luluvdo"] + self.AniworldHeaders = { + "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8", + "accept-encoding": "gzip, deflate, br, zstd", + "accept-language": "de,de-DE;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", + "cache-control": "max-age=0", + "priority": "u=0, i", + "sec-ch-ua": '"Chromium";v="136", "Microsoft Edge";v="136", "Not.A/Brand";v="99"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"Windows"', + "sec-fetch-dest": "document", + "sec-fetch-mode": "navigate", + "sec-fetch-site": "none", + "sec-fetch-user": "?1", + "upgrade-insecure-requests": "1", + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0" + } + self.INVALID_PATH_CHARS = ['<', '>', ':', '"', '/', '\\', '|', '?', '*', '&'] + self.RANDOM_USER_AGENT = UserAgent().random + self.LULUVDO_USER_AGENT = "Mozilla/5.0 (Android 15; Mobile; rv:132.0) Gecko/132.0 Firefox/132.0" + self.PROVIDER_HEADERS = { + "Vidmoly": ['Referer: "https://vidmoly.to"'], + "Doodstream": ['Referer: "https://dood.li/"'], + "VOE": [f'User-Agent: {self.RANDOM_USER_AGENT}'], + "Luluvdo": [ + f'User-Agent: {self.LULUVDO_USER_AGENT}', + 'Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7', + 'Origin: "https://luluvdo.com"', + 'Referer: "https://luluvdo.com/"' + ]} + self.ANIWORLD_TO = "https://aniworld.to" + self.session = requests.Session() + + # Configure retries with backoff + retries = Retry( + total=5, # Number of retries + backoff_factor=1, # Delay multiplier (1s, 2s, 4s, ...) + status_forcelist=[500, 502, 503, 504], # Retry for specific HTTP errors + allowed_methods=["GET"] + ) + + adapter = HTTPAdapter(max_retries=retries) + self.session.mount("https://", adapter) + self.DEFAULT_REQUEST_TIMEOUT = 30 + + self._KeyHTMLDict = {} + self._EpisodeHTMLDict = {} + self.Providers = Providers() + + def Search(self, word: str) -> list: + search_url = f"{self.ANIWORLD_TO}/ajax/seriesSearch?keyword={quote(word)}" + anime_list = self.fetch_anime_list(search_url) + + return anime_list + + + def fetch_anime_list(self, url: str) -> list: + response = self.session.get(url, timeout=self.DEFAULT_REQUEST_TIMEOUT) + response.raise_for_status() + + clean_text = response.text.strip() + + try: + decoded_data = json.loads(html.unescape(clean_text)) + return decoded_data if isinstance(decoded_data, list) else [] + except json.JSONDecodeError: + try: + # Remove BOM and problematic characters + clean_text = clean_text.encode('utf-8').decode('utf-8-sig') + # Remove problematic characters + clean_text = re.sub(r'[\x00-\x1F\x7F-\x9F]', '', clean_text) + # Parse the new text + decoded_data = json.loads(clean_text) + return decoded_data if isinstance(decoded_data, list) else [] + except (requests.RequestException, json.JSONDecodeError) as exc: + raise ValueError("Could not get valid anime: ") from exc + + def _GetLanguageKey(self, language: str) -> int: + languageCode = 0 + if (language == "German Dub"): + languageCode = 1 + if (language == "English Sub"): + languageCode = 2 + if (language == "German Sub"): + languageCode = 3 + return languageCode + def IsLanguage(self, season: int, episode: int, key: str, language: str = "German Dub") -> bool: + """ + Language Codes: + 1: German Dub + 2: English Sub + 3: German Sub + """ + languageCode = self._GetLanguageKey(language) + + episode_soup = BeautifulSoup(self._GetEpisodeHTML(season, episode, key).content, 'html.parser') + change_language_box_div = episode_soup.find( + 'div', class_='changeLanguageBox') + languages = [] + + if change_language_box_div: + img_tags = change_language_box_div.find_all('img') + for img in img_tags: + lang_key = img.get('data-lang-key') + if lang_key and lang_key.isdigit(): + languages.append(int(lang_key)) + + return languageCode in languages + + + def Download(self, baseDirectory: str, serieFolder: str, season: int, episode: int, key: str, language: str = "German Dub") -> bool: + sanitized_anime_title = ''.join( + char for char in self.GetTitle(key) if char not in self.INVALID_PATH_CHARS + ) + + if season == 0: + output_file = ( + f"{sanitized_anime_title} - " + f"Movie {episode:02} - " + f"({language}).mp4" + ) + else: + output_file = ( + f"{sanitized_anime_title} - " + f"S{season:02}E{episode:03} - " + f"({language}).mp4" + ) + + output_path = os.path.join(os.path.join(baseDirectory, serieFolder), output_file) + os.makedirs(os.path.dirname(output_path), exist_ok=True) + + for provider in self.SUPPORTED_PROVIDERS: + link, header = self._get_direct_link_from_provider(season, episode, key, language) + ydl_opts = { + 'fragment_retries': float('inf'), + 'outtmpl': output_path, + 'quiet': True, + 'no_warnings': True, + 'progress_with_newline': True + } + + if header: + ydl_opts['http_headers'] = header + + with YoutubeDL(ydl_opts) as ydl: + ydl.download([link]) + break + + + def GetSiteKey(self) -> str: + return "aniworld.to" + + def GetTitle(self, key: str) -> str: + soup = BeautifulSoup(self._GetKeyHTML(key).content, 'html.parser') + title_div = soup.find('div', class_='series-title') + + if title_div: + return title_div.find('h1').find('span').text + + return "" + + def _GetKeyHTML(self, key: str): + if key in self._KeyHTMLDict: + return self._KeyHTMLDict[key] + + + self._KeyHTMLDict[key] = self.session.get( + f"{self.ANIWORLD_TO}/anime/stream/{key}", + timeout=self.DEFAULT_REQUEST_TIMEOUT + ) + return self._KeyHTMLDict[key] + def _GetEpisodeHTML(self, season: int, episode: int, key: str): + if key in self._EpisodeHTMLDict: + return self._EpisodeHTMLDict[key] + + + link = ( + f"{self.ANIWORLD_TO}/anime/stream/{key}/" + f"staffel-{season}/episode-{episode}" + ) + html = self.session.get(link, timeout=self.DEFAULT_REQUEST_TIMEOUT) + self._EpisodeHTMLDict[key] = html + return self._EpisodeHTMLDict[key] + + def _get_provider_from_html(self, season: int, episode: int, key: str) -> dict: + """ + Parses the HTML content to extract streaming providers, + their language keys, and redirect links. + + Returns a dictionary with provider names as keys + and language key-to-redirect URL mappings as values. + + Example: + + { + 'VOE': {1: 'https://aniworld.to/redirect/1766412', + 2: 'https://aniworld.to/redirect/1766405'}, + 'Doodstream': {1: 'https://aniworld.to/redirect/1987922', + 2: 'https://aniworld.to/redirect/2700342'}, + ... + } + + Access redirect link with: + print(self.provider["VOE"][2]) + """ + + soup = BeautifulSoup(self._GetEpisodeHTML(season, episode, key).content, 'html.parser') + providers = {} + + episode_links = soup.find_all( + 'li', class_=lambda x: x and x.startswith('episodeLink') + ) + + if not episode_links: + return providers + + for link in episode_links: + provider_name_tag = link.find('h4') + provider_name = provider_name_tag.text.strip() if provider_name_tag else None + + redirect_link_tag = link.find('a', class_='watchEpisode') + redirect_link = redirect_link_tag['href'] if redirect_link_tag else None + + lang_key = link.get('data-lang-key') + lang_key = int( + lang_key) if lang_key and lang_key.isdigit() else None + + if provider_name and redirect_link and lang_key: + if provider_name not in providers: + providers[provider_name] = {} + providers[provider_name][lang_key] = f"{self.ANIWORLD_TO}{redirect_link}" + + + return providers + def _get_redirect_link(self, season: int, episode: int, key: str, language: str = "German Dub") -> str: + languageCode = self._GetLanguageKey(language) + if (self.IsLanguage(season, episode, key, language)): + for provider_name, lang_dict in self._get_provider_from_html(season, episode, key).items(): + if languageCode in lang_dict: + return(lang_dict[languageCode], provider_name) + break + return None + def _get_embeded_link(self, season: int, episode: int, key: str, language: str = "German Dub"): + redirect_link, provider_name = self._get_redirect_link(season, episode, key, language) + + embeded_link = self.session.get( + redirect_link, timeout=self.DEFAULT_REQUEST_TIMEOUT, + headers={'User-Agent': self.RANDOM_USER_AGENT}).url + return embeded_link + def _get_direct_link_from_provider(self, season: int, episode: int, key: str, language: str = "German Dub") -> str: + """ + providers = { + "Vidmoly": get_direct_link_from_vidmoly, + "Vidoza": get_direct_link_from_vidoza, + "VOE": get_direct_link_from_voe, + "Doodstream": get_direct_link_from_doodstream, + "SpeedFiles": get_direct_link_from_speedfiles, + "Luluvdo": get_direct_link_from_luluvdo + } + + """ + embeded_link = self._get_embeded_link(season, episode, key, language) + if embeded_link is None: + return None + + return self.Providers.GetProvider("VOE").GetLink(embeded_link, self.DEFAULT_REQUEST_TIMEOUT) + + def get_season_episode_count(self, slug : str) -> dict: + base_url = f"{self.ANIWORLD_TO}/anime/stream/{slug}/" + response = requests.get(base_url, timeout=self.DEFAULT_REQUEST_TIMEOUT) + soup = BeautifulSoup(response.content, 'html.parser') + + season_meta = soup.find('meta', itemprop='numberOfSeasons') + number_of_seasons = int(season_meta['content']) if season_meta else 0 + + episode_counts = {} + + for season in range(1, number_of_seasons + 1): + season_url = f"{base_url}staffel-{season}" + response = requests.get(season_url, timeout=self.DEFAULT_REQUEST_TIMEOUT) + soup = BeautifulSoup(response.content, 'html.parser') + + episode_links = soup.find_all('a', href=True) + unique_links = set( + link['href'] + for link in episode_links + if f"staffel-{season}/episode-" in link['href'] + ) + + episode_counts[season] = len(unique_links) + + return episode_counts + + + diff --git a/src/Loaders/Loader.py b/src/Loaders/Loader.py new file mode 100644 index 0000000..7d2ed25 --- /dev/null +++ b/src/Loaders/Loader.py @@ -0,0 +1,27 @@ +from abc import ABC, abstractmethod + + +class Loader(ABC): + @abstractmethod + def Search(self, word: str) -> list: + pass + + @abstractmethod + def IsLanguage(self, season: int, episode: int, key: str, language: str = "German Dub") -> bool: + pass + + @abstractmethod + def Download(self, baseDirectory: str, serieFolder: str, season: int, episode: int, key: str) -> bool: + pass + + @abstractmethod + def GetSiteKey(self) -> str: + pass + + @abstractmethod + def GetTitle(self) -> str: + pass + + @abstractmethod + def get_season_episode_count(self, slug: str) -> dict: + pass \ No newline at end of file diff --git a/src/Loaders/Loaders.py b/src/Loaders/Loaders.py new file mode 100644 index 0000000..0e5d53e --- /dev/null +++ b/src/Loaders/Loaders.py @@ -0,0 +1,10 @@ +from src.Loaders.AniWorldLoader import AniworldLoader +from src.Loaders.Loader import Loader + +class Loaders: + + def __init__(self): + self.dict = {"aniworld.to": AniworldLoader()} + + def GetLoader(self, key: str) -> Loader: + return self.dict[key] diff --git a/src/Loaders/Providers.py b/src/Loaders/Providers.py new file mode 100644 index 0000000..c4ac974 --- /dev/null +++ b/src/Loaders/Providers.py @@ -0,0 +1,12 @@ + + +from src.Loaders.provider.Provider import Provider +from src.Loaders.provider.voe import VOE + +class Providers: + + def __init__(self): + self.dict = {"VOE": VOE()} + + def GetProvider(self, key: str) -> Provider: + return self.dict[key] diff --git a/src/Loaders/__init__.py b/src/Loaders/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/Loaders/__pycache__/AniWorldLoader.cpython-310.pyc b/src/Loaders/__pycache__/AniWorldLoader.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..02d1735ed6775a525244503c6d14f70a6dfaf4b2 GIT binary patch literal 10757 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 JI;Dq|{{vh9?_K}^ literal 0 HcmV?d00001 diff --git a/src/Loaders/__pycache__/Loader.cpython-310.pyc b/src/Loaders/__pycache__/Loader.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ceaeaa64228a3e51f7da1d60ab70764066a60f74 GIT binary patch literal 1364 zcma)6OKaOe5Z;w!S&^SfoWyAlEhQ9u$qy){B#mh(4Y{~bFa{xO){dwwr7MZxT$5`L z{S$@!rM>plb8b0xW@Y7JV(7q(b{?AfW_F~c(Qp~kPxkHXm%-Q{QXZ3q$^mk^hXNSz zh|Tzr&y1nL*)anH%xeaw;8*6*1Z%*0mA@FtdWJF&KOU*3KTb302iZ(yX9)!4drS>f z4v^E|C2RAKGZ`f-S00MRw4?remCm3og{ID;TqeF?F;y zkRL}H!kN^e2`!z;#VA8q69d|?t}V5D%LZ&}OC2p8oxgz?wqRRZo3Mi&?kf8v@j*ys zT_h5eEk%~gIKcVc6P-Eo5%Mh!5!is;@Y5TbjFpOLA}eT>Yo)k*+kZEb;yf80#v!JS zV3f*WR1``V&;9ecvIoMK!5O`MOI0l6vQb3s7oI!!Sjd?lzwYN_Wv9YVlUP;7d6*_3 zl=)rEl@s~#H20?>pfn}Xxx_51s7QwdLF`o|?TKuWXp>kcu|eX#1zAH?xu4UMMRx6> z8@^m$Abjwt#@J6qKa?WK5;<43RLD?#N+O(VVBQhusmP~^L!1n zNa&8AbWwV6!=ik;av_&5*C={<@l3JqRAgSUL*8PAydcTrY?p#{@mGrxu8KVEaoNP^ zUQ0Qi7yC2edCK*?Sps=P=epq&$<{9 literal 0 HcmV?d00001 diff --git a/src/Loaders/__pycache__/Loaders.cpython-310.pyc b/src/Loaders/__pycache__/Loaders.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..576e361e1b5e48c2fb4def8293cfa4426827a3c5 GIT binary patch literal 718 zcmYjP&2G~`5T4oH*ltKs+5-|i0LUEj00^NXka|J6aHwQOT1B3%FgS5pJ3@_eYhH#| z+A9adD{x}Q8yAl>BZC|o+P#{5} z2uU5G(4?Iq<0iK}o|2;}5=t2+3u&CzmdyT9#8<2zSlc-p!VVsw!UI?y%Rj2+{>l2p zY|%Bj^3op+Rb|H6x9_O{_|3sk6a}ZG;T0JK6g4b_5rTbL z%Y`yZz!{)Iy#>^_(r6rgfh_q;{g8<+{p_2|3Y{lkef{*Y;dSBNswv(rtESOi}d=gpk15sE!>zPj#GYpZ3|TAMN= zLm!KqlYcFJxl=#gb(eV8uKlv)zFyehQ|4uC;0J8Pb0#ZhneZdZ5#59i&-KW0XBf0Q zJacUicu0xJVj^yy^vRG9I%e6JNiXLMXKgpJcG2LvW`An!ul2m%Rr~>uR-yHt$@wW8 zew=|}bkFN!YJp7(seGzpZkCPA3wpNv@!9g#g`kf;H=WGeGoX5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!H9i&acfYC(RC zV_s%?eo;&ryk0@&Ee@O9{FKt1R6CFf#Y{kgg#iEn C+8l-e literal 0 HcmV?d00001 diff --git a/src/Loaders/provider/Provider.py b/src/Loaders/provider/Provider.py new file mode 100644 index 0000000..8e14b66 --- /dev/null +++ b/src/Loaders/provider/Provider.py @@ -0,0 +1,7 @@ +from abc import ABC, abstractmethod + + +class Provider(ABC): + @abstractmethod + def GetLink(self, embededLink: str, DEFAULT_REQUEST_TIMEOUT: int) -> (str, [str]): + pass diff --git a/src/Loaders/provider/__pycache__/Provider.cpython-310.pyc b/src/Loaders/provider/__pycache__/Provider.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1fb0e2670d6dbdead5fddeccf773e46ba592ee90 GIT binary patch literal 570 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 Jg6VID{|8Q6NxuL9 literal 0 HcmV?d00001 diff --git a/src/Loaders/provider/doodstream.py b/src/Loaders/provider/doodstream.py new file mode 100644 index 0000000..b472703 --- /dev/null +++ b/src/Loaders/provider/doodstream.py @@ -0,0 +1,59 @@ +import re +import random +import time + +from fake_useragent import UserAgent +import requests +from src.Loaders.provider.Provider import Provider +class Doodstream(Provider): + + def __init__(self): + self.RANDOM_USER_AGENT = UserAgent().random + + def GetLink(self, embededLink: str, DEFAULT_REQUEST_TIMEOUT: int) -> str: + headers = { + 'User-Agent': self.RANDOM_USER_AGENT, + 'Referer': 'https://dood.li/' + } + + def extract_data(pattern, content): + match = re.search(pattern, content) + return match.group(1) if match else None + + def generate_random_string(length=10): + characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + return ''.join(random.choice(characters) for _ in range(length)) + + response = requests.get( + embededLink, + headers=headers, + timeout=DEFAULT_REQUEST_TIMEOUT, + verify=False + ) + response.raise_for_status() + + pass_md5_pattern = r"\$\.get\('([^']*\/pass_md5\/[^']*)'" + pass_md5_url = extract_data(pass_md5_pattern, response.text) + if not pass_md5_url: + raise ValueError( + f'pass_md5 URL not found using {embededLink}.') + + full_md5_url = f"https://dood.li{pass_md5_url}" + + token_pattern = r"token=([a-zA-Z0-9]+)" + token = extract_data(token_pattern, response.text) + if not token: + raise ValueError(f'Token not found using {embededLink}.') + + md5_response = requests.get( + full_md5_url, headers=headers, timeout=DEFAULT_REQUEST_TIMEOUT, verify=False) + md5_response.raise_for_status() + video_base_url = md5_response.text.strip() + + random_string = generate_random_string(10) + expiry = int(time.time()) + + direct_link = f"{video_base_url}{random_string}?token={token}&expiry={expiry}" + # print(direct_link) + + return direct_link \ No newline at end of file diff --git a/src/Loaders/provider/filemoon.py b/src/Loaders/provider/filemoon.py new file mode 100644 index 0000000..aa047eb --- /dev/null +++ b/src/Loaders/provider/filemoon.py @@ -0,0 +1,51 @@ +import re +import requests +# import jsbeautifier.unpackers.packer as packer + +from aniworld import config + +REDIRECT_REGEX = re.compile( + r'