diff --git a/kepi/trilby_api/urls.py b/kepi/trilby_api/urls.py index 6d739fb..90bb260 100644 --- a/kepi/trilby_api/urls.py +++ b/kepi/trilby_api/urls.py @@ -5,48 +5,48 @@ # Licensed under the GNU Public License v2. from django.urls import path -from .views import * +import kepi.trilby_api.views as views urlpatterns = [ - path('api/v1/instance', Instance.as_view()), - path('api/v1/instance/', Instance.as_view()), # keep tootstream happy - path('api/v1/apps', Apps.as_view()), + path('api/v1/instance', views.Instance.as_view()), + path('api/v1/instance/', views.Instance.as_view()), # keep tootstream happy + path('api/v1/apps', views.Apps.as_view()), - path('api/v1/accounts/verify_credentials', VerifyCredentials.as_view()), + path('api/v1/accounts/verify_credentials', views.VerifyCredentials.as_view()), path('api/v1/accounts/update_credentials', - UpdateCredentials.as_view()), + views.UpdateCredentials.as_view()), - path('api/v1/accounts/search', AccountsSearch.as_view()), + path('api/v1/accounts/search', views.AccountsSearch.as_view()), - path('api/v1/accounts/', User.as_view()), - path('api/v1/accounts//statuses', Statuses.as_view()), - path('api/v1/accounts//following', Following.as_view()), - path('api/v1/accounts//followers', Followers.as_view()), - path('api/v1/accounts//follow', Follow.as_view()), - path('api/v1/accounts//unfollow', Unfollow.as_view()), + path('api/v1/accounts/', views.User.as_view()), + path('api/v1/accounts//statuses', views.Statuses.as_view()), + path('api/v1/accounts//following', views.Following.as_view()), + path('api/v1/accounts//followers', views.Followers.as_view()), + path('api/v1/accounts//follow', views.FollowUser.as_view()), + path('api/v1/accounts//unfollow', views.UnfollowUser.as_view()), - path('api/v1/statuses', Statuses.as_view()), - path('api/v1/statuses/', SpecificStatus.as_view()), - path('api/v1/statuses//context', StatusContext.as_view()), + path('api/v1/statuses', views.Statuses.as_view()), + path('api/v1/statuses/', views.SpecificStatus.as_view()), + path('api/v1/statuses//context', views.StatusContext.as_view()), # Favourite, aka like - path('api/v1/statuses//favourite', Favourite.as_view()), - path('api/v1/statuses//unfavourite', Unfavourite.as_view()), - path('api/v1/statuses//favourited_by', StatusFavouritedBy.as_view()), + path('api/v1/statuses//favourite', views.Favourite.as_view()), + path('api/v1/statuses//unfavourite', views.Unfavourite.as_view()), + path('api/v1/statuses//favourited_by', views.StatusFavouritedBy.as_view()), # Reblog, aka boost - path('api/v1/statuses//reblog', Reblog.as_view()), - path('api/v1/statuses//unreblog', Unreblog.as_view()), - path('api/v1/statuses//reblogged_by', StatusRebloggedBy.as_view()), + path('api/v1/statuses//reblog', views.Reblog.as_view()), + path('api/v1/statuses//unreblog', views.Unreblog.as_view()), + path('api/v1/statuses//reblogged_by', views.StatusRebloggedBy.as_view()), - path('api/v1/notifications', Notifications.as_view()), - path('api/v1/filters', Filters.as_view()), - path('api/v1/custom_emojis', Emojis.as_view()), - path('api/v1/timelines/public', PublicTimeline.as_view()), - path('api/v1/timelines/home', HomeTimeline.as_view()), + path('api/v1/notifications', views.Notifications.as_view()), + path('api/v1/filters', views.Filters.as_view()), + path('api/v1/custom_emojis', views.Emojis.as_view()), + path('api/v1/timelines/public', views.PublicTimeline.as_view()), + path('api/v1/timelines/home', views.HomeTimeline.as_view()), - path('api/v1/search', Search.as_view()), + path('api/v1/search', views.Search.as_view()), - path('users//feed', UserFeed.as_view()), + path('users//feed', views.UserFeed.as_view()), ] diff --git a/kepi/trilby_api/views/__init__.py b/kepi/trilby_api/views/__init__.py index cd8ef92..9122bc9 100644 --- a/kepi/trilby_api/views/__init__.py +++ b/kepi/trilby_api/views/__init__.py @@ -1,73 +1,38 @@ -# trilby_api/views/__init__.py -# -# Part of kepi. -# Copyright (c) 2018-2021 Marnanel Thurman. -# Licensed under the GNU Public License v2. - -from .other import \ - Instance, \ - Emojis, \ - Filters, \ - Search, \ - AccountsSearch - -from .statuses import \ - Favourite, Unfavourite, \ - Reblog, Unreblog, \ - SpecificStatus, \ - Statuses, \ - StatusContext, \ - StatusFavouritedBy, \ - StatusRebloggedBy, \ - Notifications - -from .persons import \ - Follow, Unfollow, \ - UpdateCredentials, \ - VerifyCredentials,\ - User, \ - Followers, Following - -from .oauth import \ - Apps, \ - fix_oauth2_redirects - -from .timelines import \ - PublicTimeline, \ - HomeTimeline, \ - UserFeed +from .oauth import * +from .other import * +from .persons import * +from .statuses import * +from .timelines import * __all__ = [ - # other - 'Instance', - 'Emojis', - 'Filters', - 'Search', + 'AbstractTimeline', 'AccountsSearch', - - # statuses - 'Favourite', 'Unfavourite', - 'Reblog', 'Unreblog', + 'Apps', + 'DoSomethingWithPerson', + 'DoSomethingWithStatus', + 'Emojis', + 'Favourite', + 'Filters', + 'FollowUser', + 'Followers', + 'Followers_or_Following', + 'Following', + 'HomeTimeline', + 'Instance', + 'Notifications', + 'PublicTimeline', + 'Reblog', + 'Search', 'SpecificStatus', - 'Statuses', 'StatusContext', + 'Statuses', 'StatusFavouritedBy', 'StatusRebloggedBy', - 'Notifications', - - # persons - 'Follow', 'Unfollow', + 'Unfavourite', + 'UnfollowUser', + 'Unreblog', 'UpdateCredentials', - 'VerifyCredentials', 'User', - 'Followers', 'Following', - - # oauth - 'Apps', - 'fix_oauth2_redirects', - - # timelines - 'PublicTimeline', - 'HomeTimeline', 'UserFeed', + 'VerifyCredentials', ] diff --git a/kepi/trilby_api/views/persons.py b/kepi/trilby_api/views/persons.py index 0a25511..277b667 100644 --- a/kepi/trilby_api/views/persons.py +++ b/kepi/trilby_api/views/persons.py @@ -71,7 +71,7 @@ class DoSomethingWithPerson(generics.GenericAPIView): reason = 'Done', ) -class Follow(DoSomethingWithPerson): +class FollowUser(DoSomethingWithPerson): def _do_something_with(self, the_person, request): @@ -119,7 +119,7 @@ class Follow(DoSomethingWithPerson): except IntegrityError: logger.info(' -- not creating a follow; it already exists') -class Unfollow(DoSomethingWithPerson): +class UnfollowUser(DoSomethingWithPerson): def _do_something_with(self, the_person, request): @@ -142,76 +142,6 @@ class Unfollow(DoSomethingWithPerson): logger.info(' -- not unfollowing; they weren\'t following '+\ 'in the first place') -class UpdateCredentials(generics.GenericAPIView): - - def patch(self, request, *args, **kwargs): - - if request.user is None: - logger.debug(' -- user not logged in') - return error_response(401, 'Not logged in') - - who = request.user.localperson - - # The Mastodon spec doesn't say what to do - # if the user submits field names which don't - # exist! - - unknown_fields = [] - - # FIXME: the data in "v" needs cleaning. - - logger.info('-- updating user: %s', who) - - for f,v in request.data.items(): - - logger.info(' -- setting %s = %s', f, v) - - if f=='discoverable': - raise Http404("discoverable is not yet supported") - elif f=='bot': - who.bot = v - elif f=='display_name': - who.display_name = v - elif f=='note': - who.note = v - elif f=='avatar': - raise Http404("images are not yet supported") - elif f=='header': - raise Http404("images are not yet supported") - elif f=='locked': - who.locked = v - elif f=='source[privacy]': - who.default_visibility = v - elif f=='source[sensitive]': - who.default_sensitive = v - elif f=='source[language]': - who.language = v - elif f=='fields_attributes': - raise Http404("fields are not yet supported") - else: - logger.info(' -- field does not exist') - unknown_fields.append(f) - - if unknown_fields: - logger.info(' -- aborting because of unknown fields') - raise Http404(f"some fields do not exist: {unknown_fields}") - - who.save() - logger.info(' -- done.') - - serializer = UserSerializerWithSource( - who, - context = { - 'request': request, - }, - ) - - return JsonResponse( - serializer.data, - status = 200, - reason = 'Done', - ) - ########################### class VerifyCredentials(generics.GenericAPIView): diff --git a/kepi/trilby_api/views/statuses.py b/kepi/trilby_api/views/statuses.py index 4b1e7ef..1b3f8db 100644 --- a/kepi/trilby_api/views/statuses.py +++ b/kepi/trilby_api/views/statuses.py @@ -183,117 +183,6 @@ class Unreblog(DoSomethingWithStatus): ########################### -class DoSomethingWithPerson(generics.GenericAPIView): - - serializer_class = UserSerializer - queryset = trilby_models.Person.objects.all() - - def _do_something_with(self, the_person, request): - raise NotImplementedError() - - def post(self, request, *args, **kwargs): - - if request.user is None: - logger.debug(' -- user not logged in') - return error_response(401, 'Not logged in') - - try: - the_person = get_object_or_404( - self.get_queryset(), - id = int(kwargs['user']), - ) - except ValueError: - return error_response(404, 'Non-decimal ID') - - result = self._do_something_with(the_person, request) - - if result is None: - result = the_person - - serializer = UserSerializer( - result, - context = { - 'request': request, - }, - ) - - return JsonResponse( - serializer.data, - status = 200, - reason = 'Done', - ) - -class Follow(DoSomethingWithPerson): - - def _do_something_with(self, the_person, request): - - try: - - if the_person.auto_follow: - offer = None - else: - number = random.randint(0, 0xffffffff) - offer = uri_to_url(settings.KEPI['FOLLOW_REQUEST_LINK'] % { - 'username': request.user.username, - 'number': number, - }) - - follow = trilby_models.Follow( - follower = request.user.localperson, - following = the_person, - offer = offer, - ) - - with transaction.atomic(): - follow.save( - send_signal = True, - ) - - logger.info(' -- follow: %s', follow) - logger.debug(' -- offer ID: %s', offer) - - if the_person.auto_follow: - follow_back = trilby_models.Follow( - follower = the_person, - following = request.user.localperson, - offer = None, - ) - - with transaction.atomic(): - follow_back.save( - send_signal = True, - ) - - logger.info(' -- follow back: %s', follow_back) - - return the_person - - except IntegrityError: - logger.info(' -- not creating a follow; it already exists') - -class Unfollow(DoSomethingWithPerson): - - def _do_something_with(self, the_person, request): - - try: - follow = trilby_models.Follow.objects.get( - follower = request.user.localperson, - following = the_person, - ) - - logger.info(' -- unfollowing: %s', follow) - - with transaction.atomic(): - follow.delete( - send_signal = True, - ) - - return the_person - - except trilby_models.Follow.DoesNotExist: - logger.info(' -- not unfollowing; they weren\'t following '+\ - 'in the first place') - class SpecificStatus(generics.GenericAPIView): queryset = trilby_models.Status.objects.filter(remote_url=None)