more changes
This commit is contained in:
parent
695d8dc50f
commit
f03c698ac2
|
@ -3,6 +3,7 @@ import json, mimetypes
|
|||
from datetime import datetime, timezone
|
||||
from functools import partial
|
||||
from typing import Union
|
||||
from xml.etree.ElementTree import fromstring
|
||||
|
||||
from .dotdict import DotDict
|
||||
from .misc import DateString, Url, boolean
|
||||
|
@ -482,3 +483,72 @@ class WellknownNodeinfo(DotDict):
|
|||
'href': path
|
||||
})
|
||||
|
||||
|
||||
class Hostmeta(str):
|
||||
def __new__(cls, text):
|
||||
return str.__new__(cls, text)
|
||||
|
||||
|
||||
@classmethod
|
||||
def new(cls, domain):
|
||||
return cls(f'<?xml version="1.0" encoding="UTF-8"?><XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><Link rel="lrdd" template="https://{domain}/.well-known/webfinger?resource={{uri}}"/></XRD>')
|
||||
|
||||
|
||||
@property
|
||||
def link(self):
|
||||
return Url(fromstring(self)[0].attrib['template'])
|
||||
|
||||
|
||||
class Webfinger(DotDict):
|
||||
@property
|
||||
def profile(self):
|
||||
for link in self.links:
|
||||
if link['rel'] == 'http://webfinger.net/rel/profile-page':
|
||||
return link['href']
|
||||
|
||||
|
||||
@property
|
||||
def actor(self):
|
||||
for link in self.links:
|
||||
if link['rel'] == 'self':
|
||||
return link['href']
|
||||
|
||||
|
||||
@property
|
||||
def fullname(self):
|
||||
return self.subject[5:]
|
||||
|
||||
|
||||
@property
|
||||
def handle(self):
|
||||
return self.fullname.split('@')[0]
|
||||
|
||||
|
||||
@property
|
||||
def domain(self):
|
||||
return self.fullname.split('@')[1]
|
||||
|
||||
|
||||
@classmethod
|
||||
def new(cls, handle, domain, actor, profile=None):
|
||||
data = cls(
|
||||
subject = f'acct:{handle}@{domain}',
|
||||
aliases = [actor],
|
||||
links = [
|
||||
{
|
||||
'rel': 'self',
|
||||
'type': 'application/activity+json',
|
||||
'href': actor
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
if profile:
|
||||
data.aliases.append(profile)
|
||||
data.links.append({
|
||||
'rel': 'http://webfinger.net/rel/profile-page',
|
||||
'type': 'text/html',
|
||||
'href': profile
|
||||
})
|
||||
|
||||
return data
|
||||
|
|
|
@ -105,7 +105,7 @@ class BaseCache(OrderedDict):
|
|||
self[key]['timestamp'] = timestamp + self.ttl
|
||||
|
||||
self.move_to_end(key)
|
||||
return item.data
|
||||
return item
|
||||
|
||||
|
||||
## This doesn't work for some reason
|
||||
|
|
|
@ -43,8 +43,8 @@ class PasswordHasher:
|
|||
def get_config(self, key):
|
||||
key = self.aliases.get(key, key)
|
||||
|
||||
self[key]
|
||||
return self.get(key) / 1024 if key == 'memory_cost' else self.get(key)
|
||||
value = self.config[key]
|
||||
return value / 1024 if key == 'memory_cost' else value
|
||||
|
||||
|
||||
def set_config(self, key, value):
|
||||
|
|
|
@ -114,6 +114,9 @@ class ApplicationBase:
|
|||
|
||||
|
||||
async def handle_request(self, request, response, path=None):
|
||||
if request.host not in self.cfg.hosts and not request.path.startswith('/framework'):
|
||||
raise error.NotFound(f'Host not handled on this server: {request.host}')
|
||||
|
||||
handler = self.get_route(path or request.path, request.method)
|
||||
|
||||
await self.handle_middleware(request)
|
||||
|
|
|
@ -43,6 +43,11 @@ class Config(BaseConfig):
|
|||
self.default_headers['server'] = f'{self.name}/{__version__}'
|
||||
|
||||
|
||||
@property
|
||||
def hosts(self):
|
||||
return (self.host, self.web_host, *self.alt_hosts)
|
||||
|
||||
|
||||
def parse_value(self, key, value):
|
||||
if self._startup:
|
||||
return value
|
||||
|
|
|
@ -132,7 +132,7 @@ def set_default_client(client=None):
|
|||
@lru_cache(maxsize=512)
|
||||
def fetch_actor(url):
|
||||
if not Client:
|
||||
raise ValueError('Please set global client with "SetRequestsClient(client)"')
|
||||
raise ValueError('Please set global client with "HttpUrllibClient.set_global()"')
|
||||
|
||||
url = url.split('#')[0]
|
||||
headers = {'Accept': 'application/activity+json'}
|
||||
|
@ -165,7 +165,7 @@ def fetch_actor(url):
|
|||
@lru_cache(maxsize=512)
|
||||
def fetch_instance(domain):
|
||||
if not Client:
|
||||
raise ValueError('Please set global client with "SetRequestsClient(client)"')
|
||||
raise ValueError('Please set global client with "HttpUrllibClient.set_global()"')
|
||||
|
||||
headers = {'Accept': 'application/json'}
|
||||
resp = Client.request(f'https://{domain}/api/v1/instance', headers=headers)
|
||||
|
@ -184,7 +184,7 @@ def fetch_instance(domain):
|
|||
@lru_cache(maxsize=512)
|
||||
def fetch_nodeinfo(domain):
|
||||
if not Client:
|
||||
raise ValueError('Please set global client with HttpRequestsClient.set_global()')
|
||||
raise ValueError('Please set global client with HttpUrllibClient.set_global()')
|
||||
|
||||
webfinger = Client.request(f'https://{domain}/.well-known/nodeinfo')
|
||||
webfinger_data = DotDict(webfinger.body)
|
||||
|
@ -201,7 +201,7 @@ def fetch_nodeinfo(domain):
|
|||
@lru_cache(maxsize=512)
|
||||
def fetch_webfinger_account(handle, domain):
|
||||
if not Client:
|
||||
raise ValueError('Please set global client with HttpRequestsClient.set_global()')
|
||||
raise ValueError('Please set global client with HttpUrllibClient.set_global()')
|
||||
|
||||
data = DefaultDotDict()
|
||||
webfinger = Client.request(f'https://{domain}/.well-known/webfinger?resource=acct:{handle}@{domain}')
|
||||
|
|
|
@ -321,6 +321,7 @@ def prompt(prompt, default=None, valtype=str, options=[], password=False):
|
|||
prompt += '\n'
|
||||
|
||||
if options:
|
||||
options = [str(opt) for opt in options]
|
||||
opt = '/'.join(options)
|
||||
prompt += f'[{opt}]'
|
||||
|
||||
|
@ -442,7 +443,7 @@ def time_function(func, *args, passes=1, use_gc=True, **kwargs):
|
|||
return timer.timeit(1)
|
||||
|
||||
|
||||
def time_function_pprint(func, *args, passes=5, use_gc=True, floatlen=3, **kwargs):
|
||||
def time_function_pprint(func, *args, passes=5, use_gc=True, floatout=True, **kwargs):
|
||||
'''Run a function and print out the time it took for each pass, the average and total
|
||||
|
||||
Arguments:
|
||||
|
@ -451,25 +452,33 @@ def time_function_pprint(func, *args, passes=5, use_gc=True, floatlen=3, **kwarg
|
|||
kwargs (dict(str:various)): The keyword arguments to be passed to the timed function
|
||||
passes (int): How many times the timed function should be run
|
||||
use_gc (bool): If True, keep garbage collection enabled
|
||||
floatlen (int): The amount of decimal places each result should have
|
||||
|
||||
Return:
|
||||
None: The data gets printed to stdout
|
||||
'''
|
||||
|
||||
parse_time = lambda num: f'{round(num, floatlen)}s'
|
||||
times = []
|
||||
|
||||
for idx in range(0, passes):
|
||||
passtime = time_function(func, *args, **kwargs, passes=1, use_gc=use_gc)
|
||||
times.append(passtime)
|
||||
print(f'Pass {idx+1}: {parse_time(passtime)}')
|
||||
|
||||
if not floatout:
|
||||
print(f'Pass {idx+1}: {passtime:.0f}')
|
||||
|
||||
else:
|
||||
print(f'Pass {idx+1}: {passtime:.8f}')
|
||||
|
||||
average = statistics.fmean(times)
|
||||
|
||||
print('-----------------')
|
||||
print(f'Average: {parse_time(average)}')
|
||||
print(f'Total: {parse_time(sum(times))}')
|
||||
if not floatout:
|
||||
print(f'Average: {average:.0f}')
|
||||
print(f'Total: {sum(times):.0f}')
|
||||
|
||||
else:
|
||||
print(f'Average: {average:.8f}')
|
||||
print(f'Total: {sum(times):.8f}')
|
||||
|
||||
|
||||
def timestamp(dtobj=None, utc=False):
|
||||
|
|
Loading…
Reference in a new issue