67 lines
2.2 KiB
Python
67 lines
2.2 KiB
Python
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)
|