i want to iterate over a public folder contents using it's shared link in python and to extract it's information using mega api the only available method is for getting the files list that only available in a specific account only
def get_files_in_node(self, target):
"""
Get all files in a given target, e.g. 4=trash
"""
if type(target) == int:
# convert special nodes (e.g. trash)
node_id = self.get_node_by_type(target)
else:
node_id = [target]
files = self._api_request({'a': 'f', 'c': 1})
files_dict = {}
shared_keys = {}
self._init_shared_keys(files, shared_keys)
for file in files['f']:
processed_file = self._process_file(file, shared_keys)
if processed_file['a'] and processed_file['p'] == node_id[0]:
files_dict[file['h']] = processed_file
return files_dict
can anyone please tell me how to do this?
To access the MEGA API, applications need to present a valid API key, which can be obtained free of charge from https://mega.nz/sdk.
To get started, right-click the folder and select “Sharing.” You will then get a pop-up window where you can see a list of users with whom you have already shared the folder, and can add new users.
Look for the MEGA icon at the bottom-right corner of your taskbar. Right-click the icon and open the “settings” page. On the settings screen, navigate to the “syncs” tab. Here you'll find all the files and folders on your computer synced to your MEGA cloud storage.
Here is the code that I used to get the list of files in Mega's public folder. It uses functions related to decryptions from mega.py library.
from mega.crypto import base64_to_a32, base64_url_decode, decrypt_attr, decrypt_key
def get_nodes_in_shared_folder(root_folder: str) -> dict:
data = [{"a": "f", "c": 1, "ca": 1, "r": 1}]
response = requests.post(
"https://g.api.mega.co.nz/cs",
params={'id': 0, # self.sequence_num
'n': root_folder},
data=json.dumps(data)
)
json_resp = response.json()
return json_resp[0]["f"]
def parse_folder_url(url: str) -> Tuple[str, str]:
"Returns (public_handle, key) if valid. If not returns None."
REGEXP1 = re.compile(r"mega.[^/]+/folder/([0-z-_]+)#([0-z-_]+)(?:/folder/([0-z-_]+))*")
REGEXP2 = re.compile(r"mega.[^/]+/#F!([0-z-_]+)[!#]([0-z-_]+)(?:/folder/([0-z-_]+))*")
m = re.search(REGEXP1, url)
if not m:
m = re.search(REGEXP2, url)
if not m:
print("Not a valid URL")
return None
root_folder = m.group(1)
key = m.group(2)
# You may want to use m.groups()[-1]
# to get the id of the subfolder
return (root_folder, key)
def decrypt_node_key(key_str: str, shared_key: str) -> Tuple[int, ...]:
encrypted_key = base64_to_a32(key_str.split(":")[1])
return decrypt_key(encrypted_key, shared_key)
Example code to get a list of files and their metadata in the public shared folder.
(root_folder, shared_enc_key) = parse_folder_url("<insert url here>")
shared_key = base64_to_a32(shared_enc_key)
nodes = get_nodes_in_shared_folder(root_folder)
for node in nodes:
key = decrypt_node_key(node["k"], shared_key)
if node["t"] == 0: # Is a file
k = (key[0] ^ key[4], key[1] ^ key[5], key[2] ^ key[6], key[3] ^ key[7])
elif node["t"] == 1: # Is a folder
k = key
attrs = decrypt_attr(base64_url_decode(node["a"]), k)
file_name = attrs["n"]
file_id = node["h"]
This wasn't part of your question, but I'll just add a brief summary and maybe others will find it helpful.
To download, you will need to make a POST request with the same params as above but the data changed to this:
data = [{ 'a': 'g', 'g': 1, 'n': node['h'] }]
and then basically copy the mega.py library's _download_file
function, replacing file_key
with the key you got from decrypt_node_key(...)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With