epicyon/quote.py

109 lines
3.9 KiB
Python

__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