Python implementation of [Earthstar](https://earthstar-project.org/)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
1.8 KiB
61 lines
1.8 KiB
"""Share handling""" |
|
|
|
from random import choice |
|
import re |
|
from typing import Optional |
|
|
|
from .exc import ValidationError |
|
from .types import ALPHA_LOWER, ALPHA_LOWER_OR_DIGIT |
|
|
|
|
|
class Share: |
|
"""Class to handle a share (space or workspace in older terminology)""" |
|
|
|
_NAME_PATTERN = f'[{ALPHA_LOWER}][{ALPHA_LOWER_OR_DIGIT}]{{0,14}}' |
|
_SUFFIX_PATTERN = f'[{ALPHA_LOWER}][{ALPHA_LOWER_OR_DIGIT}]{{0,52}}' |
|
PATTERN = f'^[+]{_NAME_PATTERN}[.]{_SUFFIX_PATTERN}$' |
|
|
|
def __init__(self, name: str, suffix: Optional[str] = None) -> None: |
|
suffix = suffix or self.generate_random_suffix() |
|
|
|
if not re.match(f'^{self._NAME_PATTERN}$', name): |
|
raise ValidationError(f'Invalid name "{name}"') |
|
|
|
if not re.match(f'^{self._SUFFIX_PATTERN}$', suffix): |
|
raise ValidationError(f'Invalid suffix "{suffix}"') |
|
|
|
self.name = name |
|
self.suffix = suffix |
|
|
|
@classmethod |
|
def validate_address(cls, share_address: str) -> None: |
|
"""Check if share_address is a valid share address""" |
|
|
|
if not re.match(cls.PATTERN, share_address): |
|
raise ValidationError(f'Invalid share address {share_address}') |
|
|
|
@classmethod |
|
def from_address(cls, share_address: str) -> 'Share': |
|
"""Create a Share object from a share address""" |
|
|
|
cls.validate_address(share_address) |
|
|
|
name, suffix = share_address[1:].split('.') |
|
|
|
return cls(name, suffix) |
|
|
|
@staticmethod |
|
def generate_random_suffix(length: int = 53) -> str: |
|
"""Generate a random share suffix of the desired length""" |
|
|
|
assert 54 > length > 0 |
|
|
|
return choice(ALPHA_LOWER) + ''.join( |
|
choice(ALPHA_LOWER_OR_DIGIT) for _ in range(length - 1) |
|
) |
|
|
|
def __str__(self) -> str: |
|
return f'+{self.name}.{self.suffix}' |
|
|
|
def __repr__(self) -> str: |
|
return f'<Share {self}>'
|
|
|