mirror of
https://github.com/Second-Hand-Friends/kleinanzeigen-bot.git
synced 2026-03-12 02:31:45 +01:00
fix: Add retry logic for ad publishing (3 attempts before skipping) (#774)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# SPDX-FileCopyrightText: © Sebastian Thomschke and contributors
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# SPDX-ArtifactOfProjectHomePage: https://github.com/Second-Hand-Friends/kleinanzeigen-bot/
|
||||
import atexit, enum, json, os, re, signal, sys, textwrap # isort: skip
|
||||
import atexit, asyncio, enum, json, os, re, signal, sys, textwrap # isort: skip
|
||||
import getopt # pylint: disable=deprecated-module
|
||||
import urllib.parse as urllib_parse
|
||||
from datetime import datetime
|
||||
@@ -10,6 +10,7 @@ from pathlib import Path
|
||||
from typing import Any, Final
|
||||
|
||||
import certifi, colorama, nodriver # isort: skip
|
||||
from nodriver.core.connection import ProtocolException
|
||||
from ruamel.yaml import YAML
|
||||
from wcmatch import glob
|
||||
|
||||
@@ -1021,6 +1022,8 @@ class KleinanzeigenBot(WebScrapingMixin):
|
||||
|
||||
async def publish_ads(self, ad_cfgs:list[tuple[str, Ad, dict[str, Any]]]) -> None:
|
||||
count = 0
|
||||
failed_count = 0
|
||||
max_retries = 3
|
||||
|
||||
published_ads = json.loads(
|
||||
(await self.web_request(f"{self.root_url}/m-meine-anzeigen-verwalten.json?sort=DEFAULT"))["content"])["ads"]
|
||||
@@ -1033,16 +1036,40 @@ class KleinanzeigenBot(WebScrapingMixin):
|
||||
continue
|
||||
|
||||
count += 1
|
||||
success = False
|
||||
|
||||
await self.publish_ad(ad_file, ad_cfg, ad_cfg_orig, published_ads, AdUpdateStrategy.REPLACE)
|
||||
publish_timeout = self._timeout("publishing_result")
|
||||
await self.web_await(self.__check_publishing_result, timeout = publish_timeout)
|
||||
# Retry loop only for publish_ad (before submission completes)
|
||||
for attempt in range(1, max_retries + 1):
|
||||
try:
|
||||
await self.publish_ad(ad_file, ad_cfg, ad_cfg_orig, published_ads, AdUpdateStrategy.REPLACE)
|
||||
success = True
|
||||
break # Publish succeeded, exit retry loop
|
||||
except asyncio.CancelledError:
|
||||
raise # Respect task cancellation
|
||||
except (TimeoutError, ProtocolException) as ex:
|
||||
if attempt < max_retries:
|
||||
LOG.warning(_("Attempt %s/%s failed for '%s': %s. Retrying..."), attempt, max_retries, ad_cfg.title, ex)
|
||||
await self.web_sleep(2) # Wait before retry
|
||||
else:
|
||||
LOG.error(_("All %s attempts failed for '%s': %s. Skipping ad."), max_retries, ad_cfg.title, ex)
|
||||
failed_count += 1
|
||||
|
||||
if self.config.publishing.delete_old_ads == "AFTER_PUBLISH" and not self.keep_old_ads:
|
||||
# Check publishing result separately (no retry - ad is already submitted)
|
||||
if success:
|
||||
try:
|
||||
publish_timeout = self._timeout("publishing_result")
|
||||
await self.web_await(self.__check_publishing_result, timeout = publish_timeout)
|
||||
except TimeoutError:
|
||||
LOG.warning(_(" -> Could not confirm publishing for '%s', but ad may be online"), ad_cfg.title)
|
||||
|
||||
if success and self.config.publishing.delete_old_ads == "AFTER_PUBLISH" and not self.keep_old_ads:
|
||||
await self.delete_ad(ad_cfg, published_ads, delete_old_ads_by_title = False)
|
||||
|
||||
LOG.info("############################################")
|
||||
LOG.info("DONE: (Re-)published %s", pluralize("ad", count))
|
||||
if failed_count > 0:
|
||||
LOG.info(_("DONE: (Re-)published %s (%s failed after retries)"), pluralize("ad", count - failed_count), failed_count)
|
||||
else:
|
||||
LOG.info(_("DONE: (Re-)published %s"), pluralize("ad", count))
|
||||
LOG.info("############################################")
|
||||
|
||||
async def publish_ad(self, ad_file:str, ad_cfg:Ad, ad_cfg_orig:dict[str, Any], published_ads:list[dict[str, Any]],
|
||||
|
||||
@@ -115,6 +115,10 @@ kleinanzeigen_bot/__init__.py:
|
||||
publish_ads:
|
||||
"Processing %s/%s: '%s' from [%s]...": "Verarbeite %s/%s: '%s' von [%s]..."
|
||||
"Skipping because ad is reserved": "Überspringen, da Anzeige reserviert ist"
|
||||
" -> Could not confirm publishing for '%s', but ad may be online": " -> Veröffentlichung für '%s' konnte nicht bestätigt werden, aber Anzeige ist möglicherweise online"
|
||||
"Attempt %s/%s failed for '%s': %s. Retrying...": "Versuch %s/%s fehlgeschlagen für '%s': %s. Erneuter Versuch..."
|
||||
"All %s attempts failed for '%s': %s. Skipping ad.": "Alle %s Versuche fehlgeschlagen für '%s': %s. Überspringe Anzeige."
|
||||
"DONE: (Re-)published %s (%s failed after retries)": "FERTIG: %s (erneut) veröffentlicht (%s fehlgeschlagen nach Wiederholungen)"
|
||||
"DONE: (Re-)published %s": "FERTIG: %s (erneut) veröffentlicht"
|
||||
"ad": "Anzeige"
|
||||
apply_auto_price_reduction:
|
||||
|
||||
Reference in New Issue
Block a user