diff --git a/.gitignore b/.gitignore index fe6f14d..b46b42a 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,6 @@ tests.py *.sublime-workspace *.sublime-project *.backup + +# pycharm +.idea \ No newline at end of file diff --git a/cloud.mail.ru_API.md b/cloud.mail.ru_API.md index 0bb2763..856ce52 100644 --- a/cloud.mail.ru_API.md +++ b/cloud.mail.ru_API.md @@ -131,8 +131,8 @@ In some methods (like file.add, folder.rename, etc), which may cause a conflict - `conflict`: see [About conflict](#about-conflict) section - `token`: `csrf` token, see method `tokens/csrf` -#### *clocloXXX-upload.cloud.mail.ru/upload/* -*where XXX in url is uploading server, can be obtain by calling `/dispatcher`* +#### *cld-uploaderXXX.cloud.mail.ru/upload-web* +*where XXX in url is uploading server, can be obtained by calling `/dispatcher`* - Method: `PUT` - Description: upload file to server - CloudAPI Response example: @@ -142,7 +142,7 @@ In some methods (like file.add, folder.rename, etc), which may cause a conflict - *where second element - size of the file* - PyAPI: `>>> cm.api.file.add(local_path: str, cloud_path: str)` - `local_path`: path to file in the local env -- CloudAPI: `PUT clocloXXX-upload.cloud.mail.ru/upload/` +- CloudAPI: `PUT cld-uploader12.cloud.mail.ru/upload-web` - multipart/form-data: - Just your file - api(...) call example: diff --git a/cloud_mail_api/__init__.py b/cloud_mail_api/__init__.py index 92da4d8..85289b8 100644 --- a/cloud_mail_api/__init__.py +++ b/cloud_mail_api/__init__.py @@ -21,6 +21,19 @@ def __init__(self, login: str, password: str): def is_cookies_valid(self) -> bool: return self.api.tokens.csrf(True)["body"] != "user" + def load_csrf(self) -> bool: + """ + Download csrf-token from mail.ru server and put it in session + """ + + resp = self.api.tokens.csrf(True) + + if isinstance(resp["body"], dict): + self.session.headers["X-CSRF-Token"] = resp["body"]["token"] + return True + + return False + def auth(self) -> bool: response = self.session.post( self.api.config["endpoints"]["MAILRU_AUTH_ENDPOINT"], @@ -41,6 +54,8 @@ def auth(self) -> bool: } ) + self.load_csrf() + return self.is_cookies_valid() diff --git a/cloud_mail_api/api/api_config.json b/cloud_mail_api/api/api_config.json index 762a352..56230bd 100644 --- a/cloud_mail_api/api/api_config.json +++ b/cloud_mail_api/api/api_config.json @@ -32,7 +32,7 @@ }, "file/_upload_file": { "method": "PUT", - "endpoint": "https://cloclo21-upload.cloud.mail.ru/upload/", + "endpoint": "https://cld-uploader12.cloud.mail.ru/upload-web/", "no_path": true, "location": { "package": "cloud_mail_api.api", diff --git a/cloud_mail_api/api/file.py b/cloud_mail_api/api/file.py index cbcf884..11bb190 100644 --- a/cloud_mail_api/api/file.py +++ b/cloud_mail_api/api/file.py @@ -1,4 +1,5 @@ import os.path +import mimetypes from typing import Tuple def file( @@ -19,18 +20,19 @@ def file_upload_file( url: str, http_method: str, local_path: str) -> Tuple[str, int]: - - files = { - "file": ( - os.path.basename(local_path), - open(local_path, "rb"), - "application/octet-stream" - ) + with open(local_path, "rb") as fd: + data = fd.read() + + mime = mimetypes.guess_type(local_path)[0] + + # Not sure whether this params are required, however they are present on cloud.mail.ru website + params = { + "x-email": api.client_instance.login, + "cloud_domain": 2 } - response = api.client_instance.session.put(url, files=files) - if response.status_code == 403: - response = api.client_instance.session.put(url, files=files) + response = api.client_instance.session.put(url, params=params, headers={"Content-Type": mime}, data=data) + return response.text, int(response.request.headers["Content-Length"]) def _add(