Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ihabunek committed Oct 7, 2024
1 parent 89ea460 commit 8970d4d
Show file tree
Hide file tree
Showing 9 changed files with 477 additions and 7 deletions.
Empty file added toot/async_api/__init__.py
Empty file.
121 changes: 121 additions & 0 deletions toot/async_api/accounts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
"""
Accounts
https://docs.joinmastodon.org/methods/accounts/
"""
from typing import List, Optional
from aiohttp import ClientResponse
from toot.async_http import request
from toot.cli import AsyncContext
from toot.utils import drop_empty_values, str_bool

async def lookup(ctx: AsyncContext, acct: str) -> ClientResponse:
"""
Look up an account by name and return its info.
https://docs.joinmastodon.org/methods/accounts/#lookup
"""
return await request(ctx, "GET", "/api/v1/accounts/lookup", params={"acct": acct})


async def relationships(ctx: AsyncContext, account_ids: List[str], *, with_suspended: bool) -> ClientResponse:
"""
Check relationships to other accounts
https://docs.joinmastodon.org/methods/accounts/#relationships
"""
# TODO: verify this works with passing a list here, worked in httpx
params = {"id[]": account_ids, "with_suspended": str_bool(with_suspended)}
return await request(ctx, "GET", "/api/v1/accounts/relationships", params=params)


async def verify_credentials(ctx: AsyncContext) -> ClientResponse:
"""
Test to make sure that the user token works.
https://docs.joinmastodon.org/methods/accounts/#verify_credentials
"""
return await request(ctx, "GET", "/api/v1/accounts/verify_credentials")


async def follow(
ctx: AsyncContext,
account_id: str, *,
reblogs: Optional[bool] = None,
notify: Optional[bool] = None,
) -> ClientResponse:
"""
Follow the given account.
Can also be used to update whether to show reblogs or enable notifications.
https://docs.joinmastodon.org/methods/accounts/#follow
"""
json = drop_empty_values({"reblogs": reblogs, "notify": notify})
return await request(ctx, "POST", f"/api/v1/accounts/{account_id}/follow", json=json)


async def unfollow(ctx: AsyncContext, account_id: str) -> ClientResponse:
"""
Unfollow the given account.
https://docs.joinmastodon.org/methods/accounts/#unfollow
"""
return await request(ctx, "POST", f"/api/v1/accounts/{account_id}/unfollow")


async def remove_from_followers(ctx: AsyncContext, account_id: str) -> ClientResponse:
"""
Remove the given account from your followers.
https://docs.joinmastodon.org/methods/accounts/#remove_from_followers
"""
return await request(ctx, "POST", f"/api/v1/accounts/{account_id}/remove_from_followers")


async def block(ctx: AsyncContext, account_id: str) -> ClientResponse:
"""
Block the given account.
https://docs.joinmastodon.org/methods/accounts/#block
"""
return await request(ctx, "POST", f"/api/v1/accounts/{account_id}/block")


async def unblock(ctx: AsyncContext, account_id: str) -> ClientResponse:
"""
Unblock the given account.
https://docs.joinmastodon.org/methods/accounts/#unblock
"""
return await request(ctx, "POST", f"/api/v1/accounts/{account_id}/unblock")


async def mute(ctx: AsyncContext, account_id: str) -> ClientResponse:
"""
Mute the given account.
https://docs.joinmastodon.org/methods/accounts/#mute
"""
return await request(ctx, "POST", f"/api/v1/accounts/{account_id}/mute")


async def unmute(ctx: AsyncContext, account_id: str) -> ClientResponse:
"""
Unmute the given account.
https://docs.joinmastodon.org/methods/accounts/#unmute
"""
return await request(ctx, "POST", f"/api/v1/accounts/{account_id}/unmute")


async def pin(ctx: AsyncContext, account_id: str) -> ClientResponse:
"""
Add the given account to the user’s featured profiles.
https://docs.joinmastodon.org/methods/accounts/#pin
"""
return await request(ctx, "POST", f"/api/v1/accounts/{account_id}/pin")


async def unpin(ctx: AsyncContext, account_id: str) -> ClientResponse:
"""
Remove the given account from the user’s featured profiles.
https://docs.joinmastodon.org/methods/accounts/#unpin
"""
return await request(ctx, "POST", f"/api/v1/accounts/{account_id}/unpin")


async def note(ctx: AsyncContext, account_id: str, comment: str) -> ClientResponse:
"""
Sets a private note on a user.
https://docs.joinmastodon.org/methods/accounts/#note
"""
return await request(ctx, "POST", f"/api/v1/accounts/{account_id}/note", json={"comment": comment})
40 changes: 40 additions & 0 deletions toot/async_api/instance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
Accounts
https://docs.joinmastodon.org/methods/instance/
"""
from aiohttp import ClientResponse

from toot.async_http import request
from toot.cli import Context


async def server_information(ctx: Context) -> ClientResponse:
"""
Obtain general information about the server.
https://docs.joinmastodon.org/methods/instance/#v1
"""
return await request(ctx, "GET", "/api/v1/instance")


async def server_information_v2(ctx: Context) -> ClientResponse:
"""
Obtain general information about the server.
https://docs.joinmastodon.org/methods/instance/#v2
"""
return await request(ctx, "GET", "/api/v2/instance")


async def extended_description(ctx: Context) -> ClientResponse:
"""
Obtain an extended description of this server
https://docs.joinmastodon.org/methods/instance/#extended_description
"""
return await request(ctx, "GET", "/api/v1/instance/extended_description")


async def user_preferences(ctx: Context) -> ClientResponse:
"""
Fetch the user's server-side preferences for this instance.
https://docs.joinmastodon.org/methods/preferences/
"""
return await request(ctx, "GET", "/api/v1/preferences")
16 changes: 16 additions & 0 deletions toot/async_api/notifications.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
Notifications API
https://docs.joinmastodon.org/methods/notifications/
"""
from aiohttp import ClientResponse

from toot.async_http import request
from toot.cli import Context


async def get(ctx: Context, notification_id: str) -> ClientResponse:
"""
Fetch a single notification.
https://docs.joinmastodon.org/methods/notifications/#get-one
"""
return await request(ctx, "GET", f"/api/v1/notifications/{notification_id}")
19 changes: 19 additions & 0 deletions toot/async_api/search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""
Search endpoints
https://docs.joinmastodon.org/methods/search/
"""

from aiohttp import ClientResponse
from toot.async_http import request
from toot.cli import Context


async def search(ctx: Context, query: str) -> ClientResponse:
"""
Perform a search
https://docs.joinmastodon.org/methods/search/#v2
"""
return await request(ctx, "GET", "/api/v2/search", params={
"q": query,
# "type": "hashtags"
})
132 changes: 132 additions & 0 deletions toot/async_api/statuses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
"""
Statuses API
https://docs.joinmastodon.org/methods/statuses/
"""
from typing import Any, Dict, List, Optional
from aiohttp import ClientResponse
from uuid import uuid4

from toot.async_http import request
from toot.cli import Context


async def get(ctx: Context, status_id: str)-> ClientResponse:
"""
Fetch a single status.
https://docs.joinmastodon.org/methods/statuses/#get
"""
return await request(ctx, "GET", f"/api/v1/statuses/{status_id}")


async def context(ctx: Context, status_id: str)-> ClientResponse:
"""
View statuses above and below this status in the thread.
https://docs.joinmastodon.org/methods/statuses/#context
"""
return await request(ctx, "GET", f"/api/v1/statuses/{status_id}/context")


async def post(
ctx: Context,
status: str,
visibility: str = "public",
sensitive: bool = False,
spoiler_text: Optional[str] = None,
in_reply_to: Optional[str] = None,
local_only: Optional[bool] = None,
media_ids: Optional[List[str]] = None,
)-> ClientResponse:
# Idempotency key assures the same status is not posted multiple times
# if the request is retried.
headers = {"Idempotency-Key": uuid4().hex}

payload = drop_empty_values({
"status": status,
"visibility": visibility,
"sensitive": sensitive,
"spoiler_text": spoiler_text,
"in_reply_to_id": in_reply_to,
"local_only": local_only,
"media_ids": media_ids,
})

return await request(ctx, "POST", "/api/v1/statuses", headers=headers, json=payload)


async def edit(
ctx: Context,
status_id: str,
status: str,
visibility: str = "public",
sensitive: bool = False,
spoiler_text: Optional[str] = None,
media_ids: Optional[List[str]] = None,
)-> ClientResponse:
"""
Edit an existing status.
https://docs.joinmastodon.org/methods/statuses/#edit
"""

payload = drop_empty_values({
"status": status,
"visibility": visibility,
"sensitive": sensitive,
"spoiler_text": spoiler_text,
"media_ids": media_ids,
})

return await request(ctx, "PUT", f"/api/v1/statuses/{status_id}", json=payload)


async def delete(ctx: Context, status_id: str)-> ClientResponse:
return await request(ctx, "DELETE", f"/api/v1/statuses/{status_id}")


def drop_empty_values(data: Dict[Any, Any]) -> Dict[Any, Any]:
"""Remove keys whose values are null"""
return {k: v for k, v in data.items() if v is not None}


async def source(ctx: Context, status_id: str):
"""
Fetch the original plaintext source for a status. Only works on locally-posted statuses.
https://docs.joinmastodon.org/methods/statuses/#source
"""
path = f"/api/v1/statuses/{status_id}/source"
return await request(ctx, "GET", path)


async def favourite(ctx: Context, status_id: str):
"""
Add a status to your favourites list.
https://docs.joinmastodon.org/methods/statuses/#favourite
"""
path = f"/api/v1/statuses/{status_id}/favourite"
return await request(ctx, "POST", path)


async def unfavourite(ctx: Context, status_id: str):
"""
Remove a status from your favourites list.
https://docs.joinmastodon.org/methods/statuses/#unfavourite
"""
path = f"/api/v1/statuses/{status_id}/unfavourite"
return await request(ctx, "POST", path)


async def boost(ctx: Context, status_id: str):
"""
Reshare a status on your own profile.
https://docs.joinmastodon.org/methods/statuses/#boost
"""
path = f"/api/v1/statuses/{status_id}/reblog"
return await request(ctx, "POST", path)


async def unboost(ctx: Context, status_id: str):
"""
Undo a reshare of a status.
https://docs.joinmastodon.org/methods/statuses/#unreblog
"""
path = f"/api/v1/statuses/{status_id}/unreblog"
return await request(ctx, "POST", path)
Loading

0 comments on commit 8970d4d

Please sign in to comment.