uncia/uncia/functions.py

119 lines
2 KiB
Python

import json
from functools import wraps
from izzylib import LruCache, logging
from izzylib.http_urllib_client import HttpUrllibClient
from izzylib.http_urllib_client.error import MaxRetryError
from . import __version__
from .config import config
from .database import db
client = HttpUrllibClient(
appagent = f'UnciaRelay/{__version__}; https://{config.host}',
headers = {
'accept': 'application/activity+json,application/json'
}
)
client.set_global()
fetch_cache = LruCache()
def fetch_actor(url):
with db.session as s:
cached = s.get.actor(url)
if cached:
return cached
try:
data = fetch(url, cache=False)
except:
data = None
if not data:
data = fetch(url, sign=True, cache=False)
if not data or data.get('error'):
return
s.put.actor(url, data)
return data
def fetch(url, sign=False, cache=True):
cached_data = fetch_cache.fetch(url)
if cached_data and cache:
return cached_data
if sign:
with db.session as s:
response = client.request(url,
privkey = s.get.config('privkey'),
keyid = f'https://{config.host}/actor#main-key'
)
else:
response = client.request(url)
try:
data = response.dict
except json.decoder.JSONDecodeError:
return {}
if not data:
return {}
if cache:
fetch_cache.store(url, data)
return data
def fetch_auth(url):
return fetch(url, sign=True)
def get_inbox(actor):
if not actor:
return
try:
return actor.endpoints.sharedInbox
except:
return actor.inbox
def push_message(inbox, message):
with db.session as s:
try:
response = client.request(
inbox,
body = message.to_json(),
method = 'post',
privkey = s.get.config('privkey'),
keyid = f'https://{config.host}/actor#main-key'
)
if response.status not in [200, 202]:
try:
body = response.dict
except:
body = response.text
logging.debug(f'Error from {inbox}: {body}')
return response
## this exception catching will be used later
except Exception as s:
pass
except MaxRetryError:
pass