Implement user discoverability

This commit is contained in:
Andrew Godwin 2022-11-25 18:32:45 -07:00
parent 5fe5f04955
commit 1cf1f2e543
8 changed files with 62 additions and 13 deletions

View file

@ -83,7 +83,7 @@ class Migration(migrations.Migration):
( (
"author", "author",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT, on_delete=django.db.models.deletion.CASCADE,
related_name="posts", related_name="posts",
to="users.identity", to="users.identity",
), ),
@ -257,6 +257,8 @@ class Migration(migrations.Migration):
models.CharField( models.CharField(
choices=[ choices=[
("post", "Post"), ("post", "Post"),
("post_edited", "Post Edited"),
("post_deleted", "Post Deleted"),
("interaction", "Interaction"), ("interaction", "Interaction"),
("undo_interaction", "Undo Interaction"), ("undo_interaction", "Undo Interaction"),
], ],

View file

@ -19,7 +19,10 @@ class LoggedOutHomepage(TemplateView):
def get_context_data(self): def get_context_data(self):
return { return {
"identities": Identity.objects.filter(local=True).order_by("-created")[:20], "identities": Identity.objects.filter(
local=True,
discoverable=True,
).order_by("-created")[:20],
} }

View file

@ -13,6 +13,7 @@
{% include "forms/_field.html" with field=form.username %} {% include "forms/_field.html" with field=form.username %}
{% include "forms/_field.html" with field=form.domain %} {% include "forms/_field.html" with field=form.domain %}
{% include "forms/_field.html" with field=form.name %} {% include "forms/_field.html" with field=form.name %}
{% include "forms/_field.html" with field=form.discoverable %}
</fieldset> </fieldset>
<div class="buttons"> <div class="buttons">
<button>Create</button> <button>Create</button>

View file

@ -9,6 +9,7 @@
<legend>Details</legend> <legend>Details</legend>
{% include "forms/_field.html" with field=form.name %} {% include "forms/_field.html" with field=form.name %}
{% include "forms/_field.html" with field=form.summary %} {% include "forms/_field.html" with field=form.summary %}
{% include "forms/_field.html" with field=form.discoverable %}
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>Images</legend> <legend>Images</legend>

View file

@ -0,0 +1,18 @@
# Generated by Django 4.1.3 on 2022-11-26 01:29
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("users", "0001_initial"),
]
operations = [
migrations.AddField(
model_name="identity",
name="discoverable",
field=models.BooleanField(default=True),
),
]

View file

@ -67,6 +67,7 @@ class Identity(StatorModel):
name = models.CharField(max_length=500, blank=True, null=True) name = models.CharField(max_length=500, blank=True, null=True)
summary = models.TextField(blank=True, null=True) summary = models.TextField(blank=True, null=True)
manually_approves_followers = models.BooleanField(blank=True, null=True) manually_approves_followers = models.BooleanField(blank=True, null=True)
discoverable = models.BooleanField(default=True)
profile_uri = models.CharField(max_length=500, blank=True, null=True) profile_uri = models.CharField(max_length=500, blank=True, null=True)
inbox_uri = models.CharField(max_length=500, blank=True, null=True) inbox_uri = models.CharField(max_length=500, blank=True, null=True)
@ -240,7 +241,7 @@ class Identity(StatorModel):
}, },
"published": self.created.strftime("%Y-%m-%dT%H:%M:%SZ"), "published": self.created.strftime("%Y-%m-%dT%H:%M:%SZ"),
"url": self.absolute_profile_uri(), "url": self.absolute_profile_uri(),
"discoverable": True, "http://joinmastodon.org/ns#discoverable": self.discoverable,
} }
if self.name: if self.name:
response["name"] = self.name response["name"] = self.name
@ -373,6 +374,9 @@ class Identity(StatorModel):
self.public_key_id = document.get("publicKey", {}).get("id") self.public_key_id = document.get("publicKey", {}).get("id")
self.icon_uri = document.get("icon", {}).get("url") self.icon_uri = document.get("icon", {}).get("url")
self.image_uri = document.get("image", {}).get("url") self.image_uri = document.get("image", {}).get("url")
self.discoverable = document.get(
"http://joinmastodon.org/ns#discoverable", True
)
# Now go do webfinger with that info to see if we can get a canonical domain # Now go do webfinger with that info to see if we can get a canonical domain
actor_url_parts = urlparse(self.actor_uri) actor_url_parts = urlparse(self.actor_uri)
get_domain = sync_to_async(Domain.get_remote_domain) get_domain = sync_to_async(Domain.get_remote_domain)

View file

@ -150,6 +150,14 @@ class CreateIdentity(FormView):
name = forms.CharField( name = forms.CharField(
help_text="The display name other users see. You can change this easily." help_text="The display name other users see. You can change this easily."
) )
discoverable = forms.BooleanField(
help_text="If this user is visible on the frontpage and in user directories.",
initial=True,
widget=forms.Select(
choices=[(True, "Discoverable"), (False, "Not Discoverable")]
),
required=False,
)
def __init__(self, user, *args, **kwargs): def __init__(self, user, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -219,6 +227,7 @@ class CreateIdentity(FormView):
domain_id=domain, domain_id=domain,
name=form.cleaned_data["name"], name=form.cleaned_data["name"],
local=True, local=True,
discoverable=form.cleaned_data["discoverable"],
) )
new_identity.users.add(self.request.user) new_identity.users.add(self.request.user)
new_identity.generate_keypair() new_identity.generate_keypair()

View file

@ -33,13 +33,22 @@ class ProfilePage(FormView):
image = forms.ImageField( image = forms.ImageField(
required=False, help_text="Shown at the top of your profile" required=False, help_text="Shown at the top of your profile"
) )
discoverable = forms.BooleanField(
help_text="If this user is visible on the frontpage and in user directories.",
widget=forms.Select(
choices=[(True, "Discoverable"), (False, "Not Discoverable")]
),
required=False,
)
def get_initial(self): def get_initial(self):
identity = self.request.identity
return { return {
"name": self.request.identity.name, "name": identity.name,
"summary": self.request.identity.summary, "summary": identity.summary,
"icon": self.request.identity.icon and self.request.identity.icon.url, "icon": identity.icon and identity.icon.url,
"image": self.request.identity.image and self.request.identity.image.url, "image": identity.image and identity.image.url,
"discoverable": identity.discoverable,
} }
def resize_image(self, image: File, *, size: tuple[int, int]) -> File: def resize_image(self, image: File, *, size: tuple[int, int]) -> File:
@ -50,21 +59,23 @@ class ProfilePage(FormView):
return File(new_image_bytes) return File(new_image_bytes)
def form_valid(self, form): def form_valid(self, form):
# Update identity name and summary # Update basic info
self.request.identity.name = form.cleaned_data["name"] identity = self.request.identity
self.request.identity.summary = form.cleaned_data["summary"] identity.name = form.cleaned_data["name"]
identity.summary = form.cleaned_data["summary"]
identity.discoverable = form.cleaned_data["discoverable"]
# Resize images # Resize images
icon = form.cleaned_data.get("icon") icon = form.cleaned_data.get("icon")
image = form.cleaned_data.get("image") image = form.cleaned_data.get("image")
if isinstance(icon, File): if isinstance(icon, File):
self.request.identity.icon.save( identity.icon.save(
icon.name, icon.name,
self.resize_image(icon, size=(400, 400)), self.resize_image(icon, size=(400, 400)),
) )
if isinstance(image, File): if isinstance(image, File):
self.request.identity.image.save( identity.image.save(
image.name, image.name,
self.resize_image(image, size=(1500, 500)), self.resize_image(image, size=(1500, 500)),
) )
self.request.identity.save() identity.save()
return redirect(".") return redirect(".")