123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- # mautrix-instagram - A Matrix-Instagram puppeting bridge.
- # Copyright (C) 2022 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 __future__ import annotations
- from typing import 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: str | None = None,
- gender: str | None = None,
- phone_number: str | None = None,
- username: str | None = None,
- # TODO should there be a last_name?
- first_name: str | None = None,
- biography: str | None = None,
- email: str | None = 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
- )
|