mirror of https://gitlab.com/bashrc2/epicyon
main
commit
f217f4ad48
|
@ -12,6 +12,10 @@ from utils import has_object_dict
|
||||||
from utils import acct_dir
|
from utils import acct_dir
|
||||||
from utils import remove_id_ending
|
from utils import remove_id_ending
|
||||||
from utils import text_in_file
|
from utils import text_in_file
|
||||||
|
from utils import locate_post
|
||||||
|
from utils import load_json
|
||||||
|
from keys import get_instance_actor_key
|
||||||
|
from session import get_json
|
||||||
|
|
||||||
|
|
||||||
def _get_conversation_filename(base_dir: str, nickname: str, domain: str,
|
def _get_conversation_filename(base_dir: str, nickname: str, domain: str,
|
||||||
|
@ -98,3 +102,88 @@ def unmute_conversation(base_dir: str, nickname: str, domain: str,
|
||||||
except OSError:
|
except OSError:
|
||||||
print('EX: unmute_conversation unable to delete ' +
|
print('EX: unmute_conversation unable to delete ' +
|
||||||
conversation_filename + '.muted')
|
conversation_filename + '.muted')
|
||||||
|
|
||||||
|
|
||||||
|
def download_conversation_posts(session, http_prefix: str, base_dir: str,
|
||||||
|
nickname: str, domain: str,
|
||||||
|
post_id: str, debug: bool) -> []:
|
||||||
|
"""Downloads all posts for a conversation and returns a list of the
|
||||||
|
json objects
|
||||||
|
"""
|
||||||
|
if '://' not in post_id:
|
||||||
|
return []
|
||||||
|
profile_str = 'https://www.w3.org/ns/activitystreams'
|
||||||
|
as_header = {
|
||||||
|
'Accept': 'application/ld+json; profile="' + profile_str + '"'
|
||||||
|
}
|
||||||
|
conversation_view = []
|
||||||
|
signing_priv_key_pem = get_instance_actor_key(base_dir, domain)
|
||||||
|
post_id = remove_id_ending(post_id)
|
||||||
|
post_filename = \
|
||||||
|
locate_post(base_dir, nickname, domain, post_id)
|
||||||
|
if post_filename:
|
||||||
|
post_json = load_json(post_filename)
|
||||||
|
else:
|
||||||
|
post_json = get_json(signing_priv_key_pem, session, post_id,
|
||||||
|
as_header, None, debug, __version__,
|
||||||
|
http_prefix, domain)
|
||||||
|
if debug:
|
||||||
|
if not post_json:
|
||||||
|
print(post_id + ' returned no json')
|
||||||
|
while post_json:
|
||||||
|
if not isinstance(post_json, dict):
|
||||||
|
break
|
||||||
|
if not has_object_dict(post_json):
|
||||||
|
if not post_json.get('attributedTo'):
|
||||||
|
print(str(post_json))
|
||||||
|
if debug:
|
||||||
|
print(post_id + ' has no attributedTo')
|
||||||
|
break
|
||||||
|
if not isinstance(post_json['attributedTo'], str):
|
||||||
|
break
|
||||||
|
if not post_json.get('published'):
|
||||||
|
if debug:
|
||||||
|
print(post_id + ' has no published date')
|
||||||
|
break
|
||||||
|
if not post_json.get('to'):
|
||||||
|
if debug:
|
||||||
|
print(post_id + ' has no "to" list')
|
||||||
|
break
|
||||||
|
if not isinstance(post_json['to'], list):
|
||||||
|
break
|
||||||
|
if 'cc' not in post_json:
|
||||||
|
if debug:
|
||||||
|
print(post_id + ' has no "cc" list')
|
||||||
|
break
|
||||||
|
if not isinstance(post_json['cc'], list):
|
||||||
|
break
|
||||||
|
wrapped_post = {
|
||||||
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
'id': post_id + '/activity',
|
||||||
|
'type': 'Create',
|
||||||
|
'actor': post_json['attributedTo'],
|
||||||
|
'published': post_json['published'],
|
||||||
|
'to': post_json['to'],
|
||||||
|
'cc': post_json['cc'],
|
||||||
|
'object': post_json
|
||||||
|
}
|
||||||
|
post_json = wrapped_post
|
||||||
|
conversation_view = [post_json] + conversation_view
|
||||||
|
if not post_json['object'].get('inReplyTo'):
|
||||||
|
if debug:
|
||||||
|
print(post_id + ' is not a reply')
|
||||||
|
break
|
||||||
|
post_id = post_json['object']['inReplyTo']
|
||||||
|
post_id = remove_id_ending(post_id)
|
||||||
|
post_filename = \
|
||||||
|
locate_post(base_dir, nickname, domain, post_id)
|
||||||
|
if post_filename:
|
||||||
|
post_json = load_json(post_filename)
|
||||||
|
else:
|
||||||
|
post_json = get_json(signing_priv_key_pem, session, post_id,
|
||||||
|
as_header, None, debug, __version__,
|
||||||
|
http_prefix, domain)
|
||||||
|
if debug:
|
||||||
|
if not post_json:
|
||||||
|
print(post_id + ' returned no json')
|
||||||
|
return conversation_view
|
||||||
|
|
60
daemon.py
60
daemon.py
|
@ -83,6 +83,7 @@ from person import remove_account
|
||||||
from person import can_remove_post
|
from person import can_remove_post
|
||||||
from person import person_snooze
|
from person import person_snooze
|
||||||
from person import person_unsnooze
|
from person import person_unsnooze
|
||||||
|
from keys import get_instance_actor_key
|
||||||
from posts import get_max_profile_posts
|
from posts import get_max_profile_posts
|
||||||
from posts import set_max_profile_posts
|
from posts import set_max_profile_posts
|
||||||
from posts import get_post_expiry_keep_dms
|
from posts import get_post_expiry_keep_dms
|
||||||
|
@ -91,7 +92,6 @@ from posts import get_post_expiry_days
|
||||||
from posts import set_post_expiry_days
|
from posts import set_post_expiry_days
|
||||||
from posts import get_original_post_from_announce_url
|
from posts import get_original_post_from_announce_url
|
||||||
from posts import save_post_to_box
|
from posts import save_post_to_box
|
||||||
from posts import get_instance_actor_key
|
|
||||||
from posts import remove_post_interactions
|
from posts import remove_post_interactions
|
||||||
from posts import outbox_message_create_wrap
|
from posts import outbox_message_create_wrap
|
||||||
from posts import get_pinned_post_as_json
|
from posts import get_pinned_post_as_json
|
||||||
|
@ -221,7 +221,7 @@ from webapp_suspended import html_suspended
|
||||||
from webapp_tos import html_terms_of_service
|
from webapp_tos import html_terms_of_service
|
||||||
from webapp_confirm import html_confirm_follow
|
from webapp_confirm import html_confirm_follow
|
||||||
from webapp_confirm import html_confirm_unfollow
|
from webapp_confirm import html_confirm_unfollow
|
||||||
from webapp_post import html_conversation_thread
|
from webapp_conversation import html_conversation_view
|
||||||
from webapp_post import html_emoji_reaction_picker
|
from webapp_post import html_emoji_reaction_picker
|
||||||
from webapp_post import html_post_replies
|
from webapp_post import html_post_replies
|
||||||
from webapp_post import html_individual_post
|
from webapp_post import html_individual_post
|
||||||
|
@ -11834,34 +11834,34 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if self.server.bold_reading.get(nickname):
|
if self.server.bold_reading.get(nickname):
|
||||||
bold_reading = True
|
bold_reading = True
|
||||||
conv_str = \
|
conv_str = \
|
||||||
html_conversation_thread(post_id, self.server.translate,
|
html_conversation_view(post_id, self.server.translate,
|
||||||
base_dir,
|
base_dir,
|
||||||
http_prefix,
|
http_prefix,
|
||||||
nickname,
|
nickname,
|
||||||
domain,
|
domain,
|
||||||
self.server.project_version,
|
self.server.project_version,
|
||||||
self.server.recent_posts_cache,
|
self.server.recent_posts_cache,
|
||||||
self.server.max_recent_posts,
|
self.server.max_recent_posts,
|
||||||
curr_session,
|
curr_session,
|
||||||
self.server.cached_webfingers,
|
self.server.cached_webfingers,
|
||||||
self.server.person_cache,
|
self.server.person_cache,
|
||||||
port,
|
port,
|
||||||
self.server.yt_replace_domain,
|
self.server.yt_replace_domain,
|
||||||
self.server.twitter_replacement_domain,
|
self.server.twitter_replacement_domain,
|
||||||
self.server.show_published_date_only,
|
self.server.show_published_date_only,
|
||||||
self.server.peertube_instances,
|
self.server.peertube_instances,
|
||||||
self.server.allow_local_network_access,
|
self.server.allow_local_network_access,
|
||||||
self.server.theme_name,
|
self.server.theme_name,
|
||||||
self.server.system_language,
|
self.server.system_language,
|
||||||
self.server.max_like_count,
|
self.server.max_like_count,
|
||||||
self.server.signing_priv_key_pem,
|
self.server.signing_priv_key_pem,
|
||||||
self.server.cw_lists,
|
self.server.cw_lists,
|
||||||
self.server.lists_enabled,
|
self.server.lists_enabled,
|
||||||
timezone, bold_reading,
|
timezone, bold_reading,
|
||||||
self.server.dogwhistles,
|
self.server.dogwhistles,
|
||||||
self.server.access_keys,
|
self.server.access_keys,
|
||||||
self.server.min_images_for_accounts,
|
self.server.min_images_for_accounts,
|
||||||
self.server.debug)
|
self.server.debug)
|
||||||
if conv_str:
|
if conv_str:
|
||||||
msg = conv_str.encode('utf-8')
|
msg = conv_str.encode('utf-8')
|
||||||
msglen = len(msg)
|
msglen = len(msg)
|
||||||
|
|
|
@ -26,9 +26,9 @@ from roles import set_role
|
||||||
from webfinger import webfinger_handle
|
from webfinger import webfinger_handle
|
||||||
from bookmarks import send_bookmark_via_server
|
from bookmarks import send_bookmark_via_server
|
||||||
from bookmarks import send_undo_bookmark_via_server
|
from bookmarks import send_undo_bookmark_via_server
|
||||||
from posts import download_conversation_posts
|
from conversation import download_conversation_posts
|
||||||
|
from keys import get_instance_actor_key
|
||||||
from posts import set_post_expiry_days
|
from posts import set_post_expiry_days
|
||||||
from posts import get_instance_actor_key
|
|
||||||
from posts import send_mute_via_server
|
from posts import send_mute_via_server
|
||||||
from posts import send_undo_mute_via_server
|
from posts import send_undo_mute_via_server
|
||||||
from posts import c2s_box_json
|
from posts import c2s_box_json
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
__filename__ = "keys.py"
|
||||||
|
__author__ = "Bob Mottram"
|
||||||
|
__license__ = "AGPL3+"
|
||||||
|
__version__ = "1.3.0"
|
||||||
|
__maintainer__ = "Bob Mottram"
|
||||||
|
__email__ = "bob@libreserver.org"
|
||||||
|
__status__ = "Production"
|
||||||
|
__module_group__ = "ActivityPub"
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def _get_local_private_key(base_dir: str, nickname: str, domain: str) -> str:
|
||||||
|
"""Returns the private key for a local account
|
||||||
|
"""
|
||||||
|
if not domain or not nickname:
|
||||||
|
return None
|
||||||
|
handle = nickname + '@' + domain
|
||||||
|
key_filename = base_dir + '/keys/private/' + handle.lower() + '.key'
|
||||||
|
if not os.path.isfile(key_filename):
|
||||||
|
return None
|
||||||
|
with open(key_filename, 'r', encoding='utf-8') as pem_file:
|
||||||
|
return pem_file.read()
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _get_local_public_key(base_dir: str, nickname: str, domain: str) -> str:
|
||||||
|
"""Returns the public key for a local account
|
||||||
|
"""
|
||||||
|
if not domain or not nickname:
|
||||||
|
return None
|
||||||
|
handle = nickname + '@' + domain
|
||||||
|
key_filename = base_dir + '/keys/public/' + handle.lower() + '.key'
|
||||||
|
if not os.path.isfile(key_filename):
|
||||||
|
return None
|
||||||
|
with open(key_filename, 'r', encoding='utf-8') as pem_file:
|
||||||
|
return pem_file.read()
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_instance_actor_key(base_dir: str, domain: str) -> str:
|
||||||
|
"""Returns the private key for the instance actor used for
|
||||||
|
signing GET posts
|
||||||
|
"""
|
||||||
|
return _get_local_private_key(base_dir, 'inbox', domain)
|
||||||
|
|
||||||
|
|
||||||
|
def get_person_key(nickname: str, domain: str, base_dir: str,
|
||||||
|
key_type: str = 'public', debug: bool = False):
|
||||||
|
"""Returns the public or private key of a person
|
||||||
|
"""
|
||||||
|
if key_type == 'private':
|
||||||
|
key_pem = _get_local_private_key(base_dir, nickname, domain)
|
||||||
|
else:
|
||||||
|
key_pem = _get_local_public_key(base_dir, nickname, domain)
|
||||||
|
if not key_pem:
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: ' + key_type + ' key file not found')
|
||||||
|
return ''
|
||||||
|
if len(key_pem) < 20:
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: private key was too short: ' + key_pem)
|
||||||
|
return ''
|
||||||
|
return key_pem
|
142
posts.py
142
posts.py
|
@ -101,6 +101,7 @@ from petnames import resolve_petnames
|
||||||
from video import convert_video_to_note
|
from video import convert_video_to_note
|
||||||
from context import get_individual_post_context
|
from context import get_individual_post_context
|
||||||
from maps import geocoords_from_map_link
|
from maps import geocoords_from_map_link
|
||||||
|
from keys import get_person_key
|
||||||
|
|
||||||
|
|
||||||
def is_moderator(base_dir: str, nickname: str) -> bool:
|
def is_moderator(base_dir: str, nickname: str) -> bool:
|
||||||
|
@ -151,60 +152,6 @@ def no_of_followers_on_domain(base_dir: str, handle: str,
|
||||||
return ctr
|
return ctr
|
||||||
|
|
||||||
|
|
||||||
def _get_local_private_key(base_dir: str, nickname: str, domain: str) -> str:
|
|
||||||
"""Returns the private key for a local account
|
|
||||||
"""
|
|
||||||
if not domain or not nickname:
|
|
||||||
return None
|
|
||||||
handle = nickname + '@' + domain
|
|
||||||
key_filename = base_dir + '/keys/private/' + handle.lower() + '.key'
|
|
||||||
if not os.path.isfile(key_filename):
|
|
||||||
return None
|
|
||||||
with open(key_filename, 'r', encoding='utf-8') as pem_file:
|
|
||||||
return pem_file.read()
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def get_instance_actor_key(base_dir: str, domain: str) -> str:
|
|
||||||
"""Returns the private key for the instance actor used for
|
|
||||||
signing GET posts
|
|
||||||
"""
|
|
||||||
return _get_local_private_key(base_dir, 'inbox', domain)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_local_public_key(base_dir: str, nickname: str, domain: str) -> str:
|
|
||||||
"""Returns the public key for a local account
|
|
||||||
"""
|
|
||||||
if not domain or not nickname:
|
|
||||||
return None
|
|
||||||
handle = nickname + '@' + domain
|
|
||||||
key_filename = base_dir + '/keys/public/' + handle.lower() + '.key'
|
|
||||||
if not os.path.isfile(key_filename):
|
|
||||||
return None
|
|
||||||
with open(key_filename, 'r', encoding='utf-8') as pem_file:
|
|
||||||
return pem_file.read()
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def _get_person_key(nickname: str, domain: str, base_dir: str,
|
|
||||||
key_type: str = 'public', debug: bool = False):
|
|
||||||
"""Returns the public or private key of a person
|
|
||||||
"""
|
|
||||||
if key_type == 'private':
|
|
||||||
key_pem = _get_local_private_key(base_dir, nickname, domain)
|
|
||||||
else:
|
|
||||||
key_pem = _get_local_public_key(base_dir, nickname, domain)
|
|
||||||
if not key_pem:
|
|
||||||
if debug:
|
|
||||||
print('DEBUG: ' + key_type + ' key file not found')
|
|
||||||
return ''
|
|
||||||
if len(key_pem) < 20:
|
|
||||||
if debug:
|
|
||||||
print('DEBUG: private key was too short: ' + key_pem)
|
|
||||||
return ''
|
|
||||||
return key_pem
|
|
||||||
|
|
||||||
|
|
||||||
def _clean_html(raw_html: str) -> str:
|
def _clean_html(raw_html: str) -> str:
|
||||||
# text=BeautifulSoup(raw_html, 'html.parser').get_text()
|
# text=BeautifulSoup(raw_html, 'html.parser').get_text()
|
||||||
text = raw_html
|
text = raw_html
|
||||||
|
@ -2532,7 +2479,7 @@ def send_post(signing_priv_key_pem: str, project_version: str,
|
||||||
translate)
|
translate)
|
||||||
|
|
||||||
# get the senders private key
|
# get the senders private key
|
||||||
private_key_pem = _get_person_key(nickname, domain, base_dir, 'private')
|
private_key_pem = get_person_key(nickname, domain, base_dir, 'private')
|
||||||
if len(private_key_pem) == 0:
|
if len(private_key_pem) == 0:
|
||||||
return 6
|
return 6
|
||||||
|
|
||||||
|
@ -2937,7 +2884,7 @@ def send_signed_json(post_json_object: {}, session, base_dir: str,
|
||||||
if account_domain == i2p_domain:
|
if account_domain == i2p_domain:
|
||||||
account_domain = curr_domain
|
account_domain = curr_domain
|
||||||
private_key_pem = \
|
private_key_pem = \
|
||||||
_get_person_key(nickname, account_domain, base_dir, 'private', debug)
|
get_person_key(nickname, account_domain, base_dir, 'private', debug)
|
||||||
if len(private_key_pem) == 0:
|
if len(private_key_pem) == 0:
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: Private key not found for ' +
|
print('DEBUG: Private key not found for ' +
|
||||||
|
@ -6094,86 +6041,3 @@ def set_max_profile_posts(base_dir: str, nickname: str, domain: str,
|
||||||
max_posts_filename)
|
max_posts_filename)
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def download_conversation_posts(session, http_prefix: str, base_dir: str,
|
|
||||||
nickname: str, domain: str,
|
|
||||||
post_id: str, debug: bool) -> []:
|
|
||||||
"""Downloads all posts for a conversation and returns a list of the
|
|
||||||
json objects
|
|
||||||
"""
|
|
||||||
if '://' not in post_id:
|
|
||||||
return []
|
|
||||||
profile_str = 'https://www.w3.org/ns/activitystreams'
|
|
||||||
as_header = {
|
|
||||||
'Accept': 'application/ld+json; profile="' + profile_str + '"'
|
|
||||||
}
|
|
||||||
conversation_thread = []
|
|
||||||
signing_priv_key_pem = get_instance_actor_key(base_dir, domain)
|
|
||||||
post_id = remove_id_ending(post_id)
|
|
||||||
post_filename = \
|
|
||||||
locate_post(base_dir, nickname, domain, post_id)
|
|
||||||
if post_filename:
|
|
||||||
post_json = load_json(post_filename)
|
|
||||||
else:
|
|
||||||
post_json = get_json(signing_priv_key_pem, session, post_id,
|
|
||||||
as_header, None, debug, __version__,
|
|
||||||
http_prefix, domain)
|
|
||||||
if debug:
|
|
||||||
if not post_json:
|
|
||||||
print(post_id + ' returned no json')
|
|
||||||
while post_json:
|
|
||||||
if not has_object_dict(post_json):
|
|
||||||
if not post_json.get('attributedTo'):
|
|
||||||
print(str(post_json))
|
|
||||||
if debug:
|
|
||||||
print(post_id + ' has no attributedTo')
|
|
||||||
break
|
|
||||||
if not isinstance(post_json['attributedTo'], str):
|
|
||||||
break
|
|
||||||
if not post_json.get('published'):
|
|
||||||
if debug:
|
|
||||||
print(post_id + ' has no published date')
|
|
||||||
break
|
|
||||||
if not post_json.get('to'):
|
|
||||||
if debug:
|
|
||||||
print(post_id + ' has no "to" list')
|
|
||||||
break
|
|
||||||
if not isinstance(post_json['to'], list):
|
|
||||||
break
|
|
||||||
if 'cc' not in post_json:
|
|
||||||
if debug:
|
|
||||||
print(post_id + ' has no "cc" list')
|
|
||||||
break
|
|
||||||
if not isinstance(post_json['cc'], list):
|
|
||||||
break
|
|
||||||
wrapped_post = {
|
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
|
||||||
'id': post_id + '/activity',
|
|
||||||
'type': 'Create',
|
|
||||||
'actor': post_json['attributedTo'],
|
|
||||||
'published': post_json['published'],
|
|
||||||
'to': post_json['to'],
|
|
||||||
'cc': post_json['cc'],
|
|
||||||
'object': post_json
|
|
||||||
}
|
|
||||||
post_json = wrapped_post
|
|
||||||
conversation_thread = [post_json] + conversation_thread
|
|
||||||
if not post_json['object'].get('inReplyTo'):
|
|
||||||
if debug:
|
|
||||||
print(post_id + ' is not a reply')
|
|
||||||
break
|
|
||||||
post_id = post_json['object']['inReplyTo']
|
|
||||||
post_id = remove_id_ending(post_id)
|
|
||||||
post_filename = \
|
|
||||||
locate_post(base_dir, nickname, domain, post_id)
|
|
||||||
if post_filename:
|
|
||||||
post_json = load_json(post_filename)
|
|
||||||
else:
|
|
||||||
post_json = get_json(signing_priv_key_pem, session, post_id,
|
|
||||||
as_header, None, debug, __version__,
|
|
||||||
http_prefix, domain)
|
|
||||||
if debug:
|
|
||||||
if not post_json:
|
|
||||||
print(post_id + ' returned no json')
|
|
||||||
return conversation_thread
|
|
||||||
|
|
2
tests.py
2
tests.py
|
@ -1400,7 +1400,7 @@ def test_post_message_between_servers(base_dir: str) -> None:
|
||||||
assert 'यह एक परीक्षण है' in received_json['object']['content']
|
assert 'यह एक परीक्षण है' in received_json['object']['content']
|
||||||
print('Check that message received from Alice contains an attachment')
|
print('Check that message received from Alice contains an attachment')
|
||||||
assert received_json['object']['attachment']
|
assert received_json['object']['attachment']
|
||||||
assert len(received_json['object']['attachment']) == 1
|
assert len(received_json['object']['attachment']) == 2
|
||||||
attached = received_json['object']['attachment'][0]
|
attached = received_json['object']['attachment'][0]
|
||||||
pprint(attached)
|
pprint(attached)
|
||||||
assert attached.get('type')
|
assert attached.get('type')
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
__filename__ = "conversation.py"
|
||||||
|
__author__ = "Bob Mottram"
|
||||||
|
__license__ = "AGPL3+"
|
||||||
|
__version__ = "1.3.0"
|
||||||
|
__maintainer__ = "Bob Mottram"
|
||||||
|
__email__ = "bob@libreserver.org"
|
||||||
|
__status__ = "Production"
|
||||||
|
__module_group__ = "Timeline"
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
from conversation import download_conversation_posts
|
||||||
|
from utils import get_config_param
|
||||||
|
from webapp_utils import html_header_with_external_style
|
||||||
|
from webapp_utils import html_post_separator
|
||||||
|
from webapp_utils import html_footer
|
||||||
|
from webapp_post import individual_post_as_html
|
||||||
|
|
||||||
|
|
||||||
|
def html_conversation_view(post_id: str,
|
||||||
|
translate: {}, base_dir: str,
|
||||||
|
http_prefix: str,
|
||||||
|
nickname: str, domain: str,
|
||||||
|
project_version: str,
|
||||||
|
recent_posts_cache: {},
|
||||||
|
max_recent_posts: int,
|
||||||
|
session,
|
||||||
|
cached_webfingers,
|
||||||
|
person_cache: {},
|
||||||
|
port: int,
|
||||||
|
yt_replace_domain: str,
|
||||||
|
twitter_replacement_domain: str,
|
||||||
|
show_published_date_only: bool,
|
||||||
|
peertube_instances: [],
|
||||||
|
allow_local_network_access: bool,
|
||||||
|
theme_name: str,
|
||||||
|
system_language: str,
|
||||||
|
max_like_count: int,
|
||||||
|
signing_priv_key_pem: str,
|
||||||
|
cw_lists: {},
|
||||||
|
lists_enabled: str,
|
||||||
|
timezone: str, bold_reading: bool,
|
||||||
|
dogwhistles: {}, access_keys: {},
|
||||||
|
min_images_for_accounts: [],
|
||||||
|
debug: bool) -> str:
|
||||||
|
"""Show a page containing a conversation thread
|
||||||
|
"""
|
||||||
|
conv_posts = \
|
||||||
|
download_conversation_posts(session, http_prefix, base_dir,
|
||||||
|
nickname, domain,
|
||||||
|
post_id, debug)
|
||||||
|
|
||||||
|
if not conv_posts:
|
||||||
|
return None
|
||||||
|
|
||||||
|
css_filename = base_dir + '/epicyon-profile.css'
|
||||||
|
if os.path.isfile(base_dir + '/epicyon.css'):
|
||||||
|
css_filename = base_dir + '/epicyon.css'
|
||||||
|
|
||||||
|
instance_title = \
|
||||||
|
get_config_param(base_dir, 'instanceTitle')
|
||||||
|
conv_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:
|
||||||
|
minimize_all_images = True
|
||||||
|
for post_json_object in conv_posts:
|
||||||
|
show_individual_post_icons = False
|
||||||
|
allow_deletion = False
|
||||||
|
post_str = \
|
||||||
|
individual_post_as_html(signing_priv_key_pem,
|
||||||
|
True, recent_posts_cache,
|
||||||
|
max_recent_posts,
|
||||||
|
translate, None,
|
||||||
|
base_dir, session, cached_webfingers,
|
||||||
|
person_cache,
|
||||||
|
nickname, domain, port,
|
||||||
|
post_json_object,
|
||||||
|
None, True, allow_deletion,
|
||||||
|
http_prefix, project_version,
|
||||||
|
'search',
|
||||||
|
yt_replace_domain,
|
||||||
|
twitter_replacement_domain,
|
||||||
|
show_published_date_only,
|
||||||
|
peertube_instances,
|
||||||
|
allow_local_network_access,
|
||||||
|
theme_name, system_language,
|
||||||
|
max_like_count,
|
||||||
|
show_individual_post_icons,
|
||||||
|
show_individual_post_icons,
|
||||||
|
False, False, False, False,
|
||||||
|
cw_lists, lists_enabled,
|
||||||
|
timezone, False, bold_reading,
|
||||||
|
dogwhistles,
|
||||||
|
minimize_all_images)
|
||||||
|
if post_str:
|
||||||
|
conv_str += text_mode_separator + separator_str + post_str
|
||||||
|
|
||||||
|
conv_str += text_mode_separator + html_footer()
|
||||||
|
return conv_str
|
|
@ -21,7 +21,6 @@ from announce import no_of_announces
|
||||||
from like import liked_by_person
|
from like import liked_by_person
|
||||||
from like import no_of_likes
|
from like import no_of_likes
|
||||||
from follow import is_following_actor
|
from follow import is_following_actor
|
||||||
from posts import download_conversation_posts
|
|
||||||
from posts import post_is_muted
|
from posts import post_is_muted
|
||||||
from posts import get_person_box
|
from posts import get_person_box
|
||||||
from posts import download_announce
|
from posts import download_announce
|
||||||
|
@ -93,7 +92,6 @@ from webapp_utils import get_post_attachments_as_html
|
||||||
from webapp_utils import html_header_with_external_style
|
from webapp_utils import html_header_with_external_style
|
||||||
from webapp_utils import html_footer
|
from webapp_utils import html_footer
|
||||||
from webapp_utils import get_broken_link_substitute
|
from webapp_utils import get_broken_link_substitute
|
||||||
from webapp_utils import html_post_separator
|
|
||||||
from webapp_media import add_embedded_elements
|
from webapp_media import add_embedded_elements
|
||||||
from webapp_question import insert_question
|
from webapp_question import insert_question
|
||||||
from devices import e2e_edecrypt_message_from_device
|
from devices import e2e_edecrypt_message_from_device
|
||||||
|
@ -2922,90 +2920,3 @@ def html_emoji_reaction_picker(recent_posts_cache: {}, max_recent_posts: int,
|
||||||
'</header>\n'
|
'</header>\n'
|
||||||
|
|
||||||
return header_str + reacted_to_post_str + emoji_picks_str + html_footer()
|
return header_str + reacted_to_post_str + emoji_picks_str + html_footer()
|
||||||
|
|
||||||
|
|
||||||
def html_conversation_thread(post_id: str,
|
|
||||||
translate: {}, base_dir: str,
|
|
||||||
http_prefix: str,
|
|
||||||
nickname: str, domain: str,
|
|
||||||
project_version: str,
|
|
||||||
recent_posts_cache: {},
|
|
||||||
max_recent_posts: int,
|
|
||||||
session,
|
|
||||||
cached_webfingers,
|
|
||||||
person_cache: {},
|
|
||||||
port: int,
|
|
||||||
yt_replace_domain: str,
|
|
||||||
twitter_replacement_domain: str,
|
|
||||||
show_published_date_only: bool,
|
|
||||||
peertube_instances: [],
|
|
||||||
allow_local_network_access: bool,
|
|
||||||
theme_name: str,
|
|
||||||
system_language: str,
|
|
||||||
max_like_count: int,
|
|
||||||
signing_priv_key_pem: str,
|
|
||||||
cw_lists: {},
|
|
||||||
lists_enabled: str,
|
|
||||||
timezone: str, bold_reading: bool,
|
|
||||||
dogwhistles: {}, access_keys: {},
|
|
||||||
min_images_for_accounts: [],
|
|
||||||
debug: bool) -> str:
|
|
||||||
"""Show a page containing a conversation thread
|
|
||||||
"""
|
|
||||||
conv_posts = \
|
|
||||||
download_conversation_posts(session, http_prefix, base_dir,
|
|
||||||
nickname, domain,
|
|
||||||
post_id, debug)
|
|
||||||
|
|
||||||
if not conv_posts:
|
|
||||||
return None
|
|
||||||
|
|
||||||
css_filename = base_dir + '/epicyon-profile.css'
|
|
||||||
if os.path.isfile(base_dir + '/epicyon.css'):
|
|
||||||
css_filename = base_dir + '/epicyon.css'
|
|
||||||
|
|
||||||
instance_title = \
|
|
||||||
get_config_param(base_dir, 'instanceTitle')
|
|
||||||
conv_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:
|
|
||||||
minimize_all_images = True
|
|
||||||
for post_json_object in conv_posts:
|
|
||||||
show_individual_post_icons = False
|
|
||||||
allow_deletion = False
|
|
||||||
post_str = \
|
|
||||||
individual_post_as_html(signing_priv_key_pem,
|
|
||||||
True, recent_posts_cache,
|
|
||||||
max_recent_posts,
|
|
||||||
translate, None,
|
|
||||||
base_dir, session, cached_webfingers,
|
|
||||||
person_cache,
|
|
||||||
nickname, domain, port,
|
|
||||||
post_json_object,
|
|
||||||
None, True, allow_deletion,
|
|
||||||
http_prefix, project_version,
|
|
||||||
'search',
|
|
||||||
yt_replace_domain,
|
|
||||||
twitter_replacement_domain,
|
|
||||||
show_published_date_only,
|
|
||||||
peertube_instances,
|
|
||||||
allow_local_network_access,
|
|
||||||
theme_name, system_language,
|
|
||||||
max_like_count,
|
|
||||||
show_individual_post_icons,
|
|
||||||
show_individual_post_icons,
|
|
||||||
False, False, False, False,
|
|
||||||
cw_lists, lists_enabled,
|
|
||||||
timezone, False, bold_reading,
|
|
||||||
dogwhistles,
|
|
||||||
minimize_all_images)
|
|
||||||
if post_str:
|
|
||||||
conv_str += text_mode_separator + separator_str + post_str
|
|
||||||
|
|
||||||
conv_str += text_mode_separator + html_footer()
|
|
||||||
return conv_str
|
|
||||||
|
|
Loading…
Reference in New Issue