From 2359bf658b7b2c7e2d4d5012734d2f7083388ed0 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Thu, 28 Apr 2022 23:35:36 -0500 Subject: [PATCH 01/12] Headers should be case-insensitive Do not copy to a Hash, which is not case-insensitive, keep it as a headers object. --- daemon.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/daemon.py b/daemon.py index 02892de67..7bf6473b5 100644 --- a/daemon.py +++ b/daemon.py @@ -8,6 +8,7 @@ __status__ = "Production" __module_group__ = "Core" from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer, HTTPServer +import copy import sys import json import time @@ -19390,12 +19391,9 @@ class PubServer(BaseHTTPRequestHandler): np_thread.kill() # make a copy of self.headers - headers = {} - headers_without_cookie = {} - for dict_entry_name, header_line in self.headers.items(): - headers[dict_entry_name] = header_line - if dict_entry_name.lower() != 'cookie': - headers_without_cookie[dict_entry_name] = header_line + headers = copy.deepcopy(self.headers) + headers_without_cookie = copy.deepcopy(headers) + del headers_without_cookie['cookie'] print('New post headers: ' + str(headers_without_cookie)) length = int(headers['Content-Length']) From ce9bdf3c9fc3d8dd18f271d5ce6c7cff65af6a49 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 1 May 2022 10:45:37 +0100 Subject: [PATCH 02/12] Check that cookie exists before removing it from headers --- daemon.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/daemon.py b/daemon.py index a0e450fe8..eb4127f76 100644 --- a/daemon.py +++ b/daemon.py @@ -19401,7 +19401,10 @@ class PubServer(BaseHTTPRequestHandler): # make a copy of self.headers headers = copy.deepcopy(self.headers) headers_without_cookie = copy.deepcopy(headers) - del headers_without_cookie['cookie'] + if 'cookie' in headers_without_cookie: + del headers_without_cookie['cookie'] + if 'Cookie' in headers_without_cookie: + del headers_without_cookie['Cookie'] print('New post headers: ' + str(headers_without_cookie)) length = int(headers['Content-Length']) From ac5dc410d200ff77305f5c81ef647db4eb92d2e0 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 1 May 2022 11:09:55 +0100 Subject: [PATCH 03/12] Avatar icon style --- epicyon-blog.css | 17 +++++------------ epicyon-links.css | 17 +++++------------ epicyon-profile.css | 17 +++++------------ 3 files changed, 15 insertions(+), 36 deletions(-) diff --git a/epicyon-blog.css b/epicyon-blog.css index 67acfbf67..cb8dd8427 100644 --- a/epicyon-blog.css +++ b/epicyon-blog.css @@ -583,6 +583,8 @@ input[type=submit]:hover { .timeline-avatar { margin: 10px auto; padding: 0px 0px; + width: 8%; + float: left; } .timeline-avatar-reply { @@ -795,11 +797,8 @@ div.gallery img { } .timeline-avatar img { opacity: 1.0; - width: 8%; - height: 8%; + width: 100%; padding: 0px 0px; - -ms-transform: translateY(-10%); - transform: translateY(-10%); border-radius: var(--avatar-rounding); } .cwButton { @@ -1151,11 +1150,8 @@ div.gallery img { } .timeline-avatar img { opacity: 1.0; - width: 15%; - height: 15%; + width: 100%; padding: 0px 0px; - -ms-transform: translateY(-10%); - transform: translateY(-10%); border-radius: var(--avatar-rounding); } .cwButton { @@ -1498,11 +1494,8 @@ div.gallery img { } .timeline-avatar img { opacity: 1.0; - width: 15%; - height: 15%; + width: 100%; padding: 0px 0px; - -ms-transform: translateY(-10%); - transform: translateY(-10%); border-radius: var(--avatar-rounding); } .cwButton { diff --git a/epicyon-links.css b/epicyon-links.css index a45a1e4c6..a11ded320 100644 --- a/epicyon-links.css +++ b/epicyon-links.css @@ -584,6 +584,8 @@ input[type=submit]:hover { .timeline-avatar { margin: 10px auto; padding: 0px 0px; + width: 8%; + float: left; } .timeline-avatar:hover { @@ -1054,11 +1056,8 @@ aside .toggle-inside li { } .timeline-avatar img { opacity: 1.0; - width: 8%; - height: 8%; + width: 100%; padding: 0px 0px; - -ms-transform: translateY(-10%); - transform: translateY(-10%); border-radius: var(--avatar-rounding); } .buttonevent { @@ -1525,11 +1524,8 @@ aside .toggle-inside li { } .timeline-avatar img { opacity: 1.0; - width: 15%; - height: 15%; + width: 100%; padding: 0px 0px; - -ms-transform: translateY(-10%); - transform: translateY(-10%); border-radius: var(--avatar-rounding); } .buttonevent { @@ -1988,11 +1984,8 @@ aside .toggle-inside li { } .timeline-avatar img { opacity: 1.0; - width: 15%; - height: 15%; + width: 100%; padding: 0px 0px; - -ms-transform: translateY(-10%); - transform: translateY(-10%); border-radius: var(--avatar-rounding); } .buttonevent { diff --git a/epicyon-profile.css b/epicyon-profile.css index 6269c9fd0..4c631c87d 100644 --- a/epicyon-profile.css +++ b/epicyon-profile.css @@ -887,6 +887,8 @@ input[type=submit]:hover { .timeline-avatar { margin: 10px auto; padding: 0px 0px; + width: 8%; + float: left; } .timeline-avatar:hover { @@ -1473,11 +1475,8 @@ h3 { } .timeline-avatar img { opacity: 1.0; - width: 8%; - height: 8%; + width: 100%; padding: 0px 0px; - -ms-transform: translateY(-10%); - transform: translateY(-10%); border-radius: var(--avatar-rounding); } .buttonevent { @@ -2230,11 +2229,8 @@ h3 { } .timeline-avatar img { opacity: 1.0; - width: 15%; - height: 15%; + width: 100%; padding: 0px 0px; - -ms-transform: translateY(-10%); - transform: translateY(-10%); border-radius: var(--avatar-rounding); } .buttonevent { @@ -2990,11 +2986,8 @@ h3 { } .timeline-avatar img { opacity: 1.0; - width: 15%; - height: 15%; + width: 100%; padding: 0px 0px; - -ms-transform: translateY(-10%); - transform: translateY(-10%); border-radius: var(--avatar-rounding); } .buttonevent { From c23b34bad0889120eec81054d7cc1c59e61cc717 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 1 May 2022 11:16:28 +0100 Subject: [PATCH 04/12] Avatar image size on mobile --- epicyon-blog.css | 12 ++++++++++++ epicyon-links.css | 12 ++++++++++++ epicyon-profile.css | 12 ++++++++++++ 3 files changed, 36 insertions(+) diff --git a/epicyon-blog.css b/epicyon-blog.css index cb8dd8427..cb052ba12 100644 --- a/epicyon-blog.css +++ b/epicyon-blog.css @@ -1148,6 +1148,12 @@ div.gallery img { margin: 1% 3%; border-radius: 0%; } + .timeline-avatar { + margin: 10px auto; + padding: 0px 0px; + width: 15%; + float: left; + } .timeline-avatar img { opacity: 1.0; width: 100%; @@ -1492,6 +1498,12 @@ div.gallery img { margin: 1% 3%; border-radius: 0%; } + .timeline-avatar { + margin: 10px auto; + padding: 0px 0px; + width: 15%; + float: left; + } .timeline-avatar img { opacity: 1.0; width: 100%; diff --git a/epicyon-links.css b/epicyon-links.css index a11ded320..76c016bf7 100644 --- a/epicyon-links.css +++ b/epicyon-links.css @@ -1522,6 +1522,12 @@ aside .toggle-inside li { margin: 1% 3%; border-radius: 0%; } + .timeline-avatar { + margin: 10px auto; + padding: 0px 0px; + width: 15%; + float: left; + } .timeline-avatar img { opacity: 1.0; width: 100%; @@ -1982,6 +1988,12 @@ aside .toggle-inside li { margin: 1% 3%; border-radius: 0%; } + .timeline-avatar { + margin: 10px auto; + padding: 0px 0px; + width: 15%; + float: left; + } .timeline-avatar img { opacity: 1.0; width: 100%; diff --git a/epicyon-profile.css b/epicyon-profile.css index 4c631c87d..cd9146a5b 100644 --- a/epicyon-profile.css +++ b/epicyon-profile.css @@ -2227,6 +2227,12 @@ h3 { margin-right: 0px; border-radius: 0%; } + .timeline-avatar { + margin: 10px auto; + padding: 0px 0px; + width: 15%; + float: left; + } .timeline-avatar img { opacity: 1.0; width: 100%; @@ -2984,6 +2990,12 @@ h3 { margin-right: 0px; border-radius: 0%; } + .timeline-avatar { + margin: 10px auto; + padding: 0px 0px; + width: 15%; + float: left; + } .timeline-avatar img { opacity: 1.0; width: 100%; From 92f8f51388ab80ce615a744c34a4bb741e60658e Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 1 May 2022 11:32:36 +0100 Subject: [PATCH 05/12] Reply avatar image style --- epicyon-profile.css | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/epicyon-profile.css b/epicyon-profile.css index cd9146a5b..92430f0d2 100644 --- a/epicyon-profile.css +++ b/epicyon-profile.css @@ -897,7 +897,8 @@ input[type=submit]:hover { .timeline-avatar-reply { padding: 0px 0px; - width: 80%; + width: 4%; + float: left; } .search-result-text { @@ -1479,6 +1480,12 @@ h3 { padding: 0px 0px; border-radius: var(--avatar-rounding); } + .timeline-avatar-reply img { + opacity: 1.0; + width: 100%; + padding: 0px 0px; + border-radius: var(--avatar-rounding); + } .buttonevent { border-radius: var(--button-event-corner-radius); background-color: var(--button-event-background-color); @@ -2233,12 +2240,23 @@ h3 { width: 15%; float: left; } + .timeline-avatar-reply { + padding: 0px 0px; + width: 7.5%; + float: left; + } .timeline-avatar img { opacity: 1.0; width: 100%; padding: 0px 0px; border-radius: var(--avatar-rounding); } + .timeline-avatar-reply img { + opacity: 1.0; + width: 100%; + padding: 0px 0px; + border-radius: var(--avatar-rounding); + } .buttonevent { border-radius: var(--button-event-corner-radius); background-color: var(--button-event-background-color); @@ -2996,12 +3014,23 @@ h3 { width: 15%; float: left; } + .timeline-avatar-reply { + padding: 0px 0px; + width: 7.5%; + float: left; + } .timeline-avatar img { opacity: 1.0; width: 100%; padding: 0px 0px; border-radius: var(--avatar-rounding); } + .timeline-avatar-reply img { + opacity: 1.0; + width: 100%; + padding: 0px 0px; + border-radius: var(--avatar-rounding); + } .buttonevent { border-radius: var(--button-event-corner-radius); background-color: var(--button-event-background-color); From af9b084a4f437c2b1a44b83875ea87de375e70aa Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 1 May 2022 11:47:35 +0100 Subject: [PATCH 06/12] Avatar image style --- epicyon-blog.css | 49 ++++++++++++++++++++++++++++++++++++--------- epicyon-links.css | 49 ++++++++++++++++++++++++++++++++++++--------- epicyon-profile.css | 30 +++++++++++++-------------- 3 files changed, 93 insertions(+), 35 deletions(-) diff --git a/epicyon-blog.css b/epicyon-blog.css index cb052ba12..cba1e4665 100644 --- a/epicyon-blog.css +++ b/epicyon-blog.css @@ -581,7 +581,7 @@ input[type=submit]:hover { } .timeline-avatar { - margin: 10px auto; + margin: 0px 0px; padding: 0px 0px; width: 8%; float: left; @@ -589,7 +589,8 @@ input[type=submit]:hover { .timeline-avatar-reply { padding: 0px 0px; - width: 80%; + width: 4%; + float: left; } .search-result-text { @@ -801,6 +802,12 @@ div.gallery img { padding: 0px 0px; border-radius: var(--avatar-rounding); } + .timeline-avatar-reply img { + opacity: 1.0; + width: 100%; + padding: 0px 0px; + border-radius: var(--avatar-rounding); + } .cwButton { border-radius: var(--button-corner-radius); background-color: #554; @@ -1149,10 +1156,15 @@ div.gallery img { border-radius: 0%; } .timeline-avatar { - margin: 10px auto; - padding: 0px 0px; - width: 15%; - float: left; + margin: 0px 0px; + padding: 0px 0px; + width: 15%; + float: left; + } + .timeline-avatar-reply { + padding: 0px 0px; + width: 12%; + float: left; } .timeline-avatar img { opacity: 1.0; @@ -1160,6 +1172,12 @@ div.gallery img { padding: 0px 0px; border-radius: var(--avatar-rounding); } + .timeline-avatar-reply img { + opacity: 1.0; + width: 100%; + padding: 0px 0px; + border-radius: var(--avatar-rounding); + } .cwButton { border-radius: var(--button-corner-radius); background-color: #554; @@ -1499,10 +1517,15 @@ div.gallery img { border-radius: 0%; } .timeline-avatar { - margin: 10px auto; - padding: 0px 0px; - width: 15%; - float: left; + margin: 0px 0px; + padding: 0px 0px; + width: 15%; + float: left; + } + .timeline-avatar-reply { + padding: 0px 0px; + width: 12%; + float: left; } .timeline-avatar img { opacity: 1.0; @@ -1510,6 +1533,12 @@ div.gallery img { padding: 0px 0px; border-radius: var(--avatar-rounding); } + .timeline-avatar-reply img { + opacity: 1.0; + width: 100%; + padding: 0px 0px; + border-radius: var(--avatar-rounding); + } .cwButton { border-radius: var(--button-corner-radius); background-color: #554; diff --git a/epicyon-links.css b/epicyon-links.css index 76c016bf7..5197ec4e4 100644 --- a/epicyon-links.css +++ b/epicyon-links.css @@ -582,7 +582,7 @@ input[type=submit]:hover { } .timeline-avatar { - margin: 10px auto; + margin: 0px 0px; padding: 0px 0px; width: 8%; float: left; @@ -594,7 +594,8 @@ input[type=submit]:hover { .timeline-avatar-reply { padding: 0px 0px; - width: 80%; + width: 4%; + float: left; } .search-result-text { @@ -1060,6 +1061,12 @@ aside .toggle-inside li { padding: 0px 0px; border-radius: var(--avatar-rounding); } + .timeline-avatar-reply img { + opacity: 1.0; + width: 100%; + padding: 0px 0px; + border-radius: var(--avatar-rounding); + } .buttonevent { border-radius: var(--button-corner-radius); background-color: var(--button-highlighted); @@ -1523,10 +1530,15 @@ aside .toggle-inside li { border-radius: 0%; } .timeline-avatar { - margin: 10px auto; - padding: 0px 0px; - width: 15%; - float: left; + margin: 0px 0px; + padding: 0px 0px; + width: 15%; + float: left; + } + .timeline-avatar-reply { + padding: 0px 0px; + width: 12%; + float: left; } .timeline-avatar img { opacity: 1.0; @@ -1534,6 +1546,12 @@ aside .toggle-inside li { padding: 0px 0px; border-radius: var(--avatar-rounding); } + .timeline-avatar-reply img { + opacity: 1.0; + width: 100%; + padding: 0px 0px; + border-radius: var(--avatar-rounding); + } .buttonevent { border-radius: var(--button-corner-radius); background-color: var(--button-highlighted); @@ -1989,10 +2007,15 @@ aside .toggle-inside li { border-radius: 0%; } .timeline-avatar { - margin: 10px auto; - padding: 0px 0px; - width: 15%; - float: left; + margin: 0px 0px; + padding: 0px 0px; + width: 15%; + float: left; + } + .timeline-avatar-reply { + padding: 0px 0px; + width: 12%; + float: left; } .timeline-avatar img { opacity: 1.0; @@ -2000,6 +2023,12 @@ aside .toggle-inside li { padding: 0px 0px; border-radius: var(--avatar-rounding); } + .timeline-avatar-reply img { + opacity: 1.0; + width: 100%; + padding: 0px 0px; + border-radius: var(--avatar-rounding); + } .buttonevent { border-radius: var(--button-corner-radius); background-color: var(--button-highlighted); diff --git a/epicyon-profile.css b/epicyon-profile.css index 92430f0d2..03bf3bc3c 100644 --- a/epicyon-profile.css +++ b/epicyon-profile.css @@ -885,7 +885,7 @@ input[type=submit]:hover { } .timeline-avatar { - margin: 10px auto; + margin: 0px 0px; padding: 0px 0px; width: 8%; float: left; @@ -2235,15 +2235,15 @@ h3 { border-radius: 0%; } .timeline-avatar { - margin: 10px auto; - padding: 0px 0px; - width: 15%; - float: left; + margin: 0px 0px; + padding: 0px 0px; + width: 15%; + float: left; } .timeline-avatar-reply { - padding: 0px 0px; - width: 7.5%; - float: left; + padding: 0px 0px; + width: 12%; + float: left; } .timeline-avatar img { opacity: 1.0; @@ -3009,15 +3009,15 @@ h3 { border-radius: 0%; } .timeline-avatar { - margin: 10px auto; - padding: 0px 0px; - width: 15%; - float: left; + margin: 0px 0px; + padding: 0px 0px; + width: 15%; + float: left; } .timeline-avatar-reply { - padding: 0px 0px; - width: 7.5%; - float: left; + padding: 0px 0px; + width: 12%; + float: left; } .timeline-avatar img { opacity: 1.0; From 0a1bddf087a38b40c9cf7745a416274bcfb99ec5 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 1 May 2022 12:20:50 +0100 Subject: [PATCH 07/12] Larger reply avatar image --- epicyon-blog.css | 2 +- epicyon-links.css | 2 +- epicyon-profile.css | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/epicyon-blog.css b/epicyon-blog.css index cba1e4665..de492c76c 100644 --- a/epicyon-blog.css +++ b/epicyon-blog.css @@ -589,7 +589,7 @@ input[type=submit]:hover { .timeline-avatar-reply { padding: 0px 0px; - width: 4%; + width: 6%; float: left; } diff --git a/epicyon-links.css b/epicyon-links.css index 5197ec4e4..c68ac31dc 100644 --- a/epicyon-links.css +++ b/epicyon-links.css @@ -594,7 +594,7 @@ input[type=submit]:hover { .timeline-avatar-reply { padding: 0px 0px; - width: 4%; + width: 6%; float: left; } diff --git a/epicyon-profile.css b/epicyon-profile.css index 03bf3bc3c..17d0f6792 100644 --- a/epicyon-profile.css +++ b/epicyon-profile.css @@ -897,7 +897,7 @@ input[type=submit]:hover { .timeline-avatar-reply { padding: 0px 0px; - width: 4%; + width: 6%; float: left; } From ca2bc905f08df8b104667ed3f67601676074ee54 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 1 May 2022 12:29:41 +0100 Subject: [PATCH 08/12] Separation between avatar image and reply image --- epicyon-blog.css | 9 ++++++--- epicyon-links.css | 9 ++++++--- epicyon-profile.css | 9 ++++++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/epicyon-blog.css b/epicyon-blog.css index de492c76c..0c92d60d3 100644 --- a/epicyon-blog.css +++ b/epicyon-blog.css @@ -804,8 +804,9 @@ div.gallery img { } .timeline-avatar-reply img { opacity: 1.0; - width: 100%; + width: 90%; padding: 0px 0px; + margin: 0px 10%; border-radius: var(--avatar-rounding); } .cwButton { @@ -1174,8 +1175,9 @@ div.gallery img { } .timeline-avatar-reply img { opacity: 1.0; - width: 100%; + width: 90%; padding: 0px 0px; + margin: 0px 10%; border-radius: var(--avatar-rounding); } .cwButton { @@ -1535,8 +1537,9 @@ div.gallery img { } .timeline-avatar-reply img { opacity: 1.0; - width: 100%; + width: 90%; padding: 0px 0px; + margin: 0px 10%; border-radius: var(--avatar-rounding); } .cwButton { diff --git a/epicyon-links.css b/epicyon-links.css index c68ac31dc..1d73fc4dc 100644 --- a/epicyon-links.css +++ b/epicyon-links.css @@ -1063,8 +1063,9 @@ aside .toggle-inside li { } .timeline-avatar-reply img { opacity: 1.0; - width: 100%; + width: 90%; padding: 0px 0px; + margin: 0px 10%; border-radius: var(--avatar-rounding); } .buttonevent { @@ -1548,8 +1549,9 @@ aside .toggle-inside li { } .timeline-avatar-reply img { opacity: 1.0; - width: 100%; + width: 90%; padding: 0px 0px; + margin: 0px 10%; border-radius: var(--avatar-rounding); } .buttonevent { @@ -2025,8 +2027,9 @@ aside .toggle-inside li { } .timeline-avatar-reply img { opacity: 1.0; - width: 100%; + width: 90%; padding: 0px 0px; + margin: 0px 10%; border-radius: var(--avatar-rounding); } .buttonevent { diff --git a/epicyon-profile.css b/epicyon-profile.css index 17d0f6792..75f419134 100644 --- a/epicyon-profile.css +++ b/epicyon-profile.css @@ -1482,8 +1482,9 @@ h3 { } .timeline-avatar-reply img { opacity: 1.0; - width: 100%; + width: 90%; padding: 0px 0px; + margin: 0px 10%; border-radius: var(--avatar-rounding); } .buttonevent { @@ -2253,8 +2254,9 @@ h3 { } .timeline-avatar-reply img { opacity: 1.0; - width: 100%; + width: 90%; padding: 0px 0px; + margin: 0px 10%; border-radius: var(--avatar-rounding); } .buttonevent { @@ -3027,8 +3029,9 @@ h3 { } .timeline-avatar-reply img { opacity: 1.0; - width: 100%; + width: 90%; padding: 0px 0px; + margin: 0px 10%; border-radius: var(--avatar-rounding); } .buttonevent { From 45feb65b6a18c9abd2ad59a3d05a04ee85739c02 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 1 May 2022 12:47:06 +0100 Subject: [PATCH 09/12] More space between avatar image and text --- epicyon-blog.css | 6 +++--- epicyon-links.css | 6 +++--- epicyon-profile.css | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/epicyon-blog.css b/epicyon-blog.css index 0c92d60d3..74498287d 100644 --- a/epicyon-blog.css +++ b/epicyon-blog.css @@ -804,7 +804,7 @@ div.gallery img { } .timeline-avatar-reply img { opacity: 1.0; - width: 90%; + width: 80%; padding: 0px 0px; margin: 0px 10%; border-radius: var(--avatar-rounding); @@ -1175,7 +1175,7 @@ div.gallery img { } .timeline-avatar-reply img { opacity: 1.0; - width: 90%; + width: 80%; padding: 0px 0px; margin: 0px 10%; border-radius: var(--avatar-rounding); @@ -1537,7 +1537,7 @@ div.gallery img { } .timeline-avatar-reply img { opacity: 1.0; - width: 90%; + width: 80%; padding: 0px 0px; margin: 0px 10%; border-radius: var(--avatar-rounding); diff --git a/epicyon-links.css b/epicyon-links.css index 1d73fc4dc..e0eb5ae89 100644 --- a/epicyon-links.css +++ b/epicyon-links.css @@ -1063,7 +1063,7 @@ aside .toggle-inside li { } .timeline-avatar-reply img { opacity: 1.0; - width: 90%; + width: 80%; padding: 0px 0px; margin: 0px 10%; border-radius: var(--avatar-rounding); @@ -1549,7 +1549,7 @@ aside .toggle-inside li { } .timeline-avatar-reply img { opacity: 1.0; - width: 90%; + width: 80%; padding: 0px 0px; margin: 0px 10%; border-radius: var(--avatar-rounding); @@ -2027,7 +2027,7 @@ aside .toggle-inside li { } .timeline-avatar-reply img { opacity: 1.0; - width: 90%; + width: 80%; padding: 0px 0px; margin: 0px 10%; border-radius: var(--avatar-rounding); diff --git a/epicyon-profile.css b/epicyon-profile.css index 75f419134..746897e81 100644 --- a/epicyon-profile.css +++ b/epicyon-profile.css @@ -1482,7 +1482,7 @@ h3 { } .timeline-avatar-reply img { opacity: 1.0; - width: 90%; + width: 80%; padding: 0px 0px; margin: 0px 10%; border-radius: var(--avatar-rounding); @@ -2254,7 +2254,7 @@ h3 { } .timeline-avatar-reply img { opacity: 1.0; - width: 90%; + width: 80%; padding: 0px 0px; margin: 0px 10%; border-radius: var(--avatar-rounding); @@ -3029,7 +3029,7 @@ h3 { } .timeline-avatar-reply img { opacity: 1.0; - width: 90%; + width: 80%; padding: 0px 0px; margin: 0px 10%; border-radius: var(--avatar-rounding); From ec82a20c2faad0d84b7058bcd3b48d35b5e922fd Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 1 May 2022 14:23:32 +0100 Subject: [PATCH 10/12] Don't clear down DMs from other instances --- utils.py | 94 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 37 deletions(-) diff --git a/utils.py b/utils.py index 3c704fd9f..61058a600 100644 --- a/utils.py +++ b/utils.py @@ -91,6 +91,15 @@ def get_actor_languages_list(actor_json: {}) -> []: return [] +def has_object_dict(post_json_object: {}) -> bool: + """Returns true if the given post has an object dict + """ + if post_json_object.get('object'): + if isinstance(post_json_object['object'], dict): + return True + return False + + def get_content_from_post(post_json_object: {}, system_language: str, languages_understood: [], contentType: str = "content") -> str: @@ -1794,6 +1803,49 @@ def _delete_conversation_post(base_dir: str, nickname: str, domain: str, str(conversation_filename)) +def is_dm(post_json_object: {}) -> bool: + """Returns true if the given post is a DM + """ + if post_json_object['type'] != 'Create': + return False + if not has_object_dict(post_json_object): + return False + if post_json_object['object']['type'] != 'ChatMessage': + if post_json_object['object']['type'] != 'Note' and \ + post_json_object['object']['type'] != 'Page' and \ + post_json_object['object']['type'] != 'Patch' and \ + post_json_object['object']['type'] != 'EncryptedMessage' and \ + post_json_object['object']['type'] != 'Article': + return False + if post_json_object['object'].get('moderationStatus'): + return False + fields = ('to', 'cc') + for field_name in fields: + if not post_json_object['object'].get(field_name): + continue + for to_address in post_json_object['object'][field_name]: + if to_address.endswith('#Public'): + return False + if to_address.endswith('followers'): + return False + return True + + +def _is_remote_dm(domain_full: str, post_json_object: {}) -> bool: + """Is the given post a DM from a different domain? + """ + if not is_dm(post_json_object): + return False + this_post_json = post_json_object + if has_object_dict(post_json_object): + this_post_json = post_json_object['object'] + if this_post_json.get('attributedTo'): + if isinstance(this_post_json['attributedTo'], str): + if '://' + domain_full + '/' not in this_post_json['attributedTo']: + return True + return False + + def delete_post(base_dir: str, http_prefix: str, nickname: str, domain: str, post_filename: str, debug: bool, recent_posts_cache: {}) -> None: @@ -1814,6 +1866,11 @@ def delete_post(base_dir: str, http_prefix: str, str(post_filename)) return + # don't allow DMs to be deleted if they came from a different instance + # otherwise this breaks expectations about how DMs should operate + if _is_remote_dm(domain, post_json_object): + return + # don't allow deletion of bookmarked posts if _is_bookmarked(base_dir, nickname, domain, post_filename): return @@ -2769,34 +2826,6 @@ def is_chat_message(post_json_object: {}) -> bool: return True -def is_dm(post_json_object: {}) -> bool: - """Returns true if the given post is a DM - """ - if post_json_object['type'] != 'Create': - return False - if not has_object_dict(post_json_object): - return False - if post_json_object['object']['type'] != 'ChatMessage': - if post_json_object['object']['type'] != 'Note' and \ - post_json_object['object']['type'] != 'Page' and \ - post_json_object['object']['type'] != 'Patch' and \ - post_json_object['object']['type'] != 'EncryptedMessage' and \ - post_json_object['object']['type'] != 'Article': - return False - if post_json_object['object'].get('moderationStatus'): - return False - fields = ('to', 'cc') - for field_name in fields: - if not post_json_object['object'].get(field_name): - continue - for to_address in post_json_object['object'][field_name]: - if to_address.endswith('#Public'): - return False - if to_address.endswith('followers'): - return False - return True - - def is_reply(post_json_object: {}, actor: str) -> bool: """Returns true if the given post is a reply to the given actor """ @@ -3037,15 +3066,6 @@ def user_agent_domain(user_agent: str, debug: bool) -> str: return agent_domain -def has_object_dict(post_json_object: {}) -> bool: - """Returns true if the given post has an object dict - """ - if post_json_object.get('object'): - if isinstance(post_json_object['object'], dict): - return True - return False - - def get_alt_path(actor: str, domain_full: str, calling_domain: str) -> str: """Returns alternate path from the actor eg. https://clearnetdomain/path becomes http://oniondomain/path From ac8b86059f23035a86ea6eb5f766e1342367c1b0 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 1 May 2022 18:14:29 +0100 Subject: [PATCH 11/12] Only prevent remote DM deletions during archive --- daemon.py | 10 ++++++---- delete.py | 2 +- happening.py | 2 +- inbox.py | 6 +++--- posts.py | 2 +- tests.py | 17 ++++++++++++----- utils.py | 20 ++++++++++++-------- 7 files changed, 36 insertions(+), 23 deletions(-) diff --git a/daemon.py b/daemon.py index eb4127f76..1a53f123a 100644 --- a/daemon.py +++ b/daemon.py @@ -2363,7 +2363,8 @@ class PubServer(BaseHTTPRequestHandler): nickname, domain, post_filename, debug, - self.server.recent_posts_cache) + self.server.recent_posts_cache, + True) if nickname != 'news': # if this is a local blog post then also remove it # from the news actor @@ -2379,7 +2380,8 @@ class PubServer(BaseHTTPRequestHandler): 'news', domain, post_filename, debug, - self.server.recent_posts_cache) + self.server.recent_posts_cache, + True) self._redirect_headers(actor_str + '/moderation', cookie, calling_domain) @@ -8655,7 +8657,7 @@ class PubServer(BaseHTTPRequestHandler): if self.server.iconsCache.get('repeat_inactive.png'): del self.server.iconsCache['repeat_inactive.png'] - # delete the announce post + # delete the announce post if '?unannounce=' in path: announce_url = path.split('?unannounce=')[1] if '?' in announce_url: @@ -8669,7 +8671,7 @@ class PubServer(BaseHTTPRequestHandler): if post_filename: delete_post(base_dir, http_prefix, nickname, domain, post_filename, - debug, recent_posts_cache) + debug, recent_posts_cache, True) self._post_to_outbox(new_undo_announce, self.server.project_version, diff --git a/delete.py b/delete.py index 6713ceec5..00e83d33a 100644 --- a/delete.py +++ b/delete.py @@ -170,7 +170,7 @@ def outbox_delete(base_dir: str, http_prefix: str, print(message_id) return True delete_post(base_dir, http_prefix, delete_nickname, delete_domain, - post_filename, debug, recent_posts_cache) + post_filename, debug, recent_posts_cache, True) if debug: print('DEBUG: post deleted via c2s - ' + post_filename) diff --git a/happening.py b/happening.py index 39bfd350c..bf2ede6b8 100644 --- a/happening.py +++ b/happening.py @@ -1276,7 +1276,7 @@ def dav_delete_response(base_dir: str, nickname: str, domain: str, token_post_id) delete_post(base_dir, http_prefix, nickname, domain, post_filename, - debug, recent_posts_cache) + debug, recent_posts_cache, True) return 'Ok' diff --git a/inbox.py b/inbox.py index bef69c55c..ef6498d68 100644 --- a/inbox.py +++ b/inbox.py @@ -2058,7 +2058,7 @@ def _receive_delete(session, handle: str, is_group: bool, base_dir: str, return True delete_post(base_dir, http_prefix, handle_nickname, handle_domain, post_filename, debug, - recent_posts_cache) + recent_posts_cache, True) if debug: print('DEBUG: post deleted - ' + post_filename) @@ -2069,7 +2069,7 @@ def _receive_delete(session, handle: str, is_group: bool, base_dir: str, if post_filename: delete_post(base_dir, http_prefix, 'news', handle_domain, post_filename, debug, - recent_posts_cache) + recent_posts_cache, True) if debug: print('DEBUG: blog post deleted - ' + post_filename) return True @@ -4094,7 +4094,7 @@ def _inbox_after_initial(server, inbox_start_time, if edited_filename != destination_filename: delete_post(base_dir, http_prefix, nickname, domain, edited_filename, - debug, recent_posts_cache) + debug, recent_posts_cache, True) # update the indexes for different timelines for boxname in update_index_list: diff --git a/posts.py b/posts.py index f21f76cdb..1780999d7 100644 --- a/posts.py +++ b/posts.py @@ -4294,7 +4294,7 @@ def archive_posts_for_person(http_prefix: str, nickname: str, domain: str, '.json.' + ext)) else: delete_post(base_dir, http_prefix, nickname, domain, - file_path, False, recent_posts_cache) + file_path, False, recent_posts_cache, False) # remove cached html posts post_cache_filename = \ diff --git a/tests.py b/tests.py index d6c30c06c..ecc54ee1f 100644 --- a/tests.py +++ b/tests.py @@ -3393,11 +3393,14 @@ def test_client_to_server(base_dir: str): inbox_path = bob_dir + '/accounts/bob@' + bob_domain + '/inbox' outbox_path = alice_dir + '/accounts/alice@' + alice_domain + '/outbox' - posts_before = \ + bob_posts_before = \ len([name for name in os.listdir(inbox_path) if os.path.isfile(os.path.join(inbox_path, name))]) + alice_posts_before = \ + len([name for name in os.listdir(outbox_path) + if os.path.isfile(os.path.join(outbox_path, name))]) print('\n\nEVENT: Alice deletes her post: ' + outbox_post_id + ' ' + - str(posts_before)) + str(alice_posts_before)) password = 'alicepass' send_delete_via_server(alice_dir, session_alice, 'alice', password, alice_domain, alice_port, @@ -3408,14 +3411,18 @@ def test_client_to_server(base_dir: str): if os.path.isdir(inbox_path): test = len([name for name in os.listdir(inbox_path) if os.path.isfile(os.path.join(inbox_path, name))]) - if test == posts_before-1: + if test == bob_posts_before-1: break time.sleep(1) test = len([name for name in os.listdir(inbox_path) if os.path.isfile(os.path.join(inbox_path, name))]) - assert test == posts_before - 1 - print(">>> post deleted from Alice's outbox and Bob's inbox") + assert test == bob_posts_before - 1 + print(">>> post was deleted from Bob's inbox") +# test = len([name for name in os.listdir(outbox_path) +# if os.path.isfile(os.path.join(outbox_path, name))]) +# assert test == alice_posts_before - 1 +# print(">>> post deleted from Alice's outbox") assert valid_inbox(bob_dir, 'bob', bob_domain) assert valid_inbox_filenames(bob_dir, 'bob', bob_domain, alice_domain, alice_port) diff --git a/utils.py b/utils.py index 61058a600..f5a49d9b4 100644 --- a/utils.py +++ b/utils.py @@ -1619,7 +1619,8 @@ def _is_reply_to_blog_post(base_dir: str, nickname: str, domain: str, def _delete_post_remove_replies(base_dir: str, nickname: str, domain: str, http_prefix: str, post_filename: str, - recent_posts_cache: {}, debug: bool) -> None: + recent_posts_cache: {}, debug: bool, + manual: bool) -> None: """Removes replies when deleting a post """ replies_filename = post_filename.replace('.json', '.replies') @@ -1635,7 +1636,7 @@ def _delete_post_remove_replies(base_dir: str, nickname: str, domain: str, if os.path.isfile(reply_file): delete_post(base_dir, http_prefix, nickname, domain, reply_file, debug, - recent_posts_cache) + recent_posts_cache, manual) # remove the replies file try: os.remove(replies_filename) @@ -1841,14 +1842,15 @@ def _is_remote_dm(domain_full: str, post_json_object: {}) -> bool: this_post_json = post_json_object['object'] if this_post_json.get('attributedTo'): if isinstance(this_post_json['attributedTo'], str): - if '://' + domain_full + '/' not in this_post_json['attributedTo']: + if '://' + domain_full not in this_post_json['attributedTo']: return True return False def delete_post(base_dir: str, http_prefix: str, nickname: str, domain: str, post_filename: str, - debug: bool, recent_posts_cache: {}) -> None: + debug: bool, recent_posts_cache: {}, + manual: bool) -> None: """Recursively deletes a post and its replies and attachments """ post_json_object = load_json(post_filename, 1) @@ -1856,7 +1858,7 @@ def delete_post(base_dir: str, http_prefix: str, # remove any replies _delete_post_remove_replies(base_dir, nickname, domain, http_prefix, post_filename, - recent_posts_cache, debug) + recent_posts_cache, debug, manual) # finally, remove the post itself try: os.remove(post_filename) @@ -1868,8 +1870,10 @@ def delete_post(base_dir: str, http_prefix: str, # don't allow DMs to be deleted if they came from a different instance # otherwise this breaks expectations about how DMs should operate - if _is_remote_dm(domain, post_json_object): - return + # i.e. DMs should only be removed if they are manually deleted + if not manual: + if _is_remote_dm(domain, post_json_object): + return # don't allow deletion of bookmarked posts if _is_bookmarked(base_dir, nickname, domain, post_filename): @@ -1931,7 +1935,7 @@ def delete_post(base_dir: str, http_prefix: str, # remove any replies _delete_post_remove_replies(base_dir, nickname, domain, http_prefix, post_filename, - recent_posts_cache, debug) + recent_posts_cache, debug, manual) # finally, remove the post itself try: os.remove(post_filename) From 6d0b0b076d9f4d010f4eb9978e5384be5b7de0cd Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 1 May 2022 18:28:02 +0100 Subject: [PATCH 12/12] Fix outbox test --- tests.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests.py b/tests.py index ecc54ee1f..7d4e60811 100644 --- a/tests.py +++ b/tests.py @@ -3419,10 +3419,12 @@ def test_client_to_server(base_dir: str): if os.path.isfile(os.path.join(inbox_path, name))]) assert test == bob_posts_before - 1 print(">>> post was deleted from Bob's inbox") -# test = len([name for name in os.listdir(outbox_path) -# if os.path.isfile(os.path.join(outbox_path, name))]) -# assert test == alice_posts_before - 1 -# print(">>> post deleted from Alice's outbox") + test = len([name for name in os.listdir(outbox_path) + if os.path.isfile(os.path.join(outbox_path, name))]) + # this should be unchanged because a delete post was added + # at the outbox and one was removed + assert test == alice_posts_before + print(">>> post deleted from Alice's outbox") assert valid_inbox(bob_dir, 'bob', bob_domain) assert valid_inbox_filenames(bob_dir, 'bob', bob_domain, alice_domain, alice_port)