weeb-cli 2.16.0__tar.gz → 2.16.1__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.
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/PKG-INFO +4 -1
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/pyproject.toml +2 -1
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/__init__.py +1 -1
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/main.py +11 -0
- weeb_cli-2.16.1/weeb_cli/utils/shortcuts.py +269 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli.egg-info/PKG-INFO +4 -1
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli.egg-info/SOURCES.txt +2 -1
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli.egg-info/requires.txt +6 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/LICENSE +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/README.md +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/setup.cfg +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/tests/test_anilist_tracker.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/tests/test_aniworld_provider.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/tests/test_api.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/tests/test_cache.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/tests/test_exceptions.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/tests/test_kitsu_tracker.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/tests/test_mal_tracker.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/tests/test_providers.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/tests/test_restful_api.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/tests/test_sanitizer.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/tests/test_sanitizer_security.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/tests/test_sdk.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/__main__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/api.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/downloads.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/library.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/search/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/search/anime_details.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/search/download_flow.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/search/episode_utils.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/search/search_handlers.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/search/stream_utils.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/search/watch_flow.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/search.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/serve.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/serve_restful.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/settings/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/settings/settings_backup.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/settings/settings_cache.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/settings/settings_config.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/settings/settings_download.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/settings/settings_drives.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/settings/settings_menu.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/settings/settings_shortcuts.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/settings/settings_trackers.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/settings.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/setup.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/commands/watchlist.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/config.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/constants.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/exceptions.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/i18n.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/locales/de.json +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/locales/en.json +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/locales/pl.json +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/locales/tr.json +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/base.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/de/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/de/aniworld.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/en/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/en/allanime.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/en/hianime.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/extractors/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/extractors/doodstream.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/extractors/filemoon.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/extractors/megacloud.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/extractors/streamtape.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/extractors/vidoza.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/extractors/voe.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/pl/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/pl/docchi.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/registry.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/tr/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/tr/animecix.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/tr/anizle.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/tr/turkanime.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/providers/tr/weeb.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/sdk.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/_base.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/_tracker_base.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/aniskip.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/cache.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/database.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/dependency_manager.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/details.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/discord_rpc.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/download/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/download/context.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/download/manager.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/download/queue.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/download/strategies/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/download/strategies/aria2.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/download/strategies/base.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/download/strategies/ffmpeg.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/download/strategies/generic.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/download/strategies/ytdlp.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/downloader.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/error_handler.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/headless_downloader.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/local_library.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/logger.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/notifier.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/player.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/progress.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/scraper.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/search.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/shortcuts.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/stream_validator.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/tracker.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/updater.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/services/watch.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/templates/anilist_error.html +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/templates/anilist_success.html +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/templates/mal_error.html +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/templates/mal_success.html +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/ui/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/ui/header.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/ui/menu.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/ui/prompt.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/utils/__init__.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/utils/decorators.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli/utils/sanitizer.py +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli.egg-info/dependency_links.txt +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/weeb_cli.egg-info/entry_points.txt +0 -0
- {weeb_cli-2.16.0 → weeb_cli-2.16.1}/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.
|
|
3
|
+
Version: 2.16.1
|
|
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"
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "weeb-cli"
|
|
7
|
-
version = "2.16.
|
|
7
|
+
version = "2.16.1"
|
|
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]
|
|
@@ -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.
|
|
3
|
+
Version: 2.16.1
|
|
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"
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|