async-mega-py 2.2.1__tar.gz → 2.2.2__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.
Files changed (24) hide show
  1. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/PKG-INFO +25 -26
  2. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/README.md +24 -25
  3. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/pyproject.toml +1 -1
  4. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/data_structures.py +4 -2
  5. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/vault.py +4 -2
  6. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/LICENSE +0 -0
  7. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/__init__.py +0 -0
  8. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/__main__.py +0 -0
  9. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/api.py +0 -0
  10. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/auth.py +0 -0
  11. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/chunker.py +0 -0
  12. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/client.py +0 -0
  13. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/core.py +0 -0
  14. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/crypto.py +0 -0
  15. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/download.py +0 -0
  16. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/env.py +0 -0
  17. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/errors.py +0 -0
  18. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/filesystem.py +0 -0
  19. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/progress/__init__.py +0 -0
  20. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/progress/rich_progress.py +0 -0
  21. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/py.typed +0 -0
  22. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/transfer_it.py +0 -0
  23. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/upload.py +0 -0
  24. {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: async-mega.py
3
- Version: 2.2.1
3
+ Version: 2.2.2
4
4
  Summary: Python library for the Mega.nz and Transfer.it API
5
5
  Keywords: api,downloader,mega,mega.nz,transfer.it
6
6
  Author: NTFSvolume
@@ -79,7 +79,7 @@ Please check [`src/mega/data_structures.py`](src/mega/data_structures.py) for de
79
79
  > [!TIP]
80
80
  > You can run the commands bellow in an interactive python (the asyncio REPL). Try them in real time as is, using `async/await` keywords!
81
81
  >
82
- > ```uv run -p3.12 --with async-mega-py python -m asyncio```
82
+ > `uv run -p3.12 --with async-mega-py python -m asyncio`
83
83
 
84
84
  ```python
85
85
  from mega.client import MegaNzClient
@@ -99,7 +99,7 @@ from mega.client import MegaNzClient
99
99
  # Also works without using it as a context manager, but you have the responsability to close the session at the end
100
100
  mega = MegaNzClient()
101
101
  await mega.login() # login using a temporary anonymous account
102
- # await mega.close()
102
+ # await mega.close()
103
103
 
104
104
  ```
105
105
 
@@ -163,7 +163,7 @@ await mega.download(uploaded_file, output_dir)
163
163
 
164
164
  # Download a public file
165
165
  file_url = "https://mega.nz/file/vJ9EBJBC#vA1XpbngXcnN7lqXEWGQFPDc5ZlG6yltCHwGN-0O2LQ"
166
- public_handle, public_key = mega.parse_file_url(file_url)
166
+ public_handle, public_key = mega.parse_file_url(file_url)
167
167
  await mega.download_public_file(public_handle, public_key, output_dir)
168
168
 
169
169
  # Download a public folder
@@ -186,7 +186,7 @@ print (result.is_folder)
186
186
  > You can show a progress bar on the terminal for each download/upload by calling them within the `progress_bar` context manager (needs optional dependency `rich` to be installed):
187
187
 
188
188
  ```python
189
- with mega.progress_bar:
189
+ with mega.progress_bar:
190
190
  results = await mega.download_public_folder(public_handle, public_key, output_dir / "with_bar")
191
191
  ```
192
192
 
@@ -264,16 +264,14 @@ The output will be:
264
264
 
265
265
  ```json
266
266
  {
267
- "oImwb6nN": "/tests/script.js",
268
- "FIXitv4F": "/tests/scripts",
269
- "0fPFklV3": "/tests/scripts/notes.txt",
270
- "l9zkz1GU": "/tests/scripts/script.js",
271
- "E4LqT4EF": "/tests/scripts/styles.css",
267
+ "oImwb6nN": "/tests/script.js",
268
+ "FIXitv4F": "/tests/scripts",
269
+ "0fPFklV3": "/tests/scripts/notes.txt",
270
+ "l9zkz1GU": "/tests/scripts/script.js",
271
+ "E4LqT4EF": "/tests/scripts/styles.css"
272
272
  }
273
273
  ```
274
274
 
275
-
276
-
277
275
  ```python
278
276
  # Get the path to a node
279
277
  fs.absolute_path("0fPFklV3") # /tests/scripts/notes.txt
@@ -294,24 +292,25 @@ for node in fs.iterdir(folder.id, recursive=True):
294
292
  print(fs.absolute_path(node.id))
295
293
 
296
294
  ```
295
+
297
296
  Output will be:
298
297
 
299
298
  ```json
300
299
  [
301
- "/tests/logo.png",
302
- "/tests/logo.png",
303
- "/tests/script.js",
304
- "/tests/scripts",
305
- "/tests/scripts/notes.txt",
306
- "/tests/scripts/script.js",
307
- "/tests/scripts/styles.css",
308
- "/tests/setup.sh",
309
- "/tests/utils.py",
300
+ "/tests/logo.png",
301
+ "/tests/logo.png",
302
+ "/tests/script.js",
303
+ "/tests/scripts",
304
+ "/tests/scripts/notes.txt",
305
+ "/tests/scripts/script.js",
306
+ "/tests/scripts/styles.css",
307
+ "/tests/setup.sh",
308
+ "/tests/utils.py"
310
309
  ]
311
310
  ```
312
311
 
313
312
  > [!IMPORTANT]
314
- > Mega's filesystem is *not* POSIX-compliant: multiple nodes may have the same path.
313
+ > Mega's filesystem is _not_ POSIX-compliant: multiple nodes may have the same path.
315
314
  >
316
315
  > If 2 nodes have the same path, `find` will throw an error.
317
316
 
@@ -352,10 +351,10 @@ mega-py --help
352
351
  ```
353
352
 
354
353
  ```powershell
355
- Usage: mega-py [OPTIONS] COMMAND [ARGS]...
354
+ Usage: mega-py [OPTIONS] COMMAND [ARGS]...
356
355
 
357
- CLI app for the Mega.nz and Transfer.it. Set MEGA_NZ_EMAIL and MEGA_NZ_PASSWORD
358
- enviroment variables to use them as credentials for Mega
356
+ CLI app for the Mega.nz and Transfer.it. Set MEGA_EMAIL and MEGA_PWD
357
+ enviroment variables to use them as credentials for Mega
359
358
 
360
359
  ╭─ Options ──────────────────────────────────────────────────────────────────────╮
361
360
  │ --verbose -v Increase verbosity (-v shows debug logs, -vv │
@@ -371,6 +370,6 @@ Usage: mega-py [OPTIONS] COMMAND [ARGS]...
371
370
  ```
372
371
 
373
372
  > [!TIP]
374
- > The CLI app does *not* accept login credentials, but you can still use your account by setting up the `MEGA_EMAIL` and `MEGA_PWD` enviroment variables
373
+ > The CLI app does _not_ accept login credentials, but you can still use your account by setting up the `MEGA_EMAIL` and `MEGA_PWD` enviroment variables
375
374
  >
376
375
  > It will also read them from an `.env` file (if found)
@@ -46,7 +46,7 @@ Please check [`src/mega/data_structures.py`](src/mega/data_structures.py) for de
46
46
  > [!TIP]
47
47
  > You can run the commands bellow in an interactive python (the asyncio REPL). Try them in real time as is, using `async/await` keywords!
48
48
  >
49
- > ```uv run -p3.12 --with async-mega-py python -m asyncio```
49
+ > `uv run -p3.12 --with async-mega-py python -m asyncio`
50
50
 
51
51
  ```python
52
52
  from mega.client import MegaNzClient
@@ -66,7 +66,7 @@ from mega.client import MegaNzClient
66
66
  # Also works without using it as a context manager, but you have the responsability to close the session at the end
67
67
  mega = MegaNzClient()
68
68
  await mega.login() # login using a temporary anonymous account
69
- # await mega.close()
69
+ # await mega.close()
70
70
 
71
71
  ```
72
72
 
@@ -130,7 +130,7 @@ await mega.download(uploaded_file, output_dir)
130
130
 
131
131
  # Download a public file
132
132
  file_url = "https://mega.nz/file/vJ9EBJBC#vA1XpbngXcnN7lqXEWGQFPDc5ZlG6yltCHwGN-0O2LQ"
133
- public_handle, public_key = mega.parse_file_url(file_url)
133
+ public_handle, public_key = mega.parse_file_url(file_url)
134
134
  await mega.download_public_file(public_handle, public_key, output_dir)
135
135
 
136
136
  # Download a public folder
@@ -153,7 +153,7 @@ print (result.is_folder)
153
153
  > You can show a progress bar on the terminal for each download/upload by calling them within the `progress_bar` context manager (needs optional dependency `rich` to be installed):
154
154
 
155
155
  ```python
156
- with mega.progress_bar:
156
+ with mega.progress_bar:
157
157
  results = await mega.download_public_folder(public_handle, public_key, output_dir / "with_bar")
158
158
  ```
159
159
 
@@ -231,16 +231,14 @@ The output will be:
231
231
 
232
232
  ```json
233
233
  {
234
- "oImwb6nN": "/tests/script.js",
235
- "FIXitv4F": "/tests/scripts",
236
- "0fPFklV3": "/tests/scripts/notes.txt",
237
- "l9zkz1GU": "/tests/scripts/script.js",
238
- "E4LqT4EF": "/tests/scripts/styles.css",
234
+ "oImwb6nN": "/tests/script.js",
235
+ "FIXitv4F": "/tests/scripts",
236
+ "0fPFklV3": "/tests/scripts/notes.txt",
237
+ "l9zkz1GU": "/tests/scripts/script.js",
238
+ "E4LqT4EF": "/tests/scripts/styles.css"
239
239
  }
240
240
  ```
241
241
 
242
-
243
-
244
242
  ```python
245
243
  # Get the path to a node
246
244
  fs.absolute_path("0fPFklV3") # /tests/scripts/notes.txt
@@ -261,24 +259,25 @@ for node in fs.iterdir(folder.id, recursive=True):
261
259
  print(fs.absolute_path(node.id))
262
260
 
263
261
  ```
262
+
264
263
  Output will be:
265
264
 
266
265
  ```json
267
266
  [
268
- "/tests/logo.png",
269
- "/tests/logo.png",
270
- "/tests/script.js",
271
- "/tests/scripts",
272
- "/tests/scripts/notes.txt",
273
- "/tests/scripts/script.js",
274
- "/tests/scripts/styles.css",
275
- "/tests/setup.sh",
276
- "/tests/utils.py",
267
+ "/tests/logo.png",
268
+ "/tests/logo.png",
269
+ "/tests/script.js",
270
+ "/tests/scripts",
271
+ "/tests/scripts/notes.txt",
272
+ "/tests/scripts/script.js",
273
+ "/tests/scripts/styles.css",
274
+ "/tests/setup.sh",
275
+ "/tests/utils.py"
277
276
  ]
278
277
  ```
279
278
 
280
279
  > [!IMPORTANT]
281
- > Mega's filesystem is *not* POSIX-compliant: multiple nodes may have the same path.
280
+ > Mega's filesystem is _not_ POSIX-compliant: multiple nodes may have the same path.
282
281
  >
283
282
  > If 2 nodes have the same path, `find` will throw an error.
284
283
 
@@ -319,10 +318,10 @@ mega-py --help
319
318
  ```
320
319
 
321
320
  ```powershell
322
- Usage: mega-py [OPTIONS] COMMAND [ARGS]...
321
+ Usage: mega-py [OPTIONS] COMMAND [ARGS]...
323
322
 
324
- CLI app for the Mega.nz and Transfer.it. Set MEGA_NZ_EMAIL and MEGA_NZ_PASSWORD
325
- enviroment variables to use them as credentials for Mega
323
+ CLI app for the Mega.nz and Transfer.it. Set MEGA_EMAIL and MEGA_PWD
324
+ enviroment variables to use them as credentials for Mega
326
325
 
327
326
  ╭─ Options ──────────────────────────────────────────────────────────────────────╮
328
327
  │ --verbose -v Increase verbosity (-v shows debug logs, -vv │
@@ -338,6 +337,6 @@ Usage: mega-py [OPTIONS] COMMAND [ARGS]...
338
337
  ```
339
338
 
340
339
  > [!TIP]
341
- > The CLI app does *not* accept login credentials, but you can still use your account by setting up the `MEGA_EMAIL` and `MEGA_PWD` enviroment variables
340
+ > The CLI app does _not_ accept login credentials, but you can still use your account by setting up the `MEGA_EMAIL` and `MEGA_PWD` enviroment variables
342
341
  >
343
342
  > It will also read them from an `.env` file (if found)
@@ -34,7 +34,7 @@ license = "Apache-2.0"
34
34
  license-files = ["LICENSE"]
35
35
  readme = "README.md"
36
36
  requires-python = ">=3.11"
37
- version = "2.2.1"
37
+ version = "2.2.2"
38
38
 
39
39
  [project.optional-dependencies]
40
40
  cli = [
@@ -13,7 +13,7 @@ import dataclasses
13
13
  import time
14
14
  from enum import IntEnum
15
15
  from types import MappingProxyType
16
- from typing import TYPE_CHECKING, Any, ClassVar, Final, Self, TypeAlias, TypedDict
16
+ from typing import TYPE_CHECKING, Any, ClassVar, Final, Literal, Self, TypeAlias, TypedDict
17
17
 
18
18
  if TYPE_CHECKING:
19
19
  from collections.abc import Mapping
@@ -67,7 +67,7 @@ class NodeSerialized(TypedDict):
67
67
  h: NodeID # ID
68
68
  p: NodeID # Parent ID
69
69
  u: NotRequired[UserID] # Owner (user ID), not present in transfer.it nodes
70
- t: ReadOnly[NodeType]
70
+ t: ReadOnly[Literal[0, 1, 2, 3, 4, 5]] # Node type
71
71
  a: str # Serialized attributes
72
72
  ts: TimeStamp # creation date
73
73
 
@@ -76,6 +76,7 @@ class NodeSerialized(TypedDict):
76
76
  sk: NotRequired[str] # Share key, only present present in shared (public) files / folder
77
77
 
78
78
  s: NotRequired[int] # size (files only)
79
+ fa: NotRequired[str] # additional file attributes for multimedia files (ex: thumbail)
79
80
 
80
81
 
81
82
  class OwnerKeys(TypedDict):
@@ -267,6 +268,7 @@ class Node(_DictDumper):
267
268
  keys: dict[str, str] = {}
268
269
 
269
270
  size = node.get("s")
271
+
270
272
  return Node(
271
273
  id=node["h"],
272
274
  parent_id=node["p"],
@@ -50,12 +50,14 @@ class MegaVault:
50
50
 
51
51
  # files shared with me
52
52
  elif node.owner in self._shared_keys:
53
- real_node_id, share_key = next(p for p in self._shared_keys[node.owner].items() if p[0] in node.keys)
53
+ real_node_id = next(node_id for node_id in node.keys if node_id in self._shared_keys[node.owner])
54
+ share_key = self._shared_keys[node.owner][real_node_id]
54
55
  full_key = decrypt_key(b64_to_a32(node.keys[real_node_id]), share_key)
55
56
 
56
57
  # public files/folders
57
58
  elif share_key := self._shared_keys[_EXPORTED].get(node.id):
58
- encrypted_key = b64_to_a32(next(iter(node.keys.values())))
59
+ real_node_id = next(node_id for node_id in node.keys if node_id in self._shared_keys[_EXPORTED])
60
+ encrypted_key = b64_to_a32(node.keys[real_node_id])
59
61
  full_key = decrypt_key(encrypted_key, share_key)
60
62
 
61
63
  else:
File without changes