webtap-tool 0.1.4__py3-none-any.whl → 0.2.0__py3-none-any.whl
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.
Potentially problematic release.
This version of webtap-tool might be problematic. Click here for more details.
- webtap/commands/setup.py +135 -4
- webtap/services/setup/__init__.py +178 -0
- webtap/services/setup/chrome.py +227 -0
- webtap/services/setup/desktop.py +228 -0
- webtap/services/setup/extension.py +101 -0
- webtap/services/setup/filters.py +89 -0
- webtap/services/setup/platform.py +126 -0
- {webtap_tool-0.1.4.dist-info → webtap_tool-0.2.0.dist-info}/METADATA +4 -1
- {webtap_tool-0.1.4.dist-info → webtap_tool-0.2.0.dist-info}/RECORD +11 -6
- webtap/services/setup.py +0 -229
- {webtap_tool-0.1.4.dist-info → webtap_tool-0.2.0.dist-info}/WHEEL +0 -0
- {webtap_tool-0.1.4.dist-info → webtap_tool-0.2.0.dist-info}/entry_points.txt +0 -0
webtap/services/setup.py
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
"""Setup service for installing WebTap components."""
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
import json
|
|
5
|
-
import logging
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
from typing import Dict, Any
|
|
8
|
-
|
|
9
|
-
import requests
|
|
10
|
-
|
|
11
|
-
logger = logging.getLogger(__name__)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class SetupService:
|
|
15
|
-
"""Service for installing WebTap components."""
|
|
16
|
-
|
|
17
|
-
# GitHub URLs
|
|
18
|
-
FILTERS_URL = "https://raw.githubusercontent.com/angelsen/tap-tools/main/packages/webtap/data/filters.json"
|
|
19
|
-
EXTENSION_BASE_URL = "https://raw.githubusercontent.com/angelsen/tap-tools/main/packages/webtap/extension"
|
|
20
|
-
EXTENSION_FILES = ["manifest.json", "popup.html", "popup.js"]
|
|
21
|
-
|
|
22
|
-
def install_filters(self, force: bool = False) -> Dict[str, Any]:
|
|
23
|
-
"""Install filters to .webtap/filters.json.
|
|
24
|
-
|
|
25
|
-
Args:
|
|
26
|
-
force: Overwrite existing file
|
|
27
|
-
|
|
28
|
-
Returns:
|
|
29
|
-
Dict with success, message, path, details
|
|
30
|
-
"""
|
|
31
|
-
# Same path that FilterManager uses
|
|
32
|
-
target_path = Path.cwd() / ".webtap" / "filters.json"
|
|
33
|
-
|
|
34
|
-
# Check if exists
|
|
35
|
-
if target_path.exists() and not force:
|
|
36
|
-
return {
|
|
37
|
-
"success": False,
|
|
38
|
-
"message": f"Filters already exist at {target_path}",
|
|
39
|
-
"path": str(target_path),
|
|
40
|
-
"details": "Use --force to overwrite",
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
# Download from GitHub
|
|
44
|
-
try:
|
|
45
|
-
logger.info(f"Downloading filters from {self.FILTERS_URL}")
|
|
46
|
-
response = requests.get(self.FILTERS_URL, timeout=10)
|
|
47
|
-
response.raise_for_status()
|
|
48
|
-
|
|
49
|
-
# Validate it's proper JSON
|
|
50
|
-
filters_data = json.loads(response.text)
|
|
51
|
-
|
|
52
|
-
# Quick validation - should have dict structure
|
|
53
|
-
if not isinstance(filters_data, dict):
|
|
54
|
-
return {
|
|
55
|
-
"success": False,
|
|
56
|
-
"message": "Invalid filter format - expected JSON object",
|
|
57
|
-
"path": None,
|
|
58
|
-
"details": None,
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
# Count categories for user feedback
|
|
62
|
-
category_count = len(filters_data)
|
|
63
|
-
|
|
64
|
-
# Create directory and save
|
|
65
|
-
target_path.parent.mkdir(parents=True, exist_ok=True)
|
|
66
|
-
target_path.write_text(response.text)
|
|
67
|
-
|
|
68
|
-
logger.info(f"Saved {category_count} filter categories to {target_path}")
|
|
69
|
-
|
|
70
|
-
return {
|
|
71
|
-
"success": True,
|
|
72
|
-
"message": f"Downloaded {category_count} filter categories",
|
|
73
|
-
"path": str(target_path),
|
|
74
|
-
"details": f"Categories: {', '.join(filters_data.keys())}",
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
except requests.RequestException as e:
|
|
78
|
-
logger.error(f"Network error downloading filters: {e}")
|
|
79
|
-
return {"success": False, "message": f"Network error: {e}", "path": None, "details": None}
|
|
80
|
-
except json.JSONDecodeError as e:
|
|
81
|
-
logger.error(f"Invalid JSON in filters: {e}")
|
|
82
|
-
return {"success": False, "message": f"Invalid JSON format: {e}", "path": None, "details": None}
|
|
83
|
-
except Exception as e:
|
|
84
|
-
logger.error(f"Unexpected error: {e}")
|
|
85
|
-
return {"success": False, "message": f"Failed to download filters: {e}", "path": None, "details": None}
|
|
86
|
-
|
|
87
|
-
def install_extension(self, force: bool = False) -> Dict[str, Any]:
|
|
88
|
-
"""Install Chrome extension to ~/.config/webtap/extension/.
|
|
89
|
-
|
|
90
|
-
Args:
|
|
91
|
-
force: Overwrite existing files
|
|
92
|
-
|
|
93
|
-
Returns:
|
|
94
|
-
Dict with success, message, path, details
|
|
95
|
-
"""
|
|
96
|
-
# XDG config directory for Linux
|
|
97
|
-
target_dir = Path.home() / ".config" / "webtap" / "extension"
|
|
98
|
-
|
|
99
|
-
# Check if exists (manifest.json is required file)
|
|
100
|
-
if (target_dir / "manifest.json").exists() and not force:
|
|
101
|
-
return {
|
|
102
|
-
"success": False,
|
|
103
|
-
"message": f"Extension already exists at {target_dir}",
|
|
104
|
-
"path": str(target_dir),
|
|
105
|
-
"details": "Use --force to overwrite",
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
# Create directory
|
|
109
|
-
target_dir.mkdir(parents=True, exist_ok=True)
|
|
110
|
-
|
|
111
|
-
# Download each file
|
|
112
|
-
downloaded = []
|
|
113
|
-
failed = []
|
|
114
|
-
|
|
115
|
-
for filename in self.EXTENSION_FILES:
|
|
116
|
-
url = f"{self.EXTENSION_BASE_URL}/{filename}"
|
|
117
|
-
target_file = target_dir / filename
|
|
118
|
-
|
|
119
|
-
try:
|
|
120
|
-
logger.info(f"Downloading {filename}")
|
|
121
|
-
response = requests.get(url, timeout=10)
|
|
122
|
-
response.raise_for_status()
|
|
123
|
-
|
|
124
|
-
# For manifest.json, validate it's proper JSON
|
|
125
|
-
if filename == "manifest.json":
|
|
126
|
-
json.loads(response.text)
|
|
127
|
-
|
|
128
|
-
target_file.write_text(response.text)
|
|
129
|
-
downloaded.append(filename)
|
|
130
|
-
|
|
131
|
-
except Exception as e:
|
|
132
|
-
logger.error(f"Failed to download {filename}: {e}")
|
|
133
|
-
failed.append(filename)
|
|
134
|
-
|
|
135
|
-
# Determine success level
|
|
136
|
-
if not downloaded:
|
|
137
|
-
return {
|
|
138
|
-
"success": False,
|
|
139
|
-
"message": "Failed to download any extension files",
|
|
140
|
-
"path": None,
|
|
141
|
-
"details": "Check network connection and try again",
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if failed:
|
|
145
|
-
# Partial success - some files downloaded
|
|
146
|
-
return {
|
|
147
|
-
"success": True, # Partial is still success
|
|
148
|
-
"message": f"Downloaded {len(downloaded)}/{len(self.EXTENSION_FILES)} files",
|
|
149
|
-
"path": str(target_dir),
|
|
150
|
-
"details": f"Failed: {', '.join(failed)}",
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return {
|
|
154
|
-
"success": True,
|
|
155
|
-
"message": "Downloaded Chrome extension",
|
|
156
|
-
"path": str(target_dir),
|
|
157
|
-
"details": f"Files: {', '.join(downloaded)}",
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
def install_chrome_wrapper(self, force: bool = False) -> Dict[str, Any]:
|
|
161
|
-
"""Install Chrome wrapper script for debugging.
|
|
162
|
-
|
|
163
|
-
Args:
|
|
164
|
-
force: Overwrite existing script
|
|
165
|
-
|
|
166
|
-
Returns:
|
|
167
|
-
Dict with success, message, path, details
|
|
168
|
-
"""
|
|
169
|
-
target_path = Path.home() / ".local" / "bin" / "wrappers" / "google-chrome-stable"
|
|
170
|
-
|
|
171
|
-
if target_path.exists() and not force:
|
|
172
|
-
return {
|
|
173
|
-
"success": False,
|
|
174
|
-
"message": "Chrome wrapper already exists",
|
|
175
|
-
"path": str(target_path),
|
|
176
|
-
"details": "Use --force to overwrite",
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
wrapper_script = """#!/bin/bash
|
|
180
|
-
# Chrome wrapper using bindfs for perfect state sync with debug port
|
|
181
|
-
|
|
182
|
-
DEBUG_DIR="$HOME/.config/google-chrome-debug"
|
|
183
|
-
REAL_DIR="$HOME/.config/google-chrome"
|
|
184
|
-
|
|
185
|
-
# Check if bindfs is installed
|
|
186
|
-
if ! command -v bindfs &>/dev/null; then
|
|
187
|
-
echo "Error: bindfs not installed. Install with: yay -S bindfs" >&2
|
|
188
|
-
exit 1
|
|
189
|
-
fi
|
|
190
|
-
|
|
191
|
-
# Mount real profile via bindfs if not already mounted
|
|
192
|
-
if ! mountpoint -q "$DEBUG_DIR" 2>/dev/null; then
|
|
193
|
-
mkdir -p "$DEBUG_DIR"
|
|
194
|
-
if ! bindfs --no-allow-other "$REAL_DIR" "$DEBUG_DIR"; then
|
|
195
|
-
echo "Error: Failed to mount Chrome profile via bindfs" >&2
|
|
196
|
-
exit 1
|
|
197
|
-
fi
|
|
198
|
-
echo "Chrome debug profile mounted. To unmount: fusermount -u $DEBUG_DIR" >&2
|
|
199
|
-
fi
|
|
200
|
-
|
|
201
|
-
# Launch Chrome with debugging on bindfs mount
|
|
202
|
-
exec /usr/bin/google-chrome-stable \\
|
|
203
|
-
--remote-debugging-port=9222 \\
|
|
204
|
-
--remote-allow-origins='*' \\
|
|
205
|
-
--user-data-dir="$DEBUG_DIR" \\
|
|
206
|
-
"$@"
|
|
207
|
-
"""
|
|
208
|
-
|
|
209
|
-
# Create directory and save
|
|
210
|
-
target_path.parent.mkdir(parents=True, exist_ok=True)
|
|
211
|
-
target_path.write_text(wrapper_script)
|
|
212
|
-
target_path.chmod(0o755) # Make executable
|
|
213
|
-
|
|
214
|
-
# Check PATH
|
|
215
|
-
path_dirs = os.environ.get("PATH", "").split(":")
|
|
216
|
-
wrapper_dir = str(target_path.parent)
|
|
217
|
-
in_path = wrapper_dir in path_dirs
|
|
218
|
-
|
|
219
|
-
logger.info(f"Installed Chrome wrapper to {target_path}")
|
|
220
|
-
|
|
221
|
-
return {
|
|
222
|
-
"success": True,
|
|
223
|
-
"message": "Installed Chrome wrapper script",
|
|
224
|
-
"path": str(target_path),
|
|
225
|
-
"details": "Already in PATH ✓" if in_path else "Add to PATH",
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
__all__ = ["SetupService"]
|
|
File without changes
|
|
File without changes
|