Source code for ai_marketplace_monitor.listing

from dataclasses import asdict, dataclass
from typing import Optional, Tuple, Type

from diskcache import Cache  # type: ignore

from .utils import CacheType, cache, hash_dict


[docs] @dataclass class Listing: marketplace: str name: str # unique identification id: str title: str image: str price: str post_url: str location: str seller: str condition: str description: str @property def content(self: "Listing") -> Tuple[str, str, str]: return (self.title, self.description, self.price) @property def hash(self: "Listing") -> str: # we need to normalize post_url before hashing because post_url will be different # each time from a search page. We also does not count image return hash_dict( { x: (y.split("?")[0] if x == "post_url" else y) for x, y in asdict(self).items() if x != "image" } )
[docs] @classmethod def from_cache( cls: Type["Listing"], post_url: str, local_cache: Cache | None = None, ) -> Optional["Listing"]: try: # details could be a different datatype, miss some key etc. # and we have recently changed to save Listing as a dictionary return cls( **(cache if local_cache is None else local_cache).get( (CacheType.LISTING_DETAILS.value, post_url.split("?")[0]) ) ) except KeyboardInterrupt: raise except Exception: return None
[docs] def to_cache( self: "Listing", post_url: str, local_cache: Cache | None = None, ) -> None: (cache if local_cache is None else local_cache).set( (CacheType.LISTING_DETAILS.value, post_url.split("?")[0]), asdict(self), tag=CacheType.LISTING_DETAILS.value, )