Merge branch 'bashrc2:main' into infra-provisioning
152
blocking.py
|
@ -1460,3 +1460,155 @@ def get_cw_list_variable(list_name: str) -> str:
|
|||
"""Returns the variable associated with a CW list
|
||||
"""
|
||||
return 'list' + list_name.replace(' ', '').replace("'", '')
|
||||
|
||||
|
||||
def import_blocking_file(base_dir: str, nickname: str, domain: str,
|
||||
lines: []) -> bool:
|
||||
"""Imports blocked domains for a given account
|
||||
"""
|
||||
if not lines:
|
||||
return False
|
||||
if len(lines) < 2:
|
||||
return False
|
||||
if not lines[0].startswith('#domain,#') or \
|
||||
'comment' not in lines[0]:
|
||||
return False
|
||||
fieldnames = lines[0].split(',')
|
||||
comment_field_index = 0
|
||||
for field_str in fieldnames:
|
||||
if 'comment' in field_str:
|
||||
break
|
||||
comment_field_index += 1
|
||||
if comment_field_index >= len(fieldnames):
|
||||
return False
|
||||
|
||||
account_directory = acct_dir(base_dir, nickname, domain)
|
||||
blocking_filename = \
|
||||
account_directory + '/blocking.txt'
|
||||
blocking_reasons_filename = \
|
||||
account_directory + '/blocking_reasons.txt'
|
||||
|
||||
existing_lines = []
|
||||
if os.path.isfile(blocking_filename):
|
||||
try:
|
||||
with open(blocking_filename, 'r', encoding='utf-8') as fp_blocks:
|
||||
existing_lines = fp_blocks.read().splitlines()
|
||||
except OSError:
|
||||
print('EX: ' +
|
||||
'unable to import existing blocked instances from file ' +
|
||||
blocking_filename)
|
||||
existing_reasons = []
|
||||
if os.path.isfile(blocking_reasons_filename):
|
||||
try:
|
||||
with open(blocking_reasons_filename,
|
||||
'r', encoding='utf-8') as fp_blocks:
|
||||
existing_reasons = fp_blocks.read().splitlines()
|
||||
except OSError:
|
||||
print('EX: ' +
|
||||
'unable to import existing ' +
|
||||
'blocked instance reasons from file ' +
|
||||
blocking_reasons_filename)
|
||||
|
||||
append_blocks = []
|
||||
append_reasons = []
|
||||
for line_str in lines:
|
||||
if line_str.startswith('#'):
|
||||
continue
|
||||
block_fields = line_str.split(',')
|
||||
blocked_domain_name = block_fields[0].strip()
|
||||
if ' ' in blocked_domain_name or \
|
||||
'.' not in blocked_domain_name:
|
||||
continue
|
||||
if blocked_domain_name in existing_lines:
|
||||
# already blocked
|
||||
continue
|
||||
append_blocks.append(blocked_domain_name)
|
||||
blocked_comment = ''
|
||||
if '"' in line_str:
|
||||
quote_section = line_str.split('"')
|
||||
if len(quote_section) > 1:
|
||||
blocked_comment = quote_section[1]
|
||||
append_reasons.append(blocked_domain_name + ' ' +
|
||||
blocked_comment)
|
||||
if not blocked_comment:
|
||||
if len(block_fields) > comment_field_index:
|
||||
blocked_comment = block_fields[comment_field_index].strip()
|
||||
if blocked_comment:
|
||||
if blocked_comment.startswith('"'):
|
||||
blocked_comment = blocked_comment.replace('"', '')
|
||||
if blocked_comment not in existing_reasons:
|
||||
append_reasons.append(blocked_domain_name + ' ' +
|
||||
blocked_comment)
|
||||
if not append_blocks:
|
||||
return True
|
||||
|
||||
try:
|
||||
with open(blocking_filename, 'a+', encoding='utf-8') as fp_blocks:
|
||||
for new_block in append_blocks:
|
||||
fp_blocks.write(new_block + '\n')
|
||||
except OSError:
|
||||
print('EX: ' +
|
||||
'unable to append imported blocks to ' +
|
||||
blocking_filename)
|
||||
|
||||
try:
|
||||
with open(blocking_reasons_filename, 'a+',
|
||||
encoding='utf-8') as fp_blocks:
|
||||
for new_reason in append_reasons:
|
||||
fp_blocks.write(new_reason + '\n')
|
||||
except OSError:
|
||||
print('EX: ' +
|
||||
'unable to append imported block reasons to ' +
|
||||
blocking_reasons_filename)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def export_blocking_file(base_dir: str, nickname: str, domain: str) -> str:
|
||||
"""exports account level blocks in a csv format
|
||||
"""
|
||||
account_directory = acct_dir(base_dir, nickname, domain)
|
||||
blocking_filename = \
|
||||
account_directory + '/blocking.txt'
|
||||
blocking_reasons_filename = \
|
||||
account_directory + '/blocking_reasons.txt'
|
||||
|
||||
blocks_header = \
|
||||
'#domain,#severity,#reject_media,#reject_reports,' + \
|
||||
'#public_comment,#obfuscate\n'
|
||||
|
||||
if not os.path.isfile(blocking_filename):
|
||||
return blocks_header
|
||||
|
||||
blocking_lines = []
|
||||
if os.path.isfile(blocking_filename):
|
||||
try:
|
||||
with open(blocking_filename, 'r', encoding='utf-8') as fp_block:
|
||||
blocking_lines = fp_block.read().splitlines()
|
||||
except OSError:
|
||||
print('EX: export_blocks failed to read ' + blocking_filename)
|
||||
|
||||
blocking_reasons = []
|
||||
if os.path.isfile(blocking_reasons_filename):
|
||||
try:
|
||||
with open(blocking_reasons_filename, 'r',
|
||||
encoding='utf-8') as fp_block:
|
||||
blocking_reasons = fp_block.read().splitlines()
|
||||
except OSError:
|
||||
print('EX: export_blocks failed to read ' +
|
||||
blocking_reasons_filename)
|
||||
|
||||
blocks_str = blocks_header
|
||||
for blocked_domain in blocking_lines:
|
||||
blocked_domain = blocked_domain.strip()
|
||||
if blocked_domain.startswith('#'):
|
||||
continue
|
||||
reason_str = ''
|
||||
for reason_line in blocking_reasons:
|
||||
if reason_line.startswith(blocked_domain + ' '):
|
||||
reason_str = reason_line.split(' ', 1)[1]
|
||||
break
|
||||
blocks_str += \
|
||||
blocked_domain + ',suspend,false,false,"' + \
|
||||
reason_str + '",false\n'
|
||||
return blocks_str
|
||||
|
|
|
@ -1705,7 +1705,8 @@ def extract_text_fields_in_post(post_bytes, boundary: str, debug: bool,
|
|||
fields_with_semicolon_allowed = (
|
||||
'message', 'bio', 'autoCW', 'password', 'passwordconfirm',
|
||||
'instanceDescription', 'instanceDescriptionShort',
|
||||
'subject', 'location', 'imageDescription'
|
||||
'subject', 'location', 'imageDescription', 'importBlocks',
|
||||
'importFollows', 'importTheme'
|
||||
)
|
||||
if debug:
|
||||
if 'password' not in message_fields:
|
||||
|
|
100
daemon.py
|
@ -147,6 +147,8 @@ from media import replace_twitter
|
|||
from media import attach_media
|
||||
from media import path_is_video
|
||||
from media import path_is_audio
|
||||
from blocking import import_blocking_file
|
||||
from blocking import export_blocking_file
|
||||
from blocking import add_account_blocks
|
||||
from blocking import get_cw_list_variable
|
||||
from blocking import load_cw_lists
|
||||
|
@ -6163,6 +6165,9 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
if b'--LYNX' in post_bytes:
|
||||
boundary = '--LYNX'
|
||||
|
||||
if debug:
|
||||
print('post_bytes: ' + str(post_bytes))
|
||||
|
||||
if boundary:
|
||||
# get the various avatar, banner and background images
|
||||
actor_changed = True
|
||||
|
@ -6171,8 +6176,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
'banner', 'search_banner',
|
||||
'instanceLogo',
|
||||
'left_col_image', 'right_col_image',
|
||||
'submitImportFollows',
|
||||
'submitImportTheme'
|
||||
'importFollows',
|
||||
'importTheme'
|
||||
)
|
||||
profile_media_types_uploaded = {}
|
||||
for m_type in profile_media_types:
|
||||
|
@ -6205,7 +6210,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
if m_type == 'instanceLogo':
|
||||
filename_base = \
|
||||
base_dir + '/accounts/login.temp'
|
||||
elif m_type == 'submitImportTheme':
|
||||
elif m_type == 'importTheme':
|
||||
if not os.path.isdir(base_dir + '/imports'):
|
||||
os.mkdir(base_dir + '/imports')
|
||||
filename_base = \
|
||||
|
@ -6216,7 +6221,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
except OSError:
|
||||
print('EX: _profile_edit unable to delete ' +
|
||||
filename_base)
|
||||
elif m_type == 'submitImportFollows':
|
||||
elif m_type == 'importFollows':
|
||||
filename_base = \
|
||||
acct_dir(base_dir, nickname, domain) + \
|
||||
'/import_following.csv'
|
||||
|
@ -6236,7 +6241,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
' media, zip, csv or font filename in POST')
|
||||
continue
|
||||
|
||||
if m_type == 'submitImportFollows':
|
||||
if m_type == 'importFollows':
|
||||
if os.path.isfile(filename_base):
|
||||
print(nickname + ' imported follows csv')
|
||||
else:
|
||||
|
@ -6244,7 +6249,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
nickname)
|
||||
continue
|
||||
|
||||
if m_type == 'submitImportTheme':
|
||||
if m_type == 'importTheme':
|
||||
if nickname == admin_nickname or \
|
||||
is_artist(base_dir, nickname):
|
||||
if import_theme(base_dir, filename):
|
||||
|
@ -6316,6 +6321,14 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
cookie, calling_domain)
|
||||
self.server.postreq_busy = False
|
||||
return
|
||||
elif 'name="submitExportBlocks"' in post_bytes_str:
|
||||
print('submitExportBlocks')
|
||||
blocks_download_path = actor_str + '/exports/blocks.csv'
|
||||
print('submitExportBlocks path=' + blocks_download_path)
|
||||
self._redirect_headers(blocks_download_path,
|
||||
cookie, calling_domain)
|
||||
self.server.postreq_busy = False
|
||||
return
|
||||
|
||||
# extract all of the text fields into a dict
|
||||
fields = \
|
||||
|
@ -7807,6 +7820,50 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
else:
|
||||
add_account_blocks(base_dir,
|
||||
nickname, domain, '')
|
||||
# import blocks from csv file
|
||||
if fields.get('importBlocks'):
|
||||
blocks_str = fields['importBlocks']
|
||||
while blocks_str.startswith('\n'):
|
||||
blocks_str = blocks_str[1:]
|
||||
blocks_lines = blocks_str.split('\n')
|
||||
if import_blocking_file(base_dir, nickname, domain,
|
||||
blocks_lines):
|
||||
print('blocks imported for ' + nickname)
|
||||
else:
|
||||
print('blocks not imported for ' + nickname)
|
||||
|
||||
if fields.get('importFollows'):
|
||||
filename_base = \
|
||||
acct_dir(base_dir, nickname, domain) + \
|
||||
'/import_following.csv'
|
||||
follows_str = fields['importFollows']
|
||||
while follows_str.startswith('\n'):
|
||||
follows_str = follows_str[1:]
|
||||
try:
|
||||
with open(filename_base, 'w+',
|
||||
encoding='utf-8') as fp_foll:
|
||||
fp_foll.write(follows_str)
|
||||
except OSError:
|
||||
print('EX: unable to write imported follows ' +
|
||||
filename_base)
|
||||
|
||||
if fields.get('importTheme'):
|
||||
if not os.path.isdir(base_dir + '/imports'):
|
||||
os.mkdir(base_dir + '/imports')
|
||||
filename_base = \
|
||||
base_dir + '/imports/newtheme.zip'
|
||||
if os.path.isfile(filename_base):
|
||||
try:
|
||||
os.remove(filename_base)
|
||||
except OSError:
|
||||
print('EX: _profile_edit unable to delete ' +
|
||||
filename_base)
|
||||
if nickname == admin_nickname or \
|
||||
is_artist(base_dir, nickname):
|
||||
if import_theme(base_dir, filename_base):
|
||||
print(nickname + ' uploaded a theme')
|
||||
else:
|
||||
print('Only admin or artist can import a theme')
|
||||
|
||||
# Save DM allowed instances list.
|
||||
# The allow list for incoming DMs,
|
||||
|
@ -8363,6 +8420,25 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self._write(export_binary)
|
||||
self._404()
|
||||
|
||||
def _get_exported_blocks(self, path: str, base_dir: str,
|
||||
domain: str,
|
||||
calling_domain: str) -> None:
|
||||
"""Returns an exported blocks csv file
|
||||
"""
|
||||
filename = path.split('/exports/', 1)[1]
|
||||
filename = base_dir + '/exports/' + filename
|
||||
nickname = get_nickname_from_actor(path)
|
||||
if nickname:
|
||||
blocks_str = export_blocking_file(base_dir, nickname, domain)
|
||||
if blocks_str:
|
||||
msg = blocks_str.encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/csv',
|
||||
msglen, None, calling_domain, False)
|
||||
self._write(msg)
|
||||
return
|
||||
self._404()
|
||||
|
||||
def _get_fonts(self, calling_domain: str, path: str,
|
||||
base_dir: str, debug: bool,
|
||||
getreq_start_time) -> None:
|
||||
|
@ -17293,9 +17369,15 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
return
|
||||
|
||||
if authorized and '/exports/' in self.path:
|
||||
self._get_exported_theme(self.path,
|
||||
self.server.base_dir,
|
||||
self.server.domain_full)
|
||||
if 'blocks.csv' in self.path:
|
||||
self._get_exported_blocks(self.path,
|
||||
self.server.base_dir,
|
||||
self.server.domain,
|
||||
calling_domain)
|
||||
else:
|
||||
self._get_exported_theme(self.path,
|
||||
self.server.base_dir,
|
||||
self.server.domain_full)
|
||||
return
|
||||
|
||||
# get fonts
|
||||
|
|
|
@ -182,7 +182,7 @@ def _mark_post_as_read(actor: str, post_id: str, post_category: str) -> None:
|
|||
if post_id not in content:
|
||||
read_file.seek(0, 0)
|
||||
read_file.write(post_id + content)
|
||||
except Exception as ex:
|
||||
except OSError as ex:
|
||||
print('EX: Failed to mark post as read' + str(ex))
|
||||
else:
|
||||
with open(read_posts_filename, 'w+', encoding='utf-8') as read_file:
|
||||
|
|
|
@ -1178,6 +1178,14 @@ h3 {
|
|||
font-size: var(--font-size);
|
||||
color: var(--title-color);
|
||||
}
|
||||
.container img.postScopeIcon {
|
||||
float: none;
|
||||
width: 30px;
|
||||
margin: 0 0;
|
||||
padding: 0 0;
|
||||
border-radius: 0;
|
||||
vertical-align: -6px;
|
||||
}
|
||||
figcaption img.emojiheader {
|
||||
float: none;
|
||||
width: 25px;
|
||||
|
@ -2000,6 +2008,14 @@ h3 {
|
|||
font-size: var(--font-size-mobile);
|
||||
color: var(--title-color);
|
||||
}
|
||||
.container img.postScopeIcon {
|
||||
float: none;
|
||||
width: 50px;
|
||||
margin: 0 0;
|
||||
padding: 0 0;
|
||||
border-radius: 0;
|
||||
vertical-align: -6px;
|
||||
}
|
||||
blockquote {
|
||||
font-size: var(--quote-font-size-mobile);
|
||||
}
|
||||
|
@ -2812,6 +2828,14 @@ h3 {
|
|||
font-size: var(--font-size-tiny);
|
||||
color: var(--title-color);
|
||||
}
|
||||
.container img.postScopeIcon {
|
||||
float: none;
|
||||
width: 50px;
|
||||
margin: 0 0;
|
||||
padding: 0 0;
|
||||
border-radius: 0;
|
||||
vertical-align: -6px;
|
||||
}
|
||||
blockquote {
|
||||
font-size: var(--quote-font-size-tiny);
|
||||
}
|
||||
|
|
11
inbox.py
|
@ -822,7 +822,9 @@ def _inbox_post_recipients_add(base_dir: str, http_prefix: str, to_list: [],
|
|||
handle + ' does not exist')
|
||||
else:
|
||||
if debug:
|
||||
if recipient.endswith('#Public'):
|
||||
if recipient.endswith('#Public') or \
|
||||
recipient == 'as:Public' or \
|
||||
recipient == 'Public':
|
||||
print('DEBUG: #Public recipient is too non-specific. ' +
|
||||
recipient + ' ' + domain_match)
|
||||
else:
|
||||
|
@ -2693,7 +2695,7 @@ def _receive_announce(recent_posts_cache: {},
|
|||
announced_actor_nickname + '@' + announced_actor_domain)
|
||||
return False
|
||||
|
||||
# is this post in the outbox of the person?
|
||||
# is this post in the inbox or outbox of the account?
|
||||
post_filename = locate_post(base_dir, nickname, domain,
|
||||
message_json['object'])
|
||||
if not post_filename:
|
||||
|
@ -2701,6 +2703,7 @@ def _receive_announce(recent_posts_cache: {},
|
|||
print('DEBUG: announce post not found in inbox or outbox')
|
||||
print(message_json['object'])
|
||||
return True
|
||||
# add actor to the list of announcers for a post
|
||||
update_announce_collection(recent_posts_cache, base_dir, post_filename,
|
||||
message_json['actor'], nickname, domain, debug)
|
||||
if debug:
|
||||
|
@ -3179,7 +3182,9 @@ def _valid_post_content(base_dir: str, nickname: str, domain: str,
|
|||
'allow comments: ' + original_post_id)
|
||||
return False
|
||||
if invalid_ciphertext(message_json['object']['content']):
|
||||
print('REJECT: malformed ciphertext in content')
|
||||
print('REJECT: malformed ciphertext in content ' +
|
||||
message_json['object']['id'] + ' ' +
|
||||
message_json['object']['content'])
|
||||
return False
|
||||
if debug:
|
||||
print('ACCEPT: post content is valid')
|
||||
|
|
|
@ -48,7 +48,8 @@ beginning. The ActivityPub protocol was initially called
|
|||
creation. Fediverse servers are typically referred to as “instances”,
|
||||
but they are really just websites which can speak with each other using
|
||||
the vocabulary of ActivityPub. Choosing an instance is the same as
|
||||
choosing a website that you trust to handle your data.</p>
|
||||
choosing a website that you trust to handle your data. This is <em>the
|
||||
social web</em>.</p>
|
||||
<p>Servers such as <a
|
||||
href="https://github.com/mastodon/mastodon">Mastodon</a> are well known,
|
||||
but these are aimed at large scale deployments on powerful hardware
|
||||
|
@ -622,6 +623,9 @@ shortcuts</em> link at the bottom of the left column.</p>
|
|||
<figcaption aria-hidden="true">Keyboard shortcuts screen</figcaption>
|
||||
</figure>
|
||||
<h1 id="calendar">Calendar</h1>
|
||||
<p><em>“There is nothing in this world that does not have a decisive
|
||||
moment”</em></p>
|
||||
<p>– Henri Cartier-Bresson</p>
|
||||
<p>The calendar is not yet a standardized feature of the fediverse as a
|
||||
whole, but has existed in Friendica and Zot instances for a long time.
|
||||
Being able to attach a date and time to a post and then have it appear
|
||||
|
|
|
@ -465,6 +465,10 @@ At the bottom of the timeline there will usually be an arrow icon to go to the n
|
|||
![Keyboard shortcuts screen](manual-shortcuts.png)
|
||||
|
||||
# Calendar
|
||||
*"There is nothing in this world that does not have a decisive moment"*
|
||||
|
||||
-- Henri Cartier-Bresson
|
||||
|
||||
The calendar is not yet a standardized feature of the fediverse as a whole, but has existed in Friendica and Zot instances for a long time. Being able to attach a date and time to a post and then have it appear on your calendar and perhaps also the calendars of your followers is quite useful for organizing things with minimum effort. Until such time as federated calendar functionality becomes more standardized this may only work between Epicyon instances.
|
||||
|
||||
Calendar events are really just ordinary posts with a date, time and perhaps also a location attached to them. Posts with *Public* scope which have a date and time will appear on the calendars of your followers, unless they have opted out of receiving calendar events from you.
|
||||
|
|
|
@ -293,7 +293,7 @@ def manual_approve_follow_request(session, session_onion, session_i2p,
|
|||
followers_file.seek(0, 0)
|
||||
followers_file.write(approve_handle_full + '\n' +
|
||||
content)
|
||||
except Exception as ex:
|
||||
except OSError as ex:
|
||||
print('WARN: Manual follow accept. ' +
|
||||
'Failed to write entry to followers file ' + str(ex))
|
||||
else:
|
||||
|
|
38
posts.py
|
@ -456,7 +456,9 @@ def _is_public_feed_post(item: {}, person_posts: {}, debug: bool) -> bool:
|
|||
if this_item.get('to'):
|
||||
is_public = False
|
||||
for recipient in this_item['to']:
|
||||
if recipient.endswith('#Public'):
|
||||
if recipient.endswith('#Public') or \
|
||||
recipient == 'as:Public' or \
|
||||
recipient == 'Public':
|
||||
is_public = True
|
||||
break
|
||||
if not is_public:
|
||||
|
@ -465,7 +467,9 @@ def _is_public_feed_post(item: {}, person_posts: {}, debug: bool) -> bool:
|
|||
if item.get('to'):
|
||||
is_public = False
|
||||
for recipient in item['to']:
|
||||
if recipient.endswith('#Public'):
|
||||
if recipient.endswith('#Public') or \
|
||||
recipient == 'as:Public' or \
|
||||
recipient == 'Public':
|
||||
is_public = True
|
||||
break
|
||||
if not is_public:
|
||||
|
@ -1402,7 +1406,12 @@ def _create_post_mentions(cc_url: str, new_post: {},
|
|||
to_cc = new_post['object']['cc']
|
||||
if len(to_recipients) != 1:
|
||||
return
|
||||
if to_recipients[0].endswith('#Public') and \
|
||||
to_public_recipient = False
|
||||
if to_recipients[0].endswith('#Public') or \
|
||||
to_recipients[0] == 'as:Public' or \
|
||||
to_recipients[0] == 'Public':
|
||||
to_public_recipient = True
|
||||
if to_public_recipient and \
|
||||
cc_url.endswith('/followers'):
|
||||
for tag in tags:
|
||||
if tag['type'] != 'Mention':
|
||||
|
@ -1582,7 +1591,9 @@ def _create_post_base(base_dir: str,
|
|||
|
||||
is_public = False
|
||||
for recipient in to_recipients:
|
||||
if recipient.endswith('#Public'):
|
||||
if recipient.endswith('#Public') or \
|
||||
recipient == 'as:Public' or \
|
||||
recipient == 'Public':
|
||||
is_public = True
|
||||
break
|
||||
|
||||
|
@ -2834,7 +2845,9 @@ def _add_followers_to_public_post(post_json_object: {}) -> None:
|
|||
if len(post_json_object['to']) == 0:
|
||||
return
|
||||
if not post_json_object['to'][0].endswith('#Public'):
|
||||
return
|
||||
if not post_json_object['to'][0] == 'as:Public':
|
||||
if not post_json_object['to'][0] == 'Public':
|
||||
return
|
||||
if post_json_object.get('cc'):
|
||||
return
|
||||
post_json_object['cc'] = post_json_object['actor'] + '/followers'
|
||||
|
@ -2846,7 +2859,9 @@ def _add_followers_to_public_post(post_json_object: {}) -> None:
|
|||
if len(post_json_object['object']['to']) == 0:
|
||||
return
|
||||
if not post_json_object['object']['to'][0].endswith('#Public'):
|
||||
return
|
||||
if not post_json_object['object']['to'][0] == 'as:Public':
|
||||
if not post_json_object['object']['to'][0] == 'Public':
|
||||
return
|
||||
if post_json_object['object'].get('cc'):
|
||||
return
|
||||
post_json_object['object']['cc'] = \
|
||||
|
@ -3222,7 +3237,9 @@ def _send_to_named_addresses(server, session, session_onion, session_i2p,
|
|||
continue
|
||||
if '/' not in address:
|
||||
continue
|
||||
if address.endswith('#Public'):
|
||||
if address.endswith('#Public') or \
|
||||
address == 'as:Public' or \
|
||||
address == 'Public':
|
||||
continue
|
||||
if address.endswith('/followers'):
|
||||
continue
|
||||
|
@ -3231,7 +3248,9 @@ def _send_to_named_addresses(server, session, session_onion, session_i2p,
|
|||
address = recipients_object[rtype]
|
||||
if address:
|
||||
if '/' in address:
|
||||
if address.endswith('#Public'):
|
||||
if address.endswith('#Public') or \
|
||||
address == 'as:Public' or \
|
||||
address == 'Public':
|
||||
continue
|
||||
if address.endswith('/followers'):
|
||||
continue
|
||||
|
@ -3900,7 +3919,8 @@ def _add_post_string_to_timeline(post_str: str, boxname: str,
|
|||
('"Create"' in post_str or '"Update"' in post_str))):
|
||||
|
||||
if boxname == 'dm':
|
||||
if '#Public' in post_str or '/followers' in post_str:
|
||||
if '#Public' in post_str or \
|
||||
'/followers' in post_str:
|
||||
return False
|
||||
elif boxname == 'tlreplies':
|
||||
if box_actor not in post_str:
|
||||
|
|
15
tests.py
|
@ -5995,7 +5995,17 @@ def _test_extract_text_fields_from_post():
|
|||
'116202748023898664511855843036\r\nContent-Disposition: ' + \
|
||||
'form-data; name="attachpic"; filename=""\r\nContent-Type: ' + \
|
||||
'application/octet-stream\r\n\r\n\r\n----------------------' + \
|
||||
'-------116202748023898664511855843036--\r\n'
|
||||
'-------116202748023898664511855843036--\r\n' + \
|
||||
'Content-Disposition: form-data; name="importBlocks"; ' + \
|
||||
'filename="wildebeest_suspend.csv"\r\nContent-Type: ' + \
|
||||
'text/csv\r\n\r\n#domain,#severity,#reject_media,#reject_reports,' + \
|
||||
'#public_comment,#obfuscate\nbgp.social,suspend,false,false,' + \
|
||||
'"Wildebeest",false\ncesko.social,suspend,false,false,' + \
|
||||
'"Wildebeest",false\ncloudflare.social,suspend,false,false,' + \
|
||||
'"Wildebeest",false\ndogfood.social,suspend,false,false,' + \
|
||||
'"Wildebeest",false\ndomo.cafe,suspend,false,false,"Wildebeest",' + \
|
||||
'false\nemaw.social,suspend,false,false\n\r\n ' + \
|
||||
'-----------------------------116202748023898664511855843036--\r\n'
|
||||
debug = False
|
||||
fields = extract_text_fields_in_post(None, boundary, debug, form_data)
|
||||
assert fields['submitPost'] == 'Submit'
|
||||
|
@ -6006,6 +6016,9 @@ def _test_extract_text_fields_from_post():
|
|||
assert fields['location'] == ''
|
||||
assert fields['imageDescription'] == ''
|
||||
assert fields['message'] == 'This is a ; test'
|
||||
if not fields['importBlocks'][1:].startswith('#domain,#severity,'):
|
||||
print(fields['importBlocks'])
|
||||
assert fields['importBlocks'][1:].startswith('#domain,#severity,')
|
||||
|
||||
|
||||
def _test_speaker_replace_link():
|
||||
|
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.9 KiB |
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "طرح سؤال",
|
||||
"Possible answers": "إجابات ممكنة",
|
||||
"replying to": "الرد على",
|
||||
"publicly replying to": "الرد علنًا على",
|
||||
"replying to followers": "الرد على المتابعين",
|
||||
"replying unlisted": "الرد غير مدرج",
|
||||
"replying to themselves": "الرد على أنفسهم",
|
||||
"announces": "يعلن",
|
||||
"Previous month": "الشهر الماضى",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "رابط شراء",
|
||||
"Buy links are allowed from the following domains": "روابط الشراء مسموح بها من المجالات التالية",
|
||||
"Media license": "رخصة وسائل الإعلام",
|
||||
"Media creator": "صانع الوسائط"
|
||||
"Media creator": "صانع الوسائط",
|
||||
"Import Blocks": "استيراد مثيلات محظورة",
|
||||
"Export Blocks": "تصدير المثيلات المحظورة"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "প্রশ্ন জিজ্ঞাসা কর",
|
||||
"Possible answers": "সম্ভাব্য উত্তর",
|
||||
"replying to": "এর জবাব",
|
||||
"publicly replying to": "প্রকাশ্যে উত্তর দিচ্ছেন",
|
||||
"replying to followers": "অনুগামীদের উত্তর",
|
||||
"replying unlisted": "অতালিকাভুক্ত উত্তর",
|
||||
"replying to themselves": "নিজেদের জবাব দিচ্ছে",
|
||||
"announces": "ঘোষণা করে",
|
||||
"Previous month": "পূর্ববর্তী মাস",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "সংযোগ কেনা",
|
||||
"Buy links are allowed from the following domains": "নিম্নলিখিত ডোমেনগুলি থেকে লিঙ্কগুলি কেনার অনুমতি দেওয়া হয়েছে",
|
||||
"Media license": "মিডিয়া লাইসেন্স",
|
||||
"Media creator": "মিডিয়া নির্মাতা"
|
||||
"Media creator": "মিডিয়া নির্মাতা",
|
||||
"Import Blocks": "অবরুদ্ধ দৃষ্টান্ত আমদানি করুন",
|
||||
"Export Blocks": "অবরুদ্ধ দৃষ্টান্ত রপ্তানি করুন"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Fer una pregunta",
|
||||
"Possible answers": "Respostes possibles",
|
||||
"replying to": "responent",
|
||||
"publicly replying to": "responent públicament",
|
||||
"replying to followers": "responent als seguidors",
|
||||
"replying unlisted": "responent sense llistar",
|
||||
"replying to themselves": "responent-se",
|
||||
"announces": "anuncia",
|
||||
"Previous month": "Mes anterior",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Enllaç de compra",
|
||||
"Buy links are allowed from the following domains": "Els enllaços de compra es permeten des dels dominis següents",
|
||||
"Media license": "Llicència de mitjans",
|
||||
"Media creator": "Creador de mitjans"
|
||||
"Media creator": "Creador de mitjans",
|
||||
"Import Blocks": "Importa instàncies bloquejades",
|
||||
"Export Blocks": "Exporta instàncies bloquejades"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Gofyn cwestiwn",
|
||||
"Possible answers": "Atebion posib",
|
||||
"replying to": "ateb i",
|
||||
"publicly replying to": "yn ateb yn gyhoeddus",
|
||||
"replying to followers": "ateb i ddilynwyr",
|
||||
"replying unlisted": "ateb heb ei restru",
|
||||
"replying to themselves": "ateb iddynt eu hunain",
|
||||
"announces": "yn cyhoeddi",
|
||||
"Previous month": "Y mis blaenorol",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Prynu dolen",
|
||||
"Buy links are allowed from the following domains": "Caniateir dolenni prynu o'r parthau canlynol",
|
||||
"Media license": "Trwydded cyfryngau",
|
||||
"Media creator": "Crëwr cyfryngau"
|
||||
"Media creator": "Crëwr cyfryngau",
|
||||
"Import Blocks": "Mewnforio Achosion wedi'u Rhwystro",
|
||||
"Export Blocks": "Allforio Achosion wedi'u Rhwystro"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Stelle eine Frage",
|
||||
"Possible answers": "Mögliche Antworten",
|
||||
"replying to": "antworten auf",
|
||||
"publicly replying to": "öffentlich antworten",
|
||||
"replying to followers": "followern antworten",
|
||||
"replying unlisted": "antworten nicht aufgeführt",
|
||||
"replying to themselves": "sich selbst antworten",
|
||||
"announces": "kündigt an",
|
||||
"Previous month": "Vorheriger Monat",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Link kaufen",
|
||||
"Buy links are allowed from the following domains": "Kauflinks sind von den folgenden Domains erlaubt",
|
||||
"Media license": "Medienlizenz",
|
||||
"Media creator": "Mediengestalter"
|
||||
"Media creator": "Mediengestalter",
|
||||
"Import Blocks": "Blockierte Instanzen importieren",
|
||||
"Export Blocks": "Blockierte Instanzen exportieren"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Κάνε μια ερώτηση",
|
||||
"Possible answers": "Πιθανές απαντήσεις",
|
||||
"replying to": "απαντώντας σε",
|
||||
"publicly replying to": "απαντώντας δημόσια σε",
|
||||
"replying to followers": "απαντώντας στους ακόλουθους",
|
||||
"replying unlisted": "απαντώντας εκτός λίστας",
|
||||
"replying to themselves": "απαντώντας στον εαυτό τους",
|
||||
"announces": "ανακοινώνει",
|
||||
"Previous month": "Προηγούμενος μήνας",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Σύνδεσμος αγοράς",
|
||||
"Buy links are allowed from the following domains": "Οι σύνδεσμοι αγοράς επιτρέπονται από τους παρακάτω τομείς",
|
||||
"Media license": "Άδεια ΜΜΕ",
|
||||
"Media creator": "Δημιουργός πολυμέσων"
|
||||
"Media creator": "Δημιουργός πολυμέσων",
|
||||
"Import Blocks": "Εισαγωγή αποκλεισμένων παρουσιών",
|
||||
"Export Blocks": "Εξαγωγή αποκλεισμένων παρουσιών"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Ask a question",
|
||||
"Possible answers": "Possible answers",
|
||||
"replying to": "replying to",
|
||||
"publicly replying to": "publicly replying to",
|
||||
"replying to followers": "replying to followers",
|
||||
"replying unlisted": "replying to unlisted",
|
||||
"replying to themselves": "replying to themselves",
|
||||
"announces": "announces",
|
||||
"Previous month": "Previous month",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Buy link",
|
||||
"Buy links are allowed from the following domains": "Buy links are allowed from the following domains",
|
||||
"Media license": "Media license",
|
||||
"Media creator": "Media creator"
|
||||
"Media creator": "Media creator",
|
||||
"Import Blocks": "Import Blocks",
|
||||
"Export Blocks": "Export Blocks"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Haz una pregunta",
|
||||
"Possible answers": "Respuestas posibles",
|
||||
"replying to": "respondiendo a",
|
||||
"publicly replying to": "respondiendo públicamente a",
|
||||
"replying to followers": "en respuesta a las seguidoras",
|
||||
"replying unlisted": "respondiendo no listada",
|
||||
"replying to themselves": "respondiéndose a sí mismo",
|
||||
"announces": "anuncia",
|
||||
"Previous month": "Mes anterior",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Enlace de compra",
|
||||
"Buy links are allowed from the following domains": "Se permiten enlaces de compra de los siguientes dominios",
|
||||
"Media license": "Licencia de medios",
|
||||
"Media creator": "Creadora de medios"
|
||||
"Media creator": "Creadora de medios",
|
||||
"Import Blocks": "Importar instancias bloqueadas",
|
||||
"Export Blocks": "Exportar instancias bloqueadas"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "یه سوال بپرس",
|
||||
"Possible answers": "پاسخ های ممکن",
|
||||
"replying to": "در حال پاسخ دادن به",
|
||||
"publicly replying to": "علنی پاسخ دادن به",
|
||||
"replying to followers": "پاسخ به دنبال کنندگان",
|
||||
"replying unlisted": "در حال پاسخ به فهرست نشده",
|
||||
"replying to themselves": "به خودشان پاسخ می دهند",
|
||||
"announces": "اعلام می کند",
|
||||
"Previous month": "ماه گذشته",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "لینک خرید",
|
||||
"Buy links are allowed from the following domains": "لینک خرید از دامنه های زیر مجاز است",
|
||||
"Media license": "مجوز رسانه",
|
||||
"Media creator": "سازنده رسانه"
|
||||
"Media creator": "سازنده رسانه",
|
||||
"Import Blocks": "وارد کردن موارد مسدود شده",
|
||||
"Export Blocks": "نمونه های مسدود شده را صادر کنید"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Poser une question",
|
||||
"Possible answers": "Des réponses possibles",
|
||||
"replying to": "répondre à",
|
||||
"publicly replying to": "répondre publiquement à",
|
||||
"replying to followers": "répondre aux abonnés",
|
||||
"replying unlisted": "réponse non répertoriée",
|
||||
"replying to themselves": "se répondre à eux-mêmes",
|
||||
"announces": "annonce",
|
||||
"Previous month": "Le mois précédent",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Acheter un lien",
|
||||
"Buy links are allowed from the following domains": "Les liens d'achat sont autorisés à partir des domaines suivants",
|
||||
"Media license": "Licence média",
|
||||
"Media creator": "Créateur de médias"
|
||||
"Media creator": "Créateur de médias",
|
||||
"Import Blocks": "Importer des instances bloquées",
|
||||
"Export Blocks": "Exporter les instances bloquées"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Ceist a chur",
|
||||
"Possible answers": "Freagraí féideartha",
|
||||
"replying to": "ag freagairt",
|
||||
"publicly replying to": "ag freagairt go poiblí ar",
|
||||
"replying to followers": "ag freagairt do leantóirí",
|
||||
"replying unlisted": "freagra neamhliostaithe",
|
||||
"replying to themselves": "ag freagairt dóibh féin",
|
||||
"announces": "fógraíonn",
|
||||
"Previous month": "An mhí roimhe seo",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Ceannaigh nasc",
|
||||
"Buy links are allowed from the following domains": "Ceadaítear naisc cheannaigh ó na fearainn seo a leanas",
|
||||
"Media license": "Ceadúnas meáin",
|
||||
"Media creator": "Cruthaitheoir meáin"
|
||||
"Media creator": "Cruthaitheoir meáin",
|
||||
"Import Blocks": "Iompórtáil Cásanna Blocáilte",
|
||||
"Export Blocks": "Easpórtáil Cásanna Blocáilte"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "प्रश्न पूछें",
|
||||
"Possible answers": "संभावित उत्तर",
|
||||
"replying to": "करने के लिए जवाब दे",
|
||||
"publicly replying to": "सार्वजनिक रूप से जवाब दे रहा है",
|
||||
"replying to followers": "अनुयायियों को जवाब देना",
|
||||
"replying unlisted": "असूचीबद्ध उत्तर दे रहा है",
|
||||
"replying to themselves": "खुद को जवाब दे",
|
||||
"announces": "की घोषणा",
|
||||
"Previous month": "पिछ्ला महिना",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "लिंक खरीदें",
|
||||
"Buy links are allowed from the following domains": "निम्नलिखित डोमेन से खरीदें लिंक की अनुमति है",
|
||||
"Media license": "मीडिया लाइसेंस",
|
||||
"Media creator": "मीडिया निर्माता"
|
||||
"Media creator": "मीडिया निर्माता",
|
||||
"Import Blocks": "अवरोधित उदाहरण आयात करें",
|
||||
"Export Blocks": "निर्यात अवरुद्ध उदाहरण"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Fai una domanda",
|
||||
"Possible answers": "Possibili risposte",
|
||||
"replying to": "rispondendo a",
|
||||
"publicly replying to": "rispondendo pubblicamente a",
|
||||
"replying to followers": "rispondere ai follower",
|
||||
"replying unlisted": "rispondendo non in elenco",
|
||||
"replying to themselves": "rispondendo a se stessi",
|
||||
"announces": "annuncia",
|
||||
"Previous month": "Il mese scorso",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Link per l'acquisto",
|
||||
"Buy links are allowed from the following domains": "I link di acquisto sono consentiti dai seguenti domini",
|
||||
"Media license": "Licenza multimediale",
|
||||
"Media creator": "Creatore multimediale"
|
||||
"Media creator": "Creatore multimediale",
|
||||
"Import Blocks": "Importa istanze bloccate",
|
||||
"Export Blocks": "Esporta istanze bloccate"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "質問する",
|
||||
"Possible answers": "可能な答え",
|
||||
"replying to": "に返信する",
|
||||
"publicly replying to": "公に返信する",
|
||||
"replying to followers": "フォロワーへの返信",
|
||||
"replying unlisted": "リストにない返信",
|
||||
"replying to themselves": "自分に返信する",
|
||||
"announces": "発表する",
|
||||
"Previous month": "前月",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "購入リンク",
|
||||
"Buy links are allowed from the following domains": "次のドメインからの購入リンクが許可されています",
|
||||
"Media license": "メディアライセンス",
|
||||
"Media creator": "メディアクリエーター"
|
||||
"Media creator": "メディアクリエーター",
|
||||
"Import Blocks": "ブロックされたインスタンスのインポート",
|
||||
"Export Blocks": "ブロックされたインスタンスのエクスポート"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "질문하기",
|
||||
"Possible answers": "가능한 답변",
|
||||
"replying to": "답장",
|
||||
"publicly replying to": "공개적으로 답장",
|
||||
"replying to followers": "팔로워에게 회신",
|
||||
"replying unlisted": "목록에 없는 회신",
|
||||
"replying to themselves": "스스로에게 답장",
|
||||
"announces": "발표하다",
|
||||
"Previous month": "지난달",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "구매 링크",
|
||||
"Buy links are allowed from the following domains": "다음 도메인에서 구매 링크가 허용됩니다.",
|
||||
"Media license": "미디어 라이센스",
|
||||
"Media creator": "미디어 크리에이터"
|
||||
"Media creator": "미디어 크리에이터",
|
||||
"Import Blocks": "차단된 인스턴스 가져오기",
|
||||
"Export Blocks": "차단된 인스턴스 내보내기"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Pirsek bipirsin",
|
||||
"Possible answers": "Bersivên gengaz",
|
||||
"replying to": "bersivandin",
|
||||
"publicly replying to": "bi raya giştî re bersiv dide",
|
||||
"replying to followers": "bersiva şagirtan dide",
|
||||
"replying unlisted": "bersivê nelîste",
|
||||
"replying to themselves": "bersiva xwe didin",
|
||||
"announces": "îlan dike",
|
||||
"Previous month": "Meha berê",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Girêdanê bikirin",
|
||||
"Buy links are allowed from the following domains": "Zencîreyên kirînê ji domên jêrîn têne destûr kirin",
|
||||
"Media license": "Lîsansa medyayê",
|
||||
"Media creator": "Afirînerê medyayê"
|
||||
"Media creator": "Afirînerê medyayê",
|
||||
"Import Blocks": "Mînakên Astengkirî Import",
|
||||
"Export Blocks": "Mînakên Astengkirî Export"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Een vraag stellen",
|
||||
"Possible answers": "Mogelijke antwoorden",
|
||||
"replying to": "reageren op",
|
||||
"publicly replying to": "openbaar beantwoorden",
|
||||
"replying to followers": "reageren op volgers",
|
||||
"replying unlisted": "niet vermeld reageren",
|
||||
"replying to themselves": "zichzelf beantwoorden",
|
||||
"announces": "kondigt aan",
|
||||
"Previous month": "Vorige maand",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "koop link",
|
||||
"Buy links are allowed from the following domains": "Kooplinks zijn toegestaan vanaf de volgende domeinen",
|
||||
"Media license": "Media licentie",
|
||||
"Media creator": "Media-maker"
|
||||
"Media creator": "Media-maker",
|
||||
"Import Blocks": "Importeer geblokkeerde instanties",
|
||||
"Export Blocks": "Exporteer geblokkeerde instanties"
|
||||
}
|
||||
|
|
|
@ -190,6 +190,9 @@
|
|||
"Ask a question": "Ask a question",
|
||||
"Possible answers": "Possible answers",
|
||||
"replying to": "replying to",
|
||||
"publicly replying to": "publicly replying to",
|
||||
"replying to followers": "replying to followers",
|
||||
"replying unlisted": "replying unlisted",
|
||||
"replying to themselves": "replying to themselves",
|
||||
"announces": "announces",
|
||||
"Previous month": "Previous month",
|
||||
|
@ -610,5 +613,7 @@
|
|||
"Buy link": "Buy link",
|
||||
"Buy links are allowed from the following domains": "Buy links are allowed from the following domains",
|
||||
"Media license": "Media license",
|
||||
"Media creator": "Media creator"
|
||||
"Media creator": "Media creator",
|
||||
"Import Blocks": "Import Blocks",
|
||||
"Export Blocks": "Export Blocks"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Zadać pytanie",
|
||||
"Possible answers": "Możliwe odpowiedzi",
|
||||
"replying to": "odpowiadając na",
|
||||
"publicly replying to": "publicznie odpowiadac na",
|
||||
"replying to followers": "odpowiadanie obserwującym",
|
||||
"replying unlisted": "odpowiadanie niepubliczne",
|
||||
"replying to themselves": "odpowiadając sobie",
|
||||
"announces": "ogłasza",
|
||||
"Previous month": "Poprzedni miesiac",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Kup Link",
|
||||
"Buy links are allowed from the following domains": "Kupuj linki są dozwolone z następujących domen",
|
||||
"Media license": "Licencja medialna",
|
||||
"Media creator": "Kreator mediów"
|
||||
"Media creator": "Kreator mediów",
|
||||
"Import Blocks": "Importuj zablokowane instancje",
|
||||
"Export Blocks": "Eksportuj zablokowane instancje"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Faça uma pergunta",
|
||||
"Possible answers": "Possíveis respostas",
|
||||
"replying to": "respondendo a",
|
||||
"publicly replying to": "respondendo publicamente a",
|
||||
"replying to followers": "respondendo aos seguidores",
|
||||
"replying unlisted": "respondendo não listado",
|
||||
"replying to themselves": "respondendo a si mesmos",
|
||||
"announces": "anuncia",
|
||||
"Previous month": "Mês anterior",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Link de compra",
|
||||
"Buy links are allowed from the following domains": "Links de compra são permitidos nos seguintes domínios",
|
||||
"Media license": "Licença de mídia",
|
||||
"Media creator": "Criador de mídia"
|
||||
"Media creator": "Criador de mídia",
|
||||
"Import Blocks": "Importar instâncias bloqueadas",
|
||||
"Export Blocks": "Exportar instâncias bloqueadas"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Задайте вопрос",
|
||||
"Possible answers": "Возможные ответы",
|
||||
"replying to": "отвечая на",
|
||||
"publicly replying to": "публично отвечая на",
|
||||
"replying to followers": "отвечаю подписчикам",
|
||||
"replying unlisted": "ответ не в списке",
|
||||
"replying to themselves": "отвечая на себя",
|
||||
"announces": "анонсов",
|
||||
"Previous month": "Предыдущий месяц",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Купить ссылку",
|
||||
"Buy links are allowed from the following domains": "Ссылки на покупку разрешены со следующих доменов",
|
||||
"Media license": "Медиа лицензия",
|
||||
"Media creator": "Создатель медиа"
|
||||
"Media creator": "Создатель медиа",
|
||||
"Import Blocks": "Импорт заблокированных экземпляров",
|
||||
"Export Blocks": "Экспорт заблокированных экземпляров"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Uliza Swali",
|
||||
"Possible answers": "Majibu yawezekana",
|
||||
"replying to": "kujibu kwa",
|
||||
"publicly replying to": "kujibu hadharani",
|
||||
"replying to followers": "kujibu wafuasi",
|
||||
"replying unlisted": "kujibu bila kuorodheshwa",
|
||||
"replying to themselves": "kujibu wenyewe",
|
||||
"announces": "inatangaza",
|
||||
"Previous month": "Mwezi uliopita",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Nunua kiungo",
|
||||
"Buy links are allowed from the following domains": "Viungo vya kununua vinaruhusiwa kutoka kwa vikoa vifuatavyo",
|
||||
"Media license": "Leseni ya media",
|
||||
"Media creator": "Muundaji wa media"
|
||||
"Media creator": "Muundaji wa media",
|
||||
"Import Blocks": "Ingiza Matukio Yaliyozuiwa",
|
||||
"Export Blocks": "Hamisha Matukio Yaliyozuiwa"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Bir soru sor",
|
||||
"Possible answers": "Olası cevaplar",
|
||||
"replying to": "yanıtlamak",
|
||||
"publicly replying to": "herkese açık olarak yanıtlama",
|
||||
"replying to followers": "takipçilere cevap verme",
|
||||
"replying unlisted": "liste dışı yanıtlama",
|
||||
"replying to themselves": "kendilerine cevap vermek",
|
||||
"announces": "duyurur",
|
||||
"Previous month": "Geçtiğimiz ay",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Bağlantı satın al",
|
||||
"Buy links are allowed from the following domains": "Aşağıdaki alanlardan satın alma bağlantılarına izin verilir",
|
||||
"Media license": "Medya lisansı",
|
||||
"Media creator": "Medya yaratıcısı"
|
||||
"Media creator": "Medya yaratıcısı",
|
||||
"Import Blocks": "Engellenen Örnekleri İçe Aktar",
|
||||
"Export Blocks": "Engellenen Örnekleri Dışa Aktar"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "Задайте питання",
|
||||
"Possible answers": "Можливі відповіді",
|
||||
"replying to": "відповідаючи на",
|
||||
"publicly replying to": "публічно відповідаючи на",
|
||||
"replying to followers": "відповідаючи підписникам",
|
||||
"replying unlisted": "відповідати не в списку",
|
||||
"replying to themselves": "відповідаючи собі",
|
||||
"announces": "оголошує",
|
||||
"Previous month": "Попередній місяць",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "Купити посилання",
|
||||
"Buy links are allowed from the following domains": "Посилання на купівлю дозволено з таких доменів",
|
||||
"Media license": "Медіа ліцензія",
|
||||
"Media creator": "Творець медіа"
|
||||
"Media creator": "Творець медіа",
|
||||
"Import Blocks": "Імпортувати заблоковані екземпляри",
|
||||
"Export Blocks": "Експортувати заблоковані екземпляри"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "פרעגן אַ קשיא",
|
||||
"Possible answers": "מעגלעך ענטפֿערס",
|
||||
"replying to": "ענטפערן צו",
|
||||
"publicly replying to": "עפנטלעך ענטפער צו",
|
||||
"replying to followers": "ענטפער צו אנהענגערס",
|
||||
"replying unlisted": "ענטפערן אַנליסטיד",
|
||||
"replying to themselves": "ענטפערן צו זיך",
|
||||
"announces": "אַנאַונסיז",
|
||||
"Previous month": "פֿריִערדיקע חודש",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "קויפן לינק",
|
||||
"Buy links are allowed from the following domains": "קויפן פֿאַרבינדונגען זענען ערלויבט פֿון די פאלגענדע דאָומיינז",
|
||||
"Media license": "מעדיע דערלויבעניש",
|
||||
"Media creator": "מעדיע באשעפער"
|
||||
"Media creator": "מעדיע באשעפער",
|
||||
"Import Blocks": "ימפּאָרט בלאַקט ינסטאַנסיז",
|
||||
"Export Blocks": "עקספּאָרט בלאַקט ינסטאַנסיז"
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@
|
|||
"Ask a question": "问一个问题",
|
||||
"Possible answers": "可能的答案",
|
||||
"replying to": "回覆",
|
||||
"publicly replying to": "公开回复",
|
||||
"replying to followers": "回复关注者",
|
||||
"replying unlisted": "回复不公开",
|
||||
"replying to themselves": "回覆自己",
|
||||
"announces": "宣布",
|
||||
"Previous month": "前一个月",
|
||||
|
@ -614,5 +617,7 @@
|
|||
"Buy link": "购买链接",
|
||||
"Buy links are allowed from the following domains": "允许来自以下域的购买链接",
|
||||
"Media license": "媒体许可证",
|
||||
"Media creator": "媒体创作者"
|
||||
"Media creator": "媒体创作者",
|
||||
"Import Blocks": "导入被阻止的实例",
|
||||
"Export Blocks": "导出被阻止的实例"
|
||||
}
|
||||
|
|
12
utils.py
|
@ -2096,7 +2096,9 @@ def is_dm(post_json_object: {}) -> bool:
|
|||
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'):
|
||||
if to_address.endswith('#Public') or \
|
||||
to_address == 'as:Public' or \
|
||||
to_address == 'Public':
|
||||
return False
|
||||
if to_address.endswith('followers'):
|
||||
return False
|
||||
|
@ -2428,7 +2430,9 @@ def is_public_post(post_json_object: {}) -> bool:
|
|||
if not post_json_object['object'].get('to'):
|
||||
return False
|
||||
for recipient in post_json_object['object']['to']:
|
||||
if recipient.endswith('#Public'):
|
||||
if recipient.endswith('#Public') or \
|
||||
recipient == 'as:Public' or \
|
||||
recipient == 'Public':
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -2471,7 +2475,9 @@ def is_unlisted_post(post_json_object: {}) -> bool:
|
|||
if not has_followers:
|
||||
return False
|
||||
for recipient in post_json_object['object']['cc']:
|
||||
if recipient.endswith('#Public'):
|
||||
if recipient.endswith('#Public') or \
|
||||
recipient == 'as:Public' or \
|
||||
recipient == 'Public':
|
||||
return True
|
||||
return False
|
||||
|
||||
|
|
|
@ -353,6 +353,8 @@ def _save_individual_post_as_html_to_cache(base_dir: str,
|
|||
get_cached_post_directory(base_dir, nickname, domain)
|
||||
cached_post_filename = \
|
||||
get_cached_post_filename(base_dir, nickname, domain, post_json_object)
|
||||
if not cached_post_filename:
|
||||
return False
|
||||
|
||||
# create the cache directory if needed
|
||||
if not os.path.isdir(html_post_cache_dir):
|
||||
|
@ -362,7 +364,7 @@ def _save_individual_post_as_html_to_cache(base_dir: str,
|
|||
with open(cached_post_filename, 'w+', encoding='utf-8') as fp_cache:
|
||||
fp_cache.write(post_html)
|
||||
return True
|
||||
except Exception as ex:
|
||||
except OSError as ex:
|
||||
print('ERROR: saving post to cache, ' + str(ex))
|
||||
return False
|
||||
|
||||
|
@ -916,7 +918,9 @@ def _get_like_icon_html(nickname: str, domain_full: str,
|
|||
return like_str
|
||||
|
||||
|
||||
def _get_bookmark_icon_html(nickname: str, domain_full: str,
|
||||
def _get_bookmark_icon_html(base_dir: str,
|
||||
nickname: str, domain: str,
|
||||
domain_full: str,
|
||||
post_json_object: {},
|
||||
is_moderation_post: bool,
|
||||
translate: {},
|
||||
|
@ -924,7 +928,8 @@ def _get_bookmark_icon_html(nickname: str, domain_full: str,
|
|||
post_start_time, box_name: str,
|
||||
page_number_param: str,
|
||||
timeline_post_bookmark: str,
|
||||
first_post_id: str) -> str:
|
||||
first_post_id: str,
|
||||
post_url: str) -> str:
|
||||
"""Returns html for bookmark icon/button
|
||||
"""
|
||||
bookmark_str = ''
|
||||
|
@ -932,6 +937,9 @@ def _get_bookmark_icon_html(nickname: str, domain_full: str,
|
|||
if is_moderation_post:
|
||||
return bookmark_str
|
||||
|
||||
if not locate_post(base_dir, nickname, domain, post_url):
|
||||
return bookmark_str
|
||||
|
||||
bookmark_icon = 'bookmark_inactive.png'
|
||||
bookmark_link = 'bookmark'
|
||||
bookmark_emoji = ''
|
||||
|
@ -1375,14 +1383,27 @@ def _reply_to_yourself_html(translate: {}) -> str:
|
|||
return title_str
|
||||
|
||||
|
||||
def _replying_to_with_scope(post_json_object: {}, translate: {}) -> str:
|
||||
"""Returns the replying to string
|
||||
"""
|
||||
replying_to_str = 'replying to'
|
||||
if is_followers_post(post_json_object):
|
||||
replying_to_str = 'replying to followers'
|
||||
elif is_public_post(post_json_object):
|
||||
replying_to_str = 'publicly replying to'
|
||||
elif is_unlisted_post(post_json_object):
|
||||
replying_to_str = 'replying unlisted'
|
||||
if translate.get(replying_to_str):
|
||||
replying_to_str = translate[replying_to_str]
|
||||
return replying_to_str
|
||||
|
||||
|
||||
def _reply_to_unknown_html(translate: {},
|
||||
post_json_object: {},
|
||||
nickname: str) -> str:
|
||||
"""Returns the html title for a reply to an unknown handle
|
||||
"""
|
||||
replying_to_str = 'replying to'
|
||||
if translate.get(replying_to_str):
|
||||
replying_to_str = translate[replying_to_str]
|
||||
replying_to_str = _replying_to_with_scope(post_json_object, translate)
|
||||
post_id = post_json_object['object']['inReplyTo']
|
||||
post_link = '/users/' + nickname + '?convthread=' + \
|
||||
post_id.replace('/', '--')
|
||||
|
@ -1412,9 +1433,7 @@ def _reply_with_unknown_path_html(translate: {},
|
|||
"""Returns html title for a reply with an unknown path
|
||||
eg. does not contain /statuses/
|
||||
"""
|
||||
replying_to_str = 'replying to'
|
||||
if translate.get(replying_to_str):
|
||||
replying_to_str = translate[replying_to_str]
|
||||
replying_to_str = _replying_to_with_scope(post_json_object, translate)
|
||||
post_id = post_json_object['object']['inReplyTo']
|
||||
post_link = '/users/' + nickname + '?convthread=' + \
|
||||
post_id.replace('/', '--')
|
||||
|
@ -1430,12 +1449,11 @@ def _reply_with_unknown_path_html(translate: {},
|
|||
|
||||
def _get_reply_html(translate: {},
|
||||
in_reply_to: str, reply_display_name: str,
|
||||
nickname: str) -> str:
|
||||
nickname: str,
|
||||
post_json_object: {}) -> str:
|
||||
"""Returns html title for a reply
|
||||
"""
|
||||
replying_to_str = 'replying to'
|
||||
if translate.get(replying_to_str):
|
||||
replying_to_str = translate[replying_to_str]
|
||||
replying_to_str = _replying_to_with_scope(post_json_object, translate)
|
||||
post_link = '/users/' + nickname + '?convthread=' + \
|
||||
in_reply_to.replace('/', '--')
|
||||
return ' ' + \
|
||||
|
@ -1543,7 +1561,8 @@ def _get_post_title_reply_html(base_dir: str,
|
|||
_log_post_timing(enable_timing_log, post_start_time, '13.6')
|
||||
|
||||
title_str += \
|
||||
_get_reply_html(translate, in_reply_to, reply_display_name, nickname)
|
||||
_get_reply_html(translate, in_reply_to, reply_display_name,
|
||||
nickname, post_json_object)
|
||||
|
||||
if mitm:
|
||||
title_str += _mitm_warning_html(translate)
|
||||
|
@ -2133,9 +2152,13 @@ def individual_post_as_html(signing_priv_key_pem: str,
|
|||
translate, post_json_object['actor'],
|
||||
theme_name, system_language,
|
||||
box_name)
|
||||
with open(announce_filename + '.tts', 'w+',
|
||||
encoding='utf-8') as ttsfile:
|
||||
ttsfile.write('\n')
|
||||
try:
|
||||
with open(announce_filename + '.tts', 'w+',
|
||||
encoding='utf-8') as ttsfile:
|
||||
ttsfile.write('\n')
|
||||
except OSError:
|
||||
print('EX: unable to write tts ' +
|
||||
announce_filename + '.tts')
|
||||
|
||||
is_announced = True
|
||||
|
||||
|
@ -2161,6 +2184,26 @@ def individual_post_as_html(signing_priv_key_pem: str,
|
|||
actor_nickname = 'dev'
|
||||
actor_domain, _ = get_domain_from_actor(post_actor)
|
||||
|
||||
# scope icon before display name
|
||||
if is_followers_post(post_json_object):
|
||||
title_str += \
|
||||
' <img loading="lazy" decoding="async" src="/' + \
|
||||
'icons/scope_followers.png" class="postScopeIcon" title="' + \
|
||||
translate['Only to followers'] + ':" alt="' + \
|
||||
translate['Only to followers'] + ':"/>\n'
|
||||
elif is_unlisted_post(post_json_object):
|
||||
title_str += \
|
||||
' <img loading="lazy" decoding="async" src="/' + \
|
||||
'icons/scope_unlisted.png" class="postScopeIcon" title="' + \
|
||||
translate['Not on public timeline'] + ':" alt="' + \
|
||||
translate['Not on public timeline'] + ':"/>\n'
|
||||
elif is_reminder(post_json_object):
|
||||
title_str += \
|
||||
' <img loading="lazy" decoding="async" src="/' + \
|
||||
'icons/scope_reminder.png" class="postScopeIcon" title="' + \
|
||||
translate['Scheduled note to yourself'] + ':" alt="' + \
|
||||
translate['Scheduled note to yourself'] + ':"/>\n'
|
||||
|
||||
display_name = get_display_name(base_dir, post_actor, person_cache)
|
||||
if display_name:
|
||||
if len(display_name) < 2 or \
|
||||
|
@ -2295,15 +2338,14 @@ def individual_post_as_html(signing_priv_key_pem: str,
|
|||
_log_post_timing(enable_timing_log, post_start_time, '12.5')
|
||||
|
||||
bookmark_str = \
|
||||
_get_bookmark_icon_html(nickname, domain_full,
|
||||
post_json_object,
|
||||
is_moderation_post,
|
||||
translate,
|
||||
_get_bookmark_icon_html(base_dir, nickname, domain,
|
||||
domain_full, post_json_object,
|
||||
is_moderation_post, translate,
|
||||
enable_timing_log,
|
||||
post_start_time, box_name,
|
||||
page_number_param,
|
||||
timeline_post_bookmark,
|
||||
first_post_id)
|
||||
first_post_id, message_id)
|
||||
|
||||
_log_post_timing(enable_timing_log, post_start_time, '12.9')
|
||||
|
||||
|
@ -2652,8 +2694,10 @@ def individual_post_as_html(signing_priv_key_pem: str,
|
|||
translate)
|
||||
if map_str:
|
||||
map_str = '<center>\n' + map_str + '</center>\n'
|
||||
if map_str and post_json_object['object'].get('attributedTo'):
|
||||
attrib = None
|
||||
if post_json_object['object'].get('attributedTo'):
|
||||
attrib = post_json_object['object']['attributedTo']
|
||||
if map_str and attrib:
|
||||
# is this being sent by the author?
|
||||
if '://' + domain_full + '/users/' + nickname in attrib:
|
||||
location_domain = location_str
|
||||
|
@ -2729,10 +2773,13 @@ def individual_post_as_html(signing_priv_key_pem: str,
|
|||
if not show_public_only and store_to_cache and \
|
||||
box_name != 'tlmedia' and box_name != 'tlbookmarks' and \
|
||||
box_name != 'bookmarks':
|
||||
cached_json = post_json_object
|
||||
if announce_json_object:
|
||||
cached_json = announce_json_object
|
||||
_save_individual_post_as_html_to_cache(base_dir, nickname, domain,
|
||||
post_json_object, post_html)
|
||||
cached_json, post_html)
|
||||
update_recent_posts_cache(recent_posts_cache, max_recent_posts,
|
||||
post_json_object, post_html)
|
||||
cached_json, post_html)
|
||||
|
||||
_log_post_timing(enable_timing_log, post_start_time, '19')
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ from roles import is_devops
|
|||
from session import site_is_verified
|
||||
|
||||
THEME_FORMATS = '.zip, .gz'
|
||||
BLOCKFILE_FORMATS = '.csv'
|
||||
|
||||
|
||||
def _valid_profile_preview_post(post_json_object: {},
|
||||
|
@ -226,6 +227,11 @@ def html_profile_after_search(recent_posts_cache: {}, max_recent_posts: int,
|
|||
display_name = search_nickname
|
||||
if profile_json.get('name'):
|
||||
display_name = profile_json['name']
|
||||
display_name = remove_html(display_name)
|
||||
display_name = \
|
||||
add_emoji_to_display_name(session, base_dir, http_prefix,
|
||||
nickname, domain,
|
||||
display_name, False, translate)
|
||||
|
||||
locked_account = get_locked_account(profile_json)
|
||||
if locked_account:
|
||||
|
@ -246,6 +252,10 @@ def html_profile_after_search(recent_posts_cache: {}, max_recent_posts: int,
|
|||
profile_description = ''
|
||||
if profile_json.get('summary'):
|
||||
profile_description = profile_json['summary']
|
||||
profile_description = \
|
||||
add_emoji_to_display_name(session, base_dir, http_prefix,
|
||||
nickname, domain,
|
||||
profile_description, False, translate)
|
||||
outbox_url = None
|
||||
if not profile_json.get('outbox'):
|
||||
if debug:
|
||||
|
@ -468,7 +478,7 @@ def _get_profile_header(base_dir: str, http_prefix: str, nickname: str,
|
|||
' <b>' + occupation_name + '</b><br>\n'
|
||||
|
||||
html_str += \
|
||||
' <h1>' + remove_html(display_name) + '\n</h1>\n' + \
|
||||
' <h1>' + display_name + '\n</h1>\n' + \
|
||||
occupation_str
|
||||
|
||||
html_str += \
|
||||
|
@ -577,7 +587,7 @@ def _get_profile_header_after_search(nickname: str, default_timeline: str,
|
|||
display_name = search_nickname
|
||||
html_str += \
|
||||
' <h1>\n' + \
|
||||
' ' + remove_html(display_name) + '\n' + \
|
||||
' ' + display_name + '\n' + \
|
||||
' </h1>\n' + \
|
||||
' <p><b>@' + search_nickname + '@' + search_domain_full + \
|
||||
'</b><br>\n'
|
||||
|
@ -692,15 +702,17 @@ def html_profile(signing_priv_key_pem: str,
|
|||
domain, port = get_domain_from_actor(profile_json['id'])
|
||||
if not domain:
|
||||
return ""
|
||||
display_name = remove_html(profile_json['name'])
|
||||
display_name = \
|
||||
add_emoji_to_display_name(session, base_dir, http_prefix,
|
||||
nickname, domain,
|
||||
profile_json['name'], True, translate)
|
||||
display_name, False, translate)
|
||||
domain_full = get_full_domain(domain, port)
|
||||
profile_description = profile_json['summary']
|
||||
profile_description = \
|
||||
add_emoji_to_display_name(session, base_dir, http_prefix,
|
||||
nickname, domain,
|
||||
profile_json['summary'], False, translate)
|
||||
profile_description, False, translate)
|
||||
if profile_description:
|
||||
profile_description = standardize_text(profile_description)
|
||||
posts_button = 'button'
|
||||
|
@ -1527,8 +1539,8 @@ def _html_edit_profile_graphic_design(base_dir: str, translate: {}) -> str:
|
|||
graphics_str += \
|
||||
' <label class="labels">' + \
|
||||
translate['Import Theme'] + '</label>\n'
|
||||
graphics_str += ' <input type="file" id="import_theme" '
|
||||
graphics_str += 'name="submitImportTheme" '
|
||||
graphics_str += ' <input type="file" id="importTheme" '
|
||||
graphics_str += 'name="importTheme" '
|
||||
graphics_str += 'accept="' + THEME_FORMATS + '">\n'
|
||||
graphics_str += \
|
||||
' <label class="labels">' + \
|
||||
|
@ -2032,6 +2044,20 @@ def _html_edit_profile_filtering(base_dir: str, nickname: str, domain: str,
|
|||
edit_text_area(translate['Blocked accounts'], None, 'blocked',
|
||||
blocked_str, 200, '', False)
|
||||
|
||||
# import and export blocks
|
||||
edit_profile_form += \
|
||||
' <label class="labels">' + \
|
||||
translate['Import Blocks'] + '</label>\n'
|
||||
edit_profile_form += ' <input type="file" id="importBlocks" '
|
||||
edit_profile_form += 'name="importBlocks" '
|
||||
edit_profile_form += 'accept="' + BLOCKFILE_FORMATS + '">\n'
|
||||
edit_profile_form += \
|
||||
' <label class="labels">' + \
|
||||
translate['Export Blocks'] + '</label><br>\n'
|
||||
edit_profile_form += \
|
||||
' <button type="submit" class="button" ' + \
|
||||
'name="submitExportBlocks">➤</button><br>\n'
|
||||
|
||||
idx = 'Direct messages are always allowed from these instances.'
|
||||
edit_profile_form += \
|
||||
edit_text_area(translate['Direct Message permitted instances'], None,
|
||||
|
@ -2255,8 +2281,8 @@ def _html_edit_profile_import_export(nickname: str, domain: str,
|
|||
edit_profile_form += \
|
||||
'<p><label class="labels">' + \
|
||||
translate['Import Follows'] + '</label>\n'
|
||||
edit_profile_form += '<input type="file" id="import_follows" '
|
||||
edit_profile_form += 'name="submitImportFollows" '
|
||||
edit_profile_form += '<input type="file" id="importFollows" '
|
||||
edit_profile_form += 'name="importFollows" '
|
||||
edit_profile_form += 'accept=".csv"></p>\n'
|
||||
|
||||
edit_profile_form += \
|
||||
|
|
|
@ -333,8 +333,8 @@ def html_theme_designer(base_dir: str,
|
|||
export_import_str += \
|
||||
' <label class="labels">' + \
|
||||
translate['Import Theme'] + '</label>\n'
|
||||
export_import_str += ' <input type="file" id="import_theme" '
|
||||
export_import_str += 'name="submitImportTheme" '
|
||||
export_import_str += ' <input type="file" id="importTheme" '
|
||||
export_import_str += 'name="importTheme" '
|
||||
export_import_str += 'accept="' + theme_formats + '">\n'
|
||||
export_import_str += \
|
||||
' <label class="labels">' + \
|
||||
|
|
|
@ -564,13 +564,17 @@ def post_contains_public(post_json_object: {}) -> bool:
|
|||
return contains_public
|
||||
|
||||
for to_address in post_json_object['object']['to']:
|
||||
if to_address.endswith('#Public'):
|
||||
if to_address.endswith('#Public') or \
|
||||
to_address == 'as:Public' or \
|
||||
to_address == 'Public':
|
||||
contains_public = True
|
||||
break
|
||||
if not contains_public:
|
||||
if post_json_object['object'].get('cc'):
|
||||
for to_address2 in post_json_object['object']['cc']:
|
||||
if to_address2.endswith('#Public'):
|
||||
if to_address2.endswith('#Public') or \
|
||||
to_address2 == 'as:Public' or \
|
||||
to_address2 == 'Public':
|
||||
contains_public = True
|
||||
break
|
||||
return contains_public
|
||||
|
@ -1062,7 +1066,7 @@ def load_individual_post_as_html_from_cache(base_dir: str,
|
|||
with open(cached_post_filename, 'r', encoding='utf-8') as file:
|
||||
post_html = file.read()
|
||||
break
|
||||
except Exception as ex:
|
||||
except OSError as ex:
|
||||
print('ERROR: load_individual_post_as_html_from_cache ' +
|
||||
str(tries) + ' ' + str(ex))
|
||||
# no sleep
|
||||
|
|