parent
c7409b3500
commit
0dca7eae5f
|
@ -6,6 +6,7 @@ from api.decorators import identity_required
|
||||||
from api.pagination import MastodonPaginator
|
from api.pagination import MastodonPaginator
|
||||||
from api.views.base import api_router
|
from api.views.base import api_router
|
||||||
from users.models import Identity
|
from users.models import Identity
|
||||||
|
from users.services import IdentityService
|
||||||
|
|
||||||
|
|
||||||
@api_router.get("/v1/accounts/verify_credentials", response=schemas.Account)
|
@api_router.get("/v1/accounts/verify_credentials", response=schemas.Account)
|
||||||
|
@ -22,25 +23,7 @@ def account_relationships(request):
|
||||||
for id in ids:
|
for id in ids:
|
||||||
identity = get_object_or_404(Identity, pk=id)
|
identity = get_object_or_404(Identity, pk=id)
|
||||||
result.append(
|
result.append(
|
||||||
{
|
IdentityService(identity).mastodon_json_relationship(request.identity)
|
||||||
"id": identity.pk,
|
|
||||||
"following": identity.inbound_follows.filter(
|
|
||||||
source=request.identity
|
|
||||||
).exists(),
|
|
||||||
"followed_by": identity.outbound_follows.filter(
|
|
||||||
target=request.identity
|
|
||||||
).exists(),
|
|
||||||
"showing_reblogs": True,
|
|
||||||
"notifying": False,
|
|
||||||
"blocking": False,
|
|
||||||
"blocked_by": False,
|
|
||||||
"muting": False,
|
|
||||||
"muting_notifications": False,
|
|
||||||
"requested": False,
|
|
||||||
"domain_blocking": False,
|
|
||||||
"endorsed": False,
|
|
||||||
"note": "",
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -95,3 +78,25 @@ def account_statuses(
|
||||||
)
|
)
|
||||||
interactions = PostInteraction.get_post_interactions(posts, request.identity)
|
interactions = PostInteraction.get_post_interactions(posts, request.identity)
|
||||||
return [post.to_mastodon_json(interactions=interactions) for post in queryset]
|
return [post.to_mastodon_json(interactions=interactions) for post in queryset]
|
||||||
|
|
||||||
|
|
||||||
|
@api_router.post("/v1/accounts/{id}/follow", response=schemas.Relationship)
|
||||||
|
@identity_required
|
||||||
|
def account_follow(request, id: str):
|
||||||
|
identity = get_object_or_404(
|
||||||
|
Identity.objects.exclude(restriction=Identity.Restriction.blocked), pk=id
|
||||||
|
)
|
||||||
|
service = IdentityService(identity)
|
||||||
|
service.follow_from(request.identity)
|
||||||
|
return service.mastodon_json_relationship(request.identity)
|
||||||
|
|
||||||
|
|
||||||
|
@api_router.post("/v1/accounts/{id}/unfollow", response=schemas.Relationship)
|
||||||
|
@identity_required
|
||||||
|
def account_unfollow(request, id: str):
|
||||||
|
identity = get_object_or_404(
|
||||||
|
Identity.objects.exclude(restriction=Identity.Restriction.blocked), pk=id
|
||||||
|
)
|
||||||
|
service = IdentityService(identity)
|
||||||
|
service.unfollow_from(request.identity)
|
||||||
|
return service.mastodon_json_relationship(request.identity)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
from .identity import IdentityService # noqa
|
|
@ -0,0 +1,70 @@
|
||||||
|
from typing import cast
|
||||||
|
|
||||||
|
from users.models import Follow, FollowStates, Identity
|
||||||
|
|
||||||
|
|
||||||
|
class IdentityService:
|
||||||
|
"""
|
||||||
|
High-level helper methods for doing things to identities
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, identity: Identity):
|
||||||
|
self.identity = identity
|
||||||
|
|
||||||
|
def follow_from(self, from_identity: Identity) -> Follow:
|
||||||
|
"""
|
||||||
|
Follows a user (or does nothing if already followed).
|
||||||
|
Returns the follow.
|
||||||
|
"""
|
||||||
|
existing_follow = Follow.maybe_get(from_identity, self.identity)
|
||||||
|
if not existing_follow:
|
||||||
|
Follow.create_local(from_identity, self.identity)
|
||||||
|
elif existing_follow.state in [
|
||||||
|
FollowStates.undone,
|
||||||
|
FollowStates.undone_remotely,
|
||||||
|
]:
|
||||||
|
existing_follow.transition_perform(FollowStates.unrequested)
|
||||||
|
return cast(Follow, existing_follow)
|
||||||
|
|
||||||
|
def unfollow_from(self, from_identity: Identity):
|
||||||
|
"""
|
||||||
|
Unfollows a user (or does nothing if not followed).
|
||||||
|
"""
|
||||||
|
existing_follow = Follow.maybe_get(from_identity, self.identity)
|
||||||
|
if existing_follow:
|
||||||
|
existing_follow.transition_perform(FollowStates.undone)
|
||||||
|
|
||||||
|
def mastodon_json_relationship(self, from_identity: Identity):
|
||||||
|
"""
|
||||||
|
Returns a Relationship object for the from_identity's relationship
|
||||||
|
with this identity.
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"id": self.identity.pk,
|
||||||
|
"following": self.identity.inbound_follows.filter(source=from_identity)
|
||||||
|
.exclude(
|
||||||
|
state__in=[
|
||||||
|
FollowStates.undone,
|
||||||
|
FollowStates.undone_remotely,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
.exists(),
|
||||||
|
"followed_by": self.identity.outbound_follows.filter(target=from_identity)
|
||||||
|
.exclude(
|
||||||
|
state__in=[
|
||||||
|
FollowStates.undone,
|
||||||
|
FollowStates.undone_remotely,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
.exists(),
|
||||||
|
"showing_reblogs": True,
|
||||||
|
"notifying": False,
|
||||||
|
"blocking": False,
|
||||||
|
"blocked_by": False,
|
||||||
|
"muting": False,
|
||||||
|
"muting_notifications": False,
|
||||||
|
"requested": False,
|
||||||
|
"domain_blocking": False,
|
||||||
|
"endorsed": False,
|
||||||
|
"note": "",
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ from core.ld import canonicalise
|
||||||
from core.models import Config
|
from core.models import Config
|
||||||
from users.decorators import identity_required
|
from users.decorators import identity_required
|
||||||
from users.models import Domain, Follow, FollowStates, Identity, IdentityStates
|
from users.models import Domain, Follow, FollowStates, Identity, IdentityStates
|
||||||
|
from users.services import IdentityService
|
||||||
from users.shortcuts import by_handle_or_404
|
from users.shortcuts import by_handle_or_404
|
||||||
|
|
||||||
|
|
||||||
|
@ -146,18 +147,9 @@ class ActionIdentity(View):
|
||||||
# See what action we should perform
|
# See what action we should perform
|
||||||
action = self.request.POST["action"]
|
action = self.request.POST["action"]
|
||||||
if action == "follow":
|
if action == "follow":
|
||||||
existing_follow = Follow.maybe_get(self.request.identity, identity)
|
IdentityService(identity).follow_from(self.request.identity)
|
||||||
if not existing_follow:
|
|
||||||
Follow.create_local(self.request.identity, identity)
|
|
||||||
elif existing_follow.state in [
|
|
||||||
FollowStates.undone,
|
|
||||||
FollowStates.undone_remotely,
|
|
||||||
]:
|
|
||||||
existing_follow.transition_perform(FollowStates.unrequested)
|
|
||||||
elif action == "unfollow":
|
elif action == "unfollow":
|
||||||
existing_follow = Follow.maybe_get(self.request.identity, identity)
|
IdentityService(identity).unfollow_from(self.request.identity)
|
||||||
if existing_follow:
|
|
||||||
existing_follow.transition_perform(FollowStates.undone)
|
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Cannot handle identity action {action}")
|
raise ValueError(f"Cannot handle identity action {action}")
|
||||||
return redirect(identity.urls.view)
|
return redirect(identity.urls.view)
|
||||||
|
|
Loading…
Reference in New Issue