kleinkram 0.33.0.dev20241024121528__tar.gz → 0.33.0.dev20241027195827__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.

Potentially problematic release.


This version of kleinkram might be problematic. Click here for more details.

Files changed (24) hide show
  1. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/PKG-INFO +1 -1
  2. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/pyproject.toml +1 -1
  3. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/mission/mission.py +56 -17
  4. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/.gitignore +0 -0
  5. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/LICENSE +0 -0
  6. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/README.md +0 -0
  7. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/deploy.sh +0 -0
  8. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/dev.sh +0 -0
  9. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/requirements.txt +0 -0
  10. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/klein.py +0 -0
  11. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/__init__.py +0 -0
  12. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/api_client.py +0 -0
  13. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/auth/auth.py +0 -0
  14. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/consts.py +0 -0
  15. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/endpoint/endpoint.py +0 -0
  16. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/error_handling.py +0 -0
  17. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/file/file.py +0 -0
  18. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/helper.py +0 -0
  19. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/main.py +0 -0
  20. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/project/project.py +0 -0
  21. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/queue/queue.py +0 -0
  22. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/tag/tag.py +0 -0
  23. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/topic/topic.py +0 -0
  24. {kleinkram-0.33.0.dev20241024121528 → kleinkram-0.33.0.dev20241027195827}/src/kleinkram/user/user.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: kleinkram
3
- Version: 0.33.0.dev20241024121528
3
+ Version: 0.33.0.dev20241027195827
4
4
  Summary: A CLI for the ETH project kleinkram
5
5
  Project-URL: Homepage, https://github.com/leggedrobotics/kleinkram
6
6
  Project-URL: Issues, https://github.com/leggedrobotics/kleinkram/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "kleinkram"
7
- version = "0.33.0-dev20241024121528"
7
+ version = "0.33.0-dev20241027195827"
8
8
  description = "A CLI for the ETH project kleinkram"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.7"
@@ -1,13 +1,13 @@
1
1
  import os
2
-
3
- from botocore.utils import calculate_md5
4
- from typing_extensions import Annotated, Optional, List
2
+ import re
5
3
 
6
4
  import httpx
7
5
  import requests
8
6
  import typer
9
7
  from rich.console import Console
10
8
  from rich.table import Table
9
+ from tqdm import tqdm
10
+ from typing_extensions import Annotated, Optional, List
11
11
 
12
12
  from kleinkram.api_client import AuthenticatedClient
13
13
  from kleinkram.error_handling import AccessDeniedException
@@ -143,15 +143,20 @@ def mission_by_uuid(
143
143
 
144
144
  if json:
145
145
  print(data)
146
- else:
147
- print(f"mission: {data['name']}")
148
- print(f"Creator: {data['creator']['name']}")
149
- print("Project: " + data["project"]["name"])
150
- table = Table("Filename", "Size", "date")
151
- for file in data["files"]:
152
- table.add_row(file["filename"], f"{file['size']}", file["date"])
153
- console = Console()
154
- console.print(table)
146
+ return
147
+ print(f"mission: {data['name']}")
148
+ print(f"Creator: {data['creator']['name']}")
149
+ print("Project: " + data["project"]["name"])
150
+ table = Table("Filename", "Size", "date")
151
+
152
+ if "files" not in data:
153
+ print("No files found for mission.")
154
+ return
155
+
156
+ for file in data["files"]:
157
+ table.add_row(file["filename"], f"{file['size']}", file["date"])
158
+ console = Console()
159
+ console.print(table)
155
160
 
156
161
 
157
162
  @missionCommands.command("download")
@@ -160,6 +165,11 @@ def download(
160
165
  List[str], typer.Option(help="UUIDs of Mission to download")
161
166
  ],
162
167
  local_path: Annotated[str, typer.Option()],
168
+ pattern: Optional[str] = typer.Option(
169
+ None,
170
+ help="Simple pattern to match the filename against. Allowed are alphanumeric characters,"
171
+ " '_', '-', '.' and '*' as wildcard.",
172
+ ),
163
173
  ):
164
174
  """
165
175
 
@@ -171,7 +181,13 @@ def download(
171
181
  if not os.path.isdir(local_path):
172
182
  raise ValueError(f"Local path '{local_path}' is not a directory.")
173
183
  if not os.listdir(local_path) == []:
174
- raise ValueError(f"Local path '{local_path}' is not empty, but must be empty.")
184
+
185
+ full_local_path = os.path.abspath(local_path)
186
+
187
+ raise ValueError(
188
+ f"Local path '{full_local_path}' is not empty, it contains {len(os.listdir(local_path))} files. "
189
+ f"The local target directory must be empty."
190
+ )
175
191
 
176
192
  client = AuthenticatedClient()
177
193
  for single_mission_uuid in mission_uuid:
@@ -189,20 +205,43 @@ def download(
189
205
  if len(paths) == 0:
190
206
  continue
191
207
 
208
+ # validate search pattern
209
+ if pattern:
210
+ if not re.match(r"^[a-zA-Z0-9_\-.*]+$", pattern):
211
+ raise ValueError(
212
+ "Invalid pattern. Allowed are alphanumeric characters, '_', '-', '.' and '*' as wildcard."
213
+ )
214
+
215
+ regex = pattern.replace("*", ".*")
216
+ pattern = re.compile(regex)
217
+
218
+ print(f"Found {len(paths)} files in mission:")
219
+ paths = [
220
+ path for path in paths if not pattern or pattern.match(path["filename"])
221
+ ]
222
+
223
+ if pattern:
224
+ print(
225
+ f" » filtered to {len(paths)} files matching pattern '{pattern.pattern}'."
226
+ )
227
+
228
+ print(f"Start downloading {len(paths)} files to '{local_path}':\n")
192
229
  for path in paths:
193
230
 
194
231
  filename = path["filename"]
195
- print(f" - {filename}")
196
232
 
197
233
  response = requests.get(path["link"], stream=True) # Enable streaming mode
198
- chunk_size = 1024 * 100 # 100 KB chunks, adjust size if needed
234
+ chunk_size = 1024 * 1024 * 10 # 10 MB chunks, adjust size if needed
199
235
 
200
236
  # Open the file for writing in binary mode
201
237
  with open(os.path.join(local_path, filename), "wb") as f:
202
- for chunk in response.iter_content(chunk_size=chunk_size):
238
+ for chunk in tqdm(
239
+ response.iter_content(chunk_size=chunk_size),
240
+ unit="MB",
241
+ desc=filename,
242
+ ):
203
243
  if chunk: # Filter out keep-alive new chunks
204
244
  f.write(chunk)
205
- print(f" Downloaded {filename}")
206
245
 
207
246
 
208
247
  @missionCommands.command("upload")