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.
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/PKG-INFO +25 -26
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/README.md +24 -25
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/pyproject.toml +1 -1
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/data_structures.py +4 -2
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/vault.py +4 -2
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/LICENSE +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/__init__.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/__main__.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/api.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/auth.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/chunker.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/client.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/core.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/crypto.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/download.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/env.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/errors.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/filesystem.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/progress/__init__.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/progress/rich_progress.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/py.typed +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/transfer_it.py +0 -0
- {async_mega_py-2.2.1 → async_mega_py-2.2.2}/src/mega/upload.py +0 -0
- {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.
|
|
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
|
-
>
|
|
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
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
>
|
|
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
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
@@ -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[
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|