mirror of https://github.com/jointakahe/takahe
Compare commits
7 Commits
be39723551
...
57ec90ee24
Author | SHA1 | Date |
---|---|---|
Osma Ahvenlampi | 57ec90ee24 | |
Henri Dickson | 72eb6a6271 | |
Jamie Bliss | b2223ddf42 | |
Jamie Bliss | 045a499ddf | |
Jamie Bliss | 0fa48578f2 | |
Osma Ahvenlampi | 85ee2692f1 | |
Osma Ahvenlampi | 05ec6cbe74 |
|
@ -3,7 +3,7 @@
|
|||
A *beta* Fediverse server for microblogging. Not fully polished yet -
|
||||
we're still working towards a 1.0!
|
||||
|
||||
**Current version: [0.10.1](https://docs.jointakahe.org/en/latest/releases/0.10/)**
|
||||
**Current version: [0.11.0](https://docs.jointakahe.org/en/latest/releases/0.11/)**
|
||||
|
||||
Key features:
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ class Account(Schema):
|
|||
bot: bool
|
||||
group: bool
|
||||
discoverable: bool
|
||||
indexable: bool
|
||||
moved: Union[None, bool, "Account"]
|
||||
suspended: bool = False
|
||||
limited: bool = False
|
||||
|
|
|
@ -559,6 +559,7 @@ schemas = {
|
|||
"@context": {
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"discoverable": "toot:discoverable",
|
||||
"indexable": "toot:indexable",
|
||||
"devices": "toot:devices",
|
||||
"featured": "toot:featured",
|
||||
"featuredTags": "toot:featuredTags",
|
||||
|
|
|
@ -219,7 +219,7 @@ class HttpSignature:
|
|||
body_bytes = b""
|
||||
# GET requests get implicit accept headers added
|
||||
if method == "get":
|
||||
headers["Accept"] = "application/ld+json"
|
||||
headers["Accept"] = "application/activity+json,application/ld+json"
|
||||
# Sign the headers
|
||||
signed_string = "\n".join(
|
||||
f"{name.lower()}: {value}" for name, value in headers.items()
|
||||
|
|
|
@ -1,21 +1,37 @@
|
|||
0.11
|
||||
====
|
||||
|
||||
*Released: Not Yet Released*
|
||||
*Released: 2024-02-05*
|
||||
|
||||
Notes TBD.
|
||||
This is largely a bugfix and catch up release.
|
||||
|
||||
Some highlights:
|
||||
|
||||
Upgrade Notes
|
||||
-------------
|
||||
* Python 3.10 has been dropped. The new minimum Python version is 3.11
|
||||
* Jamie (`@astraluma@tacobelllabs.net <https://tacobelllabs.net/@astraluma>`_)
|
||||
has officially joined the project
|
||||
* If your S3 does not use TLS, you must use ``s3-insecure`` in your
|
||||
configuration
|
||||
* Takahē now supports unicode hashtags
|
||||
* Add a Maximum Media Attachments setting
|
||||
* Inverted the pruning command exit codes
|
||||
* Posts are no longer required to have text content
|
||||
|
||||
VAPID keys and Push notifications
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
And some interoperability bugs:
|
||||
|
||||
Takahē now supports push notifications if you supply a valid VAPID keypair as
|
||||
the ``TAKAHE_VAPID_PUBLIC_KEY`` and ``TAKAHE_VAPID_PRIVATE_KEY`` environment
|
||||
variables. You can generate a keypair via `https://web-push-codelab.glitch.me/`_.
|
||||
* Fixed a bug with GoToSocial
|
||||
* Attempted to fix follows from Misskey family
|
||||
* Correctly handle when a federated report doesn't have content
|
||||
|
||||
Note that users of apps may need to sign out and in again to their accounts for
|
||||
the app to notice that it can now do push notifications. Some apps, like Elk,
|
||||
may cache the fact your server didn't support it for a while.
|
||||
In additions, there's many bugfixes and minor changes, including:
|
||||
|
||||
* Several JSON handling improvements
|
||||
* Post pruning now has a random element to it
|
||||
* More specific loggers
|
||||
* Don't make local identities stale
|
||||
* Don't try to unmute when there's no expiration
|
||||
* Don't try to WebFinger local users
|
||||
* Synchronize follow accepting and profile fetching
|
||||
* Perform some basic domain validity
|
||||
* Correctly reject more operations when the identity is deleted
|
||||
* Post edit fanouts for likers/boosters
|
||||
|
|
|
@ -7,6 +7,7 @@ Versions
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
0.11
|
||||
0.10
|
||||
0.9
|
||||
0.8
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
|
||||
Upgrade Notes
|
||||
-------------
|
||||
|
||||
VAPID keys and Push notifications
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Takahē now supports push notifications if you supply a valid VAPID keypair as
|
||||
the ``TAKAHE_VAPID_PUBLIC_KEY`` and ``TAKAHE_VAPID_PRIVATE_KEY`` environment
|
||||
variables. You can generate a keypair via `https://web-push-codelab.glitch.me/`_.
|
||||
|
||||
Note that users of apps may need to sign out and in again to their accounts for
|
||||
the app to notice that it can now do push notifications. Some apps, like Elk,
|
||||
may cache the fact your server didn't support it for a while.
|
|
@ -31,6 +31,7 @@
|
|||
{% include "forms/_field.html" with field=form.domain %}
|
||||
{% include "forms/_field.html" with field=form.name %}
|
||||
{% include "forms/_field.html" with field=form.discoverable %}
|
||||
{% include "forms/_field.html" with field=form.indexable %}
|
||||
</fieldset>
|
||||
<div class="buttons">
|
||||
<button>Create</button>
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
<fieldset>
|
||||
<legend>Privacy</legend>
|
||||
{% include "forms/_field.html" with field=form.discoverable %}
|
||||
{% include "forms/_field.html" with field=form.indexable %}
|
||||
{% include "forms/_field.html" with field=form.visible_follows %}
|
||||
{% include "forms/_field.html" with field=form.search_enabled %}
|
||||
</fieldset>
|
||||
|
|
|
@ -204,6 +204,8 @@ def test_fetch_actor(httpx_mock, config_system):
|
|||
assert identity.image_uri == "https://example.com/image.jpg"
|
||||
assert identity.summary == "<p>A test user</p>"
|
||||
assert "ts-a-faaaake" in identity.public_key
|
||||
# convention is that indexability should be opt-in
|
||||
assert not identity.indexable
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# Generated by Django 4.2.3 on 2023-11-16 13:03
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("users", "0022_follow_request"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="identity",
|
||||
name="indexable",
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
|
@ -233,6 +233,7 @@ class Identity(StatorModel):
|
|||
summary = models.TextField(blank=True, null=True)
|
||||
manually_approves_followers = models.BooleanField(blank=True, null=True)
|
||||
discoverable = models.BooleanField(default=True)
|
||||
indexable = models.BooleanField(default=False)
|
||||
|
||||
profile_uri = models.CharField(max_length=500, blank=True, null=True)
|
||||
inbox_uri = models.CharField(max_length=500, blank=True, null=True)
|
||||
|
@ -597,6 +598,7 @@ class Identity(StatorModel):
|
|||
"published": self.created.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||
"url": self.absolute_profile_uri(),
|
||||
"toot:discoverable": self.discoverable,
|
||||
"toot:indexable": self.indexable,
|
||||
}
|
||||
if self.name:
|
||||
response["name"] = self.name
|
||||
|
@ -958,6 +960,7 @@ class Identity(StatorModel):
|
|||
self.icon_uri = get_first_image_url(document.get("icon", None))
|
||||
self.image_uri = get_first_image_url(document.get("image", None))
|
||||
self.discoverable = document.get("toot:discoverable", True)
|
||||
self.indexable = document.get("toot:indexable", False)
|
||||
# Profile links/metadata
|
||||
self.metadata = []
|
||||
for attachment in get_list(document, "attachment"):
|
||||
|
@ -1095,6 +1098,7 @@ class Identity(StatorModel):
|
|||
"bot": self.actor_type.lower() in ["service", "application"],
|
||||
"group": self.actor_type.lower() == "group",
|
||||
"discoverable": self.discoverable,
|
||||
"indexable": self.indexable,
|
||||
"suspended": False,
|
||||
"limited": False,
|
||||
"created_at": format_ld_date(
|
||||
|
|
|
@ -38,6 +38,7 @@ class IdentityService:
|
|||
domain: Domain,
|
||||
name: str,
|
||||
discoverable: bool = True,
|
||||
indexable: bool = False,
|
||||
) -> Identity:
|
||||
identity = Identity.objects.create(
|
||||
actor_uri=f"https://{domain.uri_domain}/@{username}@{domain.domain}/",
|
||||
|
@ -46,6 +47,7 @@ class IdentityService:
|
|||
name=name,
|
||||
local=True,
|
||||
discoverable=discoverable,
|
||||
indexable=indexable,
|
||||
)
|
||||
identity.users.add(user)
|
||||
identity.generate_keypair()
|
||||
|
|
|
@ -313,6 +313,14 @@ class CreateIdentity(FormView):
|
|||
),
|
||||
required=False,
|
||||
)
|
||||
indexable = forms.BooleanField(
|
||||
help_text="Should this user's activities be indexable on other servers.",
|
||||
initial=False,
|
||||
widget=forms.Select(
|
||||
choices=[(True, "Indexable"), (False, "Not Indexable")]
|
||||
),
|
||||
required=False,
|
||||
)
|
||||
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
@ -385,6 +393,7 @@ class CreateIdentity(FormView):
|
|||
domain=domain_instance,
|
||||
name=form.cleaned_data["name"],
|
||||
discoverable=form.cleaned_data["discoverable"],
|
||||
indexable=form.cleaned_data["indexable"],
|
||||
)
|
||||
self.request.session["identity_id"] = identity.id
|
||||
return redirect(identity.urls.view)
|
||||
|
|
|
@ -43,6 +43,13 @@ class ProfilePage(FormView):
|
|||
),
|
||||
required=False,
|
||||
)
|
||||
indexable = forms.BooleanField(
|
||||
help_text="Opt-in to be indexed for search on other servers.\n(Disabling this does not guarantee third-party servers won't index your posts without permission)",
|
||||
widget=forms.Select(
|
||||
choices=[(True, "Indexable"), (False, "Not Indexable")]
|
||||
),
|
||||
required=False,
|
||||
)
|
||||
visible_follows = forms.BooleanField(
|
||||
help_text="Whether or not to show your following and follower counts in your profile",
|
||||
widget=forms.Select(choices=[(True, "Visible"), (False, "Hidden")]),
|
||||
|
@ -93,6 +100,7 @@ class ProfilePage(FormView):
|
|||
"icon": self.identity.icon and self.identity.icon.url,
|
||||
"image": self.identity.image and self.identity.image.url,
|
||||
"discoverable": self.identity.discoverable,
|
||||
"indexable": self.identity.indexable,
|
||||
"visible_follows": self.identity.config_identity.visible_follows,
|
||||
"metadata": self.identity.metadata or [],
|
||||
"search_enabled": self.identity.config_identity.search_enabled,
|
||||
|
@ -104,6 +112,7 @@ class ProfilePage(FormView):
|
|||
service = IdentityService(self.identity)
|
||||
self.identity.name = form.cleaned_data["name"]
|
||||
self.identity.discoverable = form.cleaned_data["discoverable"]
|
||||
self.identity.indexable = form.cleaned_data["indexable"]
|
||||
service.set_summary(form.cleaned_data["summary"])
|
||||
# Resize images
|
||||
icon = form.cleaned_data.get("icon")
|
||||
|
|
Loading…
Reference in New Issue