Ver Fonte

Add image uploading and rename stuff

Tulir Asokan há 4 anos atrás
pai
commit
89379085c8

+ 3 - 2
mauigpapi/http/api.py

@@ -1,6 +1,7 @@
-from .direct_inbox_feed import DirectInboxAPI
+from .direct_inbox import DirectInboxAPI
 from .login_simulate import LoginSimulateAPI
+from .upload import UploadAPI
 
 
-class AndroidAPI(DirectInboxAPI, LoginSimulateAPI):
+class AndroidAPI(DirectInboxAPI, LoginSimulateAPI, UploadAPI):
     pass

+ 4 - 3
mauigpapi/http/base.py

@@ -90,12 +90,13 @@ class BaseAndroidAPI:
         }
         return {k: v for k, v in headers.items() if v is not None}
 
-    async def std_http_post(self, path: str, data: Optional[JSON] = None,
+    async def std_http_post(self, path: str, data: Optional[JSON] = None, raw: bool = False,
                             filter_nulls: bool = False, headers: Optional[Dict[str, str]] = None,
                             response_type: Optional[Type[T]] = JSON) -> T:
         headers = {**self.headers, **headers} if headers else self.headers
-        resp = await self.http.post(url=self.url.with_path(path), headers=headers,
-                                    data=self.sign(data, filter_nulls=filter_nulls))
+        if not raw:
+            data = self.sign(data, filter_nulls=filter_nulls)
+        resp = await self.http.post(url=self.url.with_path(path), headers=headers, data=data)
         print(f"{path} response: {await resp.text()}")
         if response_type is str or response_type is None:
             self._handle_response_headers(resp)

+ 0 - 0
mauigpapi/http/direct_inbox_feed.py → mauigpapi/http/direct_inbox.py


+ 54 - 0
mauigpapi/http/upload.py

@@ -0,0 +1,54 @@
+# mautrix-instagram - A Matrix-Instagram puppeting bridge.
+# Copyright (C) 2020 Tulir Asokan
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+from typing import Optional, Dict, Any
+from uuid import uuid4
+import random
+import time
+import json
+
+from .base import BaseAndroidAPI
+from ..types import UploadPhotoResponse
+
+
+class UploadAPI(BaseAndroidAPI):
+    async def upload_jpeg_photo(self, data: bytes, upload_id: Optional[str] = None,
+                                is_sidecar: bool = False, waterfall_id: Optional[str] = None,
+                                media_type: int = 1) -> UploadPhotoResponse:
+        upload_id = upload_id or str(time.time())
+        name = f"{upload_id}_0_{random.randint(1000000000, 9999999999)}"
+        params = {
+            "retry_context": json.dumps(
+                {"num_step_auto_retry": 0, "num_reupload": 0, "num_step_manual_retry": 0}),
+            # TODO enum?
+            "media_type": str(media_type),
+            "upload_id": upload_id,
+            "xsharing_user_ids": json.dumps([]),
+            "image_compression": json.dumps(
+                {"lib_name": "moz", "lib_version": "3.1.m", "quality": 80}),
+        }
+        if is_sidecar:
+            params["is_sidecar"] = "1"
+        headers = {
+            "X_FB_PHOTO_WATERFALL_ID": waterfall_id or str(uuid4()),
+            "X-Entity-Type": "image/jpeg",
+            "Offset": "0",
+            "X-Instagram-Rupload-Params": json.dumps(params),
+            "X-Entity-Name": name,
+            "X-Entity-Length": str(len(data)),
+            "Content-Type": "application/octet-stream",
+        }
+        return await self.std_http_post(f"/rupload_igphoto/{name}", headers=headers, data=data,
+                                        raw=True, response_type=UploadPhotoResponse)

+ 1 - 0
mauigpapi/types/__init__.py

@@ -5,3 +5,4 @@ from .error import (SpamResponse, CheckpointResponse, CheckpointChallenge,
 from .login import LoginResponseUser, LoginResponseNametag, LoginResponse, LogoutResponse
 from .account import CurrentUser, EntityText, HDProfilePictureVersion, CurrentUserResponse
 from .direct_inbox import DirectInboxResponse
+from .upload import UploadPhotoResponse

+ 27 - 0
mauigpapi/types/upload.py

@@ -0,0 +1,27 @@
+# mautrix-instagram - A Matrix-Instagram puppeting bridge.
+# Copyright (C) 2020 Tulir Asokan
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+from typing import Any
+
+from attr import dataclass
+
+from mautrix.types import SerializableAttrs
+
+
+@dataclass
+class UploadPhotoResponse(SerializableAttrs['UploadPhotoResponse']):
+    upload_id: str
+    status: str
+    xsharing_nonces: Any