WIP: Create apub_inbox crate #8

Draft
steffo wants to merge 26 commits from feature/apub-inbox into main
186 changed files with 2397 additions and 23 deletions

View file

@ -11,7 +11,10 @@
<sourceFolder url="file://$MODULE_DIR$/acrate_rd/tests" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/acrate_rd/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/acrate_mime/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/acrate_mime/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/acrate_rdserver/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/acrate_rdserver/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/acrate_apub_inbox/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/acrate_database/tests" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/acrate_database/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/acrate_astreams/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/acrate_astreams/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/acrate_utils/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/acrate_utils/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" /> <excludeFolder url="file://$MODULE_DIR$/target" />
</content> </content>

View file

@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Check" type="CargoCommandRunConfiguration" factoryName="Cargo Command" nameIsGenerated="true"> <configuration default="false" name="Check" type="CargoCommandRunConfiguration" factoryName="Cargo Command" folderName="Validate" nameIsGenerated="true">
<option name="buildProfileId" value="dev" /> <option name="buildProfileId" value="dev" />
<option name="command" value="check" /> <option name="command" value="check" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" /> <option name="workingDirectory" value="file://$PROJECT_DIR$" />

View file

@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Clippy" type="CargoCommandRunConfiguration" factoryName="Cargo Command"> <configuration default="false" name="Clippy" type="CargoCommandRunConfiguration" factoryName="Cargo Command" folderName="Validate">
<option name="buildProfileId" value="dev" /> <option name="buildProfileId" value="dev" />
<option name="command" value="clippy" /> <option name="command" value="clippy" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" /> <option name="workingDirectory" value="file://$PROJECT_DIR$" />

View file

@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test" type="CargoCommandRunConfiguration" factoryName="Cargo Command"> <configuration default="false" name="Test" type="CargoCommandRunConfiguration" factoryName="Cargo Command" folderName="Test">
<option name="buildProfileId" value="dev" /> <option name="buildProfileId" value="dev" />
<option name="command" value="test" /> <option name="command" value="test" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" /> <option name="workingDirectory" value="file://$PROJECT_DIR$" />

View file

@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test ignored" type="CargoCommandRunConfiguration" factoryName="Cargo Command"> <configuration default="false" name="Test ignored" type="CargoCommandRunConfiguration" factoryName="Cargo Command" folderName="Test">
<option name="buildProfileId" value="dev" /> <option name="buildProfileId" value="dev" />
<option name="command" value="test -- --ignored" /> <option name="command" value="test -- --ignored" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" /> <option name="workingDirectory" value="file://$PROJECT_DIR$" />

View file

@ -1,3 +1,3 @@
[workspace] [workspace]
resolver = "2" resolver = "2"
members = ["acrate_database", "acrate_rd", "acrate_nodeinfo", "acrate_rdserver", "acrate_utils"] members = ["acrate_database", "acrate_rd", "acrate_nodeinfo", "acrate_rdserver", "acrate_apub_inbox", "acrate_astreams", "acrate_utils"]

View file

@ -27,6 +27,7 @@ Federation database
### Binaries ### Binaries
- `acrate_rdserver`: Resource descriptor web server - `acrate_rdserver`: Resource descriptor web server
- `acrate_apub_inbox`: ActivityPub inbox web server
### Extra ### Extra

View file

@ -0,0 +1,27 @@
[package]
name = "acrate_apub_inbox"
version = "0.3.0"
authors = ["Stefano Pigozzi <me@steffo.eu>"]
edition = "2021"
description = "ActivityPub inbox web server for the acrate project"
repository = "https://forge.steffo.eu/unimore/tirocinio-canali-steffo-acrate"
license = "EUPL-1.2"
keywords = ["activitypub", "apub", "federation"]
categories = ["web-programming"]
[dependencies]
acrate_database = { path = "../acrate_database", features = ["connect"] }
acrate_utils = { path = "../acrate_utils" }
anyhow = "1.0.93"
axum = { version = "0.7.7", features = ["macros"] }
log = { version = "0.4.22", features = ["std", "max_level_trace", "release_max_level_debug"] }
micronfig = "0.3.0"
minijinja = "2.5.0"
pretty_env_logger = "0.5.0"
serde = { version = "1.0.215", features = ["derive"] }
serde_json = "1.0.132"
tokio = { version = "1.41.1", features = ["macros", "net", "rt-multi-thread"] }
mediatype = { version = "0.19.18", features = ["serde"] }
[lints.clippy]
tabs-in-doc-comments = "allow"

View file

@ -0,0 +1,3 @@
micronfig::config!(
ACRATE_APUB_INBOX_BIND_ADDRESS: String > std::net::SocketAddr,
);

View file

@ -0,0 +1,18 @@
use axum::routing::{get, post};
use acrate_utils::web_server;
mod config;
mod route;
#[tokio::main]
async fn main() {
web_server!(
on: *config::ACRATE_APUB_INBOX_BIND_ADDRESS(),
templates: [ ],
routes: {
"/inbox" => post(route::inbox_handler),
"/.healthcheck" => get(route::healthcheck_handler)
}
);
}

View file

@ -0,0 +1,23 @@
use axum::http::{Response, StatusCode};
use acrate_database::connect::connect_async;
pub async fn healthcheck_handler() -> Result<StatusCode, StatusCode> {
log::debug!("Handling an healthcheck request!");
log::trace!("Making sure the database is up...");
let _conn = connect_async()
.await
.map_err(|_| StatusCode::BAD_GATEWAY)?;
log::trace!("Healthcheck successful! Everything's fine!");
Ok(StatusCode::NO_CONTENT)
}
pub async fn inbox_handler() -> Result<Response<String>, StatusCode> {
log::debug!("Handling an inbox request!");
log::trace!("Creating a blank response...");
let mut response = Response::new("".to_string());
Ok(response)
}

View file

@ -0,0 +1,24 @@
[package]
name = "acrate_astreams"
version = "0.3.0"
authors = ["Stefano Pigozzi <me@steffo.eu>"]
edition = "2021"
description = "ActivityStreams definitions and utilities"
repository = "https://forge.steffo.eu/unimore/tirocinio-canali-steffo-acrate"
license = "EUPL-1.2"
keywords = ["activitypub", "activitystreams", "federation", "apub", "astreams"]
categories = ["web-programming"]
[dependencies]
iref = "3.2.2"
json-ld = { version = "0.21.1", features = ["serde", "reqwest"] }
log = "0.4.22"
serde = { version = "1.0.214", features = ["derive"] }
serde_json = "1.0.132"
static-iref = "3.0.0"
thiserror = "2.0.3"
[dev-dependencies]
tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread"] }
tokio-test = "0.4.4"

View file

@ -0,0 +1,6 @@
//! Struct definitions for ActivityStreams Core and Extended Types.
//!
//! # Specification
//!
//! - <https://www.w3.org/TR/activitystreams-vocabulary/>
//!

View file

@ -0,0 +1,6 @@
//! Struct definitions for Lemmy's Extension Types.
//!
//! # Specification
//!
//! - <https://join-lemmy.org/docs/contributors/05-federation.html>
//!

View file

@ -0,0 +1,6 @@
pub mod activitystreams;
pub mod mastodon;
pub mod miajetzt;
pub mod litepub;
pub mod lemmy;

View file

@ -0,0 +1,6 @@
//! Struct definitions for Pleroma and Akkoma's Extension Types.
//!
//! # Specification
//!
//! - <https://docs.akkoma.dev/develop/development/ap_extensions/>
//!

View file

@ -0,0 +1,6 @@
//! Struct definitions for Mastodon's Extension Types.
//!
//! # Specification
//!
//! - <https://docs.joinmastodon.org/spec/activitypub/#contexts>
//!

View file

@ -0,0 +1,6 @@
//! Struct definitions for mia's Extension Types.
//!
//! # Specification
//!
//! - <https://ns.mia.jetzt/as/>
//!

View file

@ -0,0 +1,6 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Object",
"id": "http://www.test.example/object/1",
"name": "A Simple, non-specific object"
}

View file

@ -0,0 +1,17 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally accepted Joe into the club",
"type": "Accept",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": {
"type": "Person",
"name": "Joe"
},
"target": {
"type": "Group",
"name": "The Club"
}
}

View file

@ -0,0 +1,11 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Page 1 of Sally's blog posts",
"type": "CollectionPage",
"prev": "http://example.org/collection?page=1",
"items": [
"http://example.org/posts/1",
"http://example.org/posts/2",
"http://example.org/posts/3"
]
}

View file

@ -0,0 +1,16 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Page 1 of Sally's blog posts",
"type": "CollectionPage",
"prev": {
"type": "Link",
"name": "Previous Page",
"href": "http://example.org/collection?page=1"
},
"items": [
"http://example.org/posts/1",
"http://example.org/posts/2",
"http://example.org/posts/3"
]
}

View file

@ -0,0 +1,16 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Video",
"name": "Cool New Movie",
"duration": "PT2H30M",
"preview": {
"type": "Video",
"name": "Trailer",
"duration": "PT1M",
"url": {
"href": "http://example.org/trailer.mkv",
"mediaType": "video/mkv"
}
}
}

View file

@ -0,0 +1,11 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally checked that her flight was on time",
"type": ["Activity", "http://www.verbs.example/Check"],
"actor": "http://sally.example.org",
"object": "http://example.org/flights/1",
"result": {
"type": "http://www.types.example/flightstatus",
"name": "On Time"
}
}

View file

@ -0,0 +1,19 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "A simple note",
"type": "Note",
"id": "http://www.test.example/notes/1",
"content": "I am fine.",
"replies": {
"type": "Collection",
"totalItems": 1,
"items": [
{
"summary": "A response to the note",
"type": "Note",
"content": "I am glad to hear it.",
"inReplyTo": "http://www.test.example/notes/1"
}
]
}
}

View file

@ -0,0 +1,13 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Image",
"summary": "Picture of Sally",
"url": "http://example.org/sally.jpg",
"tag": [
{
"type": "Person",
"id": "http://sally.example.org",
"name": "Sally"
}
]
}

View file

@ -0,0 +1,9 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally offered the post to John",
"type": "Offer",
"actor": "http://sally.example.org",
"object": "http://example.org/posts/1",
"target": "http://john.example.org"
}

View file

@ -0,0 +1,12 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally offered the post to John",
"type": "Offer",
"actor": "http://sally.example.org",
"object": "http://example.org/posts/1",
"target": {
"type": "Person",
"name": "John"
}
}

View file

@ -0,0 +1,9 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally offered the post to John",
"type": "Offer",
"actor": "http://sally.example.org",
"object": "http://example.org/posts/1",
"target": "http://john.example.org",
"to": [ "http://joe.example.org" ]
}

View file

@ -0,0 +1,6 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Document",
"name": "4Q Sales Forecast",
"url": "http://example.org/4q-sales-forecast.pdf"
}

View file

@ -0,0 +1,17 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally tentatively accepted an invitation to a party",
"type": "TentativeAccept",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": {
"type": "Invite",
"actor": "http://john.example.org",
"object": {
"type": "Event",
"name": "Going-Away Party for Jim"
}
}
}

View file

@ -0,0 +1,10 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Document",
"name": "4Q Sales Forecast",
"url": {
"type": "Link",
"href": "http://example.org/4q-sales-forecast.pdf"
}
}

View file

@ -0,0 +1,17 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Document",
"name": "4Q Sales Forecast",
"url": [
{
"type": "Link",
"href": "http://example.org/4q-sales-forecast.pdf",
"mediaType": "application/pdf"
},
{
"type": "Link",
"href": "http://example.org/4q-sales-forecast.html",
"mediaType": "text/html"
}
]
}

View file

@ -0,0 +1,8 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"name": "Liu Gu Lu Cun, Pingdu, Qingdao, Shandong, China",
"type": "Place",
"latitude": 36.75,
"longitude": 119.7667,
"accuracy": 94.5
}

View file

@ -0,0 +1,9 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Place",
"name": "Fresno Area",
"altitude": 15.0,
"latitude": 36.75,
"longitude": 119.7667,
"units": "miles"
}

View file

@ -0,0 +1,6 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "A simple note",
"type": "Note",
"content": "A <em>simple</em> note"
}

View file

@ -0,0 +1,10 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "A simple note",
"type": "Note",
"contentMap": {
"en": "A <em>simple</em> note",
"es": "Una nota <em>sencilla</em>",
"zh-Hans": "一段<em>简单的</em>笔记"
}
}

View file

@ -0,0 +1,7 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "A simple note",
"type": "Note",
"mediaType": "text/markdown",
"content": "## A simple note\nA simple markdown `note`"
}

View file

@ -0,0 +1,5 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Note",
"name": "A simple note"
}

View file

@ -0,0 +1,9 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Note",
"nameMap": {
"en": "A simple note",
"es": "Una nota sencilla",
"zh-Hans": "一段简单的笔记"
}
}

View file

@ -0,0 +1,7 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Video",
"name": "Birds Flying",
"url": "http://example.org/video.mkv",
"duration": "PT2H"
}

View file

@ -0,0 +1,10 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally added an object",
"type": "Add",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": "http://example.org/abc"
}

View file

@ -0,0 +1,7 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Link",
"href": "http://example.org/image.png",
"height": 100,
"width": 100
}

View file

@ -0,0 +1,7 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Link",
"href": "http://example.org/abc",
"mediaType": "text/html",
"name": "Previous"
}

View file

@ -0,0 +1,8 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Link",
"href": "http://example.org/abc",
"hreflang": "en",
"mediaType": "text/html",
"name": "Previous"
}

View file

@ -0,0 +1,17 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Page 1 of Sally's notes",
"type": "CollectionPage",
"id": "http://example.org/collection?page=1",
"partOf": "http://example.org/collection",
"items": [
{
"type": "Note",
"name": "Pizza Toppings to Try"
},
{
"type": "Note",
"name": "Thought about California"
}
]
}

View file

@ -0,0 +1,9 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Place",
"name": "Fresno Area",
"latitude": 36.75,
"longitude": 119.7667,
"radius": 15,
"units": "miles"
}

View file

@ -0,0 +1,9 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Place",
"name": "Fresno Area",
"latitude": 36.75,
"longitude": 119.7667,
"radius": 15,
"units": "miles"
}

View file

@ -0,0 +1,8 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Link",
"href": "http://example.org/abc",
"hreflang": "en",
"mediaType": "text/html",
"name": "Next"
}

View file

@ -0,0 +1,7 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Event",
"name": "Going-Away Party for Jim",
"startTime": "2014-12-31T23:00:00-08:00",
"endTime": "2015-01-01T06:00:00-08:00"
}

View file

@ -0,0 +1,7 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "A simple note",
"type": "Note",
"content": "Fish swim.",
"published": "2014-12-12T12:12:12Z"
}

View file

@ -0,0 +1,8 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Event",
"name": "Going-Away Party for Jim",
"startTime": "2014-12-31T23:00:00-08:00",
"endTime": "2015-01-01T06:00:00-08:00"
}

View file

@ -0,0 +1,22 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally added a picture of her cat to her cat picture collection",
"type": "Add",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": {
"type": "Image",
"name": "A picture of my cat",
"url": "http://example.org/img/cat.png"
},
"origin": {
"type": "Collection",
"name": "Camera Roll"
},
"target": {
"type": "Collection",
"name": "My Cat Pictures"
}
}

View file

@ -0,0 +1,9 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Place",
"name": "Fresno Area",
"latitude": 36.75,
"longitude": 119.7667,
"radius": 15,
"units": "miles"
}

View file

@ -0,0 +1,9 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Link",
"href": "http://example.org/abc",
"hreflang": "en",
"mediaType": "text/html",
"name": "Preview",
"rel": ["canonical", "preview"]
}

View file

@ -0,0 +1,16 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Page 1 of Sally's notes",
"type": "OrderedCollectionPage",
"startIndex": 0,
"orderedItems": [
{
"type": "Note",
"name": "Density of Water"
},
{
"type": "Note",
"name": "Air Mattress Idea"
}
]
}

View file

@ -0,0 +1,6 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"name": "Cane Sugar Processing",
"type": "Note",
"summary": "A simple <em>note</em>"
}

View file

@ -0,0 +1,10 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"name": "Cane Sugar Processing",
"type": "Note",
"summaryMap": {
"en": "A simple <em>note</em>",
"es": "Una <em>nota</em> sencilla",
"zh-Hans": "一段<em>简单的</em>笔记"
}
}

View file

@ -0,0 +1,16 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally's notes",
"type": "Collection",
"totalItems": 2,
"items": [
{
"type": "Note",
"name": "Which Staircase Should I Use"
},
{
"type": "Note",
"name": "Something to Remember"
}
]
}

View file

@ -0,0 +1,9 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Place",
"name": "Fresno Area",
"latitude": 36.75,
"longitude": 119.7667,
"radius": 15,
"units": "miles"
}

View file

@ -0,0 +1,7 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"name": "Cranberry Sauce Idea",
"type": "Note",
"content": "Mush it up so it does not have the same shape as the can.",
"updated": "2014-12-12T12:12:12Z"
}

View file

@ -0,0 +1,7 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Link",
"href": "http://example.org/image.png",
"height": 100,
"width": 100
}

View file

@ -0,0 +1,14 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally is an acquaintance of John's",
"type": "Relationship",
"subject": {
"type": "Person",
"name": "Sally"
},
"relationship": "http://purl.org/vocab/relationship/acquaintanceOf",
"object": {
"type": "Person",
"name": "John"
}
}

View file

@ -0,0 +1,17 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally arrived at work",
"type": "Arrive",
"actor": {
"type": "Person",
"name": "Sally"
},
"location": {
"type": "Place",
"name": "Work"
},
"origin": {
"type": "Place",
"name": "Home"
}
}

View file

@ -0,0 +1,14 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally is an acquaintance of John's",
"type": "Relationship",
"subject": {
"type": "Person",
"name": "Sally"
},
"relationship": "http://purl.org/vocab/relationship/acquaintanceOf",
"object": {
"type": "Person",
"name": "John"
}
}

View file

@ -0,0 +1,11 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally's profile",
"type": "Profile",
"describes": {
"type": "Person",
"name": "Sally"
},
"url": "http://sally.example.org"
}

View file

@ -0,0 +1,7 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "This image has been deleted",
"type": "Tombstone",
"formerType": "Image",
"url": "http://example.org/image/2"
}

View file

@ -0,0 +1,6 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "This image has been deleted",
"type": "Tombstone",
"deleted": "2016-05-03T00:00:00Z"
}

View file

@ -0,0 +1,44 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Activities in Project XYZ",
"type": "Collection",
"items": [
{
"summary": "Sally created a note",
"type": "Create",
"id": "http://activities.example.com/1",
"actor": "http://sally.example.org",
"object": {
"summary": "A note",
"type": "Note",
"id": "http://notes.example.com/1",
"content": "A note"
},
"context": {
"type": "http://example.org/Project",
"name": "Project XYZ"
},
"audience": {
"type": "Group",
"name": "Project XYZ Working Group"
},
"to": "http://john.example.org"
},
{
"summary": "John liked Sally's note",
"type": "Like",
"id": "http://activities.example.com/1",
"actor": "http://john.example.org",
"object": "http://notes.example.com/1",
"context": {
"type": "http://example.org/Project",
"name": "Project XYZ"
},
"audience": {
"type": "Group",
"name": "Project XYZ Working Group"
},
"to": "http://sally.example.org"
}
]
}

View file

@ -0,0 +1,33 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally's friends list",
"type": "Collection",
"items": [
{
"summary": "Sally is influenced by Joe",
"type": "Relationship",
"subject": {
"type": "Person",
"name": "Sally"
},
"relationship": "http://purl.org/vocab/relationship/influencedBy",
"object": {
"type": "Person",
"name": "Joe"
}
},
{
"summary": "Sally is a friend of Jane",
"type": "Relationship",
"subject": {
"type": "Person",
"name": "Sally"
},
"relationship": "http://purl.org/vocab/relationship/friendOf",
"object": {
"type": "Person",
"name": "Jane"
}
}
]
}

View file

@ -0,0 +1,13 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally became a friend of Matt",
"type": "Create",
"actor": "http://sally.example.org",
"object": {
"type": "Relationship",
"subject": "http://sally.example.org",
"relationship": "http://purl.org/vocab/relationship/friendOf",
"object": "http://matt.example.org",
"startTime": "2015-04-21T12:34:56"
}
}

View file

@ -0,0 +1,17 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "http://example.org/connection-requests/123",
"summary": "Sally requested to be a friend of John",
"type": "Offer",
"actor": "acct:sally@example.org",
"object": {
"summary": "Sally and John's friendship",
"id": "http://example.org/connections/123",
"type": "Relationship",
"subject": "acct:sally@example.org",
"relationship": "http://purl.org/vocab/relationship/friendOf",
"object": "acct:john@example.org"
},
"target": "acct:john@example.org"
}

View file

@ -0,0 +1,62 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally and John's relationship history",
"type": "Collection",
"items": [
{
"summary": "John accepted Sally's friend request",
"id": "http://example.org/activities/122",
"type": "Accept",
"actor": "acct:john@example.org",
"object": "http://example.org/connection-requests/123",
"inReplyTo": "http://example.org/connection-requests/123",
"context": "http://example.org/connections/123",
"result": [
"http://example.org/activities/123",
"http://example.org/activities/124",
"http://example.org/activities/125",
"http://example.org/activities/126"
]
},
{
"summary": "John followed Sally",
"id": "http://example.org/activities/123",
"type": "Follow",
"actor": "acct:john@example.org",
"object": "acct:sally@example.org",
"context": "http://example.org/connections/123"
},
{
"summary": "Sally followed John",
"id": "http://example.org/activities/124",
"type": "Follow",
"actor": "acct:sally@example.org",
"object": "acct:john@example.org",
"context": "http://example.org/connections/123"
},
{
"summary": "John added Sally to his friends list",
"id": "http://example.org/activities/125",
"type": "Add",
"actor": "acct:john@example.org",
"object": "http://example.org/connections/123",
"target": {
"type": "Collection",
"summary": "John's Connections"
},
"context": "http://example.org/connections/123"
},
{
"summary": "Sally added John to her friends list",
"id": "http://example.org/activities/126",
"type": "Add",
"actor": "acct:sally@example.org",
"object": "http://example.org/connections/123",
"target": {
"type": "Collection",
"summary": "Sally's Connections"
},
"context": "http://example.org/connections/123"
}
]
}

View file

@ -0,0 +1,5 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Place",
"name": "San Francisco, CA"
}

View file

@ -0,0 +1,14 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally created a note",
"type": "Create",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": {
"type": "Note",
"name": "A Simple Note",
"content": "This is a simple note"
}
}

View file

@ -0,0 +1,8 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Place",
"name": "San Francisco, CA",
"longitude": "122.4167",
"latitude": "37.7833"
}

View file

@ -0,0 +1,8 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"name": "A question about robots",
"id": "http://help.example.org/question/1",
"type": "Question",
"content": "I'd like to build a robot to feed my cat. Should I use Arduino or Raspberry Pi?"
}

View file

@ -0,0 +1,11 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "http://polls.example.org/question/1",
"name": "A question about robots",
"type": "Question",
"content": "I'd like to build a robot to feed my cat. Which platform is best?",
"oneOf": [
{"name": "arduino"},
{"name": "raspberry pi"}
]
}

View file

@ -0,0 +1,6 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"attributedTo": "http://sally.example.org",
"inReplyTo": "http://polls.example.org/question/1",
"name": "arduino"
}

View file

@ -0,0 +1,36 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"name": "A question about robots",
"id": "http://polls.example.org/question/1",
"type": "Question",
"content": "I'd like to build a robot to feed my cat. Which platform is best?",
"oneOf": [
{"name": "arduino"},
{"name": "raspberry pi"}
],
"replies": {
"type": "Collection",
"totalItems": 3,
"items": [
{
"attributedTo": "http://sally.example.org",
"inReplyTo": "http://polls.example.org/question/1",
"name": "arduino"
},
{
"attributedTo": "http://joe.example.org",
"inReplyTo": "http://polls.example.org/question/1",
"name": "arduino"
},
{
"attributedTo": "http://john.example.org",
"inReplyTo": "http://polls.example.org/question/1",
"name": "raspberry pi"
}
]
},
"result": {
"type": "Note",
"content": "Users are favoriting &quot;arduino&quot; by a 33% margin."
}
}

View file

@ -0,0 +1,35 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "History of John's note",
"type": "Collection",
"items": [
{
"summary": "Sally liked John's note",
"type": "Like",
"actor": "http://sally.example.org",
"id": "http://activities.example.com/1",
"published": "2015-11-12T12:34:56Z",
"object": {
"summary": "John's note",
"type": "Note",
"id": "http://notes.example.com/1",
"attributedTo": "http://john.example.org",
"content": "My note"
}
},
{
"summary": "Sally disliked John's note",
"type": "Dislike",
"actor": "http://sally.example.org",
"id": "http://activities.example.com/2",
"published": "2015-12-11T21:43:56Z",
"object": {
"summary": "John's note",
"type": "Note",
"id": "http://notes.example.com/1",
"attributedTo": "http://john.example.org",
"content": "My note"
}
}
]
}

View file

@ -0,0 +1,29 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "History of John's note",
"type": "Collection",
"items": [
{
"summary": "Sally liked John's note",
"type": "Like",
"id": "http://activities.example.com/1",
"actor": "http://sally.example.org",
"published": "2015-11-12T12:34:56Z",
"object": {
"summary": "John's note",
"type": "Note",
"id": "http://notes.example.com/1",
"attributedTo": "http://john.example.org",
"content": "My note"
}
},
{
"summary": "Sally no longer likes John's note",
"type": "Undo",
"id": "http://activities.example.com/2",
"actor": "http://sally.example.org",
"published": "2015-12-11T21:43:56Z",
"object": "http://activities.example.com/1"
}
]
}

View file

@ -0,0 +1,17 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"name": "A thank-you note",
"type": "Note",
"content": "Thank you <a href='http://sally.example.org'>@sally</a>
for all your hard work!
<a href='http://example.org/tags/givingthanks'>#givingthanks</a>",
"to": {
"name": "Sally",
"type": "Person",
"id": "http://sally.example.org"
},
"tag": {
"id": "http://example.org/tags/givingthanks",
"name": "#givingthanks"
}
}

View file

@ -0,0 +1,17 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"name": "A thank-you note",
"type": "Note",
"content": "Thank you @sally for all your hard work! #givingthanks",
"tag": [
{
"type": "Mention",
"href": "http://example.org/people/sally",
"name": "@sally"
},
{
"id": "http://example.org/tags/givingthanks",
"name": "#givingthanks"
}
]
}

View file

@ -0,0 +1,18 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally moved the sales figures from Folder A to Folder B",
"type": "Move",
"actor": "http://sally.example.org",
"object": {
"type": "Document",
"name": "sales figures"
},
"origin": {
"type": "Collection",
"name": "Folder A"
},
"target": {
"type": "Collection",
"name": "Folder B"
}
}

View file

@ -0,0 +1,14 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally deleted a note",
"type": "Delete",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": "http://example.org/notes/1",
"origin": {
"type": "Collection",
"name": "Sally's Notes"
}
}

View file

@ -0,0 +1,13 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally followed John",
"type": "Follow",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": {
"type": "Person",
"name": "John"
}
}

View file

@ -0,0 +1,10 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally ignored a note",
"type": "Ignore",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": "http://example.org/notes/1"
}

View file

@ -0,0 +1,13 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally joined a group",
"type": "Join",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": {
"type": "Group",
"name": "A Simple Group"
}
}

View file

@ -0,0 +1,8 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Link",
"href": "http://example.org/abc",
"hreflang": "en",
"mediaType": "text/html",
"name": "An example link"
}

View file

@ -0,0 +1,13 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally left work",
"type": "Leave",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": {
"type": "Place",
"name": "Work"
}
}

View file

@ -0,0 +1,13 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally left a group",
"type": "Leave",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": {
"type": "Group",
"name": "A Simple Group"
}
}

View file

@ -0,0 +1,10 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally liked a note",
"type": "Like",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": "http://example.org/notes/1"
}

View file

@ -0,0 +1,17 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally offered 50% off to Lewis",
"type": "Offer",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": {
"type": "http://www.types.example/ProductOffer",
"name": "50% Off!"
},
"target": {
"type": "Person",
"name": "Lewis"
}
}

View file

@ -0,0 +1,23 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally invited John and Lisa to a party",
"type": "Invite",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": {
"type": "Event",
"name": "A Party"
},
"target": [
{
"type": "Person",
"name": "John"
},
{
"type": "Person",
"name": "Lisa"
}
]
}

View file

@ -0,0 +1,18 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally rejected an invitation to a party",
"type": "Reject",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": {
"type": "Invite",
"actor": "http://john.example.org",
"object": {
"type": "Event",
"name": "Going-Away Party for Jim"
}
}
}

View file

@ -0,0 +1,18 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally tentatively rejected an invitation to a party",
"type": "TentativeReject",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": {
"type": "Invite",
"actor": "http://john.example.org",
"object": {
"type": "Event",
"name": "Going-Away Party for Jim"
}
}
}

View file

@ -0,0 +1,14 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally removed a note from her notes folder",
"type": "Remove",
"actor": {
"type": "Person",
"name": "Sally"
},
"object": "http://example.org/notes/1",
"target": {
"type": "Collection",
"name": "Notes Folder"
}
}

View file

@ -0,0 +1,17 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "The moderator removed Sally from a group",
"type": "Remove",
"actor": {
"type": "http://example.org/Role",
"name": "The Moderator"
},
"object": {
"type": "Person",
"name": "Sally"
},
"origin": {
"type": "Group",
"name": "A Simple Group"
}
}

View file

@ -0,0 +1,13 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Sally retracted her offer to John",
"type": "Undo",
"actor": "http://sally.example.org",
"object": {
"type": "Offer",
"actor": "http://sally.example.org",
"object": "http://example.org/posts/1",
"target": "http://john.example.org"
}
}

Some files were not shown because too many files have changed in this diff Show more