Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can i list the contents of a mega public folder by it's shared url using mega api in python

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?

like image 200
th3plus Avatar asked Oct 22 '20 18:10

th3plus


People also ask

Does MEGA NZ have an API?

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.

How do I open a shared folder in MEGA?

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.

How do I browse MEGA folders?

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.


1 Answers

Retrieving a list of nodes from a public folder's URL

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"]

Downloading files from shared folder

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(...).

like image 167
BlueGreenMagick Avatar answered Oct 19 '22 20:10

BlueGreenMagick