diff --git a/.travis.yml b/.travis.yml index 0bae214..d8b8c69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ language: python python: - 2.7 - 3.7 + - 3.8 env: - TOXENV=py-normal diff --git a/README.rst b/README.rst index dd191af..e7e22f5 100644 --- a/README.rst +++ b/README.rst @@ -3,12 +3,6 @@ a mirror of the primary remote located at `https://code.richard.do/explore/projects`_. Please direct issues and pull requests there. -Deprecated -========== - -Mega.py is now deprecated, please use the official SDK -`https://github.com/meganz/sdk`_. - I aim to write a wrapper for the SDK when i have the time to do so. -------------- diff --git a/requirements.txt b/requirements.txt index c48d0a3..1bb8c2f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ requests>=0.10 pycrypto +pathlib==1.0.1 +python2-secrets==1.0.5 diff --git a/setup.cfg b/setup.cfg index b56a48d..876d1db 100644 --- a/setup.cfg +++ b/setup.cfg @@ -11,7 +11,7 @@ norecursedirs = .git [flake8] exclude = .git,__pycache__,legacy,build,dist,.tox max-complexity = 15 -ignore = E741 +ignore = E741,W504 [yapf] based_on_style = pep8 diff --git a/setup.py b/setup.py index ed3190f..aab5651 100644 --- a/setup.py +++ b/setup.py @@ -14,11 +14,11 @@ os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) with open('requirements.txt') as f: install_requires = f.read().splitlines() -# with open('README.rst', 'r', encoding='utf-8') as rm_file: -# readme = rm_file.read() +with open('README.rst', 'r', encoding='utf-8') as rm_file: + readme = rm_file.read() -# with open('HISTORY.rst', 'r', encoding='utf-8') as hist_file: -# history = hist_file.read() +with open('HISTORY.rst', 'r', encoding='utf-8') as hist_file: + history = hist_file.read() setup( name='mega.py', @@ -28,6 +28,7 @@ setup( include_package_data=True, zip_safe=False, description='Python lib for the Mega.co.nz API', + long_description=readme + '\n\n' + history, author='Richard O\'Dwyer', author_email='richard@richard.do', license='Creative Commons Attribution-Noncommercial-Share Alike license', diff --git a/src/mega/example_req_to_export_folder.json b/src/mega/example_req_to_export_folder.json deleted file mode 100644 index 59572db..0000000 --- a/src/mega/example_req_to_export_folder.json +++ /dev/null @@ -1,19 +0,0 @@ -[{ - "a": "log", - "e": 99635 -}, { - "a": "s2", - "n": "oUchHSzJ", - "s": [{ - "u": "EXP", - "r": 0 - }], - "i": "q6CpLxTDNV", - "ok": "uGuwXS80VfifU1hcLlKcrQ", - "ha": "n6dI3_qVste9XPma5fMIKQ", - "cr": [ - ["oUchHSzJ"], - ["oUchHSzJ"], - [0, 0, "ff5m7sr6LZlYyRtiEE9EZA"] - ] -}] diff --git a/src/mega/mega.py b/src/mega/mega.py index 3569dc2..2169888 100644 --- a/src/mega/mega.py +++ b/src/mega/mega.py @@ -1,6 +1,8 @@ import re +import time import json import secrets +from pathlib import Path import hashlib from Crypto.Cipher import AES from Crypto.PublicKey import RSA @@ -114,7 +116,8 @@ class Mega(object): for i in range(4): if PYTHON2: l = ( - (ord(private_key[0]) * 256 + ord(private_key[1]) + 7) / 8 + (ord(private_key[0]) * 256 + + ord(private_key[1]) + 7) / 8 ) + 2 else: l = int( @@ -155,6 +158,9 @@ class Mega(object): ) json_resp = json.loads(req.text) if isinstance(json_resp, int): + if json_resp == -3: + time.sleep(0.2) + return self._api_request(data=data) raise RequestError(json_resp) return json_resp[0] @@ -289,7 +295,6 @@ class Mega(object): """ Return file object from given filename """ - from pathlib import Path path = Path(filename) filename = path.name files = self.get_files() @@ -300,12 +305,10 @@ class Mega(object): parent_node_id = self.find_path_descriptor(parent_dir_name) if ( filename and parent_node_id and - file[1]['a'] and file[1]['a']['n'] == filename - and parent_node_id == file[1]['p'] + file[1]['a'] and file[1]['a']['n'] == filename and + parent_node_id == file[1]['p'] ): return file - # if not isinstance(file[1]['a'], dict): - # continue if ( filename and file[1]['a'] and file[1]['a']['n'] == filename @@ -577,10 +580,6 @@ class Mega(object): except (RequestError, KeyError): pass - user_id = folder[1]['u'] - user_pub_key = self._api_request({'a': 'uk', 'u': user_id})['pubk'] - node_key = folder[1]['k'] - master_key_cipher = AES.new(a32_to_str(self.master_key), AES.MODE_ECB) ha = base64_url_encode( master_key_cipher.encrypt(folder[1]['h'] + folder[1]['h']) @@ -590,6 +589,7 @@ class Mega(object): ok = base64_url_encode(master_key_cipher.encrypt(share_key)) share_key_cipher = AES.new(share_key, AES.MODE_ECB) + node_key = folder[1]['k'] encrypted_node_key = base64_url_encode( share_key_cipher.encrypt(a32_to_str(node_key)) ) @@ -597,21 +597,18 @@ class Mega(object): node_id = folder[1]['h'] request_body = [ { - 'a': 's2', - 'n': node_id, - 's': [{ - 'u': 'EXP', - 'r': 0 - }], - 'i': self.request_id, - 'ok': ok, - 'ha': ha, - 'cr': [ - [node_id], - [node_id], - [0, 0, encrypted_node_key] - ] - }] + 'a': 's2', + 'n': node_id, + 's': [{ + 'u': 'EXP', + 'r': 0 + }], + 'i': self.request_id, + 'ok': ok, + 'ha': ha, + 'cr': [[node_id], [node_id], [0, 0, encrypted_node_key]] + } + ] self._api_request(request_body) nodes = self.get_files() link = self.get_folder_link(nodes[node_id]) @@ -792,18 +789,11 @@ class Mega(object): # encrypt file and upload chunk = aes.encrypt(chunk) - try: - output_file = requests.post( - ul_url + "/" + str(chunk_start), - data=chunk, - timeout=self.timeout - ) - except: - output_file = requests.post( - ul_url + "/" + str(chunk_start), - data=chunk, - timeout=self.timeout - ) + output_file = requests.post( + ul_url + "/" + str(chunk_start), + data=chunk, + timeout=self.timeout + ) completion_file_handle = output_file.text if self.options.get('verbose') is True: @@ -876,7 +866,7 @@ class Mega(object): # update attributes data = self._api_request( { - 'a':'p', + 'a': 'p', 't': dest, 'n': [ { diff --git a/src/tests/__init__.py b/src/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/tests/test_errors.py b/src/tests/test_errors.py new file mode 100644 index 0000000..e69de29 diff --git a/src/tests/tests.py b/src/tests/tests.py index 214cdea..17ee728 100644 --- a/src/tests/tests.py +++ b/src/tests/tests.py @@ -75,10 +75,10 @@ class TestExport: # Upload a single file into a folder folder = mega.find(TEST_FOLDER) dest_node_id = folder[1]['h'] - result = mega.upload( + mega.upload( __file__, dest=dest_node_id, dest_filename='test.py' ) - path = f'{TEST_FOLDER}/test.py' + path = '{}/test.py'.format(TEST_FOLDER) assert mega.find(path) for _ in range(2): diff --git a/tox.ini b/tox.ini index 82c3671..ca225eb 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{27,37}-normal,lint +envlist = py{27,37,38}-normal,lint [testenv] commands = @@ -7,7 +7,9 @@ commands = coverage erase python setup.py install pytest {toxinidir}/src/tests/tests.py - +passenv = + EMAIL + PASS deps = -rrequirements-dev.txt