add Nodeinfo class and related Enums

This commit is contained in:
Izalia Mae 2022-11-16 21:30:23 -05:00
parent 17fcdc359c
commit 530958c2f2
5 changed files with 225 additions and 1 deletions

View file

@ -12,6 +12,7 @@ MODULES = {
'Signature': 'misc',
#objects
'Nodeinfo': 'objects',
'WellKnownNodeinfo': 'objects',
# signer
@ -19,6 +20,9 @@ MODULES = {
# enums
'Enum': 'enums',
'NodeinfoProtocol': 'enums',
'NodeinfoServiceInbound': 'enums',
'NodeinfoServiceOutbound': 'enums',
'RsaKeyType': 'enums',
'RsaKeySize': 'enums',
@ -40,8 +44,10 @@ def __getattr__(key):
raise ImportError(f'Cannot import "{key}" from "aputils.{MODULES[key]}"') from None
except KeyError:
raise ImportError(f'Object "{key}" does not exist') from None
pass
except Exception as e:
traceback.print_exc()
raise e
return import_module(f'aputils.{key}')

View file

@ -35,6 +35,67 @@ class StrEnum(str, Enum):
pass
class NodeinfoProtocol(StrEnum):
'Protocols for nodeinfo'
ACTIVITYPUB = 'activitypub'
BUDDYCLOUD = 'buddycloud'
DFRN = 'dfrn'
DIASPORA = 'diaspora'
LIBERTREE = 'libertree'
OSTATUS = 'ostatus'
PUMPIO = 'pumpio'
TENT = 'tent'
XMPP = 'xmpp'
ZOT = 'zot'
class NodeinfoServiceInbound(StrEnum):
'Nodeinfo inbound services'
ATOM = 'atom1.0'
GNUSOCIAL = 'gnusocial'
IMAP = 'imap'
PNUT = 'pnut'
POP3 = 'pop3'
PUMPIO = 'pumpio'
RSS = 'rss2.0'
TWITTER = 'twitter'
class NodeinfoServiceOutbound(StrEnum):
'Nodeinfo outbound services'
ATOM = 'atom1.0'
BLOGGER = 'blogger'
BUDDYCLOUD = 'buddycloud'
DIASPORA = 'diaspora'
DREAMWIDTH = 'dreamwidth'
DRUPAL = 'drupal'
FACEBOOK = 'facebook'
FRIENDICA = 'friendica'
GNUSOCIAL = 'gnusocial'
GOOGLE = 'google'
INSANEJOURNAL = 'insanejournal'
LIBERTREE = 'libertree'
LINKEDIN = 'linkedin'
LIVEJOURNAL = 'livejournal'
MEDIAGOBLIN = 'mediagoblin'
MYSPACE = 'myspace'
PINTEREST = 'pinterest'
PNUT = 'pnut'
POSTEROUS = 'posterous'
PUMPIO = 'pumpio'
REDMATRIX = 'redmatrix'
RSS = 'rss2.0'
SMTP = 'smtp'
TENT = 'tent'
TUMBLR = 'tumblr'
TWITTER = 'twitter'
WORDPRESS = 'wordpress'
XMPP = 'xmpp'
class RsaKeyType(StrEnum):
'Type of RSA key'

View file

@ -1,3 +1,4 @@
from . import enums
from .misc import Dotdict
@ -7,6 +8,97 @@ NODEINFO_NS = {
}
class Nodeinfo(Dotdict):
'An object that represents a nodeinfo endpoint'
@classmethod
def new(cls, name:str, version:str, protocols:list=[], insrv:list=[], outsrv:list=[], metadata:list={}, **kwargs):
'''
Create a new nodeinfo object. It will default to version 2.0 if ``repo`` and ``homeage`` are not set.
:param str name: Software name to use. Can only include lowercase letters and '-', '_' characters.
:param str version: Version of the software.
:param Optional[list] protocols: List of supported protocols (see :py:class:`aputils.NodeinfoProtocol`)
:param Optional[list] insrv: Supported inbound services (see :py:class:`aputils.NodeinfoServiceInbound`)
:param Optional[list] outsrv: Supported outbound services (see :py:class:`aputils.NodeinfoServiceOutbound`)
:param Optional[dict] metadata: Extra server info
:param Optional[str] repo: Url to the repository that hosts the server code
:param Optional[str] homepage: Url to the homepage of the server software
:param Otional[bool] open_regs: Whether user registrations are open or not
:param Optional[int] users: Total number of registered users
:param Optional[int] halfyear: Number of new users in the past 6 months
:param Optional[int] month: Number of new users in the past month
:param Optional[int], optional posts: Total number of posts
:param Optional[int] comments: Total number of comments
'''
repo = kwargs.get('repo', None)
homepage = kwargs.get('homepage', None)
open_regs = kwargs.get('open_regs', True)
total_users = kwargs.get('users', 0)
halfyear_users = kwargs.get('halfyear', 0)
month_users = kwargs.get('month', 0)
posts = kwargs.get('posts', 0)
comments = kwargs.get('comments', 0)
if not re.match('^[a-z0-9-]+$', name):
raise ValueError(f'Invalid software name. Must match regex: ^[a-z0-9-]+$')
if isinstance(protocols, str):
protocols = [protocols]
elif not isinstance(protocols, (list, set, tuple)):
raise TypeError('Protocols must be a list, set, or tuple')
data = {
'version': '2.1' if repo or homepage else '2.0',
'software': {
'name': name,
'version': version
},
'protocols': tuple(enums.NodeinfoProtocol.parse(v) for v in protocols),
'services': {
'inbound': tuple(enums.NodeinfoServiceInbound.parse(v) for v in insrv),
'outbound': tuple(enums.NodeinfoServiceOutbound.parse(v) for v in outsrv)
},
'openRegistrations': open_regs,
'usage': {
'users': {
'total': total_users,
'activeHalfyear': halfyear_users,
'activeMonth': month_users,
}
},
'metadata': metadata
}
if repo:
data['software']['repository'] = repo
if homepage:
data['software']['homepage'] = homepage
if posts:
data['usage']['localPosts'] = posts
if comments:
data['usage']['localComments'] = comments
return cls(data)
@property
def sw_name(self):
'Get the software name at ``Nodeinfo.software.name``'
return self.software.name
@property
def sw_version(self):
'Get the software version at ``Nodeinfo.software.version``'
return self.software.version
class WellKnownNodeinfo(Dotdict):
'An object that represents the /.well-known/nodeinfo endpoint'

View file

@ -4,6 +4,67 @@ Enums
:members: parse
:exclude-members: __init__, __new__
.. autoclass:: aputils.NodeinfoProtocol
:show-inheritance:
:exclude-members: __init__, __new__
.. autoattribute:: ACTIVITYPUB
.. autoattribute:: BUDDYCLOUD
.. autoattribute:: DFRN
.. autoattribute:: DIASPORA
.. autoattribute:: LIBERTREE
.. autoattribute:: OSTATUS
.. autoattribute:: PUMPIO
.. autoattribute:: TENT
.. autoattribute:: XMPP
.. autoattribute:: ZOT
.. autoclass:: aputils.NodeinfoServiceInbound
:show-inheritance:
:exclude-members: __init__, __new__
.. autoattribute:: ATOM
.. autoattribute:: GNUSOCIAL
.. autoattribute:: IMAP
.. autoattribute:: PNUT
.. autoattribute:: POP3
.. autoattribute:: PUMPIO
.. autoattribute:: RSS
.. autoattribute:: TWITTER
.. autoclass:: aputils.NodeinfoServiceOutbound
:show-inheritance:
:exclude-members: __init__, __new__
.. autoattribute:: ATOM
.. autoattribute:: BLOGGER
.. autoattribute:: BUDDYCLOUD
.. autoattribute:: DIASPORA
.. autoattribute:: DREAMWIDTH
.. autoattribute:: DRUPAL
.. autoattribute:: FACEBOOK
.. autoattribute:: FRIENDICA
.. autoattribute:: GNUSOCIAL
.. autoattribute:: GOOGLE
.. autoattribute:: INSANEJOURNAL
.. autoattribute:: LIBERTREE
.. autoattribute:: LINKEDIN
.. autoattribute:: LIVEJOURNAL
.. autoattribute:: MEDIAGOBLIN
.. autoattribute:: MYSPACE
.. autoattribute:: PINTEREST
.. autoattribute:: PNUT
.. autoattribute:: POSTEROUS
.. autoattribute:: PUMPIO
.. autoattribute:: REDMATRIX
.. autoattribute:: RSS
.. autoattribute:: SMTP
.. autoattribute:: TENT
.. autoattribute:: TUMBLR
.. autoattribute:: TWITTER
.. autoattribute:: WORDPRESS
.. autoattribute:: XMPP
.. autoclass:: aputils.RsaKeySize
:show-inheritance:
:exclude-members: __init__, __new__, parse

View file

@ -1,4 +1,8 @@
Objects
=======
.. autoclass:: aputils.Nodeinfo
:members:
.. autoclass:: aputils.WellKnownNodeinfo
:members: