camera-client 0.2.5__tar.gz → 0.2.7__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.
- {camera_client-0.2.5/camera_client.egg-info → camera_client-0.2.7}/PKG-INFO +15 -2
- {camera_client-0.2.5 → camera_client-0.2.7}/README.md +12 -0
- camera_client-0.2.7/camera_client/__main__.py +219 -0
- camera_client-0.2.7/camera_client/script.py +7 -0
- {camera_client-0.2.5 → camera_client-0.2.7/camera_client.egg-info}/PKG-INFO +15 -2
- {camera_client-0.2.5 → camera_client-0.2.7}/camera_client.egg-info/SOURCES.txt +2 -0
- {camera_client-0.2.5 → camera_client-0.2.7}/pyproject.toml +1 -1
- {camera_client-0.2.5 → camera_client-0.2.7}/LICENSE +0 -0
- {camera_client-0.2.5 → camera_client-0.2.7}/MANIFEST.in +0 -0
- {camera_client-0.2.5 → camera_client-0.2.7}/camera_client/__init__.py +0 -0
- {camera_client-0.2.5 → camera_client-0.2.7}/camera_client/client.py +0 -0
- {camera_client-0.2.5 → camera_client-0.2.7}/camera_client/loading.py +0 -0
- {camera_client-0.2.5 → camera_client-0.2.7}/camera_client.egg-info/dependency_links.txt +0 -0
- {camera_client-0.2.5 → camera_client-0.2.7}/camera_client.egg-info/entry_points.txt +0 -0
- {camera_client-0.2.5 → camera_client-0.2.7}/camera_client.egg-info/requires.txt +0 -0
- {camera_client-0.2.5 → camera_client-0.2.7}/camera_client.egg-info/top_level.txt +0 -0
- {camera_client-0.2.5 → camera_client-0.2.7}/requirements.txt +0 -0
- {camera_client-0.2.5 → camera_client-0.2.7}/setup.cfg +0 -0
- {camera_client-0.2.5 → camera_client-0.2.7}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: camera-client
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.7
|
|
4
4
|
Summary: Python SDK for camera calibration and projection transformations - handle lens distortion, coordinate transformations, and 3D ray casting with symbolic expressions.
|
|
5
5
|
Author-email: Alexander Abramov <extremal.ru@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -26,6 +26,7 @@ Description-Content-Type: text/markdown
|
|
|
26
26
|
License-File: LICENSE
|
|
27
27
|
Requires-Dist: numpy>=1.20.0
|
|
28
28
|
Requires-Dist: sympy>=1.10.0
|
|
29
|
+
Dynamic: license-file
|
|
29
30
|
|
|
30
31
|
# camera-client
|
|
31
32
|
|
|
@@ -49,6 +50,18 @@ Install from PyPI:
|
|
|
49
50
|
pip install camera-client
|
|
50
51
|
```
|
|
51
52
|
|
|
53
|
+
## CLI Usage
|
|
54
|
+
|
|
55
|
+
Download camera calibration archives from URL:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Download single archive
|
|
59
|
+
python -m camera_client get_camera_archive https://example.com/camera.npz
|
|
60
|
+
|
|
61
|
+
# Download from file with URLs (one per line, non-URL lines ignored)
|
|
62
|
+
python -m camera_client get_camera_archive -f urls.txt -o ./archives
|
|
63
|
+
```
|
|
64
|
+
|
|
52
65
|
## Quick Start
|
|
53
66
|
|
|
54
67
|
```python
|
|
@@ -20,6 +20,18 @@ Install from PyPI:
|
|
|
20
20
|
pip install camera-client
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
## CLI Usage
|
|
24
|
+
|
|
25
|
+
Download camera calibration archives from URL:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Download single archive
|
|
29
|
+
python -m camera_client get_camera_archive https://example.com/camera.npz
|
|
30
|
+
|
|
31
|
+
# Download from file with URLs (one per line, non-URL lines ignored)
|
|
32
|
+
python -m camera_client get_camera_archive -f urls.txt -o ./archives
|
|
33
|
+
```
|
|
34
|
+
|
|
23
35
|
## Quick Start
|
|
24
36
|
|
|
25
37
|
```python
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"""Command-line interface for camera-client package."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from urllib.request import urlopen, Request
|
|
9
|
+
from urllib.parse import urlparse
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def is_url(text: str) -> bool:
|
|
13
|
+
"""
|
|
14
|
+
Check if a string is a valid URL.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
text: String to check
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
True if the string looks like a URL, False otherwise
|
|
21
|
+
"""
|
|
22
|
+
text = text.strip()
|
|
23
|
+
return text.startswith('http://') or text.startswith('https://')
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def download_archive(url: str, output_dir: str = ".", silent: bool = False) -> bool:
|
|
27
|
+
"""
|
|
28
|
+
Download camera calibration archive from URL to the specified directory.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
url: URL to download the archive from
|
|
32
|
+
output_dir: Directory to save the downloaded file (default: current directory)
|
|
33
|
+
silent: If True, suppress success messages (errors still printed)
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
True if download succeeded, False otherwise
|
|
37
|
+
"""
|
|
38
|
+
try:
|
|
39
|
+
# Parse the URL to extract filename from path or Content-Disposition header
|
|
40
|
+
parsed_url = urlparse(url)
|
|
41
|
+
|
|
42
|
+
# Create request with headers
|
|
43
|
+
request = Request(url, headers={'User-Agent': 'camera-client'})
|
|
44
|
+
|
|
45
|
+
# Open URL and get response
|
|
46
|
+
if not silent:
|
|
47
|
+
print(f"Downloading from: {url}")
|
|
48
|
+
with urlopen(request) as response:
|
|
49
|
+
# Try to get filename from Content-Disposition header
|
|
50
|
+
content_disposition = response.headers.get('Content-Disposition', '')
|
|
51
|
+
filename = None
|
|
52
|
+
|
|
53
|
+
if 'filename=' in content_disposition:
|
|
54
|
+
# Extract filename from Content-Disposition header
|
|
55
|
+
parts = content_disposition.split('filename=')
|
|
56
|
+
if len(parts) > 1:
|
|
57
|
+
filename = parts[1].strip('"')
|
|
58
|
+
|
|
59
|
+
# Fallback to URL path if no Content-Disposition
|
|
60
|
+
if not filename:
|
|
61
|
+
path_parts = parsed_url.path.split('/')
|
|
62
|
+
filename = path_parts[-1] if path_parts[-1] else 'camera_archive.npz'
|
|
63
|
+
|
|
64
|
+
# Ensure .npz extension
|
|
65
|
+
if not filename.endswith('.npz'):
|
|
66
|
+
filename += '.npz'
|
|
67
|
+
|
|
68
|
+
# Create output path
|
|
69
|
+
output_path = Path(output_dir) / filename
|
|
70
|
+
|
|
71
|
+
# Download file
|
|
72
|
+
if not silent:
|
|
73
|
+
print(f"Saving to: {output_path}")
|
|
74
|
+
with open(output_path, 'wb') as f:
|
|
75
|
+
f.write(response.read())
|
|
76
|
+
|
|
77
|
+
if not silent:
|
|
78
|
+
print(f"Successfully downloaded: {filename}")
|
|
79
|
+
print(f"File size: {output_path.stat().st_size} bytes")
|
|
80
|
+
|
|
81
|
+
return True
|
|
82
|
+
|
|
83
|
+
except Exception as e:
|
|
84
|
+
print(f"Error downloading archive from {url}: {e}", file=sys.stderr)
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def download_from_file(file_path: str, output_dir: str = ".", camera_id: int = None) -> None:
|
|
89
|
+
"""
|
|
90
|
+
Download camera calibration archives from a .txt file with URLs or a .json config.
|
|
91
|
+
|
|
92
|
+
For .txt files: one URL per line, non-URL lines are ignored.
|
|
93
|
+
For .json files: expects a list of objects with "archive_url" key.
|
|
94
|
+
Optionally filter by camera_id.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
file_path: Path to .txt or .json file
|
|
98
|
+
output_dir: Directory to save the downloaded files (default: current directory)
|
|
99
|
+
camera_id: If provided, only download archives for this camera_id (JSON only)
|
|
100
|
+
"""
|
|
101
|
+
try:
|
|
102
|
+
if file_path.endswith('.json'):
|
|
103
|
+
with open(file_path, 'r') as f:
|
|
104
|
+
configs = json.load(f)
|
|
105
|
+
|
|
106
|
+
if not isinstance(configs, list):
|
|
107
|
+
configs = [configs]
|
|
108
|
+
|
|
109
|
+
if camera_id is not None:
|
|
110
|
+
configs = [c for c in configs if c.get('camera_id') == camera_id]
|
|
111
|
+
|
|
112
|
+
urls = [c['archive_url'] for c in configs if 'archive_url' in c]
|
|
113
|
+
|
|
114
|
+
if not urls:
|
|
115
|
+
msg = f"No matching entries found in {file_path}"
|
|
116
|
+
if camera_id is not None:
|
|
117
|
+
msg += f" for camera_id={camera_id}"
|
|
118
|
+
print(msg, file=sys.stderr)
|
|
119
|
+
sys.exit(1)
|
|
120
|
+
else:
|
|
121
|
+
with open(file_path, 'r') as f:
|
|
122
|
+
urls = [line.strip() for line in f if is_url(line)]
|
|
123
|
+
|
|
124
|
+
if not urls:
|
|
125
|
+
print(f"No URLs found in {file_path}", file=sys.stderr)
|
|
126
|
+
sys.exit(1)
|
|
127
|
+
|
|
128
|
+
print(f"Found {len(urls)} URL(s) in {file_path}")
|
|
129
|
+
print(f"Downloading to: {output_dir}\n")
|
|
130
|
+
|
|
131
|
+
success_count = 0
|
|
132
|
+
failed_count = 0
|
|
133
|
+
|
|
134
|
+
for i, url in enumerate(urls, 1):
|
|
135
|
+
print(f"[{i}/{len(urls)}] Processing: {url}")
|
|
136
|
+
if download_archive(url, output_dir, silent=False):
|
|
137
|
+
success_count += 1
|
|
138
|
+
else:
|
|
139
|
+
failed_count += 1
|
|
140
|
+
print() # Empty line between downloads
|
|
141
|
+
|
|
142
|
+
# Summary
|
|
143
|
+
print("=" * 50)
|
|
144
|
+
print(f"Download complete: {success_count} succeeded, {failed_count} failed")
|
|
145
|
+
|
|
146
|
+
if failed_count > 0:
|
|
147
|
+
sys.exit(1)
|
|
148
|
+
|
|
149
|
+
except FileNotFoundError:
|
|
150
|
+
print(f"Error: File not found: {file_path}", file=sys.stderr)
|
|
151
|
+
sys.exit(1)
|
|
152
|
+
except (json.JSONDecodeError, KeyError) as e:
|
|
153
|
+
print(f"Error parsing JSON file {file_path}: {e}", file=sys.stderr)
|
|
154
|
+
sys.exit(1)
|
|
155
|
+
except Exception as e:
|
|
156
|
+
print(f"Error reading file {file_path}: {e}", file=sys.stderr)
|
|
157
|
+
sys.exit(1)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def main():
|
|
161
|
+
"""Main entry point for camera-client CLI."""
|
|
162
|
+
parser = argparse.ArgumentParser(
|
|
163
|
+
prog='camera-client',
|
|
164
|
+
description='Camera calibration client utilities'
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
subparsers = parser.add_subparsers(dest='command', help='Available commands')
|
|
168
|
+
|
|
169
|
+
# get_camera_archive command
|
|
170
|
+
download_parser = subparsers.add_parser(
|
|
171
|
+
'get_camera_archive',
|
|
172
|
+
help='Get camera calibration archive(s) from URL or file'
|
|
173
|
+
)
|
|
174
|
+
download_parser.add_argument(
|
|
175
|
+
'url',
|
|
176
|
+
nargs='?',
|
|
177
|
+
help='URL to download the archive from'
|
|
178
|
+
)
|
|
179
|
+
download_parser.add_argument(
|
|
180
|
+
'-f', '--file',
|
|
181
|
+
help='File containing URLs (one per line)'
|
|
182
|
+
)
|
|
183
|
+
download_parser.add_argument(
|
|
184
|
+
'-o', '--output-dir',
|
|
185
|
+
default='.',
|
|
186
|
+
help='Output directory (default: current directory)'
|
|
187
|
+
)
|
|
188
|
+
download_parser.add_argument(
|
|
189
|
+
'--camera_id',
|
|
190
|
+
type=int,
|
|
191
|
+
default=None,
|
|
192
|
+
help='Filter by camera_id (only used with JSON config files)'
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
args = parser.parse_args()
|
|
196
|
+
|
|
197
|
+
if args.command == 'get_camera_archive':
|
|
198
|
+
# Check that either url or file is provided (but not both)
|
|
199
|
+
if args.url and args.file:
|
|
200
|
+
print("Error: Cannot specify both URL and file. Use either positional URL or -f/--file option.", file=sys.stderr)
|
|
201
|
+
sys.exit(1)
|
|
202
|
+
elif not args.url and not args.file:
|
|
203
|
+
print("Error: Must specify either URL or file with -f/--file option.", file=sys.stderr)
|
|
204
|
+
download_parser.print_help()
|
|
205
|
+
sys.exit(1)
|
|
206
|
+
|
|
207
|
+
# Process based on input type
|
|
208
|
+
if args.file:
|
|
209
|
+
download_from_file(args.file, args.output_dir, camera_id=args.camera_id)
|
|
210
|
+
else:
|
|
211
|
+
success = download_archive(args.url, args.output_dir)
|
|
212
|
+
sys.exit(0 if success else 1)
|
|
213
|
+
else:
|
|
214
|
+
parser.print_help()
|
|
215
|
+
sys.exit(1)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
if __name__ == '__main__':
|
|
219
|
+
main()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: camera-client
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.7
|
|
4
4
|
Summary: Python SDK for camera calibration and projection transformations - handle lens distortion, coordinate transformations, and 3D ray casting with symbolic expressions.
|
|
5
5
|
Author-email: Alexander Abramov <extremal.ru@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -26,6 +26,7 @@ Description-Content-Type: text/markdown
|
|
|
26
26
|
License-File: LICENSE
|
|
27
27
|
Requires-Dist: numpy>=1.20.0
|
|
28
28
|
Requires-Dist: sympy>=1.10.0
|
|
29
|
+
Dynamic: license-file
|
|
29
30
|
|
|
30
31
|
# camera-client
|
|
31
32
|
|
|
@@ -49,6 +50,18 @@ Install from PyPI:
|
|
|
49
50
|
pip install camera-client
|
|
50
51
|
```
|
|
51
52
|
|
|
53
|
+
## CLI Usage
|
|
54
|
+
|
|
55
|
+
Download camera calibration archives from URL:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Download single archive
|
|
59
|
+
python -m camera_client get_camera_archive https://example.com/camera.npz
|
|
60
|
+
|
|
61
|
+
# Download from file with URLs (one per line, non-URL lines ignored)
|
|
62
|
+
python -m camera_client get_camera_archive -f urls.txt -o ./archives
|
|
63
|
+
```
|
|
64
|
+
|
|
52
65
|
## Quick Start
|
|
53
66
|
|
|
54
67
|
```python
|
|
@@ -5,8 +5,10 @@ pyproject.toml
|
|
|
5
5
|
requirements.txt
|
|
6
6
|
setup.py
|
|
7
7
|
camera_client/__init__.py
|
|
8
|
+
camera_client/__main__.py
|
|
8
9
|
camera_client/client.py
|
|
9
10
|
camera_client/loading.py
|
|
11
|
+
camera_client/script.py
|
|
10
12
|
camera_client.egg-info/PKG-INFO
|
|
11
13
|
camera_client.egg-info/SOURCES.txt
|
|
12
14
|
camera_client.egg-info/dependency_links.txt
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "camera-client"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.7"
|
|
8
8
|
description = "Python SDK for camera calibration and projection transformations - handle lens distortion, coordinate transformations, and 3D ray casting with symbolic expressions."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.7"
|
|
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
|