weeb-cli 2.16.0__tar.gz → 2.16.2__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 (129) hide show
  1. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/PKG-INFO +35 -2
  2. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/README.md +31 -1
  3. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/pyproject.toml +2 -1
  4. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/__init__.py +1 -1
  5. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/main.py +11 -0
  6. weeb_cli-2.16.2/weeb_cli/utils/shortcuts.py +269 -0
  7. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli.egg-info/PKG-INFO +35 -2
  8. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli.egg-info/SOURCES.txt +2 -1
  9. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli.egg-info/requires.txt +6 -0
  10. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/LICENSE +0 -0
  11. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/setup.cfg +0 -0
  12. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/tests/test_anilist_tracker.py +0 -0
  13. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/tests/test_aniworld_provider.py +0 -0
  14. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/tests/test_api.py +0 -0
  15. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/tests/test_cache.py +0 -0
  16. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/tests/test_exceptions.py +0 -0
  17. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/tests/test_kitsu_tracker.py +0 -0
  18. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/tests/test_mal_tracker.py +0 -0
  19. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/tests/test_providers.py +0 -0
  20. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/tests/test_restful_api.py +0 -0
  21. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/tests/test_sanitizer.py +0 -0
  22. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/tests/test_sanitizer_security.py +0 -0
  23. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/tests/test_sdk.py +0 -0
  24. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/__main__.py +0 -0
  25. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/__init__.py +0 -0
  26. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/api.py +0 -0
  27. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/downloads.py +0 -0
  28. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/library.py +0 -0
  29. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/search/__init__.py +0 -0
  30. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/search/anime_details.py +0 -0
  31. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/search/download_flow.py +0 -0
  32. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/search/episode_utils.py +0 -0
  33. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/search/search_handlers.py +0 -0
  34. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/search/stream_utils.py +0 -0
  35. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/search/watch_flow.py +0 -0
  36. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/search.py +0 -0
  37. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/serve.py +0 -0
  38. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/serve_restful.py +0 -0
  39. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/settings/__init__.py +0 -0
  40. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/settings/settings_backup.py +0 -0
  41. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/settings/settings_cache.py +0 -0
  42. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/settings/settings_config.py +0 -0
  43. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/settings/settings_download.py +0 -0
  44. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/settings/settings_drives.py +0 -0
  45. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/settings/settings_menu.py +0 -0
  46. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/settings/settings_shortcuts.py +0 -0
  47. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/settings/settings_trackers.py +0 -0
  48. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/settings.py +0 -0
  49. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/setup.py +0 -0
  50. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/commands/watchlist.py +0 -0
  51. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/config.py +0 -0
  52. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/constants.py +0 -0
  53. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/exceptions.py +0 -0
  54. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/i18n.py +0 -0
  55. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/locales/de.json +0 -0
  56. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/locales/en.json +0 -0
  57. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/locales/pl.json +0 -0
  58. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/locales/tr.json +0 -0
  59. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/__init__.py +0 -0
  60. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/base.py +0 -0
  61. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/de/__init__.py +0 -0
  62. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/de/aniworld.py +0 -0
  63. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/en/__init__.py +0 -0
  64. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/en/allanime.py +0 -0
  65. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/en/hianime.py +0 -0
  66. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/extractors/__init__.py +0 -0
  67. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/extractors/doodstream.py +0 -0
  68. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/extractors/filemoon.py +0 -0
  69. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/extractors/megacloud.py +0 -0
  70. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/extractors/streamtape.py +0 -0
  71. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/extractors/vidoza.py +0 -0
  72. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/extractors/voe.py +0 -0
  73. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/pl/__init__.py +0 -0
  74. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/pl/docchi.py +0 -0
  75. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/registry.py +0 -0
  76. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/tr/__init__.py +0 -0
  77. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/tr/animecix.py +0 -0
  78. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/tr/anizle.py +0 -0
  79. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/tr/turkanime.py +0 -0
  80. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/providers/tr/weeb.py +0 -0
  81. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/sdk.py +0 -0
  82. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/__init__.py +0 -0
  83. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/_base.py +0 -0
  84. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/_tracker_base.py +0 -0
  85. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/aniskip.py +0 -0
  86. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/cache.py +0 -0
  87. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/database.py +0 -0
  88. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/dependency_manager.py +0 -0
  89. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/details.py +0 -0
  90. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/discord_rpc.py +0 -0
  91. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/download/__init__.py +0 -0
  92. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/download/context.py +0 -0
  93. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/download/manager.py +0 -0
  94. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/download/queue.py +0 -0
  95. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/download/strategies/__init__.py +0 -0
  96. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/download/strategies/aria2.py +0 -0
  97. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/download/strategies/base.py +0 -0
  98. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/download/strategies/ffmpeg.py +0 -0
  99. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/download/strategies/generic.py +0 -0
  100. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/download/strategies/ytdlp.py +0 -0
  101. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/downloader.py +0 -0
  102. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/error_handler.py +0 -0
  103. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/headless_downloader.py +0 -0
  104. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/local_library.py +0 -0
  105. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/logger.py +0 -0
  106. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/notifier.py +0 -0
  107. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/player.py +0 -0
  108. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/progress.py +0 -0
  109. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/scraper.py +0 -0
  110. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/search.py +0 -0
  111. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/shortcuts.py +0 -0
  112. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/stream_validator.py +0 -0
  113. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/tracker.py +0 -0
  114. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/updater.py +0 -0
  115. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/services/watch.py +0 -0
  116. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/templates/anilist_error.html +0 -0
  117. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/templates/anilist_success.html +0 -0
  118. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/templates/mal_error.html +0 -0
  119. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/templates/mal_success.html +0 -0
  120. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/ui/__init__.py +0 -0
  121. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/ui/header.py +0 -0
  122. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/ui/menu.py +0 -0
  123. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/ui/prompt.py +0 -0
  124. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/utils/__init__.py +0 -0
  125. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/utils/decorators.py +0 -0
  126. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli/utils/sanitizer.py +0 -0
  127. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli.egg-info/dependency_links.txt +0 -0
  128. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/weeb_cli.egg-info/entry_points.txt +0 -0
  129. {weeb_cli-2.16.0 → weeb_cli-2.16.2}/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.16.0
3
+ Version: 2.16.2
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
@@ -35,6 +35,9 @@ Requires-Dist: pyyaml>=6.0; extra == "serve"
35
35
  Provides-Extra: serve-restful
36
36
  Requires-Dist: flask>=3.0; extra == "serve-restful"
37
37
  Requires-Dist: flask-cors>=4.0; extra == "serve-restful"
38
+ Provides-Extra: shortcuts
39
+ Requires-Dist: pywin32; sys_platform == "win32" and extra == "shortcuts"
40
+ Requires-Dist: winshell; sys_platform == "win32" and extra == "shortcuts"
38
41
  Provides-Extra: dev
39
42
  Requires-Dist: build; extra == "dev"
40
43
  Requires-Dist: pyinstaller; extra == "dev"
@@ -144,7 +147,37 @@ Download the appropriate file for your platform from [Releases](https://github.c
144
147
  ```bash
145
148
  git clone https://github.com/ewgsta/weeb-cli.git
146
149
  cd weeb-cli
147
- pip install -e .
150
+
151
+ # Install with Makefile
152
+ make install-dev
153
+
154
+ # Or install manually
155
+ pip install -e ".[dev]"
156
+ ```
157
+
158
+ #### Makefile Commands
159
+
160
+ The project includes a Makefile for common development tasks:
161
+
162
+ ```bash
163
+ # Installation
164
+ make install # Install core dependencies
165
+ make install-dev # Install with development dependencies
166
+ make install-serve # Install with server dependencies
167
+ make install-all # Install all dependencies
168
+
169
+ # Testing
170
+ make test # Run tests
171
+ make test-cov # Run tests with coverage report
172
+
173
+ # Build
174
+ make build # Build distribution packages
175
+ make clean # Clean build artifacts
176
+
177
+ # Utilities
178
+ make lint # Run linting checks
179
+ make check-deps # Verify dependencies
180
+ make help # Show all available commands
148
181
  ```
149
182
 
150
183
  ---
@@ -98,7 +98,37 @@ Download the appropriate file for your platform from [Releases](https://github.c
98
98
  ```bash
99
99
  git clone https://github.com/ewgsta/weeb-cli.git
100
100
  cd weeb-cli
101
- pip install -e .
101
+
102
+ # Install with Makefile
103
+ make install-dev
104
+
105
+ # Or install manually
106
+ pip install -e ".[dev]"
107
+ ```
108
+
109
+ #### Makefile Commands
110
+
111
+ The project includes a Makefile for common development tasks:
112
+
113
+ ```bash
114
+ # Installation
115
+ make install # Install core dependencies
116
+ make install-dev # Install with development dependencies
117
+ make install-serve # Install with server dependencies
118
+ make install-all # Install all dependencies
119
+
120
+ # Testing
121
+ make test # Run tests
122
+ make test-cov # Run tests with coverage report
123
+
124
+ # Build
125
+ make build # Build distribution packages
126
+ make clean # Clean build artifacts
127
+
128
+ # Utilities
129
+ make lint # Run linting checks
130
+ make check-deps # Verify dependencies
131
+ make help # Show all available commands
102
132
  ```
103
133
 
104
134
  ---
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "weeb-cli"
7
- version = "2.16.0"
7
+ version = "2.16.2"
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" }]
@@ -37,6 +37,7 @@ dependencies = [
37
37
  [project.optional-dependencies]
38
38
  serve = ["flask>=3.0", "pyyaml>=6.0"]
39
39
  serve-restful = ["flask>=3.0", "flask-cors>=4.0"]
40
+ shortcuts = ["pywin32; sys_platform == 'win32'", "winshell; sys_platform == 'win32'"]
40
41
  dev = ["build", "pyinstaller", "pytest>=7.0.0", "pytest-cov", "pytest-asyncio", "pytest-mock"]
41
42
 
42
43
  [tool.setuptools.packages.find]
@@ -31,7 +31,7 @@ Attributes:
31
31
  __version__ (str): Current version of Weeb CLI.
32
32
  """
33
33
 
34
- __version__ = "2.16.0"
34
+ __version__ = "2.16.2"
35
35
 
36
36
  # SDK exports for easy import
37
37
  from weeb_cli.sdk import WeebSDK, list_providers, get_provider_info
@@ -65,6 +65,17 @@ def start():
65
65
  if not config.get("language"):
66
66
  run_setup()
67
67
 
68
+ # Create desktop shortcuts in background (non-blocking)
69
+ import threading
70
+ def _create_shortcuts_background():
71
+ try:
72
+ from weeb_cli.utils.shortcuts import create_shortcuts
73
+ create_shortcuts()
74
+ except Exception:
75
+ pass # Silently fail, shortcuts are optional
76
+
77
+ threading.Thread(target=_create_shortcuts_background, daemon=True).start()
78
+
68
79
  # Initialize AniSkip service with config
69
80
  from weeb_cli.services.aniskip import aniskip_service
70
81
  aniskip_enabled = config.get("aniskip_enabled", False)
@@ -0,0 +1,269 @@
1
+ """Desktop shortcut creation utilities.
2
+
3
+ Creates platform-specific shortcuts for easy application access:
4
+ - Linux: .desktop file in ~/.local/share/applications/
5
+ - macOS: .app alias in /Applications/
6
+ - Windows: Start Menu shortcut
7
+ """
8
+
9
+ import os
10
+ import sys
11
+ import shutil
12
+ from pathlib import Path
13
+ from typing import Optional
14
+
15
+
16
+ def get_executable_path() -> str:
17
+ """Get the path to the weeb-cli executable.
18
+
19
+ Returns:
20
+ Path to the executable or python script.
21
+ """
22
+ if getattr(sys, 'frozen', False):
23
+ # Running as compiled executable
24
+ return sys.executable
25
+ else:
26
+ # Running as Python script
27
+ return shutil.which('weeb-cli') or sys.executable
28
+
29
+
30
+ def get_icon_path() -> Optional[str]:
31
+ """Get the path to the application icon if available.
32
+
33
+ Returns:
34
+ Path to icon file or None.
35
+ """
36
+ # Try to find icon in package
37
+ try:
38
+ import weeb_cli
39
+ package_dir = Path(weeb_cli.__file__).parent
40
+ icon_path = package_dir / 'assets' / 'icon.png'
41
+ if icon_path.exists():
42
+ return str(icon_path)
43
+ except Exception:
44
+ pass
45
+ return None
46
+
47
+
48
+ def create_linux_desktop_file() -> bool:
49
+ """Create .desktop file for Linux.
50
+
51
+ Creates a desktop entry in ~/.local/share/applications/
52
+ following the freedesktop.org specification.
53
+
54
+ Returns:
55
+ True if successful, False otherwise.
56
+ """
57
+ try:
58
+ apps_dir = Path.home() / '.local' / 'share' / 'applications'
59
+ apps_dir.mkdir(parents=True, exist_ok=True)
60
+
61
+ desktop_file = apps_dir / 'weeb-cli.desktop'
62
+
63
+ # Don't recreate if it already exists
64
+ if desktop_file.exists():
65
+ return True
66
+
67
+ executable = get_executable_path()
68
+ icon = get_icon_path() or 'utilities-terminal'
69
+
70
+ content = f"""[Desktop Entry]
71
+ Version=1.0
72
+ Type=Application
73
+ Name=Weeb CLI
74
+ Comment=Terminal-based anime streaming application
75
+ Exec={executable}
76
+ Icon={icon}
77
+ Terminal=true
78
+ Categories=AudioVideo;Video;Player;
79
+ Keywords=anime;streaming;video;
80
+ StartupNotify=false
81
+ """
82
+
83
+ desktop_file.write_text(content)
84
+ desktop_file.chmod(0o755)
85
+
86
+ return True
87
+ except Exception:
88
+ return False
89
+
90
+
91
+ def create_macos_alias() -> bool:
92
+ """Create application alias for macOS.
93
+
94
+ Creates a symbolic link in /Applications/ if user has permissions,
95
+ otherwise creates in ~/Applications/.
96
+
97
+ Returns:
98
+ True if successful, False otherwise.
99
+ """
100
+ try:
101
+ executable = get_executable_path()
102
+
103
+ # Try system Applications first, fallback to user Applications
104
+ for apps_dir in [Path('/Applications'), Path.home() / 'Applications']:
105
+ apps_dir.mkdir(parents=True, exist_ok=True)
106
+
107
+ link_path = apps_dir / 'Weeb CLI'
108
+
109
+ # Don't recreate if it already exists
110
+ if link_path.exists():
111
+ return True
112
+
113
+ try:
114
+ # Create symbolic link
115
+ link_path.symlink_to(executable)
116
+ return True
117
+ except PermissionError:
118
+ # Try next location
119
+ continue
120
+
121
+ return False
122
+ except Exception:
123
+ return False
124
+
125
+
126
+ def create_windows_shortcut() -> bool:
127
+ """Create Start Menu shortcut for Windows.
128
+
129
+ Creates a shortcut in the Start Menu using Windows COM API.
130
+
131
+ Returns:
132
+ True if successful, False otherwise.
133
+ """
134
+ try:
135
+ import winshell
136
+ from win32com.client import Dispatch
137
+
138
+ start_menu = Path(winshell.start_menu())
139
+ programs = start_menu / 'Programs'
140
+ programs.mkdir(parents=True, exist_ok=True)
141
+
142
+ shortcut_path = programs / 'Weeb CLI.lnk'
143
+
144
+ # Don't recreate if it already exists
145
+ if shortcut_path.exists():
146
+ return True
147
+
148
+ executable = get_executable_path()
149
+
150
+ shell = Dispatch('WScript.Shell')
151
+ shortcut = shell.CreateShortCut(str(shortcut_path))
152
+ shortcut.TargetPath = executable
153
+ shortcut.WorkingDirectory = str(Path.home())
154
+ shortcut.Description = 'Terminal-based anime streaming application'
155
+
156
+ icon = get_icon_path()
157
+ if icon:
158
+ shortcut.IconLocation = icon
159
+
160
+ shortcut.save()
161
+
162
+ return True
163
+ except ImportError:
164
+ # winshell or pywin32 not available
165
+ return False
166
+ except Exception:
167
+ return False
168
+
169
+
170
+ def should_create_shortcuts() -> bool:
171
+ """Check if shortcuts should be created.
172
+
173
+ Returns:
174
+ True if this is first run or shortcuts are missing.
175
+ """
176
+ from weeb_cli.config import CONFIG_DIR
177
+
178
+ marker_file = CONFIG_DIR / '.shortcuts_created'
179
+
180
+ # If marker exists, check if shortcuts still exist
181
+ if marker_file.exists():
182
+ if sys.platform == 'linux':
183
+ desktop_file = Path.home() / '.local' / 'share' / 'applications' / 'weeb-cli.desktop'
184
+ return not desktop_file.exists()
185
+ elif sys.platform == 'darwin':
186
+ for apps_dir in [Path('/Applications'), Path.home() / 'Applications']:
187
+ if (apps_dir / 'Weeb CLI').exists():
188
+ return False
189
+ return True
190
+ elif sys.platform == 'win32':
191
+ try:
192
+ import winshell
193
+ start_menu = Path(winshell.start_menu())
194
+ shortcut = start_menu / 'Programs' / 'Weeb CLI.lnk'
195
+ return not shortcut.exists()
196
+ except ImportError:
197
+ return False
198
+
199
+ return True
200
+
201
+
202
+ def create_shortcuts() -> bool:
203
+ """Create platform-specific shortcuts.
204
+
205
+ Automatically detects the platform and creates appropriate shortcuts.
206
+ Only runs on first launch or if shortcuts are missing.
207
+
208
+ Returns:
209
+ True if shortcuts were created successfully.
210
+ """
211
+ if not should_create_shortcuts():
212
+ return True
213
+
214
+ success = False
215
+
216
+ if sys.platform == 'linux':
217
+ success = create_linux_desktop_file()
218
+ elif sys.platform == 'darwin':
219
+ success = create_macos_alias()
220
+ elif sys.platform == 'win32':
221
+ success = create_windows_shortcut()
222
+
223
+ # Mark as created even if failed to avoid repeated attempts
224
+ if success:
225
+ from weeb_cli.config import CONFIG_DIR
226
+ marker_file = CONFIG_DIR / '.shortcuts_created'
227
+ CONFIG_DIR.mkdir(parents=True, exist_ok=True)
228
+ marker_file.touch()
229
+
230
+ return success
231
+
232
+
233
+ def remove_shortcuts() -> bool:
234
+ """Remove all platform-specific shortcuts.
235
+
236
+ Returns:
237
+ True if shortcuts were removed successfully.
238
+ """
239
+ try:
240
+ if sys.platform == 'linux':
241
+ desktop_file = Path.home() / '.local' / 'share' / 'applications' / 'weeb-cli.desktop'
242
+ if desktop_file.exists():
243
+ desktop_file.unlink()
244
+
245
+ elif sys.platform == 'darwin':
246
+ for apps_dir in [Path('/Applications'), Path.home() / 'Applications']:
247
+ link_path = apps_dir / 'Weeb CLI'
248
+ if link_path.exists():
249
+ link_path.unlink()
250
+
251
+ elif sys.platform == 'win32':
252
+ try:
253
+ import winshell
254
+ start_menu = Path(winshell.start_menu())
255
+ shortcut = start_menu / 'Programs' / 'Weeb CLI.lnk'
256
+ if shortcut.exists():
257
+ shortcut.unlink()
258
+ except ImportError:
259
+ pass
260
+
261
+ # Remove marker
262
+ from weeb_cli.config import CONFIG_DIR
263
+ marker_file = CONFIG_DIR / '.shortcuts_created'
264
+ if marker_file.exists():
265
+ marker_file.unlink()
266
+
267
+ return True
268
+ except Exception:
269
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weeb-cli
3
- Version: 2.16.0
3
+ Version: 2.16.2
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
@@ -35,6 +35,9 @@ Requires-Dist: pyyaml>=6.0; extra == "serve"
35
35
  Provides-Extra: serve-restful
36
36
  Requires-Dist: flask>=3.0; extra == "serve-restful"
37
37
  Requires-Dist: flask-cors>=4.0; extra == "serve-restful"
38
+ Provides-Extra: shortcuts
39
+ Requires-Dist: pywin32; sys_platform == "win32" and extra == "shortcuts"
40
+ Requires-Dist: winshell; sys_platform == "win32" and extra == "shortcuts"
38
41
  Provides-Extra: dev
39
42
  Requires-Dist: build; extra == "dev"
40
43
  Requires-Dist: pyinstaller; extra == "dev"
@@ -144,7 +147,37 @@ Download the appropriate file for your platform from [Releases](https://github.c
144
147
  ```bash
145
148
  git clone https://github.com/ewgsta/weeb-cli.git
146
149
  cd weeb-cli
147
- pip install -e .
150
+
151
+ # Install with Makefile
152
+ make install-dev
153
+
154
+ # Or install manually
155
+ pip install -e ".[dev]"
156
+ ```
157
+
158
+ #### Makefile Commands
159
+
160
+ The project includes a Makefile for common development tasks:
161
+
162
+ ```bash
163
+ # Installation
164
+ make install # Install core dependencies
165
+ make install-dev # Install with development dependencies
166
+ make install-serve # Install with server dependencies
167
+ make install-all # Install all dependencies
168
+
169
+ # Testing
170
+ make test # Run tests
171
+ make test-cov # Run tests with coverage report
172
+
173
+ # Build
174
+ make build # Build distribution packages
175
+ make clean # Clean build artifacts
176
+
177
+ # Utilities
178
+ make lint # Run linting checks
179
+ make check-deps # Verify dependencies
180
+ make help # Show all available commands
148
181
  ```
149
182
 
150
183
  ---
@@ -123,4 +123,5 @@ weeb_cli/ui/menu.py
123
123
  weeb_cli/ui/prompt.py
124
124
  weeb_cli/utils/__init__.py
125
125
  weeb_cli/utils/decorators.py
126
- weeb_cli/utils/sanitizer.py
126
+ weeb_cli/utils/sanitizer.py
127
+ weeb_cli/utils/shortcuts.py
@@ -31,3 +31,9 @@ pyyaml>=6.0
31
31
  [serve-restful]
32
32
  flask>=3.0
33
33
  flask-cors>=4.0
34
+
35
+ [shortcuts]
36
+
37
+ [shortcuts:sys_platform == "win32"]
38
+ pywin32
39
+ winshell
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes