Merge branch 'main' of gitlab.com:bashrc2/epicyon

merge-requests/30/head
Bob Mottram 2022-12-24 18:21:16 +00:00
commit e902d7851e
8 changed files with 46 additions and 6 deletions

View File

@ -8,7 +8,7 @@ Epicyon is a [fediverse](https://en.wikipedia.org/wiki/Fediverse) server suitabl
Key features:
* Open standards: HTML, CSS, ActivityPub, RSS, CalDAV.
* Open standards: HTML, CSS, ActivityPub S2S and C2S, RSS, CalDAV.
* Supports common web browsers and [shell browsers](https://lynx.invisible-island.net).
* Will not drain your mobile or laptop battery.
* Customisable themes. It doesn't have to look bland.

View File

@ -17,7 +17,7 @@ Epicyon is a fediverse server suitable for self-hosting a small number of accoun
Key features:
* Open standards: HTML, CSS, ActivityPub, RSS, CalDAV.
* Open standards: HTML, CSS, ActivityPub S2S and C2S, RSS, CalDAV.
* Supports common web browsers and shell browsers.
* Will not drain your mobile or laptop battery.
* Customisable themes. It doesn't have to look bland.

View File

@ -18,6 +18,7 @@ from languages import understood_post_language
from like import update_likes_collection
from reaction import update_reaction_collection
from reaction import valid_emoji_content
from utils import is_quote_toot
from utils import acct_handle_dir
from utils import is_account_dir
from utils import remove_eol
@ -656,6 +657,10 @@ def save_post_to_inbox_queue(base_dir: str, http_prefix: str,
post_domain = get_full_domain(post_domain, post_port)
if has_object_dict(post_json_object):
if is_quote_toot(post_json_object):
if debug:
print('REJECT: inbox quote toot ' + str(post_json_object))
return None
if post_json_object['object'].get('inReplyTo'):
if isinstance(post_json_object['object']['inReplyTo'], str):
in_reply_to = \

View File

@ -31,7 +31,7 @@ The word *fediverse* (federated universe) appears to have originated around 2012
Servers such as [Mastodon](https://github.com/mastodon/mastodon) are well known, but these are aimed at large scale deployments on powerful hardware running within data centers, making use of content distribution networks (CDN) and due to their large number of dependencies requiring someone with a high level of systems administration skill to maintain. Epicyon is designed for the opposite situation where it is only intended to have a single user or a small number of users (less than ten) running from your home location or on a modest VPS and where maintenance is extremely trivial such that it's possible to keep an instance running for long durations with minimal intervention.
Epicyon is part of the [small web](https://neustadt.fr/essays/the-small-web) category of internet software, in that it is intended to scale via federation rather than to scale vertically via resource intensive and expensive hardware. Think many small communicating nodes rather than a small number of large servers. Also, in spite of the prevailing great obsession with scale, not everything needs to. You can federate with a small number of servers for a particular purpose - such as running a club or hackspace - and that's ok.
Epicyon is part of the [small web](https://neustadt.fr/essays/the-small-web) category of internet software, in that it is intended to scale via federation rather than to scale vertically via resource intensive and expensive hardware. Think many small communicating nodes rather than a small number of large servers. Also, in spite of the prevailing great obsession with scale, not everything needs to. You can federate with a small number of servers for a particular purpose - such as running a club or hackspace - and that's ok. It supports both the server-to-server (S2S) and client-to-server (C2S) versions of the ActivityPub protocol, with [basic auth](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication) for C2S authentication.
[Anti-virality](https://uxdesign.cc/mastodon-is-antiviral-design-42f090ab8d51?gi=9baf6195c60b) is a common design approach in the fediverse, and Epicyon also follows this convention by having chronological timelines and avoiding lists of trending things or ranking profiles by numbers of followers. Recent hashtags are presented *in alphabetical order* to avoid any frequency bias. Typically if a post gets more than ten likes then its count will only show as *"10+"*, to try to avoid getting fixated upon making numbers go up at the expense of more considered forms of interaction.

View File

@ -31,6 +31,7 @@ from utils import save_json
from utils import acct_dir
from utils import local_actor_url
from utils import has_actor
from utils import is_quote_toot
from blocking import is_blocked_domain
from blocking import outbox_block
from blocking import outbox_undo_block
@ -263,6 +264,10 @@ def post_message_to_outbox(session, translate: {},
# check that the outgoing post doesn't contain any markup
# which can be used to implement exploits
if has_object_dict(message_json):
if is_quote_toot(message_json):
print('REJECT: POST quote toot ' + str(message_json))
return False
content_str = get_base_content_from_post(message_json, system_language)
if content_str:
_capitalize_hashtag(content_str, message_json,

View File

@ -4127,3 +4127,32 @@ def save_reverse_timeline(base_dir: str, reverse_sequence: []) -> []:
print('EX: failed to delete reverse ' +
reverse_filename)
break
def is_quote_toot(post_json_object: str) -> bool:
"""Returns true if the given post is a quote toot
"""
# Pleroma implementation
if post_json_object['object'].get('quoteUri') or \
post_json_object['object'].get('quoteUrl'):
return True
# More correct ActivityPub implementation
if post_json_object['object'].get('tag'):
if isinstance(post_json_object['object']['tag'], list):
for item in post_json_object['object']['tag']:
if not isinstance(item, dict):
continue
if not item.get('type'):
continue
if not item.get('mediaType'):
continue
if not isinstance(item['type'], str):
continue
if item['type'] != 'Link':
continue
if not isinstance(item['mediaType'], str):
continue
if 'json' not in item['mediaType']:
continue
return True
return False

View File

@ -2917,6 +2917,7 @@ def html_conversation_thread(post_id: str,
html_header_with_external_style(css_filename, instance_title, None)
separator_str = html_post_separator(base_dir, None)
text_mode_separator = '<div class="transparent"><hr></div>'
minimize_all_images = False
if nickname in min_images_for_accounts:
@ -2951,7 +2952,7 @@ def html_conversation_thread(post_id: str,
dogwhistles,
minimize_all_images)
if post_str:
conv_str += separator_str + post_str
conv_str += text_mode_separator + separator_str + post_str
conv_str += html_footer()
conv_str += text_mode_separator + html_footer()
return conv_str

View File

@ -1198,7 +1198,7 @@
<div class="features">
<p class="intro">Key features:</p>
<ul class="features_list">
<li>Open standards: HTML, CSS, ActivityPub, RSS, CalDAV.</li>
<li>Open standards: HTML, CSS, ActivityPub S2S and C2S, RSS, CalDAV.</li>
<li>Supports common web browsers and <a href="https://lynx.invisible-island.net">shell browsers</a>.</li>
<li>Will not drain your mobile or laptop battery.</li>
<li>Customisable themes. It doesn't have to look bland.</li>