From d6428d8392eb3af2331580cde828b3e80788ce4e Mon Sep 17 00:00:00 2001 From: fivestones Date: Sun, 26 Jun 2022 08:18:32 -0500 Subject: [PATCH] Making drive work properly This is based on a previous PR (https://github.com/picklepete/pyicloud/pull/343/files) but done on the current drive.py main branch file. Hopefully it can be merged! Without this PR, I can't actually see any of the files or sub-directories in any directory belonging to any apps (e.g., a 'Logseq' directory used by the Logseq iPhone app). --- pyicloud/services/drive.py | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/pyicloud/services/drive.py b/pyicloud/services/drive.py index 87573ce6..3cbcd8c3 100644 --- a/pyicloud/services/drive.py +++ b/pyicloud/services/drive.py @@ -34,7 +34,7 @@ def _get_token_from_cookie(self): return {"token": match.group(1)} raise Exception("Token cookie not found") - def get_node_data(self, node_id): + def get_node_data(self, drivewsid): """Returns the node data.""" request = self.session.post( self._service_root + "/retrieveItemDetailsInFolders", @@ -42,7 +42,7 @@ def get_node_data(self, node_id): data=json.dumps( [ { - "drivewsid": "FOLDER::com.apple.CloudDocs::%s" % node_id, + "drivewsid": drivewsid, "partialData": False, } ] @@ -51,12 +51,12 @@ def get_node_data(self, node_id): self._raise_if_error(request) return request.json()[0] - def get_file(self, file_id, **kwargs): + def get_file(self, file_id, zone="com.apple.CloudDocs", **kwargs): """Returns iCloud Drive file.""" file_params = dict(self.params) file_params.update({"document_id": file_id}) response = self.session.get( - self._document_root + "/ws/com.apple.CloudDocs/download/by_id", + self._document_root + "/ws/%s/download/by_id" % zone, params=file_params, ) self._raise_if_error(response) @@ -77,7 +77,7 @@ def get_app_data(self): self._raise_if_error(request) return request.json()["items"] - def _get_upload_contentws_url(self, file_object): + def _get_upload_contentws_url(self, file_object, zone="com.apple.CloudDocs"): """Get the contentWS endpoint URL to add a new file.""" content_type = mimetypes.guess_type(file_object.name)[0] if content_type is None: @@ -93,7 +93,7 @@ def _get_upload_contentws_url(self, file_object): file_params.update(self._get_token_from_cookie()) request = self.session.post( - self._document_root + "/ws/com.apple.CloudDocs/upload/web", + self._document_root + "/ws/%s/upload/web" % zone, params=file_params, headers={"Content-Type": "text/plain"}, data=json.dumps( @@ -108,7 +108,9 @@ def _get_upload_contentws_url(self, file_object): self._raise_if_error(request) return (request.json()[0]["document_id"], request.json()[0]["url"]) - def _update_contentws(self, folder_id, sf_info, document_id, file_object): + def _update_contentws( + self, folder_id, sf_info, document_id, file_object, zone="com.apple.CloudDocs" + ): data = { "data": { "signature": sf_info["fileChecksum"], @@ -121,7 +123,7 @@ def _update_contentws(self, folder_id, sf_info, document_id, file_object): "document_id": document_id, "path": { "starting_document_id": folder_id, - "path": file_object.name, + "path": os.path.basename(file_object.name), }, "allow_conflict": True, "file_flags": { @@ -138,7 +140,7 @@ def _update_contentws(self, folder_id, sf_info, document_id, file_object): data["data"].update({"receipt": sf_info["receipt"]}) request = self.session.post( - self._document_root + "/ws/com.apple.CloudDocs/update/documents", + self._document_root + "/ws/%s/update/documents" % zone, params=self.params, headers={"Content-Type": "text/plain"}, data=json.dumps(data), @@ -146,14 +148,14 @@ def _update_contentws(self, folder_id, sf_info, document_id, file_object): self._raise_if_error(request) return request.json() - def send_file(self, folder_id, file_object): + def send_file(self, folder_id, file_object, zone="com.apple.CloudDocs"): """Send new file to iCloud Drive.""" - document_id, content_url = self._get_upload_contentws_url(file_object) + document_id, content_url = self._get_upload_contentws_url(file_object, zone) request = self.session.post(content_url, files={file_object.name: file_object}) self._raise_if_error(request) content_response = request.json()["singleFile"] - self._update_contentws(folder_id, content_response, document_id, file_object) + self._update_contentws(folder_id, content_response, document_id, file_object, zone) def create_folders(self, parent, name): """Creates a new iCloud Drive folder""" @@ -220,7 +222,7 @@ def move_items_to_trash(self, node_id, etag): def root(self): """Returns the root node.""" if not self._root: - self._root = DriveNode(self, self.get_node_data("root")) + self._root = DriveNode(self, self.get_node_data("FOLDER::com.apple.CloudDocs::root")) return self._root def __getattr__(self, attr): @@ -263,7 +265,7 @@ def get_children(self): """Gets the node children.""" if not self._children: if "items" not in self.data: - self.data.update(self.connection.get_node_data(self.data["docwsid"])) + self.data.update(self.connection.get_node_data(self.data["drivewsid"])) if "items" not in self.data: raise KeyError("No items in folder, status: %s" % self.data["status"]) self._children = [ @@ -302,11 +304,11 @@ def open(self, **kwargs): response = Response() response.raw = io.BytesIO() return response - return self.connection.get_file(self.data["docwsid"], **kwargs) + return self.connection.get_file(self.data["docwsid"], zone=self.data["zone"], **kwargs) def upload(self, file_object, **kwargs): """Upload a new file.""" - return self.connection.send_file(self.data["docwsid"], file_object, **kwargs) + return self.connection.send_file(self.data["docwsid"], file_object, zone=self.data["zone"], **kwargs) def dir(self): """Gets the node list of directories."""