"""``CioType`` is similar to a MIME type:
`type/subtype+suffix?parameter=value`."""
from __future__ import annotations
from json import loads
from urllib.parse import quote, unquote
from pyramid.request import Request
CIOTYPE_DIRECTORY = 'directory'
ICON_UNKNOWN = 'unknown.svg'
# =============================================================================
[docs]
class CioType():
"""A class to manage `CioType`.
:param str string:
String representation of a `CioType`.
"""
# -------------------------------------------------------------------------
def __init__(self, type_: str | None, subtype: str | None = None):
"""Constructor method."""
if not type_:
self.type_: str | None = None
self.subtype: str | None = None
else:
self.type_ = type_
self.subtype = None if not subtype or subtype == '*' else subtype
# -------------------------------------------------------------------------
[docs]
@classmethod
def from_str(cls, string: str | None) -> CioType:
"""Return a new `CioType` created from a string."""
if not string:
return CioType(None)
if '/' in string:
return CioType(*string.partition('/')[::2])
return CioType(string)
# -------------------------------------------------------------------------
[docs]
@classmethod
def from_request(
cls, request: Request) -> CioType:
"""Look for a `CioType` in a request.
:type request: pyramid.request.Request
:param request:
Current request.
:rtype: .lib.ciotype.CioType
"""
# Explicit `CioType`
ciotype_str = request.matchdict.get('ciotype')
if not ciotype_str:
return CioType(None)
if ciotype_str != '-':
return CioType.from_str(unquote(ciotype_str))
# Guessed `CioType`
ciopath_list = request.matchdict.get('ciopath')
if not ciopath_list or len(ciopath_list) < 2:
return CioType(None)
ciopath_str = f"{ciopath_list[0]}:{'/'.join(ciopath_list[1:])}"
backend = request.registry['modules']['ciowarehouse2'].backend
reply, error = backend.search(
f'ciopath: IN ["{ciopath_str}" "{ciopath_str}/"]', 1)
if reply is None or error is not None or not reply.hits:
return CioType(None)
return CioType.from_str(loads(reply.hits[0].json)['ciotype'][0])
# -------------------------------------------------------------------------
def __repr__(self):
"""Return a string representation of the `CioType`.
:rtype: str
"""
if self.type_ is None:
return ''
return f"{self.type_}/{'*' if not self.subtype else self.subtype}"
# -------------------------------------------------------------------------
def __eq__(self, other):
"""Override the default implementation."""
if isinstance(other, CioType):
return self.type_ == other.type_ and self.subtype == other.subtype
return False
# -------------------------------------------------------------------------
def __bool__(self) -> bool:
"""Override the default implementation."""
return self.type_ is not None
# -------------------------------------------------------------------------
def __hash__(self):
"""Override the default implementation."""
return hash(str(self))
# -------------------------------------------------------------------------
[docs]
def uid(self) -> str:
"""Return a Unique ID for this `CioType`.
:rtype: str
"""
if self.type_ is None:
return ''
if self.subtype is None:
return self.type_
return str(self).replace('/', '-')
# -------------------------------------------------------------------------
[docs]
def match(self, other) -> bool:
"""Return `true` if the given `CioType` matches with this one.
:rtype: bool
"""
if other == self:
return True
if not isinstance(other, CioType):
return False
if self.subtype is None:
return other.type_ == self.type_
if other.subtype is not None and '+' in other.subtype:
return other.type_ == self.type_ \
and other.subtype.split('+')[0] == self.subtype
return False
# -------------------------------------------------------------------------
[docs]
def is_directory(self):
"""Return `true` if `CioType` represents a directory.
:rtype: bool
"""
return self.type_ == CIOTYPE_DIRECTORY
# -------------------------------------------------------------------------
[docs]
def route(self) -> str:
"""Return a safe string representing the `CioType` in a route."""
return quote(str(self), safe='')