Update architecture documentation

merge-requests/30/head
Bob Mottram 2024-12-25 14:31:14 +00:00
parent e07d9170db
commit 547f0d5a5a
72 changed files with 79 additions and 69 deletions

View File

@ -46,6 +46,10 @@ This is so that the system can be accessed and used normally with javascript in
Ordinarily web crawlers would not be a problem, but in the context of a social network even having crawlers index public posts can create ethical dilemmas in some circumstances. News and blogging instances may allow crawlers, but other types of instances should block them.
### Poison Scrapers
Rather than merely block unethical scrapers a better solution is to poison them in a manner which corrodes their viability. So by supplying text with the statistical profile of natural language but which is semantically worthless to known "AI" scrapers means that they then need to perform manual review to keep this data out of their training set, which decreases their profit. Ingesting random data bends generative AI models correspondingly towards entropy.
### No Local or Federated Timelines
The local and federated timelines of other ActivityPub servers don't add much value (especially the federated one), and tend to pollute the default timeline with irrelevant posts from people that you don't follow.
@ -76,13 +80,13 @@ In general avoid using web frameworks and instead use local modules which are pr
The main modules are *epicyon.py* and *daemon.py*. *epicyon.py* is the commandline interface and *daemon.py* is the http server. The daemon has submodules for HTTP GET and HTTP POST.
![commandline and core modules](https://gitlab.com/bashrc2/epicyon/-/raw/main/architecture/epicyon_groups_Commandline-Interface_Core.png)
![commandline and daemon modules](https://gitlab.com/bashrc2/epicyon/-/raw/main/architecture/epicyon_groups_Commandline-Interface_Daemon.png)
The daemon runs the inbox queue in a separate thread (see *inbox.py*) and the inbox queue processes incoming ActivityPub posts one at a time in a strictly serial fashion. Doing it this way means minimum potential for any parallelism/locking issues. It also means that the inbox queue is not highly scalable, but that's ok for a system which is only intended to have a few users per instance.
All ActivityPub posts are stored as text files, and there is no database as such other than the filesystem itself. Think of it as being like an email server. Each post is a json file stored in *accounts/nick@domain/inbox* or *accounts/nick@domain/outbox*. To avoid parsing problems slashes are replaced by hashes within the ActivityPub post filename. The filename for each post is the same as its ActivityPub id.
![timeline and core modules](https://gitlab.com/bashrc2/epicyon/-/raw/main/architecture/epicyon_groups_Timeline_Core.png)
![timeline and daemon modules](https://gitlab.com/bashrc2/epicyon/-/raw/main/architecture/epicyon_groups_Timeline_Daemon.png)
## Security
@ -103,6 +107,8 @@ This currently uses basic auth, which is simple to implement. Oauth2 is conventi
The *inbox* queue makes calls to check http and linked data signatures. Various modules call *auth* typically because they're implementing the basic auth of the C2S interface.
![timeline and daemon modules](https://gitlab.com/bashrc2/epicyon/-/raw/main/architecture/epicyon_groups_Timeline_Daemon-Timeline_Daemon.png)
## Accessibility
Trying to keep up with web accessibility standards. There should be configurable keyboard shortcuts for all of the main navigation actions. High contrast themes should be available. The desktop client should support text-to-speech. There should be the ability to run in a shell browser such as Lynx, without any significant loss of functionality.
@ -115,4 +121,4 @@ The *webapp_post* module generates html for each post from its ActivityPub json
The *daemon* module (http server) also calls *webapp_accesskeys* to display the key shortcuts screen.
![core and accessibility modules](https://gitlab.com/bashrc2/epicyon/-/raw/main/architecture/epicyon_groups_Core_Accessibility.png)
![daemon and accessibility modules](https://gitlab.com/bashrc2/epicyon/-/raw/main/architecture/epicyon_groups_Daemon_Accessibility.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core"
__module_group__ = "Daemon"
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer, HTTPServer
import sys

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core"
__module_group__ = "Daemon"
import os
import time

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
from httpcodes import write2
from session import establish_session

View File

@ -7,7 +7,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
from manualapprove import manual_deny_follow_request_thread
from manualapprove import manual_approve_follow_request_thread

View File

@ -7,7 +7,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import os
from utils import delete_post

View File

@ -7,7 +7,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import os
from utils import get_cached_post_filename

View File

@ -7,7 +7,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import os
from utils import undo_likes_collection_entry

View File

@ -7,7 +7,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import os
from utils import is_dm

View File

@ -7,7 +7,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import os
import urllib.parse

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import json
from context import get_individual_post_context

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import os
import time

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import os
from httpcodes import http_404

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import os
import urllib.parse

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import json
from follow import get_following_feed

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import json
import urllib.parse

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import os
import datetime

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import json
from httprequests import request_http

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
from webapp_column_left import html_edit_links
from httpheaders import set_headers

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon Login"
from utils import get_instance_url
from utils import string_ends_with

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import json
from httpheaders import set_headers

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import urllib.parse
from session import establish_session

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import json
from httpcodes import http_400

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon Timeline"
import os
import json

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import os
import json

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import json
from httpcodes import write2

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
from httpcodes import write2
from httpheaders import redirect_headers

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import os
from utils import data_dir

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon Timeline"
import json
from securemode import secure_mode

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import os
from daemon_utils import has_accept

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core GET"
__module_group__ = "Daemon GET"
import json
from httpcodes import write2

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core"
__module_group__ = "Daemon"
import os
import datetime

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core"
__module_group__ = "Daemon"
import time
import errno

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import errno
import urllib.parse

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import os
import errno

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import os
import errno

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import errno
import urllib.parse

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import os
import errno

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import os
import time

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import os
import errno

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import os
import errno

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import os
import errno

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import os
import errno

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import os
import errno

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import os
import time

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import os
import errno

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import errno
import urllib.parse

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core POST"
__module_group__ = "Daemon POST"
import errno
import urllib.parse

View File

@ -5,7 +5,7 @@ __version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core"
__module_group__ = "Daemon"
import os
import time

View File

@ -6045,30 +6045,34 @@ def _test_functions():
_diagram_groups(['Commandline Interface', 'ActivityPub'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Commandline Interface', 'Core'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Timeline', 'Core'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Web Interface', 'Core'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Web Interface Columns', 'Core'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Core'], [],
modules, mod_groups, max_module_calls)
_diagram_groups(['ActivityPub'], [],
modules, mod_groups, max_module_calls)
_diagram_groups(['ActivityPub', 'Core'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['ActivityPub', 'Security'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Core', 'Security'], ['utils'],
_diagram_groups(['Commandline Interface', 'Daemon'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Timeline', 'Security'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Web Interface', 'Accessibility'],
['utils', 'webapp_utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Core', 'Accessibility'], ['utils'],
_diagram_groups(['Daemon', 'Accessibility'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Timeline', 'Daemon Timeline', 'Daemon'],
['utils'], modules, mod_groups, max_module_calls)
_diagram_groups(['Web Interface', 'Core', 'Daemon'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Web Interface Columns', 'Core', 'Daemon'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Daemon'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Core', 'Daemon', 'Daemon Login', 'Security'],
['daemon_utils', 'utils', 'daemon_post',
'daemon_head', 'flags'],
modules, mod_groups, max_module_calls)
_diagram_groups(['ActivityPub'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['ActivityPub', 'Daemon'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['ActivityPub', 'Security'], ['utils'],
modules, mod_groups, max_module_calls)
_diagram_groups(['Core', 'Security'], ['utils'],
modules, mod_groups, max_module_calls)