diff --git a/bundle_checker.py b/bundle_checker.py index b796bbb..b4a493a 100644 --- a/bundle_checker.py +++ b/bundle_checker.py @@ -21,13 +21,15 @@ logger = logging.getLogger(__name__) # Basis-Klasse für SQLAlchemy-Modelle (SQLAlchemy 2.0-konform) Base = declarative_base() -# Tabelle für das Bundle (statische Identifikation) +# --------------------------- +# Datenbank-Modelle +# --------------------------- + class Bundle(Base): __tablename__ = 'bundles' id = Column(Integer, primary_key=True) machine_name = Column(String, unique=True) - human_name = Column(String) - # current_version_id verweist auf die aktuelle Version in bundle_versions + human_name = Column(String) # Falls vorhanden; kann leer bleiben, wenn nicht extrahiert current_version_id = Column(Integer, ForeignKey('bundle_versions.id')) # Beziehung zur aktuellen Version; post_update=True hilft bei zirkulären Abhängigkeiten @@ -39,8 +41,9 @@ class Bundle(Base): foreign_keys=lambda: [BundleVersion.bundle_id]) # Verkaufshistorie sales_history = relationship("BundleSalesHistory", back_populates="bundle") + # Einzelne Elemente des Bundles (z. B. die enthaltenen Bücher, Spiele etc.) + items = relationship("BundleItem", back_populates="bundle") -# Tabelle für Versionen eines Bundles class BundleVersion(Base): __tablename__ = 'bundle_versions' id = Column(Integer, primary_key=True) @@ -49,10 +52,9 @@ class BundleVersion(Base): version_data = Column(Text) # Relevante Bundle-Daten als JSON-String timestamp = Column(DateTime, default=datetime.utcnow) - # Eindeutige Beziehung: wir verwenden hier explizit bundle_id + # Explizite Angabe des Fremdschlüssels bundle = relationship("Bundle", back_populates="versions", foreign_keys=[bundle_id]) -# Tabelle für Verkaufshistorie class BundleSalesHistory(Base): __tablename__ = 'bundle_sales_history' id = Column(Integer, primary_key=True) @@ -62,15 +64,32 @@ class BundleSalesHistory(Base): bundle = relationship("Bundle", back_populates="sales_history") +class BundleItem(Base): + __tablename__ = 'bundle_items' + id = Column(Integer, primary_key=True) + bundle_id = Column(Integer, ForeignKey('bundles.id')) + title = Column(String) # Titel des Elements (z. B. Buch- oder Spielname) + category = Column(String) # Kategorie, z. B. "book", "game" oder "software" + details = Column(Text) # Optional: ganze Detaildaten als JSON-String + + bundle = relationship("Bundle", back_populates="items") + +# --------------------------- +# Hilfsfunktionen +# --------------------------- + def calculate_hash(data: dict) -> str: - """Berechnet einen SHA-256 Hash aus dem sortierten JSON-String der relevanten Daten.""" + """Berechnet einen SHA-256-Hash aus dem sortierten JSON-String der relevanten Daten.""" json_string = json.dumps(data, sort_keys=True, ensure_ascii=False) hash_value = hashlib.sha256(json_string.encode('utf-8')).hexdigest() logger.debug(f"Berechneter Hash: {hash_value}") return hash_value def fetch_bundle_data(url: str) -> dict: - """Lädt die Detailseite eines Bundles und extrahiert den JSON-Inhalt aus dem