weeb-cli 2.17.0__tar.gz → 3.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/PKG-INFO +1 -11
  2. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/pyproject.toml +1 -12
  3. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/__init__.py +1 -1
  4. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/serve.py +0 -8
  5. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/serve_restful.py +0 -8
  6. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/config.py +0 -1
  7. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/constants.py +0 -1
  8. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/main.py +0 -8
  9. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/base.py +30 -58
  10. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/sdk.py +0 -5
  11. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/cache.py +5 -18
  12. weeb_cli-3.0.0/weeb_cli/services/download/manager.py +69 -0
  13. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/error_handler.py +2 -13
  14. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/logger.py +6 -19
  15. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/scraper.py +0 -5
  16. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli.egg-info/PKG-INFO +1 -11
  17. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli.egg-info/SOURCES.txt +0 -1
  18. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli.egg-info/requires.txt +0 -11
  19. weeb_cli-2.17.0/weeb_cli/services/download/manager.py +0 -89
  20. weeb_cli-2.17.0/weeb_cli/services/telemetry.py +0 -417
  21. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/LICENSE +0 -0
  22. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/README.md +0 -0
  23. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/setup.cfg +0 -0
  24. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/tests/test_anilist_tracker.py +0 -0
  25. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/tests/test_aniworld_provider.py +0 -0
  26. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/tests/test_api.py +0 -0
  27. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/tests/test_cache.py +0 -0
  28. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/tests/test_exceptions.py +0 -0
  29. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/tests/test_kitsu_tracker.py +0 -0
  30. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/tests/test_mal_tracker.py +0 -0
  31. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/tests/test_providers.py +0 -0
  32. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/tests/test_restful_api.py +0 -0
  33. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/tests/test_sanitizer.py +0 -0
  34. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/tests/test_sanitizer_security.py +0 -0
  35. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/tests/test_sdk.py +0 -0
  36. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/__main__.py +0 -0
  37. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/__init__.py +0 -0
  38. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/api.py +0 -0
  39. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/downloads.py +0 -0
  40. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/library.py +0 -0
  41. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/search/__init__.py +0 -0
  42. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/search/anime_details.py +0 -0
  43. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/search/download_flow.py +0 -0
  44. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/search/episode_utils.py +0 -0
  45. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/search/search_handlers.py +0 -0
  46. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/search/stream_utils.py +0 -0
  47. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/search/watch_flow.py +0 -0
  48. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/search.py +0 -0
  49. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/settings/__init__.py +0 -0
  50. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/settings/settings_backup.py +0 -0
  51. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/settings/settings_cache.py +0 -0
  52. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/settings/settings_config.py +0 -0
  53. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/settings/settings_download.py +0 -0
  54. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/settings/settings_drives.py +0 -0
  55. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/settings/settings_menu.py +0 -0
  56. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/settings/settings_shortcuts.py +0 -0
  57. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/settings/settings_trackers.py +0 -0
  58. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/settings.py +0 -0
  59. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/setup.py +0 -0
  60. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/commands/watchlist.py +0 -0
  61. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/exceptions.py +0 -0
  62. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/i18n.py +0 -0
  63. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/locales/de.json +0 -0
  64. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/locales/en.json +0 -0
  65. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/locales/pl.json +0 -0
  66. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/locales/tr.json +0 -0
  67. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/__init__.py +0 -0
  68. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/de/__init__.py +0 -0
  69. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/de/aniworld.py +0 -0
  70. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/en/__init__.py +0 -0
  71. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/en/allanime.py +0 -0
  72. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/en/hianime.py +0 -0
  73. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/extractors/__init__.py +0 -0
  74. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/extractors/doodstream.py +0 -0
  75. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/extractors/filemoon.py +0 -0
  76. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/extractors/megacloud.py +0 -0
  77. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/extractors/streamtape.py +0 -0
  78. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/extractors/vidoza.py +0 -0
  79. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/extractors/voe.py +0 -0
  80. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/pl/__init__.py +0 -0
  81. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/pl/docchi.py +0 -0
  82. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/registry.py +0 -0
  83. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/tr/__init__.py +0 -0
  84. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/tr/animecix.py +0 -0
  85. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/tr/anizle.py +0 -0
  86. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/tr/turkanime.py +0 -0
  87. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/providers/tr/weeb.py +0 -0
  88. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/__init__.py +0 -0
  89. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/_base.py +0 -0
  90. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/_tracker_base.py +0 -0
  91. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/aniskip.py +0 -0
  92. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/database.py +0 -0
  93. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/dependency_manager.py +0 -0
  94. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/details.py +0 -0
  95. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/discord_rpc.py +0 -0
  96. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/download/__init__.py +0 -0
  97. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/download/context.py +0 -0
  98. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/download/queue.py +0 -0
  99. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/download/strategies/__init__.py +0 -0
  100. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/download/strategies/aria2.py +0 -0
  101. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/download/strategies/base.py +0 -0
  102. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/download/strategies/ffmpeg.py +0 -0
  103. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/download/strategies/generic.py +0 -0
  104. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/download/strategies/ytdlp.py +0 -0
  105. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/downloader.py +0 -0
  106. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/headless_downloader.py +0 -0
  107. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/local_library.py +0 -0
  108. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/notifier.py +0 -0
  109. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/player.py +0 -0
  110. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/progress.py +0 -0
  111. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/search.py +0 -0
  112. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/shortcuts.py +0 -0
  113. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/stream_validator.py +0 -0
  114. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/tracker.py +0 -0
  115. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/updater.py +0 -0
  116. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/services/watch.py +0 -0
  117. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/templates/anilist_error.html +0 -0
  118. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/templates/anilist_success.html +0 -0
  119. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/templates/mal_error.html +0 -0
  120. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/templates/mal_success.html +0 -0
  121. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/ui/__init__.py +0 -0
  122. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/ui/header.py +0 -0
  123. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/ui/menu.py +0 -0
  124. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/ui/prompt.py +0 -0
  125. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/utils/__init__.py +0 -0
  126. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/utils/decorators.py +0 -0
  127. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/utils/sanitizer.py +0 -0
  128. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli/utils/shortcuts.py +0 -0
  129. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli.egg-info/dependency_links.txt +0 -0
  130. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli.egg-info/entry_points.txt +0 -0
  131. {weeb_cli-2.17.0 → weeb_cli-3.0.0}/weeb_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weeb-cli
3
- Version: 2.17.0
3
+ Version: 3.0.0
4
4
  Summary: No browser, no ads, no distractions. Just you and an unparalleled anime viewing experience.
5
5
  Author-email: ewgsta <ewgst@proton.me>
6
6
  License-Expression: GPL-3.0-only
@@ -51,16 +51,6 @@ Requires-Dist: mkdocs-material>=9.7.6; extra == "docs"
51
51
  Requires-Dist: mkdocstrings[python]>=1.0.4; extra == "docs"
52
52
  Requires-Dist: pymdown-extensions>=10.21.2; extra == "docs"
53
53
  Requires-Dist: mkdocs-static-i18n>=1.3.1; extra == "docs"
54
- Provides-Extra: telemetry
55
- Requires-Dist: opentelemetry-api<2.0,>=1.25.0; extra == "telemetry"
56
- Requires-Dist: opentelemetry-sdk<2.0,>=1.25.0; extra == "telemetry"
57
- Requires-Dist: opentelemetry-exporter-otlp-proto-http<2.0,>=1.25.0; extra == "telemetry"
58
- Requires-Dist: opentelemetry-exporter-otlp-proto-grpc<2.0,>=1.25.0; extra == "telemetry"
59
- Requires-Dist: opentelemetry-instrumentation-requests<1.0,>=0.46b0; extra == "telemetry"
60
- Requires-Dist: opentelemetry-instrumentation-urllib3<1.0,>=0.46b0; extra == "telemetry"
61
- Requires-Dist: opentelemetry-instrumentation-sqlite3<1.0,>=0.46b0; extra == "telemetry"
62
- Requires-Dist: opentelemetry-instrumentation-flask<1.0,>=0.46b0; extra == "telemetry"
63
- Requires-Dist: opentelemetry-instrumentation-logging<1.0,>=0.46b0; extra == "telemetry"
64
54
  Dynamic: license-file
65
55
 
66
56
  <p align="center">
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "weeb-cli"
7
- version = "2.17.0"
7
+ version = "3.0.0"
8
8
  description = "No browser, no ads, no distractions. Just you and an unparalleled anime viewing experience."
9
9
  readme = "README.md"
10
10
  authors = [{ name = "ewgsta", email = "ewgst@proton.me" }]
@@ -40,17 +40,6 @@ serve-restful = ["flask>=3.0", "flask-cors>=4.0"]
40
40
  shortcuts = ["pywin32; sys_platform == 'win32'", "winshell; sys_platform == 'win32'"]
41
41
  dev = ["build", "pyinstaller", "pytest>=7.0.0", "pytest-cov>=7.1.0", "pytest-asyncio>=1.3.0", "pytest-mock>=3.15.1"]
42
42
  docs = ["mkdocs>=1.6.1", "mkdocs-material>=9.7.6", "mkdocstrings[python]>=1.0.4", "pymdown-extensions>=10.21.2", "mkdocs-static-i18n>=1.3.1"]
43
- telemetry = [
44
- "opentelemetry-api>=1.25.0,<2.0",
45
- "opentelemetry-sdk>=1.25.0,<2.0",
46
- "opentelemetry-exporter-otlp-proto-http>=1.25.0,<2.0",
47
- "opentelemetry-exporter-otlp-proto-grpc>=1.25.0,<2.0",
48
- "opentelemetry-instrumentation-requests>=0.46b0,<1.0",
49
- "opentelemetry-instrumentation-urllib3>=0.46b0,<1.0",
50
- "opentelemetry-instrumentation-sqlite3>=0.46b0,<1.0",
51
- "opentelemetry-instrumentation-flask>=0.46b0,<1.0",
52
- "opentelemetry-instrumentation-logging>=0.46b0,<1.0",
53
- ]
54
43
 
55
44
  [tool.setuptools.packages.find]
56
45
  where = ["."]
@@ -31,7 +31,7 @@ Attributes:
31
31
  __version__ (str): Current version of Weeb CLI.
32
32
  """
33
33
 
34
- __version__ = "2.17.0"
34
+ __version__ = "3.0.0"
35
35
 
36
36
  # SDK exports for easy import
37
37
  from weeb_cli.sdk import WeebSDK, list_providers, get_provider_info
@@ -259,10 +259,6 @@ def serve_torznab(
259
259
  from weeb_cli.config import config as weeb_config
260
260
  weeb_config.set_headless(True)
261
261
 
262
- # Initialize telemetry
263
- from weeb_cli.services.telemetry import init_telemetry
264
- init_telemetry(environment="server-torznab")
265
-
266
262
  logging.basicConfig(
267
263
  level=logging.INFO,
268
264
  format="%(asctime)s [%(levelname)s] %(message)s",
@@ -304,10 +300,6 @@ def serve_torznab(
304
300
  # Flask app
305
301
  flask_app = Flask(__name__)
306
302
 
307
- # Instrument Flask app for telemetry
308
- from weeb_cli.services.telemetry import instrument_flask_app
309
- instrument_flask_app(flask_app)
310
-
311
303
  @flask_app.route("/api", methods=["GET"])
312
304
  def torznab_api():
313
305
  t = request.args.get("t", "")
@@ -102,10 +102,6 @@ def serve_restful(
102
102
  from weeb_cli.config import config as weeb_config
103
103
  weeb_config.set_headless(True)
104
104
 
105
- # Initialize telemetry
106
- from weeb_cli.services.telemetry import init_telemetry
107
- init_telemetry(environment="server-restful")
108
-
109
105
  # Setup logging
110
106
  logging.basicConfig(
111
107
  level=logging.DEBUG if debug else logging.INFO,
@@ -116,10 +112,6 @@ def serve_restful(
116
112
 
117
113
  # Create Flask app
118
114
  flask_app = Flask(__name__)
119
-
120
- # Instrument Flask app for telemetry
121
- from weeb_cli.services.telemetry import instrument_flask_app
122
- instrument_flask_app(flask_app)
123
115
 
124
116
  if enable_cors:
125
117
  try:
@@ -70,7 +70,6 @@ DEFAULT_CONFIG = {
70
70
  "discord_rpc_enabled": True,
71
71
  "shortcuts_enabled": False,
72
72
  "aniskip_enabled": False,
73
- "telemetry_enabled": True,
74
73
  }
75
74
 
76
75
 
@@ -25,7 +25,6 @@ class ConfigKey(str, Enum):
25
25
  DISCORD_RPC_ENABLED = "discord_rpc_enabled"
26
26
  SHORTCUTS_ENABLED = "shortcuts_enabled"
27
27
  ANISKIP_ENABLED = "aniskip_enabled"
28
- TELEMETRY_ENABLED = "telemetry_enabled"
29
28
 
30
29
 
31
30
  class DownloadStatus(str, Enum):
@@ -62,12 +62,6 @@ def check_ffmpeg_silent():
62
62
 
63
63
  @app.command()
64
64
  def start():
65
- from weeb_cli.services.telemetry import init_telemetry
66
- init_telemetry(environment="cli")
67
-
68
- from weeb_cli.services.logger import reload as reload_logger
69
- reload_logger()
70
-
71
65
  if not config.get("language"):
72
66
  run_setup()
73
67
 
@@ -99,8 +93,6 @@ def start():
99
93
  finally:
100
94
  from weeb_cli.services.discord_rpc import discord_rpc
101
95
  discord_rpc.disconnect()
102
- from weeb_cli.services.telemetry import shutdown_telemetry
103
- shutdown_telemetry()
104
96
 
105
97
  def check_incomplete_downloads():
106
98
  from weeb_cli.services.downloader import queue_manager
@@ -253,61 +253,33 @@ class BaseProvider(ABC):
253
253
  import requests
254
254
  import time
255
255
  import random
256
- from weeb_cli.services.telemetry import get_tracer, record_exception, get_metrics
257
-
258
- tracer = get_tracer()
259
- metrics = get_metrics()
260
-
261
- with tracer.start_as_current_span(
262
- f"provider.request",
263
- attributes={
264
- "weeb.provider.name": getattr(self, "name", "unknown"),
265
- "http.url": url[:256],
266
- "weeb.request.max_retries": max_retries,
267
- },
268
- ) as span:
269
- for attempt in range(max_retries):
270
- try:
271
- response = requests.get(
272
- url,
273
- headers=self.headers,
274
- params=params,
275
- timeout=15
276
- )
277
- response.raise_for_status()
278
-
279
- span.set_attribute("weeb.request.attempts", attempt + 1)
280
- metrics.provider_requests.add(1, {
281
- "weeb.provider.name": getattr(self, "name", "unknown"),
282
- "weeb.request.status": "success",
283
- })
284
-
285
- if json_response:
286
- return response.json()
287
- return response.text
288
-
289
- except requests.RequestException as e:
290
- debug(f"[HTTP] Request failed (attempt {attempt + 1}/{max_retries}): {url} - {e}")
291
-
292
- if attempt < max_retries - 1:
293
- # Skip retries for permanent errors
294
- if isinstance(e, requests.HTTPError) and hasattr(e, 'response') and e.response is not None and e.response.status_code in [404, 403, 401]:
295
- debug(f"[HTTP] Permanent error, skipping retries")
296
- span.set_attribute("weeb.request.attempts", attempt + 1)
297
- metrics.provider_requests.add(1, {
298
- "weeb.provider.name": getattr(self, "name", "unknown"),
299
- "weeb.request.status": "permanent_error",
300
- })
301
- return None
302
-
303
- # Exponential backoff with jitter
304
- delay = min(2 ** attempt, 10) + random.uniform(0, 1)
305
- time.sleep(delay)
306
- continue
307
-
308
- record_exception(span, e)
309
- metrics.provider_requests.add(1, {
310
- "weeb.provider.name": getattr(self, "name", "unknown"),
311
- "weeb.request.status": "failed",
312
- })
313
- return None
256
+
257
+ for attempt in range(max_retries):
258
+ try:
259
+ response = requests.get(
260
+ url,
261
+ headers=self.headers,
262
+ params=params,
263
+ timeout=15
264
+ )
265
+ response.raise_for_status()
266
+
267
+ if json_response:
268
+ return response.json()
269
+ return response.text
270
+
271
+ except requests.RequestException as e:
272
+ debug(f"[HTTP] Request failed (attempt {attempt + 1}/{max_retries}): {url} - {e}")
273
+
274
+ if attempt < max_retries - 1:
275
+ # Skip retries for permanent errors
276
+ if isinstance(e, requests.HTTPError) and hasattr(e, 'response') and e.response is not None and e.response.status_code in [404, 403, 401]:
277
+ debug(f"[HTTP] Permanent error, skipping retries")
278
+ return None
279
+
280
+ # Exponential backoff with jitter
281
+ delay = min(2 ** attempt, 10) + random.uniform(0, 1)
282
+ time.sleep(delay)
283
+ continue
284
+
285
+ return None
@@ -55,7 +55,6 @@ Functions:
55
55
  get_provider_info: Get metadata for a specific provider
56
56
  """
57
57
 
58
- import os
59
58
  from typing import List, Optional, Dict, Any
60
59
  from pathlib import Path
61
60
 
@@ -105,10 +104,6 @@ class WeebSDK:
105
104
  if headless:
106
105
  config.set_headless(True)
107
106
  debug("[SDK] Initialized in headless mode")
108
-
109
- # Initialize telemetry if enabled in config
110
- from weeb_cli.services.telemetry import init_telemetry
111
- init_telemetry(environment="sdk")
112
107
 
113
108
  def list_providers(self) -> List[Dict[str, Any]]:
114
109
  """List all available anime providers.
@@ -70,24 +70,14 @@ class CacheManager:
70
70
 
71
71
  def _get_cache_key(self, key: str) -> str:
72
72
  """Generate SHA256 hash for cache key.
73
-
73
+
74
74
  Args:
75
75
  key: Original cache key.
76
-
76
+
77
77
  Returns:
78
78
  Hexadecimal hash string.
79
79
  """
80
80
  return hashlib.sha256(key.encode()).hexdigest()
81
-
82
- def _record_cache_metric(self, result: str, tier: str) -> None:
83
- try:
84
- from weeb_cli.services.telemetry import get_metrics
85
- get_metrics().cache_operations.add(1, {
86
- "weeb.cache.result": result,
87
- "weeb.cache.tier": tier,
88
- })
89
- except Exception:
90
- pass
91
81
 
92
82
  def get(self, key: str, max_age: int = 3600) -> Optional[Any]:
93
83
  """Retrieve cached value if not expired.
@@ -110,15 +100,14 @@ class CacheManager:
110
100
  if key in self._memory_cache:
111
101
  value, timestamp = self._memory_cache[key]
112
102
  if time.time() - timestamp < max_age:
113
- self._record_cache_metric("hit", "memory")
114
103
  return value
115
104
  else:
116
105
  del self._memory_cache[key]
117
-
106
+
118
107
  # Check file cache
119
108
  cache_key = self._get_cache_key(key)
120
109
  cache_file = self.cache_dir / f"{cache_key}.cache"
121
-
110
+
122
111
  if cache_file.exists():
123
112
  age = time.time() - cache_file.stat().st_mtime
124
113
  if age < max_age:
@@ -126,12 +115,10 @@ class CacheManager:
126
115
  with open(cache_file, 'r', encoding='utf-8') as f:
127
116
  value = json.load(f)
128
117
  self._memory_cache[key] = (value, time.time())
129
- self._record_cache_metric("hit", "file")
130
118
  return value
131
119
  except (json.JSONDecodeError, UnicodeDecodeError, OSError):
132
120
  cache_file.unlink(missing_ok=True)
133
-
134
- self._record_cache_metric("miss", "none")
121
+
135
122
  return None
136
123
 
137
124
  def set(self, key: str, value: Any, ttl: Optional[int] = None) -> None:
@@ -0,0 +1,69 @@
1
+ """Download manager with strategy pattern."""
2
+
3
+ from typing import List
4
+ from pathlib import Path
5
+
6
+ from weeb_cli.services.download.context import DownloadContext
7
+ from weeb_cli.services.download.strategies import (
8
+ DownloadStrategy,
9
+ Aria2Strategy,
10
+ YtdlpStrategy,
11
+ FFmpegStrategy,
12
+ GenericStrategy
13
+ )
14
+ from weeb_cli.services.logger import debug
15
+ from weeb_cli.exceptions import DownloadError
16
+
17
+
18
+ class DownloadManager:
19
+ """Manages download operations using multiple strategies.
20
+
21
+ Tries strategies in priority order until one succeeds.
22
+ """
23
+
24
+ def __init__(self):
25
+ self.strategies: List[DownloadStrategy] = [
26
+ Aria2Strategy(),
27
+ YtdlpStrategy(),
28
+ FFmpegStrategy(),
29
+ GenericStrategy()
30
+ ]
31
+ self.strategies.sort(key=lambda s: s.get_priority())
32
+
33
+ def download(self, url: str, output_path: str, item: dict = None) -> None:
34
+ """Download a file using the best available strategy.
35
+
36
+ Args:
37
+ url: Stream URL to download.
38
+ output_path: Path where file should be saved.
39
+ item: Optional queue item metadata for progress tracking.
40
+
41
+ Raises:
42
+ DownloadError: If all strategies fail.
43
+ """
44
+ context = DownloadContext(
45
+ url=url,
46
+ output_path=output_path,
47
+ item=item
48
+ )
49
+
50
+ last_error = None
51
+
52
+ for strategy in self.strategies:
53
+ if not strategy.can_handle(url):
54
+ continue
55
+
56
+ strategy_name = strategy.__class__.__name__
57
+ debug(f"[DownloadManager] Trying {strategy_name} for {url[:80]}...")
58
+
59
+ try:
60
+ strategy.download(context)
61
+ debug(f"[DownloadManager] Success with {strategy_name}")
62
+ return
63
+ except Exception as e:
64
+ last_error = e
65
+ debug(f"[DownloadManager] {strategy_name} failed: {e}")
66
+ continue
67
+
68
+ error_msg = f"All download strategies failed. Last error: {last_error}"
69
+ raise DownloadError(error_msg, code="ALL_STRATEGIES_FAILED")
@@ -9,22 +9,11 @@ console = Console()
9
9
 
10
10
  def handle_error(e: Exception, context: str = "", user_message: Optional[str] = None) -> None:
11
11
  is_debug = config.get("debug_mode", False)
12
-
12
+
13
13
  if is_debug:
14
14
  log_error(f"[{context}] {type(e).__name__}: {str(e)}")
15
15
  log_error(traceback.format_exc())
16
-
17
- try:
18
- from opentelemetry import trace as _trace
19
- span = _trace.get_current_span()
20
- if span.is_recording():
21
- from weeb_cli.services.telemetry import record_exception
22
- record_exception(span, e)
23
- if context:
24
- span.set_attribute("weeb.error.context", context)
25
- except (ImportError, Exception):
26
- pass
27
-
16
+
28
17
  if user_message:
29
18
  console.print(f"[red]{user_message}[/red]")
30
19
  else:
@@ -16,21 +16,21 @@ def _setup_logger():
16
16
  logger = logging.getLogger("weeb-cli")
17
17
  logger.setLevel(logging.DEBUG)
18
18
  logger.handlers = []
19
-
19
+
20
20
  if config.get("debug_mode", False):
21
21
  log_dir = Path.home() / ".weeb-cli" / "logs"
22
22
  log_dir.mkdir(parents=True, exist_ok=True)
23
-
23
+
24
24
  try:
25
25
  _clean_old_logs(log_dir)
26
26
  except OSError:
27
27
  pass
28
-
28
+
29
29
  log_file = log_dir / f"debug_{datetime.now().strftime('%Y%m%d')}.log"
30
-
30
+
31
31
  handler = logging.FileHandler(log_file, encoding='utf-8')
32
32
  handler.setLevel(logging.DEBUG)
33
-
33
+
34
34
  formatter = logging.Formatter(
35
35
  '%(asctime)s | %(levelname)s | %(module)s:%(lineno)d | %(message)s',
36
36
  datefmt='%H:%M:%S'
@@ -39,20 +39,7 @@ def _setup_logger():
39
39
  logger.addHandler(handler)
40
40
  else:
41
41
  logger.addHandler(logging.NullHandler())
42
-
43
- try:
44
- from weeb_cli.services.telemetry import is_enabled
45
- if is_enabled():
46
- from opentelemetry._logs import get_logger_provider
47
- from opentelemetry.sdk._logs import LoggingHandler
48
- otel_handler = LoggingHandler(
49
- level=logging.DEBUG,
50
- logger_provider=get_logger_provider(),
51
- )
52
- logger.addHandler(otel_handler)
53
- except (ImportError, Exception):
54
- pass
55
-
42
+
56
43
  return logger
57
44
 
58
45
  def debug(msg, *args):
@@ -4,7 +4,6 @@ from weeb_cli.providers import get_provider, get_default_provider, list_provider
4
4
  from weeb_cli.providers.base import AnimeResult, AnimeDetails, Episode, StreamLink
5
5
  from weeb_cli.exceptions import ProviderError
6
6
  from weeb_cli.services.error_handler import handle_provider_error
7
- from weeb_cli.services.telemetry import traced
8
7
 
9
8
 
10
9
  class Scraper:
@@ -31,7 +30,6 @@ class Scraper:
31
30
 
32
31
  return self._provider
33
32
 
34
- @traced(name="scraper.search")
35
33
  def search(self, query: str) -> List[AnimeResult]:
36
34
  self.last_error = None
37
35
  if not self.provider:
@@ -47,7 +45,6 @@ class Scraper:
47
45
  handle_provider_error(e, self._provider_name)
48
46
  return []
49
47
 
50
- @traced(name="scraper.get_details")
51
48
  def get_details(self, anime_id: str) -> Optional[AnimeDetails]:
52
49
  self.last_error = None
53
50
  if not self.provider:
@@ -63,7 +60,6 @@ class Scraper:
63
60
  handle_provider_error(e, self._provider_name)
64
61
  return None
65
62
 
66
- @traced(name="scraper.get_episodes")
67
63
  def get_episodes(self, anime_id: str) -> List[Episode]:
68
64
  self.last_error = None
69
65
  if not self.provider:
@@ -79,7 +75,6 @@ class Scraper:
79
75
  handle_provider_error(e, self._provider_name)
80
76
  return []
81
77
 
82
- @traced(name="scraper.get_streams")
83
78
  def get_streams(self, anime_id: str, episode_id: str) -> List[StreamLink]:
84
79
  from weeb_cli.services.logger import debug
85
80
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weeb-cli
3
- Version: 2.17.0
3
+ Version: 3.0.0
4
4
  Summary: No browser, no ads, no distractions. Just you and an unparalleled anime viewing experience.
5
5
  Author-email: ewgsta <ewgst@proton.me>
6
6
  License-Expression: GPL-3.0-only
@@ -51,16 +51,6 @@ Requires-Dist: mkdocs-material>=9.7.6; extra == "docs"
51
51
  Requires-Dist: mkdocstrings[python]>=1.0.4; extra == "docs"
52
52
  Requires-Dist: pymdown-extensions>=10.21.2; extra == "docs"
53
53
  Requires-Dist: mkdocs-static-i18n>=1.3.1; extra == "docs"
54
- Provides-Extra: telemetry
55
- Requires-Dist: opentelemetry-api<2.0,>=1.25.0; extra == "telemetry"
56
- Requires-Dist: opentelemetry-sdk<2.0,>=1.25.0; extra == "telemetry"
57
- Requires-Dist: opentelemetry-exporter-otlp-proto-http<2.0,>=1.25.0; extra == "telemetry"
58
- Requires-Dist: opentelemetry-exporter-otlp-proto-grpc<2.0,>=1.25.0; extra == "telemetry"
59
- Requires-Dist: opentelemetry-instrumentation-requests<1.0,>=0.46b0; extra == "telemetry"
60
- Requires-Dist: opentelemetry-instrumentation-urllib3<1.0,>=0.46b0; extra == "telemetry"
61
- Requires-Dist: opentelemetry-instrumentation-sqlite3<1.0,>=0.46b0; extra == "telemetry"
62
- Requires-Dist: opentelemetry-instrumentation-flask<1.0,>=0.46b0; extra == "telemetry"
63
- Requires-Dist: opentelemetry-instrumentation-logging<1.0,>=0.46b0; extra == "telemetry"
64
54
  Dynamic: license-file
65
55
 
66
56
  <p align="center">
@@ -100,7 +100,6 @@ weeb_cli/services/scraper.py
100
100
  weeb_cli/services/search.py
101
101
  weeb_cli/services/shortcuts.py
102
102
  weeb_cli/services/stream_validator.py
103
- weeb_cli/services/telemetry.py
104
103
  weeb_cli/services/tracker.py
105
104
  weeb_cli/services/updater.py
106
105
  weeb_cli/services/watch.py
@@ -44,14 +44,3 @@ flask-cors>=4.0
44
44
  [shortcuts:sys_platform == "win32"]
45
45
  pywin32
46
46
  winshell
47
-
48
- [telemetry]
49
- opentelemetry-api<2.0,>=1.25.0
50
- opentelemetry-sdk<2.0,>=1.25.0
51
- opentelemetry-exporter-otlp-proto-http<2.0,>=1.25.0
52
- opentelemetry-exporter-otlp-proto-grpc<2.0,>=1.25.0
53
- opentelemetry-instrumentation-requests<1.0,>=0.46b0
54
- opentelemetry-instrumentation-urllib3<1.0,>=0.46b0
55
- opentelemetry-instrumentation-sqlite3<1.0,>=0.46b0
56
- opentelemetry-instrumentation-flask<1.0,>=0.46b0
57
- opentelemetry-instrumentation-logging<1.0,>=0.46b0
@@ -1,89 +0,0 @@
1
- """Download manager with strategy pattern."""
2
-
3
- import time as _time
4
- from typing import List
5
- from pathlib import Path
6
-
7
- from weeb_cli.services.download.context import DownloadContext
8
- from weeb_cli.services.download.strategies import (
9
- DownloadStrategy,
10
- Aria2Strategy,
11
- YtdlpStrategy,
12
- FFmpegStrategy,
13
- GenericStrategy
14
- )
15
- from weeb_cli.services.logger import debug
16
- from weeb_cli.exceptions import DownloadError
17
- from weeb_cli.services.telemetry import get_tracer, get_metrics, record_exception
18
-
19
-
20
- class DownloadManager:
21
- """Manages download operations using multiple strategies.
22
-
23
- Tries strategies in priority order until one succeeds.
24
- """
25
-
26
- def __init__(self):
27
- self.strategies: List[DownloadStrategy] = [
28
- Aria2Strategy(),
29
- YtdlpStrategy(),
30
- FFmpegStrategy(),
31
- GenericStrategy()
32
- ]
33
- self.strategies.sort(key=lambda s: s.get_priority())
34
-
35
- def download(self, url: str, output_path: str, item: dict = None) -> None:
36
- """Download a file using the best available strategy.
37
-
38
- Args:
39
- url: Stream URL to download.
40
- output_path: Path where file should be saved.
41
- item: Optional queue item metadata for progress tracking.
42
-
43
- Raises:
44
- DownloadError: If all strategies fail.
45
- """
46
- tracer = get_tracer()
47
- m = get_metrics()
48
- start = _time.monotonic()
49
-
50
- with tracer.start_as_current_span("download", attributes={
51
- "weeb.download.url_prefix": url[:80],
52
- "weeb.download.output": output_path,
53
- }) as span:
54
- context = DownloadContext(
55
- url=url,
56
- output_path=output_path,
57
- item=item
58
- )
59
-
60
- last_error = None
61
-
62
- for strategy in self.strategies:
63
- if not strategy.can_handle(url):
64
- continue
65
-
66
- strategy_name = strategy.__class__.__name__
67
- debug(f"[DownloadManager] Trying {strategy_name} for {url[:80]}...")
68
-
69
- try:
70
- strategy.download(context)
71
- debug(f"[DownloadManager] Success with {strategy_name}")
72
- duration = _time.monotonic() - start
73
- span.set_attribute("weeb.download.strategy", strategy_name)
74
- m.download_duration.record(duration, {"weeb.download.strategy": strategy_name, "weeb.download.status": "success"})
75
- m.download_status.add(1, {"status": "success"})
76
- return
77
- except Exception as e:
78
- last_error = e
79
- debug(f"[DownloadManager] {strategy_name} failed: {e}")
80
- continue
81
-
82
- duration = _time.monotonic() - start
83
- m.download_duration.record(duration, {"weeb.download.status": "failed"})
84
- m.download_status.add(1, {"status": "failed"})
85
-
86
- error_msg = f"All download strategies failed. Last error: {last_error}"
87
- err = DownloadError(error_msg, code="ALL_STRATEGIES_FAILED")
88
- record_exception(span, err)
89
- raise err