mirror of https://gitlab.com/bashrc2/epicyon
Allow for the possibility of a v2 instance within the masto API
parent
2c0b8202c6
commit
7a5f06f28c
164
mastoapiv1.py
164
mastoapiv1.py
|
@ -13,7 +13,145 @@ from utils import get_config_param
|
||||||
from utils import acct_dir
|
from utils import acct_dir
|
||||||
from utils import remove_html
|
from utils import remove_html
|
||||||
from utils import get_attachment_property_value
|
from utils import get_attachment_property_value
|
||||||
from metadata import meta_data_instance
|
from utils import no_of_accounts
|
||||||
|
from utils import get_status_count
|
||||||
|
|
||||||
|
|
||||||
|
def _meta_data_instance_v1(show_accounts: bool,
|
||||||
|
instance_title: str,
|
||||||
|
instance_description_short: str,
|
||||||
|
instance_description: str,
|
||||||
|
http_prefix: str, base_dir: str,
|
||||||
|
admin_nickname: str, domain: str, domain_full: str,
|
||||||
|
registration: bool, system_language: str,
|
||||||
|
version: str) -> {}:
|
||||||
|
""" /api/v1/instance endpoint
|
||||||
|
"""
|
||||||
|
admin_actor_filename = \
|
||||||
|
base_dir + '/accounts/' + admin_nickname + '@' + domain + '.json'
|
||||||
|
if not os.path.isfile(admin_actor_filename):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
admin_actor = load_json(admin_actor_filename, 0)
|
||||||
|
if not admin_actor:
|
||||||
|
print('WARN: json load exception _meta_data_instance_v1')
|
||||||
|
return {}
|
||||||
|
|
||||||
|
rules_list = []
|
||||||
|
rules_filename = \
|
||||||
|
base_dir + '/accounts/tos.md'
|
||||||
|
if os.path.isfile(rules_filename):
|
||||||
|
with open(rules_filename, 'r', encoding='utf-8') as fp_rules:
|
||||||
|
rules_lines = fp_rules.readlines()
|
||||||
|
rule_ctr = 1
|
||||||
|
for line in rules_lines:
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
if line.startswith('#'):
|
||||||
|
continue
|
||||||
|
rules_list.append({
|
||||||
|
'id': str(rule_ctr),
|
||||||
|
'text': line
|
||||||
|
})
|
||||||
|
rule_ctr += 1
|
||||||
|
|
||||||
|
is_bot = False
|
||||||
|
is_group = False
|
||||||
|
if admin_actor['type'] == 'Group':
|
||||||
|
is_group = True
|
||||||
|
elif admin_actor['type'] != 'Person':
|
||||||
|
is_bot = True
|
||||||
|
|
||||||
|
url = \
|
||||||
|
http_prefix + '://' + domain_full + '/@' + \
|
||||||
|
admin_actor['preferredUsername']
|
||||||
|
|
||||||
|
if show_accounts:
|
||||||
|
active_accounts = no_of_accounts(base_dir)
|
||||||
|
local_posts = get_status_count(base_dir)
|
||||||
|
else:
|
||||||
|
active_accounts = 1
|
||||||
|
local_posts = 1
|
||||||
|
|
||||||
|
created_at = ''
|
||||||
|
if admin_actor.get('published'):
|
||||||
|
created_at = admin_actor['published']
|
||||||
|
|
||||||
|
icon_url = remove_html(admin_actor['icon']['url'])
|
||||||
|
image_url = remove_html(admin_actor['image']['url'])
|
||||||
|
instance = {
|
||||||
|
'approval_required': False,
|
||||||
|
'invites_enabled': False,
|
||||||
|
'registrations': registration,
|
||||||
|
'contact_account': {
|
||||||
|
'acct': admin_actor['preferredUsername'],
|
||||||
|
'created_at': created_at,
|
||||||
|
'avatar': icon_url,
|
||||||
|
'avatar_static': icon_url,
|
||||||
|
'header': image_url,
|
||||||
|
'header_static': image_url,
|
||||||
|
'bot': is_bot,
|
||||||
|
'discoverable': True,
|
||||||
|
'group': is_group,
|
||||||
|
'display_name': admin_actor['name'],
|
||||||
|
'locked': admin_actor['manuallyApprovesFollowers'],
|
||||||
|
'note': '<p>Admin of ' + domain + '</p>',
|
||||||
|
'url': url,
|
||||||
|
'username': admin_actor['preferredUsername']
|
||||||
|
},
|
||||||
|
'description': instance_description,
|
||||||
|
'languages': [system_language],
|
||||||
|
'short_description': instance_description_short,
|
||||||
|
'stats': {
|
||||||
|
'domain_count': 2,
|
||||||
|
'status_count': local_posts,
|
||||||
|
'user_count': active_accounts
|
||||||
|
},
|
||||||
|
'thumbnail': http_prefix + '://' + domain_full + '/login.png',
|
||||||
|
'title': instance_title,
|
||||||
|
'uri': domain_full,
|
||||||
|
'urls': {},
|
||||||
|
'version': version,
|
||||||
|
'rules': rules_list,
|
||||||
|
'configuration': {
|
||||||
|
'statuses': {
|
||||||
|
'max_media_attachments': 1
|
||||||
|
},
|
||||||
|
'media_attachments': {
|
||||||
|
'supported_mime_types': [
|
||||||
|
'image/jpeg',
|
||||||
|
'image/jxl',
|
||||||
|
'image/png',
|
||||||
|
'image/gif',
|
||||||
|
'image/webp',
|
||||||
|
'image/avif',
|
||||||
|
'image/heic',
|
||||||
|
'image/svg+xml',
|
||||||
|
'video/webm',
|
||||||
|
'video/mp4',
|
||||||
|
'video/ogv',
|
||||||
|
'audio/ogg',
|
||||||
|
'audio/wav',
|
||||||
|
'audio/x-wav',
|
||||||
|
'audio/x-pn-wave',
|
||||||
|
'audio/vnd.wave',
|
||||||
|
'audio/opus',
|
||||||
|
'audio/speex',
|
||||||
|
'audio/x-speex',
|
||||||
|
'audio/flac',
|
||||||
|
'audio/mpeg'
|
||||||
|
],
|
||||||
|
'image_size_limit': 10485760,
|
||||||
|
'image_matrix_limit': 16777216,
|
||||||
|
'video_size_limit': 41943040,
|
||||||
|
'video_frame_rate_limit': 60,
|
||||||
|
'video_matrix_limit': 2304000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
def _get_mast_api_v1id(path: str) -> int:
|
def _get_mast_api_v1id(path: str) -> int:
|
||||||
|
@ -322,18 +460,18 @@ def masto_api_v1_response(path: str, calling_domain: str,
|
||||||
show_node_info_accounts = False
|
show_node_info_accounts = False
|
||||||
|
|
||||||
send_json = \
|
send_json = \
|
||||||
meta_data_instance(show_node_info_accounts,
|
_meta_data_instance_v1(show_node_info_accounts,
|
||||||
instance_title,
|
instance_title,
|
||||||
instance_description_short,
|
instance_description_short,
|
||||||
instance_description,
|
instance_description,
|
||||||
http_prefix,
|
http_prefix,
|
||||||
base_dir,
|
base_dir,
|
||||||
admin_nickname,
|
admin_nickname,
|
||||||
domain,
|
domain,
|
||||||
domain_full,
|
domain_full,
|
||||||
registration,
|
registration,
|
||||||
system_language,
|
system_language,
|
||||||
project_version)
|
project_version)
|
||||||
send_json_str = 'masto API instance metadata sent ' + ua_str
|
send_json_str = 'masto API instance metadata sent ' + ua_str
|
||||||
elif path.startswith('/api/v1/instance/peers'):
|
elif path.startswith('/api/v1/instance/peers'):
|
||||||
# This is just a dummy result.
|
# This is just a dummy result.
|
||||||
|
|
162
metadata.py
162
metadata.py
|
@ -8,28 +8,9 @@ __status__ = "Production"
|
||||||
__module_group__ = "Metadata"
|
__module_group__ = "Metadata"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from utils import is_account_dir
|
|
||||||
from utils import load_json
|
|
||||||
from utils import no_of_accounts
|
|
||||||
from utils import no_of_active_accounts_monthly
|
from utils import no_of_active_accounts_monthly
|
||||||
from utils import remove_html
|
from utils import no_of_accounts
|
||||||
|
from utils import get_status_count
|
||||||
|
|
||||||
def _get_status_count(base_dir: str) -> int:
|
|
||||||
"""Get the total number of posts
|
|
||||||
"""
|
|
||||||
status_ctr = 0
|
|
||||||
accounts_dir = base_dir + '/accounts'
|
|
||||||
for _, dirs, _ in os.walk(accounts_dir):
|
|
||||||
for acct in dirs:
|
|
||||||
if not is_account_dir(acct):
|
|
||||||
continue
|
|
||||||
acct_dir = os.path.join(accounts_dir, acct + '/outbox')
|
|
||||||
for _, _, files2 in os.walk(acct_dir):
|
|
||||||
status_ctr += len(files2)
|
|
||||||
break
|
|
||||||
break
|
|
||||||
return status_ctr
|
|
||||||
|
|
||||||
|
|
||||||
def meta_data_node_info(base_dir: str,
|
def meta_data_node_info(base_dir: str,
|
||||||
|
@ -52,7 +33,7 @@ def meta_data_node_info(base_dir: str,
|
||||||
active_accounts = no_of_accounts(base_dir)
|
active_accounts = no_of_accounts(base_dir)
|
||||||
active_accounts_monthly = no_of_active_accounts_monthly(base_dir, 1)
|
active_accounts_monthly = no_of_active_accounts_monthly(base_dir, 1)
|
||||||
active_accounts_half_year = no_of_active_accounts_monthly(base_dir, 6)
|
active_accounts_half_year = no_of_active_accounts_monthly(base_dir, 6)
|
||||||
local_posts = _get_status_count(base_dir)
|
local_posts = get_status_count(base_dir)
|
||||||
else:
|
else:
|
||||||
active_accounts = 1
|
active_accounts = 1
|
||||||
active_accounts_monthly = 1
|
active_accounts_monthly = 1
|
||||||
|
@ -94,143 +75,6 @@ def meta_data_node_info(base_dir: str,
|
||||||
return nodeinfo
|
return nodeinfo
|
||||||
|
|
||||||
|
|
||||||
def meta_data_instance(show_accounts: bool,
|
|
||||||
instance_title: str,
|
|
||||||
instance_description_short: str,
|
|
||||||
instance_description: str,
|
|
||||||
http_prefix: str, base_dir: str,
|
|
||||||
admin_nickname: str, domain: str, domain_full: str,
|
|
||||||
registration: bool, system_language: str,
|
|
||||||
version: str) -> {}:
|
|
||||||
""" /api/v1/instance endpoint
|
|
||||||
"""
|
|
||||||
admin_actor_filename = \
|
|
||||||
base_dir + '/accounts/' + admin_nickname + '@' + domain + '.json'
|
|
||||||
if not os.path.isfile(admin_actor_filename):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
admin_actor = load_json(admin_actor_filename, 0)
|
|
||||||
if not admin_actor:
|
|
||||||
print('WARN: json load exception meta_data_instance')
|
|
||||||
return {}
|
|
||||||
|
|
||||||
rules_list = []
|
|
||||||
rules_filename = \
|
|
||||||
base_dir + '/accounts/tos.md'
|
|
||||||
if os.path.isfile(rules_filename):
|
|
||||||
with open(rules_filename, 'r', encoding='utf-8') as fp_rules:
|
|
||||||
rules_lines = fp_rules.readlines()
|
|
||||||
rule_ctr = 1
|
|
||||||
for line in rules_lines:
|
|
||||||
line = line.strip()
|
|
||||||
if not line:
|
|
||||||
continue
|
|
||||||
if line.startswith('#'):
|
|
||||||
continue
|
|
||||||
rules_list.append({
|
|
||||||
'id': str(rule_ctr),
|
|
||||||
'text': line
|
|
||||||
})
|
|
||||||
rule_ctr += 1
|
|
||||||
|
|
||||||
is_bot = False
|
|
||||||
is_group = False
|
|
||||||
if admin_actor['type'] == 'Group':
|
|
||||||
is_group = True
|
|
||||||
elif admin_actor['type'] != 'Person':
|
|
||||||
is_bot = True
|
|
||||||
|
|
||||||
url = \
|
|
||||||
http_prefix + '://' + domain_full + '/@' + \
|
|
||||||
admin_actor['preferredUsername']
|
|
||||||
|
|
||||||
if show_accounts:
|
|
||||||
active_accounts = no_of_accounts(base_dir)
|
|
||||||
local_posts = _get_status_count(base_dir)
|
|
||||||
else:
|
|
||||||
active_accounts = 1
|
|
||||||
local_posts = 1
|
|
||||||
|
|
||||||
created_at = ''
|
|
||||||
if admin_actor.get('published'):
|
|
||||||
created_at = admin_actor['published']
|
|
||||||
|
|
||||||
icon_url = remove_html(admin_actor['icon']['url'])
|
|
||||||
image_url = remove_html(admin_actor['image']['url'])
|
|
||||||
instance = {
|
|
||||||
'approval_required': False,
|
|
||||||
'invites_enabled': False,
|
|
||||||
'registrations': registration,
|
|
||||||
'contact_account': {
|
|
||||||
'acct': admin_actor['preferredUsername'],
|
|
||||||
'created_at': created_at,
|
|
||||||
'avatar': icon_url,
|
|
||||||
'avatar_static': icon_url,
|
|
||||||
'header': image_url,
|
|
||||||
'header_static': image_url,
|
|
||||||
'bot': is_bot,
|
|
||||||
'discoverable': True,
|
|
||||||
'group': is_group,
|
|
||||||
'display_name': admin_actor['name'],
|
|
||||||
'locked': admin_actor['manuallyApprovesFollowers'],
|
|
||||||
'note': '<p>Admin of ' + domain + '</p>',
|
|
||||||
'url': url,
|
|
||||||
'username': admin_actor['preferredUsername']
|
|
||||||
},
|
|
||||||
'description': instance_description,
|
|
||||||
'languages': [system_language],
|
|
||||||
'short_description': instance_description_short,
|
|
||||||
'stats': {
|
|
||||||
'domain_count': 2,
|
|
||||||
'status_count': local_posts,
|
|
||||||
'user_count': active_accounts
|
|
||||||
},
|
|
||||||
'thumbnail': http_prefix + '://' + domain_full + '/login.png',
|
|
||||||
'title': instance_title,
|
|
||||||
'uri': domain_full,
|
|
||||||
'urls': {},
|
|
||||||
'version': version,
|
|
||||||
'rules': rules_list,
|
|
||||||
'configuration': {
|
|
||||||
'statuses': {
|
|
||||||
'max_media_attachments': 1
|
|
||||||
},
|
|
||||||
'media_attachments': {
|
|
||||||
'supported_mime_types': [
|
|
||||||
'image/jpeg',
|
|
||||||
'image/jxl',
|
|
||||||
'image/png',
|
|
||||||
'image/gif',
|
|
||||||
'image/webp',
|
|
||||||
'image/avif',
|
|
||||||
'image/heic',
|
|
||||||
'image/svg+xml',
|
|
||||||
'video/webm',
|
|
||||||
'video/mp4',
|
|
||||||
'video/ogv',
|
|
||||||
'audio/ogg',
|
|
||||||
'audio/wav',
|
|
||||||
'audio/x-wav',
|
|
||||||
'audio/x-pn-wave',
|
|
||||||
'audio/vnd.wave',
|
|
||||||
'audio/opus',
|
|
||||||
'audio/speex',
|
|
||||||
'audio/x-speex',
|
|
||||||
'audio/flac',
|
|
||||||
'audio/mpeg'
|
|
||||||
],
|
|
||||||
'image_size_limit': 10485760,
|
|
||||||
'image_matrix_limit': 16777216,
|
|
||||||
'video_size_limit': 41943040,
|
|
||||||
'video_frame_rate_limit': 60,
|
|
||||||
'video_matrix_limit': 2304000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return instance
|
|
||||||
|
|
||||||
|
|
||||||
def metadata_custom_emoji(base_dir: str,
|
def metadata_custom_emoji(base_dir: str,
|
||||||
http_prefix: str, domain_full: str) -> {}:
|
http_prefix: str, domain_full: str) -> {}:
|
||||||
"""Returns the custom emoji
|
"""Returns the custom emoji
|
||||||
|
|
17
utils.py
17
utils.py
|
@ -4624,3 +4624,20 @@ def binary_is_image(filename: str, media_binary) -> bool:
|
||||||
if '<svg' in str(media_binary):
|
if '<svg' in str(media_binary):
|
||||||
bin_is_image = True
|
bin_is_image = True
|
||||||
return bin_is_image
|
return bin_is_image
|
||||||
|
|
||||||
|
|
||||||
|
def get_status_count(base_dir: str) -> int:
|
||||||
|
"""Get the total number of posts
|
||||||
|
"""
|
||||||
|
status_ctr = 0
|
||||||
|
accounts_dir = base_dir + '/accounts'
|
||||||
|
for _, dirs, _ in os.walk(accounts_dir):
|
||||||
|
for acct in dirs:
|
||||||
|
if not is_account_dir(acct):
|
||||||
|
continue
|
||||||
|
acct_dir = os.path.join(accounts_dir, acct + '/outbox')
|
||||||
|
for _, _, files2 in os.walk(acct_dir):
|
||||||
|
status_ctr += len(files2)
|
||||||
|
break
|
||||||
|
break
|
||||||
|
return status_ctr
|
||||||
|
|
Loading…
Reference in New Issue