mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-09-27 14:00:21 +00:00
5b051631ec
* update User model to allow for moved_to and also_known_as values * allow users to add aliases (also_known_as) in UI * allow users to move account to another one (moved_to) * redirect webfinger to the new account after a move * present notification to followers inviting to follow at new account Note: unlike Mastodon we're not running any unfollow/autofollow action here: users can decide for themselves This makes undoing moves easier. TODO There is still a bug with incoming Moves, at least from Mastodon. This seems to be something to do with Update activities (rather than Move, strictly).
145 lines
4.4 KiB
Python
145 lines
4.4 KiB
Python
""" responds to various requests to /.well-know """
|
|
|
|
from dateutil.relativedelta import relativedelta
|
|
from django.http import HttpResponseNotFound
|
|
from django.http import JsonResponse
|
|
from django.shortcuts import get_object_or_404
|
|
from django.template.response import TemplateResponse
|
|
from django.utils import timezone
|
|
from django.views.decorators.http import require_GET
|
|
|
|
from bookwyrm import models
|
|
from bookwyrm.settings import DOMAIN, VERSION, LANGUAGE_CODE
|
|
|
|
|
|
@require_GET
|
|
def webfinger(request):
|
|
"""allow other servers to ask about a user"""
|
|
resource = request.GET.get("resource")
|
|
if not resource or not resource.startswith("acct:"):
|
|
return HttpResponseNotFound()
|
|
|
|
username = resource.replace("acct:", "")
|
|
user = get_object_or_404(models.User, username__iexact=username)
|
|
href = user.moved_to if user.moved_to else user.remote_id
|
|
|
|
return JsonResponse(
|
|
{
|
|
"subject": f"acct:{user.username}",
|
|
"links": [
|
|
{
|
|
"rel": "self",
|
|
"type": "application/activity+json",
|
|
"href": href,
|
|
},
|
|
{
|
|
"rel": "http://ostatus.org/schema/1.0/subscribe",
|
|
"template": f"https://{DOMAIN}/ostatus_subscribe?acct={{uri}}",
|
|
},
|
|
],
|
|
}
|
|
)
|
|
|
|
|
|
@require_GET
|
|
def nodeinfo_pointer(_):
|
|
"""direct servers to nodeinfo"""
|
|
return JsonResponse(
|
|
{
|
|
"links": [
|
|
{
|
|
"rel": "http://nodeinfo.diaspora.software/ns/schema/2.0",
|
|
"href": f"https://{DOMAIN}/nodeinfo/2.0",
|
|
}
|
|
]
|
|
}
|
|
)
|
|
|
|
|
|
@require_GET
|
|
def nodeinfo(_):
|
|
"""basic info about the server"""
|
|
status_count = models.Status.objects.filter(user__local=True, deleted=False).count()
|
|
user_count = models.User.objects.filter(is_active=True, local=True).count()
|
|
|
|
month_ago = timezone.now() - relativedelta(months=1)
|
|
last_month_count = models.User.objects.filter(
|
|
is_active=True, local=True, last_active_date__gt=month_ago
|
|
).count()
|
|
|
|
six_months_ago = timezone.now() - relativedelta(months=6)
|
|
six_month_count = models.User.objects.filter(
|
|
is_active=True, local=True, last_active_date__gt=six_months_ago
|
|
).count()
|
|
|
|
site = models.SiteSettings.get()
|
|
return JsonResponse(
|
|
{
|
|
"version": "2.0",
|
|
"software": {"name": "bookwyrm", "version": VERSION},
|
|
"protocols": ["activitypub"],
|
|
"usage": {
|
|
"users": {
|
|
"total": user_count,
|
|
"activeMonth": last_month_count,
|
|
"activeHalfyear": six_month_count,
|
|
},
|
|
"localPosts": status_count,
|
|
},
|
|
"openRegistrations": site.allow_registration,
|
|
}
|
|
)
|
|
|
|
|
|
@require_GET
|
|
def instance_info(_):
|
|
"""let's talk about your cool unique instance"""
|
|
user_count = models.User.objects.filter(is_active=True, local=True).count()
|
|
status_count = models.Status.objects.filter(user__local=True, deleted=False).count()
|
|
|
|
site = models.SiteSettings.get()
|
|
logo = site.logo_url
|
|
return JsonResponse(
|
|
{
|
|
"uri": DOMAIN,
|
|
"title": site.name,
|
|
"short_description": site.instance_short_description,
|
|
"description": site.instance_description,
|
|
"version": VERSION,
|
|
"stats": {
|
|
"user_count": user_count,
|
|
"status_count": status_count,
|
|
},
|
|
"thumbnail": logo,
|
|
"languages": [LANGUAGE_CODE[:2]],
|
|
"registrations": site.allow_registration,
|
|
"approval_required": not site.allow_registration
|
|
and site.allow_invite_requests,
|
|
"email": site.admin_email,
|
|
}
|
|
)
|
|
|
|
|
|
@require_GET
|
|
def peers(_):
|
|
"""list of federated servers this instance connects with"""
|
|
names = models.FederatedServer.objects.filter(status="federated").values_list(
|
|
"server_name", flat=True
|
|
)
|
|
return JsonResponse(list(names), safe=False)
|
|
|
|
|
|
@require_GET
|
|
def host_meta(request):
|
|
"""meta of the host"""
|
|
return TemplateResponse(request, "host_meta.xml", {"DOMAIN": DOMAIN})
|
|
|
|
|
|
@require_GET
|
|
def opensearch(request):
|
|
"""Open Search xml spec"""
|
|
site = models.SiteSettings.get()
|
|
image = site.favicon_url
|
|
return TemplateResponse(
|
|
request, "opensearch.xml", {"image": image, "DOMAIN": DOMAIN}
|
|
)
|