kleinkram 0.33.0.dev20241024121528__py3-none-any.whl → 0.33.0.dev20241024133645__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 kleinkram might be problematic. Click here for more details.

@@ -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
@@ -160,6 +160,11 @@ def download(
160
160
  List[str], typer.Option(help="UUIDs of Mission to download")
161
161
  ],
162
162
  local_path: Annotated[str, typer.Option()],
163
+ pattern: Optional[str] = typer.Option(
164
+ None,
165
+ help="Simple pattern to match the filename against. Allowed are alphanumeric characters,"
166
+ " '_', '-', '.' and '*' as wildcard.",
167
+ ),
163
168
  ):
164
169
  """
165
170
 
@@ -171,7 +176,13 @@ def download(
171
176
  if not os.path.isdir(local_path):
172
177
  raise ValueError(f"Local path '{local_path}' is not a directory.")
173
178
  if not os.listdir(local_path) == []:
174
- raise ValueError(f"Local path '{local_path}' is not empty, but must be empty.")
179
+
180
+ full_local_path = os.path.abspath(local_path)
181
+
182
+ raise ValueError(
183
+ f"Local path '{full_local_path}' is not empty, it contains {len(os.listdir(local_path))} files. "
184
+ f"The local target directory must be empty."
185
+ )
175
186
 
176
187
  client = AuthenticatedClient()
177
188
  for single_mission_uuid in mission_uuid:
@@ -189,20 +200,43 @@ def download(
189
200
  if len(paths) == 0:
190
201
  continue
191
202
 
203
+ # validate search pattern
204
+ if pattern:
205
+ if not re.match(r"^[a-zA-Z0-9_\-.*]+$", pattern):
206
+ raise ValueError(
207
+ "Invalid pattern. Allowed are alphanumeric characters, '_', '-', '.' and '*' as wildcard."
208
+ )
209
+
210
+ regex = pattern.replace("*", ".*")
211
+ pattern = re.compile(regex)
212
+
213
+ print(f"Found {len(paths)} files in mission:")
214
+ paths = [
215
+ path for path in paths if not pattern or pattern.match(path["filename"])
216
+ ]
217
+
218
+ if pattern:
219
+ print(
220
+ f" » filtered to {len(paths)} files matching pattern '{pattern.pattern}'."
221
+ )
222
+
223
+ print(f"Start downloading {len(paths)} files to '{local_path}':\n")
192
224
  for path in paths:
193
225
 
194
226
  filename = path["filename"]
195
- print(f" - {filename}")
196
227
 
197
228
  response = requests.get(path["link"], stream=True) # Enable streaming mode
198
- chunk_size = 1024 * 100 # 100 KB chunks, adjust size if needed
229
+ chunk_size = 1024 * 1024 * 10 # 10 MB chunks, adjust size if needed
199
230
 
200
231
  # Open the file for writing in binary mode
201
232
  with open(os.path.join(local_path, filename), "wb") as f:
202
- for chunk in response.iter_content(chunk_size=chunk_size):
233
+ for chunk in tqdm(
234
+ response.iter_content(chunk_size=chunk_size),
235
+ unit="MB",
236
+ desc=filename,
237
+ ):
203
238
  if chunk: # Filter out keep-alive new chunks
204
239
  f.write(chunk)
205
- print(f" Downloaded {filename}")
206
240
 
207
241
 
208
242
  @missionCommands.command("upload")
@@ -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.dev20241024133645
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
@@ -7,14 +7,14 @@ kleinkram/main.py,sha256=cgDTfFQW91wlHZYg4_MmlERcFXDd1z--lUP6bGu8YnM,12536
7
7
  kleinkram/auth/auth.py,sha256=w3-TsxWxURzLQ3_p43zgV4Rlh4dVL_WqI6HG2aes-b4,4991
8
8
  kleinkram/endpoint/endpoint.py,sha256=uez5UrAnP7L5rVHUysA9tFkN3dB3dG1Ojt9g3w-UWuQ,1441
9
9
  kleinkram/file/file.py,sha256=gLCZDHHgQWq25OmeG-lwkIh4aRZaLK12xxLkbhZ_m-g,5390
10
- kleinkram/mission/mission.py,sha256=KI_r-DbaXr8uKi9rnSopj-G1N4Nq_ELEBn4mPJXMQzQ,8861
10
+ kleinkram/mission/mission.py,sha256=n7W7RKMuJSXXhgFKIGaxX1GyXexnrHUIcTFem6UsEBs,10019
11
11
  kleinkram/project/project.py,sha256=le85GN9RgrqJeAL5mS-PhowFDjv-HBCYhgkKeFAUcGs,3780
12
12
  kleinkram/queue/queue.py,sha256=MaLBjAu8asi9BkPvbbT-5AobCcpy3ex5rxM1kHpRINA,181
13
13
  kleinkram/tag/tag.py,sha256=JSHbDPVfsvP34MuQhw__DPQk-Bah5G9BgwYsj_K_JGc,1805
14
14
  kleinkram/topic/topic.py,sha256=IaXhrIHcJ3FSIr0WC-N7u9fkz-lAvSBgQklTX67t0Yc,1641
15
15
  kleinkram/user/user.py,sha256=hDrbWeFPPnh2sswDd445SwcIFGyAbfXXWpYq1VqrK0g,1379
16
- kleinkram-0.33.0.dev20241024121528.dist-info/METADATA,sha256=_68yPVnug6xFs04N2uqmSzeGCBnTB13ziNb_4ma-sMA,845
17
- kleinkram-0.33.0.dev20241024121528.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
18
- kleinkram-0.33.0.dev20241024121528.dist-info/entry_points.txt,sha256=RHXtRzcreVHImatgjhQwZQ6GdJThElYjHEWcR1BPXUI,45
19
- kleinkram-0.33.0.dev20241024121528.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
20
- kleinkram-0.33.0.dev20241024121528.dist-info/RECORD,,
16
+ kleinkram-0.33.0.dev20241024133645.dist-info/METADATA,sha256=Wc73pOlVWTIdUE9mmPX5wF6TTUUkEM92R4-3WUBkKsk,845
17
+ kleinkram-0.33.0.dev20241024133645.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
18
+ kleinkram-0.33.0.dev20241024133645.dist-info/entry_points.txt,sha256=RHXtRzcreVHImatgjhQwZQ6GdJThElYjHEWcR1BPXUI,45
19
+ kleinkram-0.33.0.dev20241024133645.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
20
+ kleinkram-0.33.0.dev20241024133645.dist-info/RECORD,,