123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- # 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, Type, TypeVar
- import json
- from ..types import CurrentUserResponse
- from .base import BaseAndroidAPI
- T = TypeVar('T')
- class AccountAPI(BaseAndroidAPI):
- async def current_user(self) -> CurrentUserResponse:
- return await self.std_http_get(f"/api/v1/accounts/current_user/", query={"edit": "true"},
- response_type=CurrentUserResponse)
- async def set_biography(self, text: str) -> CurrentUserResponse:
- # TODO entities?
- return await self.__command("set_biography", device_id=self.state.device.id, raw_text=text)
- async def set_profile_picture(self, upload_id: str) -> CurrentUserResponse:
- return await self.__command("change_profile_picture",
- use_fbuploader="true", upload_id=upload_id)
- async def remove_profile_picture(self) -> CurrentUserResponse:
- return await self.__command("remove_profile_picture")
- async def set_private(self, private: bool) -> CurrentUserResponse:
- return await self.__command("set_private" if private else "set_public")
- async def confirm_email(self, slug: str) -> CurrentUserResponse:
- # slug can contain slashes, but it shouldn't start or end with one
- return await self.__command(f"confirm_email/{slug}")
- async def send_recovery_flow_email(self, query: str):
- req = {
- "_csrftoken": self.state.cookies.csrf_token,
- "adid": "",
- "guid": self.state.device.uuid,
- "device_id": self.state.device.id,
- "query": query,
- }
- # TODO parse response content
- return await self.std_http_post(f"/api/v1/accounts/send_recovery_flow_email/", data=req)
- async def edit_profile(self, external_url: Optional[str] = None, gender: Optional[str] = None,
- phone_number: Optional[str] = None, username: Optional[str] = None,
- # TODO should there be a last_name?
- first_name: Optional[str] = None, biography: Optional[str] = None,
- email: Optional[str] = None) -> CurrentUserResponse:
- return await self.__command("edit_profile", device_id=self.state.device.id, email=email,
- external_url=external_url, first_name=first_name,
- username=username, phone_number=phone_number, gender=gender,
- biography=biography)
- async def __command(self, command: str, response_type: Type[T] = CurrentUserResponse,
- **kwargs: str) -> T:
- req = {
- "_csrftoken": self.state.cookies.csrf_token,
- "_uid": self.state.cookies.user_id,
- "_uuid": self.state.device.uuid,
- **kwargs,
- }
- return await self.std_http_post(f"/api/v1/accounts/{command}/", data=req,
- filter_nulls=True, response_type=response_type)
- async def read_msisdn_header(self, usage: str = "default"):
- req = {
- "mobile_subno_usage": usage,
- "device_id": self.state.device.uuid,
- }
- return await self.std_http_post("/api/v1/accounts/read_msisdn_header/", data=req)
- async def msisdn_header_bootstrap(self, usage: str = "default"):
- req = {
- "mobile_subno_usage": usage,
- "device_id": self.state.device.uuid,
- }
- return await self.std_http_post("/api/v1/accounts/msisdn_header_bootstrap/", data=req)
- async def contact_point_prefill(self, usage: str = "default"):
- req = {
- "mobile_subno_usage": usage,
- "device_id": self.state.device.uuid,
- }
- return await self.std_http_post("/api/v1/accounts/contact_point_prefill/", data=req)
- async def get_prefill_candidates(self):
- req = {
- "android_device_id": self.state.device.id,
- "usages": json.dumps(["account_recovery_omnibox"]),
- "device_id": self.state.device.uuid,
- }
- # TODO parse response content
- return await self.std_http_post("/api/v1/accounts/get_prefill_candidates/", data=req)
- async def process_contact_point_signals(self):
- req = {
- "phone_id": self.state.device.phone_id,
- "_csrftoken": self.state.cookies.csrf_token,
- "_uid": self.state.cookies.user_id,
- "device_id": self.state.device.uuid,
- "_uuid": self.state.device.uuid,
- "google_tokens": json.dumps([]),
- }
- return await self.std_http_post("/api/v1/accounts/process_contact_point_signals/",
- data=req)
|