docker run --name postgres \
-e POSTGRES_PASSWORD=password \
-d postgres
docker run -i -t --rm \
-p 80:80 \ # map HOST:CONTAINER ports
-e '[email protected]' \
-e 'PGADMIN_DEFAULT_PASSWORD=password'
-v \
-d dpage/pgadmin4
- By default, containers are hooked into the bridge docker subnetwork.
- Running the following command will list out the containers connected to bridge
docker network inspect bridge
- Containers can then access each other by using the IP address assigned to them in the docker subnetwork
- This is useful for connecting from pgadmin to a postgres
consists of two layers:
- server to server federation
- client to server protocol
representation of users, with properties:
- inbox
- messages from the world
- outbox
- send messages out
these endpoints are listed in the activitystreams description:
{"@context": "https://www.w3.org/ns/activitystreams",
"type": "Person",
"id": "https://social.example/alyssa/",
"preferredUsername": "alyssa",
"summary": "Lisp enthusiast",
"inbox": "https://social.example/alyssa/inbox/",
"outbox": "https://social.example/alyssa/outbox/"
}
read latest send messages
messages to actor from
server
actor <---GET--- [inbox] <---POST--- rest of the world
actor ---POST---> [outbox] ---GET---> rest of the world
post messages retreive messages
to world produced by server
- example usecase:
- alyssa’s client posts a message to her outbox on her server
- NOTE: as a message is not an activity, her server wraps it in a create object
- server looks up ben’s activitystreams actor and posts object to inbox
- ....
- alysa’s client gets her inbox, and recieves ben’s message (has also been wrapped in create)
- alyssa’s client posts a message to her outbox on her server
- another usecase:
- alyssa wants to like ben’s post
- alyssa’s client posts to outbox {type: like, to=[“ben”]; actor: alyssa; object: “id of ben’s post”}
- NOTE: as a like is an activity, no need to wrap in create
- to send a public/followers message, include followers & public
- saves an activity to a box
- logic is:
- retrieve meta information (lookup what _meta does)
- if into outbox and is follow, then set follow status of meta information to waiting
- else if create activity,
- get object being created
- retrieve mentions and hashtags
- append to metadata
- insert into box, raw activity, type, id, and meta information
- looks up in db if there exists a entry
- in outbox
- with block status
- id being the selected id
- and in metadata, has not been undone
- returns the BASE_URL plus, url_for (outbox_detail, id = item_id)
- logic is:
- get actor for activity
- if activity with remote_id matching activity in inbox, ignore
- else
- save activity to inbox
- if not a delete or update activity
- queue task to update cached actor
- queue task to process activity
- queue task to finish post to inbox
- the following logic is run before any of the generic processing
- if outbox is blocked, return without doing anything
- else if
- actor is an application type
- actor id ends with /relay
- activity type is announce
- and there are no creation activities with the same id
- and no replies from the remote id of object id of activity
- then queue a process reply of object id
- else if
- update activity
- id is object_id
- then queue task to update cached actor
- get visibility of activity
- get published date of activity (or now if not present)
- insert activity into replies
{ "activity": "<json>", "type": activity.type, "remote_id": activity.id, "meta": { "undo": false, "deleted": false, "public": is_public, "server": urlparse(id).hostname, "visibility", "actor_id": activity.get_actor().id "published" } }
- if activity is create type, wrap activity in create type
- obj_id = assign create a random id
- create uri for obj id
- if create activity,
- activity._data.object.id = base_url + url_for outbox + obj_id
- if no url field in data for object, then assign object url: base_url + url_for note_by_id + obj_id
- reset object cache for activity
- save object to outbox
- queue task to update the cached actor
- queue task to finish posting to outbox activity
- retrieve id for actor
- create accept object, with type follow, id being activity.id, actor being actor_id, send to actor, published now
- update one_activity by the remote id and set accepted status to true
- post activity to outbox accepted
- retrieve choice from create.get_object().name
- if choice not in c[“name”] for c in question.data.get(“oneOf”, question.any_of)
- ignore
- else
- retrieve answer key
- if duplicate vote then ignore
- else
- update create object with question.id,
- increment question replies
- increment question_answers.answer_key by 1
- also update remote id of create
- poll_answer to question.id
- answer choice to choice
- stream to false?
- poll_answer to true
- update create object with question.id,
- retrieve answer key
- retrieve in reply to of create object
- if not found, ignore
- retrieve remote activity in reply to
- get reply from remote create object (ensure is create)
- if local reply to local question
- i.e, starts with base url
- is a question type
- create is local reply
- and create is not public
- then handle question reply locally
- else if private vote to remote question
- set sent to true to reply .id in inbox
- tracks object id & separate remote_id in metadata
- box field represents inbox or outbox
- Update tests url with url and port of postgres
- Add test user to database with password password:
CREATE USER test PASSWORD 'password';
- Create test database:
CREATE DATABASE test;
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "https://my-example.com/my-first-follow",
"type": "Follow",
"actor": "https://my-example.com/actor",
"object": "https://mastodon.social/users/Mastodon"
}
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://ocamlot.xyz/schemas/litepub-0.1.jsonld",
{
"@language": "und"
}
],
"actor": "https://ocamlot.xyz/users/example",
"cc": [],
"id": "https://ocamlot.xyz/activities/c99c2ba5-3ec0-412d-8cd0-2788867b7f67",
"object": {
"actor": "https://ocamlot.nfshost.com/users/example",
"id": "https://ocamlot.nfshost.com/activity/7612618e-7c66-4792-b410-e4c971f5de51",
"object": "https://ocamlot.xyz/users/example",
"type": "Follow"
},
"to": [
"https://ocamlot.nfshost.com/users/example"
],
"type": "Accept"
}
Write single SQL function to update entry in following database, using remote actor url + local user username
Submission from user’s post is:
- title (optional)
- publicity of post (public, followers, direct)
- list of addresses to be sent to
- content type
- source
Upon receiving request:
- for each target, attempt to resolve actor, ignore users who are not present
- add post to database