Merge remote-tracking branch 'origin/main'

This commit is contained in:
rimu 2024-11-27 09:30:14 +13:00
commit dcb883a06f
9 changed files with 660 additions and 38 deletions

39
FEDERATION.md Normal file
View file

@ -0,0 +1,39 @@
# Federation
## Supported federation protocols and standards
- [ActivityPub](https://www.w3.org/TR/activitypub/) (Server-to-Server)
- [WebFinger](https://webfinger.net/)
- [Http Signatures](https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures)
- [NodeInfo](https://nodeinfo.diaspora.software/)
## Supported FEPS
- [FEP-67ff: FEDERATION.md](https://codeberg.org/fediverse/fep/src/branch/main/fep/67ff/fep-67ff.md)
- [FEP-f1d5: NodeInfo in Fediverse Software](https://codeberg.org/fediverse/fep/src/branch/main/fep/f1d5/fep-f1d5.md)
- [FEP-1b12: Group federation](https://codeberg.org/fediverse/fep/src/branch/main/fep/1b12/fep-1b12.md)
- [FEP-5feb: Search indexing consent for actors](https://codeberg.org/fediverse/fep/src/branch/main/fep/5feb/fep-5feb.md)
- [FEP-2677: Identifying the Application Actor](https://codeberg.org/fediverse/fep/src/branch/main/fep/2677/fep-2677.md)
## Partially Supported FEPS
- [FEP-c0e0: Emoji reactions](https://codeberg.org/fediverse/fep/src/branch/main/fep/c0e0/fep-c0e0.md)
- Treated as a `like` or `upvote`
- [FEP-268d: Search consent signals for objects](https://codeberg.org/fediverse/fep/src/branch/main/fep/268d/fep-268d.md)
- `"searchableBy": "https://www.w3.org/ns/activitystreams#Public"` == `"indexable": true`, any other content sets `"indexable": false`
- `"searchableBy": ["https://alice.example/actor", "https://example.com/users/1/followers"]` is not currently supported.
## ActivityPub
- Communities are ['Group' actors](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-group)
- Users are ['Person' actors](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-person)
- Posts on Communities are one of the following:
- [Page](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-page)
- [Article](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-article)
- [Link](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-link)
- [Note](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-note)
- [Question](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-question)
## Additional documentation
See the `docs/activitypub_examples` for examples of [communities](./docs/activitypub_examples/communities.md), [users](./docs/activitypub_examples/users.md), and [posts](./docs/activitypub_examples/posts.md).

View file

@ -972,7 +972,7 @@ def admin_content_trash():
page = request.args.get('page', 1, type=int)
posts = Post.query.filter(Post.posted_at > utcnow() - timedelta(days=3), Post.deleted == False).order_by(Post.score)
posts = Post.query.filter(Post.posted_at > utcnow() - timedelta(days=3), Post.deleted == False, Post.down_votes > 0).order_by(Post.score)
posts = posts.paginate(page=page, per_page=100, error_out=False)
next_url = url_for('admin.admin_content_trash', page=posts.next_num) if posts.has_next else None
@ -1034,12 +1034,12 @@ def admin_content_deleted():
posts = Post.query.\
filter(Post.deleted == True).\
order_by(Post.posted_at)
order_by(desc(Post.posted_at))
posts = posts.paginate(page=page, per_page=100, error_out=False)
post_replies = PostReply.query. \
filter(PostReply.deleted == True). \
order_by(PostReply.posted_at)
order_by(desc(PostReply.posted_at))
post_replies = post_replies.paginate(page=replies_page, per_page=100, error_out=False)
next_url = url_for('admin.admin_content_deleted', page=posts.next_num) if posts.has_next else None

View file

@ -19,7 +19,6 @@
<table class="table table-striped">
<tr>
<th>Name</th>
<th>Title</th>
<th>Topic</th>
<th>#&nbsp;Posts</th>
<th>Retention</th>
@ -32,8 +31,8 @@
</tr>
{% for community in communities.items %}
<tr>
<td><a href="/c/{{ community.link() }}">{{ community.name }}</a></td>
<td>{{ render_communityname(community) }}{% if community.banned %} (banned){% endif %}</td>
<td>{{ render_communityname(community, add_domain=False) }}{% if community.banned %} (banned){% endif %}<br />
!<a href="/c/{{ community.link() }}">{{ community.name }}</a><wbr />@<a href="{{ community.ap_profile_id }}">{{ community.ap_domain }}</a></td>
<td>{{ community.topic.name }}</td>
<td>{{ community.post_count }}</td>
<td>{{ community.content_retention if community.content_retention != -1 }}</td>

View file

@ -20,7 +20,6 @@
<table class="table table-striped mt-1">
<tr>
<th title="{{ _('Display name.') }}">{{ _('Name') }}</th>
<th>{{ _('Local/Remote') }}</th>
<th title="{{ _('Last seen.') }}">{{ _('Seen') }}</th>
<th title="{{ _('Attitude: Percentage of up votes vs. down votes the account made.') }}">{{ _('Attitude') }}</th>
<th title="{{ _('Reputation: The Karma of the account. Total up votes minus down votes they got.') }}">{{ _('Reputation') }}</th>
@ -32,29 +31,21 @@
</tr>
{% for user in users.items %}
<tr>
<td><a href="/u/{{ user.link() }}">
<img src="{{ user.avatar_thumbnail() }}" class="community_icon rounded-circle" loading="lazy" />
{{ user.display_name() }}</a></td>
<td>{% if user.is_local() %}Local{% else %}<a href="{{ user.ap_profile_id }}">Remote</a>{% endif %}</td>
<td>{{ render_username(user, add_domain=False) }}<br />
<a href="/u/{{ user.link() }}">{{ user.user_name }}</a>{% if not user.is_local() %}<wbr />@<a href="{{ user.ap_profile_id }}">{{ user.ap_domain }}</a>{% endif %}</td>
<td>{% if request.args.get('local_remote', '') == 'local' %}
{{ arrow.get(user.last_seen).humanize(locale=locale) }}
{% else %}
{{ user.last_seen }}
{% endif %}
</td>
<td>{{ user.attitude * 100 if user.attitude != 1 }}</td>
<td>{{ 'R ' + str(user.reputation) if user.reputation }}</td>
<td>{% if user.attitude != 1 %}{{ (user.attitude * 100) | round | int }}%{% endif %}</td>
<td>{% if user.reputation %}R {{ user.reputation | round | int }}{% endif %}</td>
<td>{{ '<span class="red">Banned</span>'|safe if user.banned }} </td>
<td>{{ user.reports if user.reports > 0 }} </td>
<td>{{ user.ip_address if user.ip_address }}<br />{{ user.ip_address_country if user.ip_address_country }}</td>
<td>{{ user.referrer if user.referrer }} </td>
<td><a href="/u/{{ user.link() }}">View local</a> |
{% if not user.is_local() %}
<a href="{{ user.ap_profile_id }}">View remote</a> |
{% else %}
View remote |
{% endif %}
<a href="{{ url_for('admin.admin_user_edit', user_id=user.id) }}">Edit</a> |
<td><a href="{{ url_for('admin.admin_user_edit', user_id=user.id) }}">Edit</a> |
<a href="{{ url_for('admin.admin_user_delete', user_id=user.id) }}" class="confirm_first">Delete</a>
</td>
</tr>

View file

@ -22,7 +22,6 @@
<table class="table table-striped mt-1">
<tr>
<th>Name</th>
<th>Local/Remote</th>
<th>Seen</th>
<th>Attitude</th>
<th>Rep</th>
@ -34,29 +33,21 @@
</tr>
{% for user in users.items %}
<tr>
<td><a href="/u/{{ user.link() }}">
<img src="{{ user.avatar_thumbnail() }}" class="community_icon rounded-circle" loading="lazy" />
{{ user.display_name() }}</a></td>
<td>{% if user.is_local() %}Local{% else %}<a href="{{ user.ap_profile_id }}">Remote</a>{% endif %}</td>
<td>{{ render_username(user, add_domain=False) }}<br />
<a href="/u/{{ user.link() }}">{{ user.user_name }}</a>{% if not user.is_local() %}<wbr />@<a href="{{ user.ap_profile_id }}">{{ user.ap_domain }}</a>{% endif %}</td>
<td>{% if request.args.get('local_remote', '') == 'local' %}
{{ arrow.get(user.last_seen).humanize(locale=locale) }}
{% else %}
{{ user.last_seen }}
{% endif %}
</td>
<td>{{ user.attitude * 100 if user.attitude != 1 }}</td>
<td>{{ 'R ' + str(user.reputation) if user.reputation }}</td>
<td>{% if user.attitude != 1 %}{{ (user.attitude * 100) | round | int }}%{% endif %}</td>
<td>{% if user.reputation %}R {{ user.reputation | round | int }}{% endif %}</td>
<td>{{ '<span class="red">Banned</span>'|safe if user.banned }} </td>
<td>{{ user.reports if user.reports > 0 }} </td>
<td>{{ user.ip_address if user.ip_address }} </td>
<td>{{ user.referrer if user.referrer }} </td>
<td><a href="/u/{{ user.link() }}">View local</a> |
{% if not user.is_local() %}
<a href="{{ user.ap_profile_id }}">View remote</a> |
{% else %}
View remote |
{% endif %}
<a href="{{ url_for('admin.admin_user_edit', user_id=user.id) }}">Edit</a> |
<td><a href="{{ url_for('admin.admin_user_edit', user_id=user.id) }}">Edit</a> |
<a href="{{ url_for('admin.admin_user_delete', user_id=user.id) }}" class="confirm_first">Delete</a>
</td>
</tr>

View file

@ -1,4 +1,4 @@
{% macro render_username(user) -%}
{% macro render_username(user, add_domain=True) -%}
<span class="render_username">
{% if user.deleted -%}
[deleted]
@ -7,7 +7,7 @@
{% if user.avatar_id and not low_bandwidth and not collapsed -%}
<img src="{{ user.avatar_thumbnail() }}" alt="" loading="lazy" />
{% endif -%}
{{ user.display_name() }}{% if not user.is_local() %}<span class="text-muted">@{{ user.ap_domain }}</span>{% endif %}
{{ user.display_name() }}{% if add_domain and not user.is_local() %}<span class="text-muted">@{{ user.ap_domain }}</span>{% endif %}
</a>
{% if user.created_recently() -%}
<span class="fe fe-new-account" title="New account"> </span>
@ -26,13 +26,13 @@
{% endif -%}
</span>
{% endmacro -%}
{% macro render_communityname(community) -%}
{% macro render_communityname(community, add_domain=True) -%}
<span class="render_community">
<a href="/c/{{ community.link() }}" aria-label="{{ _('Go to community %(name)s', name=community.name) }}">
{% if community.icon_id and not low_bandwidth and not collapsed -%}
<img src="{{ community.icon_image('tiny') }}" class="community_icon rounded-circle" alt="" loading="lazy" />
{% endif -%}
c/{{ community.display_name() }}
{{ community.title }}{% if add_domain and not community.is_local() %}<span class="text-muted">@{{ community.ap_domain }}</span>{% endif %}
</a>
</span>
{% endmacro -%}

View file

@ -0,0 +1,194 @@
# Communities as ActivityPub 'Group' Actors
The communities that make up the heart of the "threadiverse" are represented as ActivityPub Group Actors. As such they are implemented to follow [FEP-1b12: Group federation](https://codeberg.org/fediverse/fep/src/branch/main/fep/1b12/fep-1b12.md)
## Group objects as JSON
Server-to-server or server-to-client traffic that represents Communities is sent as .json. I.e. when a remote server wishes to find out information about your local server's `technology` community, the remote server will be sent that data in a json payload.
### Getting community information
Piefed internally keeps track of communities in a database, but you can query the information from the server as .json. There are many ways to do so, but here is an example using `curl`.
We will use the https://piefed.social flagship instance in the example. We will ask for information about the `piefed_meta` community.
Run this curl command:
```bash
curl -H 'Accept: application/activity+json' https://piefed.social/c/piefed_meta
```
The result should look something like this:
```json
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"attributedTo": "https://piefed.social/c/piefed_meta/moderators",
"endpoints": {
"sharedInbox": "https://piefed.social/inbox"
},
"featured": "https://piefed.social/c/piefed_meta/featured",
"followers": "https://piefed.social/c/piefed_meta/followers",
"icon": {
"type": "Image",
"url": "https://piefed.social/static/media/communities/HG/yB/HGyB58LEAHeHwdN.png"
},
"id": "https://piefed.social/c/piefed_meta",
"inbox": "https://piefed.social/c/piefed_meta/inbox",
"moderators": "https://piefed.social/c/piefed_meta/moderators",
"name": "PieFed Meta",
"newModsWanted": false,
"outbox": "https://piefed.social/c/piefed_meta/outbox",
"postingRestrictedToMods": false,
"preferredUsername": "piefed_meta",
"privateMods": false,
"publicKey": {
"id": "https://piefed.social/c/piefed_meta#main-key",
"owner": "https://piefed.social/c/piefed_meta",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm694+pAd9VdRWjsb84u0\nWGoAI7d/riiQVC5GHHgDJX4EYqTD1tvD2kB3URsHGgj4lf8pCHrjXHk/H3CpogRc\nOwyJ+ZLHrXYKyPz8r9SO0sR8KbM3tfD7EXhDLjgsK91gzPxvQ9OLneghb1n0uSmn\n4cWxbbdebDsB+jyPcF37KkSayAYwkaAjwb2nVNgxLN0w7J3ENnhpO/F6FpOBJEx1\nAHEfstlhHl6Cd2PfLFMiW4hYaryeJNMnGxE2ZqE6JGeRTikY7+ZbiG/Rx6OLXM8v\nAx/92BwQSnIEDIPsLyHOH2fFhfrtlNTA740ujq5mUjeBUz11ueGEn9GwZ5JrVc6S\nxQIDAQAB\n-----END PUBLIC KEY-----\n"
},
"published": "2024-01-04T08:55:20.668181+00:00",
"sensitive": false,
"source": {
"content": "Discuss PieFed project direction, provide feedback, ask questions, suggest improvements, and engage in conversations related to the platform organization, policies, features, and community dynamics.\r\n\r\n## [Wiki](https://piefed.social/community/piefed_meta/wiki/index)",
"mediaType": "text/markdown"
},
"summary": "<p>Discuss PieFed project direction, provide feedback, ask questions, suggest improvements, and engage in conversations related to the platform organization, policies, features, and community dynamics.</p>\n<h2><a href=\"https://piefed.social/community/piefed_meta/wiki/index\" rel=\"nofollow ugc\" target=\"\">Wiki</a></h2>\n",
"type": "Group",
"updated": "2024-11-12T05:01:43.466282+00:00",
"url": "https://piefed.social/c/piefed_meta"
}
```
### Getting the posts
Now that we have the communities object we can parse it for the information we want. Since this is the threadiverse we are mostly wanting the posts in the community.
Those can be found by requesting the actors `outbox`.
Run this curl command:
```bash
curl -H 'Accept: application/activity+json' https://piefed.social/c/piefed_meta/outbox
```
The result should look something like this:
```json
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"orderedItems": [...],
"id": "https://piefed.social/c/piefed_meta/outbox",
"totalItems": 50,
"type": "OrderedCollection"
}
```
The `oderedItems` list will be a list of [Announce](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-announce) activities that have wrap Objects that represent the activity in the community. Usually these are [Create](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-create) activity objects for [Page](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-page), [Article](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-article), [Link](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-link), [Note](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-note), or [Question](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-question) objects.
Here is an example `Announce` object, wrapping a `Create` object, that creates a `Page` object. On the web it looks like [this](https://piefed.social/post/317673), and in .json it looks like:
```json
{
"actor": "https://piefed.social/c/piefed_meta",
"cc": [
"https://piefed.social/c/piefed_meta/followers"
],
"id": "https://piefed.social/activities/announce/CEgCNWWTDQc3ZZ8",
"object": {
"actor": "https://piefed.social/u/rimu",
"audience": "https://piefed.social/c/piefed_meta",
"cc": [
"https://piefed.social/c/piefed_meta"
],
"id": "https://piefed.social/activities/create/oesyDhuiRuQ3wNZ",
"object": {
"attachment": [],
"attributedTo": "https://piefed.social/u/rimu",
"audience": "https://piefed.social/c/piefed_meta",
"cc": [],
"commentsEnabled": true,
"content": "<p>Key updates include the addition of community icons for better identification, a notification management interface, and various enhancements to our API for eventual mobile app support. Below is a detailed overview of the changes we've made.</p>\n<h2>Jeena</h2>\n<ul>\n<li>Community icon alongside name in post teaser. This helps differentiate between communities with the same name and adds visual interest.</li>\n</ul>\n<h2>Freamon</h2>\n<ul>\n<li>Added a notification management interface to manage notifications from all the communities and posts you are subscribed to - <a href=\"https://piefed.social/alerts\" rel=\"nofollow ugc\" target=\"_blank\">https://piefed.social/alerts</a></li>\n<li>Soft deletion of comments, so they can be un-deleted again.</li>\n<li>Lots of API work for the mobile app. Lots!</li>\n</ul>\n<h1>Rimu</h1>\n<ul>\n<li>Generate YouTube thumbnails more reliably.</li>\n<li>Instance overview pages which make it easy to see posts and people from any instance. Start exploring at <a href=\"https://piefed.social/instances\" rel=\"nofollow ugc\" target=\"_blank\">https://piefed.social/instances</a>.</li>\n<li>FEP-268d: Search consent signals for objects. This FEP is a convention for how instances can signal to other instances which posts should be searchable.</li>\n<li>Track who deleted which posts, for accountability among moderators.</li>\n<li>Refactoring to support API work by Freamon.</li>\n<li>Automatically delete voting data older than 6 months (aggregated totals are unaffected). Voting data consumes gigabytes of space and it only meaningfully affects ranking of posts in the first few days. The only other reason to keep this data is for vote manipulation analysis and 6 months worth of data should be plenty.</li>\n<li>Instances with open registrations automatically close registrations after one week of having no admins log in. This will avoid abandoned instances becoming a vector for spam or a home of trolls.</li>\n<li>Show instance name after display name. If you notice undesirable patterns of behaviour associated with certain instances you can block the whole instance.</li>\n<li>Improve visibility of user-level instance blocking functionality. This is separate and in addition to defederation which is controlled by admins.</li>\n<li>Display PeerTube licence info on video posts. This could be rolled out to other post types in future?</li>\n<li>Topics now have an option to show posts from communities that are in child topics. E.g. <a href=\"https://piefed.social/topic/arts-craft\" rel=\"nofollow ugc\" target=\"_blank\">https://piefed.social/topic/arts-craft</a> only has two communities in it so the number of posts shown there is very low. However it\u2019s child topics (Arts, Craft and Photography) have quite a few communities so to populate the top-level topic it makes sense to display posts from all the child topics too. <a href=\"https://piefed.social/topic/tech/programming\" rel=\"nofollow ugc\" target=\"_blank\">https://piefed.social/topic/tech/programming</a> is a similar case.</li>\n</ul>\n<p>--</p>\n<p>As a free and open source project, PieFed receives no funding and developers are not paid. Any donations you can spare will help cover server and infrastructure costs - <a href=\"https://piefed.social/donate\" rel=\"nofollow ugc\" target=\"_blank\">https://piefed.social/donate</a>. Thanks!</p>\n",
"id": "https://piefed.social/post/317673",
"language": {
"identifier": "en",
"name": "English"
},
"mediaType": "text/html",
"name": "PieFed development update Oct/Nov 2024",
"published": "2024-11-09T00:36:19.078892+00:00",
"replies": [
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"attributedTo": "https://piefed.social/u/imaqtpie",
"audience": "https://piefed.social/c/piefed_meta",
"cc": [
"https://piefed.social/c/piefed_meta",
"https://piefed.social/u/imaqtpie/followers"
],
"content": "<p>Good work! Much thanks to all contributors, you are appreciated. The site is running smooth and looking great.</p>\n",
"distinguished": false,
"id": "https://piefed.social/comment/3526458",
"inReplyTo": "https://piefed.social/post/317673",
"language": {
"identifier": "en",
"name": "English"
},
"mediaType": "text/html",
"published": "2024-11-09T03:55:50.533858+00:00",
"source": {
"content": "Good work! Much thanks to all contributors, you are appreciated. The site is running smooth and looking great.",
"mediaType": "text/markdown"
},
"to": [
"https://www.w3.org/ns/activitystreams#Public",
"https://piefed.social/u/rimu"
],
"type": "Note"
}
],
"searchableBy": "https://www.w3.org/ns/activitystreams#Public",
"sensitive": false,
"source": {
"content": "Key updates include the addition of community icons for better identification, a notification management interface, and various enhancements to our API for eventual mobile app support. Below is a detailed overview of the changes we've made.\r\n\r\n##Jeena\r\n\r\n- Community icon alongside name in post teaser. This helps differentiate between communities with the same name and adds visual interest.\r\n\r\n##Freamon\r\n\r\n- Added a notification management interface to manage notifications from all the communities and posts you are subscribed to - https://piefed.social/alerts\r\n- Soft deletion of comments, so they can be un-deleted again.\r\n- Lots of API work for the mobile app. Lots!\r\n\r\n#Rimu\r\n\r\n- Generate YouTube thumbnails more reliably.\r\n- Instance overview pages which make it easy to see posts and people from any instance. Start exploring at https://piefed.social/instances.\r\n- FEP-268d: Search consent signals for objects. This FEP is a convention for how instances can signal to other instances which posts should be searchable.\r\n- Track who deleted which posts, for accountability among moderators.\r\n- Refactoring to support API work by Freamon.\r\n- Automatically delete voting data older than 6 months (aggregated totals are unaffected). Voting data consumes gigabytes of space and it only meaningfully affects ranking of posts in the first few days. The only other reason to keep this data is for vote manipulation analysis and 6 months worth of data should be plenty.\r\n- Instances with open registrations automatically close registrations after one week of having no admins log in. This will avoid abandoned instances becoming a vector for spam or a home of trolls.\r\n- Show instance name after display name. If you notice undesirable patterns of behaviour associated with certain instances you can block the whole instance.\r\n- Improve visibility of user-level instance blocking functionality. This is separate and in addition to defederation which is controlled by admins.\r\n- Display PeerTube licence info on video posts. This could be rolled out to other post types in future?\r\n- Topics now have an option to show posts from communities that are in child topics. E.g. https://piefed.social/topic/arts-craft only has two communities in it so the number of posts shown there is very low. However it\u2019s child topics (Arts, Craft and Photography) have quite a few communities so to populate the top-level topic it makes sense to display posts from all the child topics too. https://piefed.social/topic/tech/programming is a similar case.\r\n\r\n\r\n--\r\n\r\nAs a free and open source project, PieFed receives no funding and developers are not paid. Any donations you can spare will help cover server and infrastructure costs - https://piefed.social/donate. Thanks!",
"mediaType": "text/markdown"
},
"stickied": false,
"tag": [
{
"href": "https://piefed.social/tag/fediverse",
"name": "#fediverse",
"type": "Hashtag"
},
{
"href": "https://piefed.social/tag/piefed",
"name": "#piefed",
"type": "Hashtag"
}
],
"to": [
"https://piefed.social/c/piefed_meta",
"https://www.w3.org/ns/activitystreams#Public"
],
"type": "Page"
},
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"type": "Create"
},
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"type": "Announce"
}
```

View file

@ -0,0 +1,351 @@
# Posts as ActivityPub Objects
Piefed has the following kinds of posts for communities.
## Discussion / Page
This is a discussion post on the web: https://piefed.social/post/342105
You can also see it represented as a `Page` object in .json format.
Run this curl command:
```bash
curl -H 'Accept: application/activity+json' https://piefed.social/post/342105
```
The result should look something like this:
```json
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"attachment": [],
"attributedTo": "https://jolly-piefed.jomandoa.net/u/jollyroberts",
"audience": "https://piefed.social/c/playground",
"cc": [],
"commentsEnabled": true,
"content": "<p>Example Discussion Post Body</p>\n",
"id": "https://jolly-piefed.jomandoa.net/post/79757",
"language": {
"identifier": "en",
"name": "English"
},
"mediaType": "text/html",
"name": "Example Discussion Post Title",
"published": "2024-11-24T22:18:50.230305+00:00",
"replies": [],
"sensitive": false,
"source": {
"content": "Example Discussion Post Body",
"mediaType": "text/markdown"
},
"stickied": false,
"tag": [
{
"href": "https://piefed.social/tag/tagone",
"name": "#tagone",
"type": "Hashtag"
},
{
"href": "https://piefed.social/tag/tagtwo",
"name": "#tagtwo",
"type": "Hashtag"
}
],
"to": [
"https://piefed.social/c/playground",
"https://www.w3.org/ns/activitystreams#Public"
],
"type": "Page"
}
```
## Link / Page
This is a link post on the web: https://piefed.social/post/342122
You can also see it represented as a `Page` object in .json format.
Run this curl command:
```bash
curl -H 'Accept: application/activity+json' https://piefed.social/post/342122
```
The result should look something like this:
```json
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"attachment": [
{
"href": "https://www.w3.org/TR/activitystreams-vocabulary",
"type": "Link"
}
],
"attributedTo": "https://jolly-piefed.jomandoa.net/u/jollyroberts",
"audience": "https://piefed.social/c/playground",
"cc": [],
"commentsEnabled": true,
"content": "<p>Example Link Post Body</p>\n",
"id": "https://jolly-piefed.jomandoa.net/post/79771",
"language": {
"identifier": "en",
"name": "English"
},
"mediaType": "text/html",
"name": "Example Link Post Title",
"published": "2024-11-24T22:34:56.000879+00:00",
"replies": [],
"sensitive": false,
"source": {
"content": "Example Link Post Body",
"mediaType": "text/markdown"
},
"stickied": false,
"tag": [
{
"href": "https://piefed.social/tag/tagone",
"name": "#tagone",
"type": "Hashtag"
},
{
"href": "https://piefed.social/tag/tagtwo",
"name": "#tagtwo",
"type": "Hashtag"
}
],
"to": [
"https://piefed.social/c/playground",
"https://www.w3.org/ns/activitystreams#Public"
],
"type": "Page"
}
```
## Image / Page
This is a image post on the web: https://piefed.social/post/342166
You can also see it represented as a `Page` object in .json format.
Run this curl command:
```bash
curl -H 'Accept: application/activity+json' https://piefed.social/post/342166
```
The result should look something like this:
```json
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"attachment": [
{
"name": "a painting of a crystal flower, AI art, stable diffusion",
"type": "Image",
"url": "https://jolly-piefed.jomandoa.net/static/media/posts/Ef/lI/EflI4MtZdsQDOUP.png"
}
],
"attributedTo": "https://jolly-piefed.jomandoa.net/u/jollyroberts",
"audience": "https://piefed.social/c/playground",
"cc": [],
"commentsEnabled": true,
"content": "<p>Example Image Post Body</p>\n",
"id": "https://jolly-piefed.jomandoa.net/post/79799",
"image": {
"type": "Image",
"url": "https://jolly-piefed.jomandoa.net/static/media/posts/Ef/lI/EflI4MtZdsQDOUP.png"
},
"language": {
"identifier": "en",
"name": "English"
},
"mediaType": "text/html",
"name": "Example Image Post Title",
"published": "2024-11-24T23:19:37.419801+00:00",
"replies": [],
"sensitive": false,
"source": {
"content": "Example Image Post Body",
"mediaType": "text/markdown"
},
"stickied": false,
"tag": [],
"to": [
"https://piefed.social/c/playground",
"https://www.w3.org/ns/activitystreams#Public"
],
"type": "Page"
}
```
## Video / Page
This is a video post on the web: https://piefed.social/post/276328
You can also see it represented as a `Page` object in .json format.
Run this curl command:
```bash
curl -H 'Accept: application/activity+json' https://piefed.social/post/276328
```
The result should look something like this:
```json
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"attachment": [
{
"href": "https://files.catbox.moe/swf46b.mp4",
"type": "Link"
}
],
"attributedTo": "https://piefed.social/u/Binzy_Boi",
"audience": "https://piefed.social/c/playground",
"cc": [],
"commentsEnabled": true,
"content": "",
"id": "https://piefed.social/post/276328",
"image": {
"type": "Image",
"url": "https://files.catbox.moe/swf46b.mp4"
},
"language": {
"identifier": "en",
"name": "English"
},
"mediaType": "text/html",
"name": "Video post test 3",
"published": "2024-10-14T00:03:41.660107+00:00",
"replies": [],
"sensitive": false,
"source": {
"content": "",
"mediaType": "text/markdown"
},
"stickied": false,
"tag": [],
"to": [
"https://piefed.social/c/playground",
"https://www.w3.org/ns/activitystreams#Public"
],
"type": "Page"
}
```
## Poll / Question
This is a poll post on the web: https://piefed.social/post/341021
You can also see it represented as a `Question` object in .json format.
Run this curl command:
```bash
curl -H 'Accept: application/activity+json' https://piefed.social/post/341021
```
The result should look something like this:
```json
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"attachment": [],
"attributedTo": "https://jolly-piefed.jomandoa.net/u/jollyroberts",
"audience": "https://piefed.social/c/playground",
"cc": [],
"commentsEnabled": true,
"content": "<p>this is the poll post body</p>\n",
"endTime": "2024-11-27T00:47:11.362544+00:00",
"id": "https://jolly-piefed.jomandoa.net/post/79247",
"language": {
"identifier": "en",
"name": "English"
},
"mediaType": "text/html",
"name": "Poll Post Test",
"oneOf": [
{
"name": "Yes",
"replies": {
"totalItems": 2,
"type": "Collection"
},
"type": "Note"
},
{
"name": "No",
"replies": {
"totalItems": 0,
"type": "Collection"
},
"type": "Note"
},
{
"name": "Maybe",
"replies": {
"totalItems": 0,
"type": "Collection"
},
"type": "Note"
}
],
"published": "2024-11-24T00:47:11.789789+00:00",
"replies": [
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"attributedTo": "https://hub.netzgemeinde.eu/channel/jupiter_rowland",
"audience": "https://piefed.social/c/playground",
"cc": [
"https://piefed.social/c/playground",
"https://hub.netzgemeinde.eu/followers/jupiter_rowland"
],
"content": "<p></p>",
"distinguished": false,
"id": "https://hub.netzgemeinde.eu/item/73970039-849a-458e-b994-3014482fe0e9",
"inReplyTo": "https://jolly-piefed.jomandoa.net/post/79247",
"language": {
"identifier": "en",
"name": "English"
},
"mediaType": "text/html",
"published": "2024-11-24T08:22:25.906356+00:00",
"source": {
"content": "",
"mediaType": "text/markdown"
},
"to": [
"https://www.w3.org/ns/activitystreams#Public",
"https://jolly-piefed.jomandoa.net/u/jollyroberts"
],
"type": "Note"
}
],
"sensitive": false,
"source": {
"content": "this is the poll post body",
"mediaType": "text/markdown"
},
"stickied": false,
"tag": [],
"to": [
"https://piefed.social/c/playground",
"https://www.w3.org/ns/activitystreams#Public"
],
"type": "Question",
"votersCount": 2
}
```

View file

@ -0,0 +1,57 @@
# Users as ActivityPub 'Person' Actors
Users on the fediverse are [Person](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-person) actors.
## User objects as JSON
Server-to-server or server-to-client traffic that represents Users are sent as .json. I.e. when a remote server wishes to find out information about your user account on your local server, the remote server will be sent that data in a json payload.
### Getting user information
Piefed internally keeps track of users in a database, but you can query the information from the server as .json. There are many ways to do so, but here is an example using `curl`.
We will use the https://piefed.social flagship instance in the example. We will ask for information about the `rimu` user, PieFeds main developer.
Run this curl command:
```bash
curl -H 'Accept: application/activity+json' https://piefed.social/u/rimu
```
The result should look something like this:
```json
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"discoverable": true,
"endpoints": {
"sharedInbox": "https://piefed.social/inbox"
},
"icon": {
"type": "Image",
"url": "https://piefed.social/static/media/users/oW/FB/oWFBklQomqpBX52.jpg"
},
"id": "https://piefed.social/u/rimu",
"inbox": "https://piefed.social/u/rimu/inbox",
"indexable": true,
"manuallyApprovesFollowers": false,
"matrixUserId": "@rimuatkinson:matrix.org",
"name": "Rimu",
"outbox": "https://piefed.social/u/rimu/outbox",
"preferredUsername": "rimu",
"publicKey": {
"id": "https://piefed.social/u/rimu#main-key",
"owner": "https://piefed.social/u/rimu",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA165M8pQFvf7YY08Yt9pM\nC7CAf9nW/Xy16dk65pIsdKZ42Le1eQrJ6vEplbFdeO7WJkF89liSBnSnYhdfKCId\nGg1hD5rDjKNHgvNPNWHh2y4KXGgkZ2ry6uxk1h4iAu+zJbQ7l2gUHscalY1/wtOz\naRPGKdhN6A49VShjujTHBV3ZxieddC60AjF5m/CHeNg0PXCdfvdqniOp9m33+2bF\nEYnyV4IbreBg24tmmxWAjEaH0NntCh/5KhLz3YZcqQnrmC5QNNk5K1yeeEDMukOd\nK+tT0khsudgcfC26iBdzyKUNXkKOwSP1ivBSPEFxMKqJvL0BKhjtm8WjQMJhZVOM\nrwIDAQAB\n-----END PUBLIC KEY-----\n"
},
"published": "2024-01-04T03:12:32.116738+00:00",
"source": {
"content": "Developer of [PieFed](https://piefed.social), a sibling of Lemmy & Kbin.",
"mediaType": "text/markdown"
},
"summary": "<p>Developer of <a href=\"https://piefed.social\" rel=\"nofollow ugc\" target=\"_blank\">PieFed</a>, a sibling of Lemmy &amp; Kbin.</p>\n",
"type": "Person"
}
```