added no msrp prirority so they don't starve in queue
This commit is contained in:
1 parent
6c309b1e62
commit
dee090edaf
10 files changed
+1684
-1
No files matched your search
@@ -0,0 +1,163 @@
|
||||
"""Dataclass models shared across monitors and the consumer bot."""
|
||||
|
||||
from dataclasses import field
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic.dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class CycleResult:
|
||||
"""Tallied outcome of one monitor cycle.
|
||||
|
||||
Pure counts for the caller to log or act on as it sees fit; no policy is
|
||||
baked in.
|
||||
|
||||
Attributes:
|
||||
successes: Category tasks that completed without an expected error.
|
||||
failures: Category tasks that raised an expected error.
|
||||
skipped: True when pre_task_func failed and no category tasks ran.
|
||||
"""
|
||||
|
||||
successes: int = 0
|
||||
failures: int = 0
|
||||
skipped: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class ConsumerConfig:
|
||||
"""Configuration for a single retailer's consumer.
|
||||
|
||||
Attributes:
|
||||
monitor_name: Retailer name (matches setup_config key).
|
||||
collection: MongoDB collection for this retailer's products.
|
||||
channel_ids: Discord webhook/channel routing config.
|
||||
min_percentage: Minimum discount % to trigger a ping.
|
||||
ping_threshold: Price floor for the secondary 40% rule (e.g. Woot pings
|
||||
on 40%+ discounts if the item is >= this price). None disables
|
||||
the secondary rule.
|
||||
"""
|
||||
|
||||
monitor_name: str
|
||||
collection: object
|
||||
channel_ids: dict
|
||||
min_percentage: int
|
||||
ping_threshold: int | None = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class PricingInfo:
|
||||
"""Price fields for a product.
|
||||
|
||||
Attributes:
|
||||
original_price: Pre-discount price.
|
||||
current_price: Current listed price.
|
||||
price_before_drop: Stored price prior to the last detected drop.
|
||||
edu_price: Education-store price when offered.
|
||||
past_prices: Prior price history as price/date entries, oldest first.
|
||||
"""
|
||||
|
||||
original_price: float
|
||||
current_price: float
|
||||
price_before_drop: float | None = None
|
||||
edu_price: float | None = None
|
||||
past_prices: list[dict] | None = None
|
||||
has_msrp: bool = True
|
||||
|
||||
|
||||
@dataclass
|
||||
class AvailabilityInfo:
|
||||
"""Availability and membership flags for a product.
|
||||
|
||||
Attributes:
|
||||
available: Whether the product is purchasable.
|
||||
condition: Product condition such as new or open box.
|
||||
app_exclusive: Only purchasable through the retailer's app.
|
||||
member_pick: Flagged as a member pick offer.
|
||||
member_deal: Flagged as a member deal offer.
|
||||
availability_last_checked: When available was last verified against
|
||||
the retailer, letting monitors skip rechecks within an interval.
|
||||
"""
|
||||
|
||||
available: bool | None = None
|
||||
condition: str | None = None
|
||||
app_exclusive: bool | None = None
|
||||
member_pick: bool | None = None
|
||||
member_deal: bool | None = None
|
||||
availability_last_checked: datetime | None = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class ProductMetadata:
|
||||
"""Presentation and routing metadata for a product.
|
||||
|
||||
Attributes:
|
||||
image_url: Product image URL.
|
||||
channel_id: Resolved Discord channel id for the ping.
|
||||
customization_index: Config number when priced via customization.
|
||||
member_non_member_comparison: Display string comparing member and
|
||||
non-member pricing.
|
||||
overstock_text: Overstock label text when present.
|
||||
percentage: Computed discount percentage.
|
||||
affiliate_url: Affiliate link when available.
|
||||
promo_code: Event-level checkout code (e.g. "BIRTHDAY26") when the
|
||||
product's event advertises one, else None.
|
||||
promo_percentage: Advertised percent off from a percentage code
|
||||
("extra 22% off" -> 22); None for dollar codes or no code. This is
|
||||
the claimed discount, not the actual price delta.
|
||||
promo_dollar_off: Advertised dollar amount off from a spend-threshold
|
||||
code ("get an extra $22 off" -> 22); None for percentage codes or
|
||||
no code. Pairs with promo_min_spend.
|
||||
promo_min_spend: Spend threshold a dollar code requires ("Spend $100"
|
||||
-> 100); None unless promo_dollar_off is set.
|
||||
"""
|
||||
|
||||
image_url: str | None = None
|
||||
channel_id: str | None = None
|
||||
customization_index: str | None = None
|
||||
member_non_member_comparison: str | None = None
|
||||
overstock_text: str | None = None
|
||||
percentage: int | None = None
|
||||
affiliate_url: str | None = None
|
||||
promo_code: str | None = None
|
||||
promo_percentage: int | None = None
|
||||
promo_dollar_off: int | None = None
|
||||
promo_min_spend: int | None = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class ProductTiming:
|
||||
"""Lifecycle timestamps for a product.
|
||||
|
||||
Attributes:
|
||||
discovered_date: When the product was first stored.
|
||||
start_date: Offer start when the retailer provides one.
|
||||
end_date: Offer end when the retailer provides one.
|
||||
"""
|
||||
|
||||
discovered_date: datetime | None = None
|
||||
start_date: datetime | None = None
|
||||
end_date: datetime | None = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class Product:
|
||||
"""A monitored product assembled from retailer data.
|
||||
|
||||
Attributes:
|
||||
product_id: Retailer-specific product identifier.
|
||||
title: Product title.
|
||||
url: Product page URL.
|
||||
pricing: Price fields.
|
||||
metadata: Presentation and routing metadata.
|
||||
timing: Lifecycle timestamps.
|
||||
availability: Availability and membership flags.
|
||||
"""
|
||||
|
||||
product_id: str
|
||||
title: str
|
||||
url: str
|
||||
pricing: PricingInfo
|
||||
metadata: ProductMetadata = field(default_factory=ProductMetadata)
|
||||
timing: ProductTiming = field(default_factory=ProductTiming)
|
||||
availability: AvailabilityInfo = field(default_factory=AvailabilityInfo)
|
||||
Reference in new issue
Block a user