Skip to content

Commit 6db1e41

Browse files
BookWyrm Botgithub-actions[bot]
authored andcommitted
deploy versions
1 parent e62fe3a commit 6db1e41

File tree

86 files changed

+1632
-212
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+1632
-212
lines changed

locale/de_DE/content/codebase/activitypub.md

Lines changed: 83 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
- - -
2-
Title: ActivityPub Date: 2021-04-20 Order: 1
2+
Title: ActivityPub Date: 2025-04-21 Order: 1
33
- - -
44

55
BookWyrm verwendet das [ActivityPub](http://activitypub.rocks/)-Protokoll, um Benutzer*innenaktivitäten zwischen anderen BookWyrm-Instanzen und anderen Diensten, die ActivityPub implementieren (wie [Mastodon](https://joinmastodon.org/)), zu senden und zu empfangen. Um Buchdaten zu handhaben, hat BookWyrm eine Handvoll erweiterter Aktivitätstypen, die nicht zum Standard gehören, aber für andere BookWyrm-Instanzen lesbar sind.
66

7+
To view the ActivityPub data for a BookWyrm entity (user, book, list, etc) you can usually add `.json` to the end of the URL. e.g. `https://www.example.com/user/sam.json` and see the JSON in your web browser or via an http request (e.g. using `curl`).
8+
79
## Aktivitäten und Objekte
810

911
### Benutzer*innen und Beziehungen
@@ -16,6 +18,7 @@ Benutzer*innenbeziehungsinteraktionen folgen der Standard ActivityPub Spezifikat
1618
- `Update`: Aktualisiert das Profil und die Einstellungen eine*r Benutzer*in
1719
- `Löschen`: Deaktiviert eine*n Benutzer*in
1820
- `Rückgängig`: Reversiert `Folgen` oder `Blocken`
21+
- `Move`: communicate that a user has changed their ID and has moved to a new server. Most ActivityPub software will "follow" the user to the new identity. BookWyrm sends a notification to followers and requires them to confirm they want to follow the user to their new identity.
1922

2023
### Status
2124
#### Objekttypen
@@ -25,16 +28,16 @@ Benutzer*innenbeziehungsinteraktionen folgen der Standard ActivityPub Spezifikat
2528
- `Kommentar`: Ein Kommentar zu einem Buch erwähnt ein Buch und hat einen Text.
2629
- `Zitat`: Ein Zitat enthält einen Text, einen Auszug aus dem Buch und erwähnt ein Buch.
2730

28-
2931
#### Aktivitäten
3032

3133
- `Erstellen`: Speichert einen neuen Status in der Datenbank.
3234

33-
**Hinweis**: BookWyrm akzeptiert nur `Erstellen`-Aktivitäten, wenn sie sind:
35+
**Hinweis**: BookWyrm akzeptiert nur `Erstellen`-Aktivitäten, wenn sie sind:
36+
37+
- Direktnachrichten (d.h. `Hinweis`e mit der Datenschutzstufe `direkt`, welche einen lokalen Benutzer erwähnen),
38+
- Verbunden mit einem Buch (eines benutzerdefinierten Statusstyps, der das Feld `inReplyToBook` enthält),
39+
- Antworten auf existierende Status in der Datenbank
3440

35-
- Direktnachrichten (d.h. `Hinweis`e mit der Datenschutzstufe `direkt`, welche einen lokalen Benutzer erwähnen),
36-
- Verbunden mit einem Buch (eines benutzerdefinierten Statusstyps, der das Feld `inReplyToBook` enthält),
37-
- Antworten auf existierende Status in der Datenbank
3841
- `Löschen`: Entfernt einen Status
3942
- `Gefällt`: Erstellt einen Favoriten für den Status
4043
- `Ankündigung`: Teilt den Status in der Zeitleiste des Akteurs
@@ -45,7 +48,7 @@ Bücher und Listen von Benutzern werden durch [`Sortierte Sammlung`](https://www
4548

4649
#### Objekte
4750

48-
- `Regal`: Buchsammlung eines Benutzers. Standardmäßig hat jeder Benutzer ein `zu lesen`, `liest`, und `gelesen` Regal, die verwendet werden, um den Lesefortschritt zu verfolgen.
51+
- `Regal`: Buchsammlung eines Benutzers. By default, every user has a `to-read`, `reading`, `stop-reading` and `read` shelf which are used to track reading progress.
4952
- `Liste`: Eine Sammlung von Büchern, zu der auch andere Personen als die, die die Liste erstellt hat, Bücher beitragen können.
5053

5154
#### Aktivitäten
@@ -55,6 +58,78 @@ Bücher und Listen von Benutzern werden durch [`Sortierte Sammlung`](https://www
5558
- `Hinzufügen`: Fügt ein Buch zu einem Regal oder einer Liste hinzu.
5659
- `Entfernen`: Entfernt ein Buch aus einem Regal oder einer Liste.
5760

58-
5961
## Alternative Serialisierung
6062
Weil BookWyrm eigene Objekttypen (`Rezension`, `Kommentar`, `Zitat`) benutzt, die nicht von ActivityPub unterstützt werden, werden Status in Standardtypen umgewandelt, wenn sie an nicht-BookWyrm-Dienste gesendet oder angezeigt werden. `Rezension`en werden in `Artikel` umgewandelt und `Kommentar`e und `Zitat`e werden in `Notiz`en mit einem Link zu dem Buch und dem Titelbild als Anhang konvertiert.
63+
64+
This may change in future in favor of the more ActivityPub-compliant [extended Object types](https://www.w3.org/TR/activitystreams-core/#fig-following-is-an-example-object-that-uses-the-id-and-type-properties-to-express-the-global-identifier-and-object-type) listed alongside core ActivityPub types.
65+
66+
## Making ActivityPub-aware models
67+
68+
The way BookWyrm sends and receives ActivityPub objects can be confusing for developers who are new to BookWyrm. It is mostly controlled by:
69+
70+
* Functions and [data classes](https://docs.python.org/3/library/dataclasses.html) outlined in the [activitypub](https://github.com/bookwyrm-social/bookwyrm/tree/main/bookwyrm/activitypub) directory
71+
* The [ActivitypubMixin](https://github.com/bookwyrm-social/bookwyrm/blob/c458cdcb992a36f3c4a06752499461c3dd991e07/bookwyrm/models/activitypub_mixin.py#L40) and its children for models that are serializable for ActivityPub requests
72+
73+
### Serializing data to and from ActivityPub JSON
74+
75+
BookWyrm needs to know how to _serialize_ the data from the model into an ActivityPub JSON-LD object.
76+
77+
The `/activitypub/base_activity.py` file provides the core functions that turn ActivityPub JSON-LD strings into usable Django model objects, and vice-versa. We do this by creating a data class in `bookwyrm/activitypub`, and defining how the model should be serialized by providing an `activity_serializer` value in the model, which points to the relevant data class. From `ActivityObject` we inherit `id` and `type`, and two _class methods_:
78+
79+
**`to_model`**
80+
81+
This method takes an ActivityPub JSON string and tries to turn it into a BookWyrm model object, finding an existing object wherever possible. This is how we process **incoming** ActivityPub objects.
82+
83+
**`serialize`**
84+
85+
This method takes a BookWyrm model object, and turns it into a valid ActivityPub JSON string using the dataclass definitions. This is how we process **outgoing** ActivityPub objects.
86+
87+
### Example - Users
88+
89+
A BookWyrm user [is defined in `models/user.py`](https://github.com/bookwyrm-social/bookwyrm/blob/main/bookwyrm/models/user.py):
90+
91+
```py
92+
class User(OrderedCollectionPageMixin, AbstractUser):
93+
"""a user who wants to read books"""
94+
```
95+
Notice that we are inheriting from ("subclassing") `OrderedCollectionPageMixin`. This in turn inherits from `ObjectMixin`, which inherits from `ActivitypubMixin`. This may seem convoluted, but this inheritence chain allows us to avoid duplicating code as our ActivityPub objects become more specific. `AbstractUser` is [a Django model intended to be subclassed](https://docs.djangoproject.com/en/5.1/topics/auth/customizing/#specifying-custom-user-model), giving us things like hashed password logins and permission levels "out of the box".
96+
97+
Because `User` inherits from [`ObjectMixin`](https://github.com/bookwyrm-social/bookwyrm/blob/c458cdcb992a36f3c4a06752499461c3dd991e07/bookwyrm/models/activitypub_mixin.py#L213), when we `save()` a `User` object we will send a `Create` activity (if this is the first time the user was saved) or an `Update` activity (if we're just saving a change – e.g. to the user description or avatar). Any other model you add to BookWyrm will have the same capability if it inherits from `ObjectMixin`.
98+
99+
For BookWyrm users, the `activity_serializer` is defined in the `User` model:
100+
101+
```py
102+
activity_serializer = activitypub.Person
103+
```
104+
105+
The data class definition for `activitypub.Person` is at `/activitypub/person.py`:
106+
107+
```py
108+
@dataclass(init=False)
109+
class Person(ActivityObject):
110+
"""actor activitypub json"""
111+
112+
preferredUsername: str
113+
inbox: str
114+
publicKey: PublicKey
115+
followers: str = None
116+
following: str = None
117+
outbox: str = None
118+
endpoints: Dict = None
119+
name: str = None
120+
summary: str = None
121+
icon: Image = None
122+
bookwyrmUser: bool = False
123+
manuallyApprovesFollowers: str = False
124+
discoverable: str = False
125+
hideFollows: str = False
126+
movedTo: str = None
127+
alsoKnownAs: dict[str] = None
128+
type: str = "Person"
129+
```
130+
131+
You might notice that some of these fields are not a perfect match to the fields in the `User` model. If you have a field name in your model that needs to be called something different in the ActivityPub object (e.g. to comply with Python naming conventions in the model but JSON naming conventions in JSON string), you can define an `activitypub_field` in the model field definition:
132+
133+
```py
134+
followers_url = fields.CharField(max_length=255, activitypub_field="followers")
135+
```

locale/de_DE/content/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Da sich das Projekt noch in den Anfangsphasen befindet, wachsen die Funktionen j
1616
- Gesamte Rezensionen eines Buches über verbundene BookWyrm-Instanzen ansehen
1717
- Unterscheide lokale und föderierte Rezensionen und Bewertungen in deinem Aktivitätsfeed
1818
- Leseaktivität verfolgen
19-
- Bücher in die Standardregale "Zu Lesen", "Aktuell Lesend" und "Gelesen" einsortieren
19+
- Shelve books on default "to-read," "currently reading," "stopped reading," and "read" shelves
2020
- Erstelle eigene Regale
2121
- Speichere Lesestart/Leseende Daten sowie Fortschrittsaktualisierungen während des Lesens
2222
- Aktualisiere Follower über Leseaktivitäten (optional mit granularen Privatsphäreeinstellungen)

locale/en_Oulipo/content/codebase/activitypub.md

Lines changed: 83 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
- - -
2-
Title: ActivityPub Date: 2021-04-20 Order: 1
2+
Title: ActivityPub Date: 2025-04-21 Order: 1
33
- - -
44

55
BookWyrm works with [ActivityPub](http://activitypub.rocks/) to trasnmit user activity across BookWyrm instantiations and any ActivityPub software, such as [Mastodon](https://joinmastodon.org/). For book data, BookWyrm has a handful of Activity forms which are not standard, but work across BookWyrm instantiations.
66

7+
To view the ActivityPub data for a BookWyrm entity (user, book, list, etc) you can usually add `.json` to the end of the URL. e.g. `https://www.example.com/user/sam.json` and see the JSON in your web browser or via an http request (e.g. using `curl`).
8+
79
## Activities and Objects
810

911
### Accounts and following
@@ -16,6 +18,7 @@ User relationship interactions follow the standard ActivityPub spec.
1618
- `Update`: updates a user's profile and settings
1719
- `Delete`: deactivates a user
1820
- `Undo`: reverses a `Follow` or `Block`
21+
- `Move`: communicate that a user has changed their ID and has moved to a new server. Most ActivityPub software will "follow" the user to the new identity. BookWyrm sends a notification to followers and requires them to confirm they want to follow the user to their new identity.
1922

2023
### Statuses
2124
#### Object types
@@ -25,16 +28,16 @@ User relationship interactions follow the standard ActivityPub spec.
2528
- `Comment`: A comment on a book mentions a book and has a message body.
2629
- `Quotation`: A quote has a message body, an excerpt from a book, and mentions a book.
2730

28-
2931
#### Activities
3032

3133
- `Create`: saves a new status in the database.
3234

33-
**Note**: BookWyrm only accepts `Create` activities if they are:
35+
**Note**: BookWyrm only accepts `Create` activities if they are:
36+
37+
- Direct messages (i.e., `Note`s with the privacy level `direct`, which mention a local user),
38+
- Related to a book (of a custom status type that includes the field `inReplyToBook`),
39+
- Replies to existing statuses saved in the database
3440

35-
- Direct messages (i.e., `Note`s with the privacy level `direct`, which mention a local user),
36-
- Related to a book (of a custom status type that includes the field `inReplyToBook`),
37-
- Replies to existing statuses saved in the database
3841
- `Delete`: Removes a status
3942
- `Like`: Creates a favorite on the status
4043
- `Announce`: Boosts the status into the actor's timeline
@@ -45,7 +48,7 @@ User's books and lists are represented by [`OrderedCollection`](https://www.w3.o
4548

4649
#### Objects
4750

48-
- `Shelf`: A user's book collection. By default, every user has a `to-read`, `reading`, and `read` shelf which are used to track reading progress.
51+
- `Shelf`: A user's book collection. By default, every user has a `to-read`, `reading`, `stop-reading` and `read` shelf which are used to track reading progress.
4952
- `List`: A collection of books that may have items contributed by users other than the one who created the list.
5053

5154
#### Activities
@@ -55,6 +58,78 @@ User's books and lists are represented by [`OrderedCollection`](https://www.w3.o
5558
- `Add`: Adds a book to a shelf or list.
5659
- `Remove`: Removes a book from a shelf or list.
5760

58-
5961
## Alternative Serialization
6062
Because BookWyrm uses custom object types (`Review`, `Comment`, `Quotation`) that aren't supported by ActivityPub, statuses are transformed into standard types when sent to or viewed by non-BookWyrm services. `Review`s are converted into `Article`s, and `Comment`s and `Quotation`s are converted into `Note`s, with a link to the book and the cover image attached.
63+
64+
This may change in future in favor of the more ActivityPub-compliant [extended Object types](https://www.w3.org/TR/activitystreams-core/#fig-following-is-an-example-object-that-uses-the-id-and-type-properties-to-express-the-global-identifier-and-object-type) listed alongside core ActivityPub types.
65+
66+
## Making ActivityPub-aware models
67+
68+
The way BookWyrm sends and receives ActivityPub objects can be confusing for developers who are new to BookWyrm. It is mostly controlled by:
69+
70+
* Functions and [data classes](https://docs.python.org/3/library/dataclasses.html) outlined in the [activitypub](https://github.com/bookwyrm-social/bookwyrm/tree/main/bookwyrm/activitypub) directory
71+
* The [ActivitypubMixin](https://github.com/bookwyrm-social/bookwyrm/blob/c458cdcb992a36f3c4a06752499461c3dd991e07/bookwyrm/models/activitypub_mixin.py#L40) and its children for models that are serializable for ActivityPub requests
72+
73+
### Serializing data to and from ActivityPub JSON
74+
75+
BookWyrm needs to know how to _serialize_ the data from the model into an ActivityPub JSON-LD object.
76+
77+
The `/activitypub/base_activity.py` file provides the core functions that turn ActivityPub JSON-LD strings into usable Django model objects, and vice-versa. We do this by creating a data class in `bookwyrm/activitypub`, and defining how the model should be serialized by providing an `activity_serializer` value in the model, which points to the relevant data class. From `ActivityObject` we inherit `id` and `type`, and two _class methods_:
78+
79+
**`to_model`**
80+
81+
This method takes an ActivityPub JSON string and tries to turn it into a BookWyrm model object, finding an existing object wherever possible. This is how we process **incoming** ActivityPub objects.
82+
83+
**`serialize`**
84+
85+
This method takes a BookWyrm model object, and turns it into a valid ActivityPub JSON string using the dataclass definitions. This is how we process **outgoing** ActivityPub objects.
86+
87+
### Example - Users
88+
89+
A BookWyrm user [is defined in `models/user.py`](https://github.com/bookwyrm-social/bookwyrm/blob/main/bookwyrm/models/user.py):
90+
91+
```py
92+
class User(OrderedCollectionPageMixin, AbstractUser):
93+
"""a user who wants to read books"""
94+
```
95+
Notice that we are inheriting from ("subclassing") `OrderedCollectionPageMixin`. This in turn inherits from `ObjectMixin`, which inherits from `ActivitypubMixin`. This may seem convoluted, but this inheritence chain allows us to avoid duplicating code as our ActivityPub objects become more specific. `AbstractUser` is [a Django model intended to be subclassed](https://docs.djangoproject.com/en/5.1/topics/auth/customizing/#specifying-custom-user-model), giving us things like hashed password logins and permission levels "out of the box".
96+
97+
Because `User` inherits from [`ObjectMixin`](https://github.com/bookwyrm-social/bookwyrm/blob/c458cdcb992a36f3c4a06752499461c3dd991e07/bookwyrm/models/activitypub_mixin.py#L213), when we `save()` a `User` object we will send a `Create` activity (if this is the first time the user was saved) or an `Update` activity (if we're just saving a change – e.g. to the user description or avatar). Any other model you add to BookWyrm will have the same capability if it inherits from `ObjectMixin`.
98+
99+
For BookWyrm users, the `activity_serializer` is defined in the `User` model:
100+
101+
```py
102+
activity_serializer = activitypub.Person
103+
```
104+
105+
The data class definition for `activitypub.Person` is at `/activitypub/person.py`:
106+
107+
```py
108+
@dataclass(init=False)
109+
class Person(ActivityObject):
110+
"""actor activitypub json"""
111+
112+
preferredUsername: str
113+
inbox: str
114+
publicKey: PublicKey
115+
followers: str = None
116+
following: str = None
117+
outbox: str = None
118+
endpoints: Dict = None
119+
name: str = None
120+
summary: str = None
121+
icon: Image = None
122+
bookwyrmUser: bool = False
123+
manuallyApprovesFollowers: str = False
124+
discoverable: str = False
125+
hideFollows: str = False
126+
movedTo: str = None
127+
alsoKnownAs: dict[str] = None
128+
type: str = "Person"
129+
```
130+
131+
You might notice that some of these fields are not a perfect match to the fields in the `User` model. If you have a field name in your model that needs to be called something different in the ActivityPub object (e.g. to comply with Python naming conventions in the model but JSON naming conventions in JSON string), you can define an `activitypub_field` in the model field definition:
132+
133+
```py
134+
followers_url = fields.CharField(max_length=255, activitypub_field="followers")
135+
```

locale/en_Oulipo/content/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Since the project is still in its early stages, the features are growing every d
1616
- View aggregate reviews of a book across connected BookWyrm instances
1717
- Differentiate local and federated reviews and rating in your activity feed
1818
- Track reading activity
19-
- Shelve books on default "to-read," "currently reading," and "read" shelves
19+
- Shelve books on default "to-read," "currently reading," "stopped reading," and "read" shelves
2020
- Create custom shelves
2121
- Store started reading/finished reading dates, as well as progress updates along the way
2222
- Update followers about reading activity (optionally, and with granular privacy controls)

locale/en_US/LC_MESSAGES/messages.po

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ msgid ""
88
msgstr ""
99
"Project-Id-Version: PACKAGE VERSION\n"
1010
"Report-Msgid-Bugs-To: \n"
11-
"POT-Creation-Date: 2025-07-04 08:50+0000\n"
11+
"POT-Creation-Date: 2025-07-05 04:19+0000\n"
1212
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1414
"Language-Team: LANGUAGE <LL@li.org>\n"

0 commit comments

Comments
 (0)