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,
)