Quote toot functions in their own module

main
Bob Mottram 2025-05-27 11:51:21 +01:00
parent e1b3b7a1a0
commit 54adba4575
9 changed files with 115 additions and 101 deletions

View File

@ -15,7 +15,7 @@ from session import get_json_valid
from session import create_session from session import create_session
from flags import is_evil from flags import is_evil
from flags import is_quote_toot from flags import is_quote_toot
from utils import get_quote_toot_url from quote import get_quote_toot_url
from utils import get_user_paths from utils import get_user_paths
from utils import contains_statuses from utils import contains_statuses
from utils import data_dir from utils import data_dir

View File

@ -27,7 +27,7 @@ from utils import date_from_string_format
from utils import get_reply_to from utils import get_reply_to
from utils import text_in_file from utils import text_in_file
from utils import get_group_paths from utils import get_group_paths
from utils import get_quote_toot_url from quote import get_quote_toot_url
def is_featured_writer(base_dir: str, nickname: str, domain: str) -> bool: def is_featured_writer(base_dir: str, nickname: str, domain: str) -> bool:

View File

@ -22,9 +22,9 @@ from flags import is_group_account
from flags import has_group_type from flags import has_group_type
from flags import is_quote_toot from flags import is_quote_toot
from flags import url_permitted from flags import url_permitted
from quote import quote_toots_allowed
from utils import save_mitm_servers from utils import save_mitm_servers
from utils import harmless_markup from utils import harmless_markup
from utils import quote_toots_allowed
from utils import lines_in_file from utils import lines_in_file
from utils import date_epoch from utils import date_epoch
from utils import date_utcnow from utils import date_utcnow

View File

@ -12,7 +12,7 @@ import time
from flags import is_recent_post from flags import is_recent_post
from flags import is_quote_toot from flags import is_quote_toot
from status import actor_status_expired from status import actor_status_expired
from utils import get_quote_toot_url from quote import get_quote_toot_url
from utils import get_actor_from_post_id from utils import get_actor_from_post_id
from utils import contains_invalid_actor_url_chars from utils import contains_invalid_actor_url_chars
from utils import get_attributed_to from utils import get_attributed_to

View File

@ -17,8 +17,8 @@ from posts import send_to_followers_thread
from posts import send_to_named_addresses_thread from posts import send_to_named_addresses_thread
from flags import is_featured_writer from flags import is_featured_writer
from flags import is_quote_toot from flags import is_quote_toot
from quote import quote_toots_allowed
from utils import data_dir from utils import data_dir
from utils import quote_toots_allowed
from utils import get_post_attachments from utils import get_post_attachments
from utils import get_attributed_to from utils import get_attributed_to
from utils import contains_invalid_actor_url_chars from utils import contains_invalid_actor_url_chars

108
quote.py 100644
View File

@ -0,0 +1,108 @@
__filename__ = "quote.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.6.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core"
import os
from utils import acct_dir
from utils import resembles_url
from utils import remove_html
from utils import text_in_file
def get_quote_toot_url(post_json_object: str) -> str:
""" Returns the url for a quote toot
This suffers from a general lack of protocol consensus
"""
# adhoc quote toot implementations
object_quote_url_fields = (
'quoteUri', 'quoteUrl', 'quoteReply', 'toot:quoteReply',
'_misskey_quote'
)
for fieldname in object_quote_url_fields:
if not post_json_object['object'].get(fieldname):
continue
quote_url = post_json_object['object'][fieldname]
if isinstance(quote_url, str):
if resembles_url(quote_url):
return remove_html(quote_url)
# as defined by FEP-dd4b
# https://codeberg.org/fediverse/fep/src/branch/main/fep/dd4b/fep-dd4b.md
if ((post_json_object.get('content') or
post_json_object.get('contentMap')) and
(not post_json_object['object'].get('content') and
not post_json_object['object'].get('contentMap')) and
post_json_object['object'].get('id')):
quote_url = post_json_object['object']['id']
if isinstance(quote_url, str):
if resembles_url(quote_url):
return remove_html(quote_url)
# Other ActivityPub implementation - adding a Link tag
if not post_json_object['object'].get('tag'):
return ''
if not isinstance(post_json_object['object']['tag'], list):
return ''
for item in post_json_object['object']['tag']:
if not isinstance(item, dict):
continue
if item.get('rel'):
mk_quote = False
if isinstance(item['rel'], list):
for rel_str in item['rel']:
if not isinstance(rel_str, str):
continue
if '_misskey_quote' in rel_str:
mk_quote = True
elif isinstance(item['rel'], str):
if '_misskey_quote' in item['rel']:
mk_quote = True
if mk_quote and item.get('href'):
if isinstance(item['href'], str):
if resembles_url(item['href']):
return remove_html(item['href'])
if not item.get('type'):
continue
if not item.get('mediaType'):
continue
if not isinstance(item['type'], str):
continue
if item['type'] != 'Link':
continue
if not isinstance(item['mediaType'], str):
continue
if 'json' not in item['mediaType']:
continue
if item.get('href'):
if isinstance(item['href'], str):
if resembles_url(item['href']):
return remove_html(item['href'])
return ''
def quote_toots_allowed(base_dir: str, nickname: str, domain: str,
sender_nickname: str, sender_domain: str) -> bool:
""" Returns true if quote toots are allowed by the given account
for the given sender
"""
account_dir = acct_dir(base_dir, nickname, domain)
quotes_enabled_filename = account_dir + '/.allowQuotes'
if os.path.isfile(quotes_enabled_filename):
# check blocks on individual sending accounts
quotes_blocked_filename = account_dir + '/quotesblocked.txt'
if sender_nickname is None:
return True
if os.path.isfile(quotes_blocked_filename):
sender_handle = sender_nickname + '@' + sender_domain
if text_in_file(sender_handle, quotes_blocked_filename, False):
# quote toots not permitted from this sender
return False
return True
return False

View File

@ -4684,100 +4684,6 @@ def save_reverse_timeline(base_dir: str, reverse_sequence: []) -> []:
break break
def get_quote_toot_url(post_json_object: str) -> str:
""" Returns the url for a quote toot
This suffers from a general lack of protocol consensus
"""
# adhoc quote toot implementations
object_quote_url_fields = (
'quoteUri', 'quoteUrl', 'quoteReply', 'toot:quoteReply',
'_misskey_quote'
)
for fieldname in object_quote_url_fields:
if not post_json_object['object'].get(fieldname):
continue
quote_url = post_json_object['object'][fieldname]
if isinstance(quote_url, str):
if resembles_url(quote_url):
return remove_html(quote_url)
# as defined by FEP-dd4b
# https://codeberg.org/fediverse/fep/src/branch/main/fep/dd4b/fep-dd4b.md
if ((post_json_object.get('content') or
post_json_object.get('contentMap')) and
(not post_json_object['object'].get('content') and
not post_json_object['object'].get('contentMap')) and
post_json_object['object'].get('id')):
quote_url = post_json_object['object']['id']
if isinstance(quote_url, str):
if resembles_url(quote_url):
return remove_html(quote_url)
# Other ActivityPub implementation - adding a Link tag
if not post_json_object['object'].get('tag'):
return ''
if not isinstance(post_json_object['object']['tag'], list):
return ''
for item in post_json_object['object']['tag']:
if not isinstance(item, dict):
continue
if item.get('rel'):
mk_quote = False
if isinstance(item['rel'], list):
for rel_str in item['rel']:
if not isinstance(rel_str, str):
continue
if '_misskey_quote' in rel_str:
mk_quote = True
elif isinstance(item['rel'], str):
if '_misskey_quote' in item['rel']:
mk_quote = True
if mk_quote and item.get('href'):
if isinstance(item['href'], str):
if resembles_url(item['href']):
return remove_html(item['href'])
if not item.get('type'):
continue
if not item.get('mediaType'):
continue
if not isinstance(item['type'], str):
continue
if item['type'] != 'Link':
continue
if not isinstance(item['mediaType'], str):
continue
if 'json' not in item['mediaType']:
continue
if item.get('href'):
if isinstance(item['href'], str):
if resembles_url(item['href']):
return remove_html(item['href'])
return ''
def quote_toots_allowed(base_dir: str, nickname: str, domain: str,
sender_nickname: str, sender_domain: str) -> bool:
""" Returns true if quote toots are allowed by the given account
for the given sender
"""
account_dir = acct_dir(base_dir, nickname, domain)
quotes_enabled_filename = account_dir + '/.allowQuotes'
if os.path.isfile(quotes_enabled_filename):
# check blocks on individual sending accounts
quotes_blocked_filename = account_dir + '/quotesblocked.txt'
if sender_nickname is None:
return True
if os.path.isfile(quotes_blocked_filename):
sender_handle = sender_nickname + '@' + sender_domain
if text_in_file(sender_handle, quotes_blocked_filename, False):
# quote toots not permitted from this sender
return False
return True
return False
def license_link_from_name(license_name: str) -> str: def license_link_from_name(license_name: str) -> str:
"""Returns the license link from its name """Returns the license link from its name
""" """

View File

@ -14,8 +14,8 @@ from person import is_person_snoozed
from posts import is_moderator from posts import is_moderator
from flags import is_featured_writer from flags import is_featured_writer
from flags import is_dormant from flags import is_dormant
from quote import quote_toots_allowed
from utils import data_dir from utils import data_dir
from utils import quote_toots_allowed
from utils import get_full_domain from utils import get_full_domain
from utils import get_config_param from utils import get_config_param
from utils import remove_html from utils import remove_html

View File

@ -36,12 +36,12 @@ from flags import is_recent_post
from flags import is_chat_message from flags import is_chat_message
from flags import is_pgp_encrypted from flags import is_pgp_encrypted
from textmode import text_mode_removals from textmode import text_mode_removals
from quote import get_quote_toot_url
from utils import save_json from utils import save_json
from utils import remove_header_tags from utils import remove_header_tags
from utils import get_actor_from_post_id from utils import get_actor_from_post_id
from utils import contains_statuses from utils import contains_statuses
from utils import data_dir from utils import data_dir
from utils import get_quote_toot_url
from utils import get_post_attachments from utils import get_post_attachments
from utils import get_url_from_post from utils import get_url_from_post
from utils import date_from_string_format from utils import date_from_string_format