import logging import re from decimal import Decimal from .data import DKK, USD, Asset, AssetAmount, FiatCurrency logger = logging.getLogger(__name__) RE_PRICE_RAW = r'\b(?:dkk|sek|usd|nok|eur)?\s*([1-9][\d.]*[\d](?:,\d+)?)\s*(?:,-|:-|.-|;-)?\s*(?:(?:kr|kroner|krone|dkk|sek|usd|eur|nok)\b)?\.?' RE_PRICE = re.compile(RE_PRICE_RAW, flags=re.IGNORECASE) def parse_price(text: str, default_currency: Asset) -> AssetAmount | None: """ Attempts to parse price from the given text. Text does not need to be stripped beforehand. """ if isinstance(text, AssetAmount): return text text = str(text) if m := re.match(r'^Kr\s*([\d.]+(?:,\d+))?$', text): return AssetAmount( DKK, Decimal(m.group(1).replace('.', '').replace(',', '.')), ) if m := re.match(r'^(\d+)\s*DKK$', text): return AssetAmount(DKK, Decimal(m.group(1))) if m := re.match(r'^\$\s*([0-9.]+)(\s+USD)?$', text): return AssetAmount(USD, Decimal(m.group(1))) if text.lower().strip() == 'free': return AssetAmount(default_currency, Decimal(0.0)) text = str(text).strip().lower().removesuffix('.') if m := RE_PRICE.fullmatch(text): currency = default_currency price_tag = m.group(1).replace('.', '').replace(',', '.') # TODO if text.endswith('dkk') or text.startswith('dkk'): currency = FiatCurrency('DKK') elif text.endswith('sek') or text.startswith('sek'): currency = FiatCurrency('SEK') elif text.endswith('nok') or text.startswith('nok'): currency = FiatCurrency('NOK') elif text.endswith('usd') or text.startswith('usd'): currency = FiatCurrency('USD') return AssetAmount(currency, Decimal(price_tag)) logger.warning('Unknown price format: %s', text) return None def parse_usd_price(s: str | int) -> AssetAmount: assert s is not None if isinstance(s, str) or isinstance(s, int): text = str(s) else: text = s.text_content() text = text.strip().replace(',', '').removeprefix('$') if text in {'-', ''}: return AssetAmount(USD, Decimal(0)) # TODO dollar_amount = Decimal(text) return AssetAmount(USD, dollar_amount)