uncia/uncia/views.py

217 lines
4.8 KiB
Python

from izzylib import DotDict, logging
from izzylib.http_server import View
from . import __version__
from .config import config
from .database import db
from .processing import ProcessData
### Frontend
class UnciaHome(View):
paths = ['/']
async def get(self, request, response):
instances = []
with db.session as s:
for row in s.get.inbox_list():
if not row.followid:
instances.append({
'domain': row.domain,
'date': row.timestamp.strftime('%Y-%m-%d')
})
return response.template('page/home.haml', {'instances': instances})
class UnciaRules(View):
paths = ['/rules']
async def get(self, request, response):
pass
class UnciaAbout(View):
paths = ['/about']
async def get(self, request, response):
return response.template('page/about.haml')
class UnciaRegister(View):
paths = ['/register']
async def get(self, request, response, error=None, message=None, form={}):
data = {
'form': form,
'error': error,
'message': message
}
return response.template('page/register.haml', data)
async def post(self, request, response):
return await self.get(request, response, form=request.data.form)
class UnciaLogin(View):
paths = ['/login']
async def get(self, request, response, error=None, message=None, form={}):
data = {
'form': form,
'error': error,
'message': message
}
return response.template('page/login.haml', data)
async def post(self, request, response):
return await self.get(request, response, form=request.data.form)
class UnciaLogout(View):
paths = ['/logout']
async def get(self, request, response):
return response.redir('/')
class UnciaAdmin(View):
paths = ['/admin']
async def get(self, request, response):
return response.template('page/home.haml')
async def post(self, request, response):
return await self.get(request, response)
### ActivityPub and AP-related endpoints
class UnciaActor(View):
paths = ['/actor', '/inbox']
async def get(self, request, response):
with db.session as s:
cfg = s.get.config_all()
data = {
'@context': [
'https://www.w3.org/ns/activitystreams',
{'manuallyApprovesFollowers': 'as:manuallyApprovesFollowers'},
],
'endpoints': {
'sharedInbox': f"https://{config.host}/inbox"
},
#'followers': f'https://{host}/followers',
#'following': f'https://{host}/following',
'inbox': f'https://{config.host}/inbox',
'name': cfg.name,
'type': 'Application',
'id': f'https://{config.host}/actor',
'manuallyApprovesFollowers': cfg.require_approval,
'publicKey': {
'id': f'https://{config.host}/actor#main-key',
'owner': f'https://{config.host}/actor',
'publicKeyPem': cfg.pubkey
},
'summary': 'Relay Actor',
'preferredUsername': 'relay',
'url': f'https://{config.host}/actor'
}
return response.json(data)
async def post(self, request, response):
data = ProcessData(request, response, request.data.json)
# return error to let mastodon retry instead of having to re-add relay
return data.new_response or response.text('UvU', status=202)
#return response.text('Merp! uvu')
class UnciaNodeinfo(View):
paths = ['/nodeinfo/2.0.json', '/nodeinfo/2.0']
async def get(self, request, response):
with db.session as s:
instances = s.get.inbox_list('domain')
domainbans = [row.domain for row in s.get.ban_list('domain')]
userbans = [f"{row.handle}@{row.domain}" for row in s.get.ban_list('user')]
data = {
'openRegistrations': True,
'protocols': ['activitypub'],
'services': {
'inbound': [],
'outbound': []
},
'software': {
'name': 'unciarelay',
'version': f'{__version__}'
},
'usage': {
'localPosts': 0,
'users': {
'total': len(instances)
}
},
'version': '2.0',
'metadata': {
'require_approval': s.get.config('require_approval'),
'peers': instances,
'email': s.get.config('email'),
'federation': {
'instance_blocks': False if not s.get.config('show_domain_bans') else domainbans,
'user_blocks': False if not s.get.config('show_user_bans') else userbans
}
}
}
return response.json(data)
class UnciaWebfinger(View):
paths = ['/.well-known/webfinger']
async def get(self, request, response):
resource = request.data.query.get('resource')
if resource != f'acct:relay@{config.host}':
return response.text('', status=404)
return response.json({
'subject': f'acct:relay@{config.host}',
'aliases': [
f'https://{config.host}/actor'
],
'links': [
{
'rel': 'self',
'type': 'application/activity+json',
'href': f'https://{config.host}/actor'
}
]
})
class UnciaWellknownNodeinfo(View):
paths = ['/.well-known/nodeinfo']
async def get(self, request, response):
return response.json({
'links': [
{
'rel': 'http://nodeinfo.diaspora.software/ns/schema/2.0',
'href': f'https://{config.host}/nodeinfo/2.0.json'
}
]
})