From 4b5ddf1d482e533270de2b7f86e16bed8704fd23 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 13 Nov 2019 12:45:41 +0000 Subject: [PATCH] instance metadata endpoint --- daemon.py | 25 +++++++++++++++++++- epicyon.py | 17 +++++++++++++- metadata.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 2 deletions(-) diff --git a/daemon.py b/daemon.py index d575bf933..763680541 100644 --- a/daemon.py +++ b/daemon.py @@ -25,6 +25,7 @@ from webfinger import webfingerNodeInfo from webfinger import webfingerLookup from webfinger import webfingerHandle from metadata import metaDataNodeInfo +from metadata import metaDataInstance from donate import getDonationUrl from donate import setDonationUrl from person import activateAccount @@ -336,6 +337,26 @@ class PubServer(BaseHTTPRequestHandler): return False if self.server.debug: print('DEBUG: mastodon api '+self.path) + if self.path=='/api/v1/instance': + adminNickname=getConfigParam(self.server.baseDir,'admin') + instanceDescriptionShort=getConfigParam(self.server.baseDir,'instanceDescriptionShort') + instanceDescription=getConfigParam(self.server.baseDir,'instanceDescription') + instanceTitle=getConfigParam(self.server.baseDir,'instanceTitle') + instanceJson= \ + metaDataInstance(instanceTitle, \ + instanceDescriptionShort, \ + instanceDescription, \ + self.server.httpPrefix, \ + self.server.baseDir, \ + adminNickname, \ + self.server.domain,self.server.domainFull, \ + self.server.registration, \ + self.server.systemLanguage, \ + self.server.projectVersion) + msg=json.dumps(instanceJson).encode('utf-8') + self._set_headers('application/ld+json',len(msg),None) + self._write(msg) + return True if self.path.startswith('/api/v1/instance/peers'): # This is just a dummy result. # Showing the full list of peers would have privacy implications. @@ -365,7 +386,7 @@ class PubServer(BaseHTTPRequestHandler): self._set_headers('application/ld+json',len(msg),None) self._write(msg) return True - + def _webfinger(self) -> bool: if not self.path.startswith('/.well-known'): return False @@ -4465,6 +4486,7 @@ def runDaemon(registration: bool, \ # load translations dictionary httpd.translate={} + httpd.systemLanguage='en' if not unitTest: if not os.path.isdir(baseDir+'/translations'): print('ERROR: translations directory not found') @@ -4486,6 +4508,7 @@ def runDaemon(registration: bool, \ systemLanguage='en' translationsFile=baseDir+'/translations/'+systemLanguage+'.json' print('System language: '+systemLanguage) + httpd.systemLanguage=systemLanguage httpd.translate=loadJson(translationsFile) httpd.registration=registration diff --git a/epicyon.py b/epicyon.py index 8959d19ed..323e906eb 100644 --- a/epicyon.py +++ b/epicyon.py @@ -366,7 +366,22 @@ if not os.path.isdir(baseDir+'/cache/announce'): themeName=getConfigParam(baseDir,'theme') if not themeName: setConfigParam(baseDir,'theme','default') - + +# set the instance title in config.json +title=getConfigParam(baseDir,'instanceTitle') +if not title: + setConfigParam(baseDir,'instanceTitle','Epicyon') + +# set the instance description in config.json +descFull=getConfigParam(baseDir,'instanceDescription') +if not descFull: + setConfigParam(baseDir,'instanceDescription','Just another ActivityPub server') + +# set the short instance description in config.json +descShort=getConfigParam(baseDir,'instanceDescriptionShort') +if not descShort: + setConfigParam(baseDir,'instanceDescriptionShort','Just another ActivityPub server') + if args.domain: domain=args.domain setConfigParam(baseDir,'domain',domain) diff --git a/metadata.py b/metadata.py index 337eb3357..da69ae9c9 100644 --- a/metadata.py +++ b/metadata.py @@ -6,7 +6,9 @@ __maintainer__ = "Bob Mottram" __email__ = "bob@freedombone.net" __status__ = "Production" +import os import json +import commentjson def metaDataNodeInfo(registration: bool,version: str) -> {}: """ /nodeinfo/2.0 endpoint @@ -29,3 +31,67 @@ def metaDataNodeInfo(registration: bool,version: str) -> {}: 'version': '2.0' } return nodeinfo + +def metaDataInstance(instanceTitle: str, \ + instanceDescriptionShort: str, \ + instanceDescription: str, \ + httpPrefix: str,baseDir: str, \ + adminNickname: str,domain: str,domainFull: str, \ + registration: bool,systemLanguage: str, \ + version: str) -> {}: + """ /api/v1/instance endpoint + """ + adminActorFilename=baseDir+'/accounts/'+adminNickname+'@'+domain+'.json' + if not os.path.isfile(adminActorFilename): + return {} + + adminActor=None + try: + with open(adminActorFilename, 'r') as fp: + adminActor=commentjson.load(fp) + except: + print('WARN: commentjson exception metaDataInstance') + + if not adminActor: + return {} + + instance = { + 'approval_required': False, + 'contact_account': {'acct': adminActor['preferredUsername'], + 'avatar': adminActor['icon']['url'], + 'avatar_static': adminActor['icon']['url'], + 'bot': False, + 'created_at': '2019-07-01T10:30:00Z', + 'display_name': adminActor['name'], + 'emojis': [], + 'fields': [], + 'followers_count': 1, + 'following_count': 1, + 'header': adminActor['image']['url'], + 'header_static': adminActor['image']['url'], + 'id': '1', + 'last_status_at': '2019-07-01T10:30:00Z', + 'locked': False, + 'note': '

Admin of '+domain+'

', + 'statuses_count': 1, + 'url': httpPrefix+'://'+domainFull+'/@'+adminActor['preferredUsername'], + 'username': adminActor['preferredUsername'] + }, + 'description': instanceDescription, + 'email': 'admin@'+domain, + 'languages': [systemLanguage], + 'registrations': registration, + 'short_description': instanceDescriptionShort, + 'stats': { + 'domain_count': 1, + 'status_count': 1, + 'user_count': 1 + }, + 'thumbnail': httpPrefix+'://'+domainFull+'/login.png', + 'title': instanceTitle, + 'uri': domainFull, + 'urls': {}, + 'version': version + } + + return instance