diff --git a/crawlers.py b/crawlers.py index d95aa2aa4..de61358f7 100644 --- a/crawlers.py +++ b/crawlers.py @@ -16,7 +16,7 @@ from blocking import update_blocked_cache from blocking import is_blocked_domain default_user_agent_blocks = [ - 'fedilist' + 'fedilist', 'ncsc scan' ] diff --git a/daemon.py b/daemon.py index 7522aee37..a636836fe 100644 --- a/daemon.py +++ b/daemon.py @@ -58,6 +58,8 @@ from donate import get_donation_url from donate import set_donation_url from donate import get_website from donate import set_website +from donate import get_gemini_link +from donate import set_gemini_link from person import clear_person_qrcodes from person import add_alternate_domains from person import add_actor_update_timestamp @@ -6452,6 +6454,21 @@ class PubServer(BaseHTTPRequestHandler): set_website(actor_json, '', self.server.translate) actor_changed = True + # change gemini link + current_gemini_link = \ + get_gemini_link(actor_json, self.server.translate) + if fields.get('geminiLink'): + if fields['geminiLink'] != current_gemini_link: + set_gemini_link(actor_json, + fields['geminiLink'], + self.server.translate) + actor_changed = True + else: + if current_gemini_link: + set_gemini_link(actor_json, '', + self.server.translate) + actor_changed = True + # account moved to new address moved_to = '' if actor_json.get('movedTo'): @@ -8035,6 +8052,7 @@ class PubServer(BaseHTTPRequestHandler): is_group = False donate_url = None website_url = None + gemini_link = None enigma_pub_key = None pgp_pub_key = None pgp_fingerprint = None @@ -8064,6 +8082,8 @@ class PubServer(BaseHTTPRequestHandler): locked_account = get_locked_account(actor_json) donate_url = get_donation_url(actor_json) website_url = get_website(actor_json, self.server.translate) + gemini_link = get_gemini_link(actor_json, + self.server.translate) xmpp_address = get_xmpp_address(actor_json) matrix_address = get_matrix_address(actor_json) ssb_address = get_ssb_address(actor_json) @@ -8116,6 +8136,7 @@ class PubServer(BaseHTTPRequestHandler): options_profile_url, options_link, page_number, donate_url, website_url, + gemini_link, xmpp_address, matrix_address, ssb_address, blog_address, tox_address, briar_address, diff --git a/donate.py b/donate.py index 343c8a817..0635b0e85 100644 --- a/donate.py +++ b/donate.py @@ -21,6 +21,10 @@ def _get_website_strings() -> []: return ['www', 'website', 'web', 'homepage'] +def _get_gemini_strings() -> []: + return ['gemini', 'capsule', 'gemlog'] + + def get_donation_url(actor_json: {}) -> str: """Returns a link used for donations """ @@ -82,6 +86,34 @@ def get_website(actor_json: {}, translate: {}) -> str: return '' +def get_gemini_link(actor_json: {}, translate: {}) -> str: + """Returns a gemini link + """ + if not actor_json.get('attachment'): + return '' + match_strings = _get_gemini_strings() + for property_value in actor_json['attachment']: + name_value = None + if property_value.get('name'): + name_value = property_value['name'] + elif property_value.get('schema:name'): + name_value = property_value['schema:name'] + if not name_value: + continue + if name_value.lower() not in match_strings: + continue + if not property_value.get('type'): + continue + prop_value_name, _ = \ + get_attachment_property_value(property_value) + if not prop_value_name: + continue + if not property_value['type'].endswith('PropertyValue'): + continue + return property_value[prop_value_name] + return '' + + def set_donation_url(actor_json: {}, donate_url: str) -> None: """Sets a link used for donations """ @@ -203,3 +235,46 @@ def set_website(actor_json: {}, website_url: str, translate: {}) -> None: "value": website_url } actor_json['attachment'].append(new_entry) + + +def set_gemini_link(actor_json: {}, gemini_link: str, translate: {}) -> None: + """Sets a gemini link + """ + gemini_link = gemini_link.strip() + not_link = False + if '.' not in gemini_link: + not_link = True + if '://' not in gemini_link: + not_link = True + if ' ' in gemini_link: + not_link = True + if '<' in gemini_link: + not_link = True + + if not actor_json.get('attachment'): + actor_json['attachment'] = [] + + match_strings = _get_gemini_strings() + + # remove any existing value + property_found = None + for property_value in actor_json['attachment']: + if not property_value.get('name'): + continue + if not property_value.get('type'): + continue + if property_value['name'].lower() not in match_strings: + continue + property_found = property_value + break + if property_found: + actor_json['attachment'].remove(property_found) + if not_link: + return + + new_entry = { + "name": 'Gemini', + "type": "PropertyValue", + "value": gemini_link + } + actor_json['attachment'].append(new_entry) diff --git a/manual/manual.epub b/manual/manual.epub index 5020d2fd0..a1bfaf2a4 100644 Binary files a/manual/manual.epub and b/manual/manual.epub differ diff --git a/manual/manual.html b/manual/manual.html index d65392cd8..b8aeb7cc8 100644 --- a/manual/manual.html +++ b/manual/manual.html @@ -277,6 +277,21 @@ server then see caddy.example.conf.
Now you can navigate to your domain and register an account. The first account becomes the administrator.
+Since Epicyon does not use javascript there are no notifications in +the browser. However, you can receive notifications via email, XMPP, Matrix or ntfy.
+Copy the notifications script:
+cp /opt/epicyon/scripts/epicyon-notification /usr/local/bin/epicyon-notification
+chmod +x /usr/local/bin/epicyon-notification
If you are using email for notifications and it is a single user +instance then you might want to edit MY_EMAIL_ADDRESS within +/usr/local/bin/epicyon-notification.
+Then add the following to /etc/crontab.
+# */1 * * * * root /usr/local/bin/epicyon-notification
If you donโt have access to the clearnet, or prefer to avoid it, then @@ -294,24 +309,24 @@ instances.
Unlike some other instance types, Epicyon is really easy to upgrade. It only requires a git pull to obtain the changes from the upstream repo, then set permissions and restart the daemon.
-cd /opt/epicyon
-git pull
-chown -R epicyon:epicyon *
-systemctl restart epicyon
cd /opt/epicyon
+git pull
+chown -R epicyon:epicyon *
+systemctl restart epicyon
To avoid running out of disk space you will want to clear down old inbox posts. Posts from your instance outboxes will be unaffected.
Create an archive script /usr/bin/epicyon-archive:
-#!/bin/bash
-cd /opt/epicyon || exit 0
-/usr/bin/python3 epicyon.py --archive none --archiveweeks 4 --maxposts 32000
#!/bin/bash
+cd /opt/epicyon || exit 0
+/usr/bin/python3 epicyon.py --archive none --archiveweeks 4 --maxposts 32000
You can adjust the maximum number of weeks and the maximum number of inbox posts as needed. Then add it as a cron entry.
-echo "*/60 * * * * root /usr/bin/epicyon-archive" >> /etc/crontab
echo "*/60 * * * * root /usr/bin/epicyon-archive" >> /etc/crontab
You will notice that within the systemd daemon the registration option is set to open. In a browser if diff --git a/manual/manual.md b/manual/manual.md index e481b3424..c4cd66ccd 100644 --- a/manual/manual.md +++ b/manual/manual.md @@ -245,6 +245,24 @@ If you are using the [Caddy web server](https://caddyserver.com) then see [caddy Now you can navigate to your domain and register an account. The first account becomes the administrator. +## Configuring notifications +Since Epicyon does not use javascript there are no notifications in the browser. However, you can receive notifications via email, XMPP, [Matrix](https://matrix.org) or [ntfy](https://ntfy.sh). + +Copy the notifications script: + +``` bash +cp /opt/epicyon/scripts/epicyon-notification /usr/local/bin/epicyon-notification +chmod +x /usr/local/bin/epicyon-notification +``` + +If you are using email for notifications and it is a single user instance then you might want to edit *MY_EMAIL_ADDRESS* within */usr/local/bin/epicyon-notification*. + +Then add the following to */etc/crontab*. + +``` bash +# */1 * * * * root /usr/local/bin/epicyon-notification +``` + ## Installing on Onion or i2p domains If you don't have access to the clearnet, or prefer to avoid it, then it's possible to run an Epicyon instance easily from your laptop. There are scripts within the *deploy* directory which can be used to install an instance on a Debian or Arch/Parabola operating system. With some modification of package names they could be also used with other distros. diff --git a/webapp_person_options.py b/webapp_person_options.py index 2b152b075..ff89710f6 100644 --- a/webapp_person_options.py +++ b/webapp_person_options.py @@ -140,6 +140,7 @@ def html_person_options(default_timeline: str, page_number: int, donate_url: str, web_address: str, + gemini_link: str, xmpp_address: str, matrix_address: str, ssb_address: str, @@ -340,6 +341,13 @@ def html_person_options(default_timeline: str, options_str += \ '
\n' + if gemini_link: + gemini_str = remove_html(gemini_link) + if '://' not in gemini_str: + gemini_str = 'gemini://' + gemini_str + options_str += \ + '\n' if xmpp_address: options_str += \ '' + translate['XMPP'] + \ diff --git a/webapp_profile.py b/webapp_profile.py index 5d24f5977..f780fecba 100644 --- a/webapp_profile.py +++ b/webapp_profile.py @@ -46,6 +46,7 @@ from posts import parse_user_feed from posts import is_create_inside_announce from donate import get_donation_url from donate import get_website +from donate import get_gemini_link from xmpp import get_xmpp_address from matrix import get_matrix_address from ssb import get_ssb_address @@ -699,6 +700,7 @@ def html_profile(signing_priv_key_pem: str, donate_section = '' donate_url = get_donation_url(profile_json) website_url = get_website(profile_json, translate) + gemini_link = get_gemini_link(profile_json, translate) blog_address = get_blog_address(profile_json) enigma_pub_key = get_enigma_pub_key(profile_json) pgp_pub_key = get_pgp_pub_key(profile_json) @@ -725,6 +727,10 @@ def html_profile(signing_priv_key_pem: str, donate_section += \ '
' + translate['Website'] + ': ' + website_url + '
\n' + if gemini_link: + donate_section += \ + '' + 'Gemini' + ': ' + gemini_link + '
\n' if email_address: donate_section += \ '