"""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''