brn: Introduce BRN as a class
This commit is contained in:
parent
8c411e39bc
commit
a0da4d4641
8 changed files with 116 additions and 9 deletions
3
app/brm/__init__.py
Normal file
3
app/brm/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
"""
|
||||
Bypass Censorship Resource Management API.
|
||||
"""
|
58
app/brm/brn.py
Normal file
58
app/brm/brn.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
"""
|
||||
Bypass Censorship Resource Names.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any
|
||||
|
||||
from flask import current_app
|
||||
|
||||
from app.brm.utils import is_integer
|
||||
|
||||
|
||||
def global_namespace() -> str:
|
||||
return str(current_app.config["GLOBAL_NAMESPACE"])
|
||||
|
||||
|
||||
@dataclass
|
||||
class BRN:
|
||||
group_id: int
|
||||
product: str
|
||||
provider: str
|
||||
resource_type: str
|
||||
resource_id: str
|
||||
global_namespace: str = field(default_factory=global_namespace)
|
||||
|
||||
@classmethod
|
||||
def from_str(cls, s: str) -> BRN:
|
||||
parts = s.split(":")
|
||||
if len(parts) != 6 or parts[0].lower() != "brn" or not is_integer(parts[2]):
|
||||
raise TypeError(f"Expected a valid BRN but got {repr(s)}.")
|
||||
resource_parts = parts[4].split("/")
|
||||
if len(resource_parts) != 5:
|
||||
raise TypeError(f"Expected a valid BRN but got {repr(s)}.")
|
||||
return cls(
|
||||
global_namespace=parts[1],
|
||||
group_id=int(parts[2]),
|
||||
product=parts[3],
|
||||
provider=parts[4],
|
||||
resource_type=resource_parts[0],
|
||||
resource_id=resource_parts[1]
|
||||
)
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
return str(self) == str(other)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return ":".join([
|
||||
"brn",
|
||||
self.global_namespace,
|
||||
str(self.group_id),
|
||||
self.product,
|
||||
self.provider,
|
||||
f"{self.resource_type}/{self.resource_id}"
|
||||
])
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<BRN {str(self)}>"
|
20
app/brm/utils.py
Normal file
20
app/brm/utils.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
def is_integer(n: Any) -> bool:
|
||||
"""
|
||||
Determine if a string (or other object type that can be converted automatically) represents an integer.
|
||||
|
||||
Thanks to https://note.nkmk.me/en/python-check-int-float/.
|
||||
|
||||
:param n: object to test
|
||||
:return: true if it's an integer
|
||||
"""
|
||||
try:
|
||||
float(n)
|
||||
except ValueError:
|
||||
return False
|
||||
else:
|
||||
return float(n).is_integer()
|
Loading…
Add table
Add a link
Reference in a new issue