fix(download): show final directory path in INFO logs instead of staging path (#916)

## ℹ️ Description

- Link to the related issue(s): Issue N/A
- Improves logging clarity for the `download` command by addressing two
user-facing issues:

1. **Path accuracy**: INFO logs now show the final download directory
instead of the temporary staging directory, eliminating confusion about
where files actually end up.

2. **Message clarity**: Log messages now distinguish between the two
fetch operations — JSON API (metadata) vs HTML scan (navigation URLs) —
so the dual-fetch design is explicit rather than appearing redundant.

## 📋 Changes Summary

- Demoted staging directory path to DEBUG level; added INFO log for
final download path
- Updated fetch-related log messages to indicate purpose (metadata vs
navigation URLs)

### ⚙️ Type of Change
- [x] 🐞 Bug fix (non-breaking change which fixes an issue)
- [ ]  New feature (adds new functionality without breaking existing
usage)
- [ ] 💥 Breaking change (changes that might break existing user setups,
scripts, or configurations)

##  Checklist
Before requesting a review, confirm the following:
- [x] I have reviewed my changes to ensure they meet the project's
standards.
- [x] I have tested my changes and ensured that all tests pass (`pdm run
test`).
- [x] I have formatted the code (`pdm run format`).
- [x] I have verified that linting passes (`pdm run lint`).
- [x] I have updated documentation where necessary.

By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Improved logging and progress messages to separately report staging
and final download paths and to clarify scanning progress when
discovering ad URLs.
* Clarified wording to describe the downloaded API payload as "ad
metadata (status, expiry dates)" and to use "ad URL" when reporting
counts.
* **Localization**
* Updated German pluralization to correctly form "Anzeigen‑URLs" where
applicable.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Jens
2026-04-01 11:07:38 +02:00
committed by GitHub
parent 498d0934d2
commit 2ab167952c
4 changed files with 13 additions and 11 deletions

View File

@@ -2607,7 +2607,7 @@ class KleinanzeigenBot(WebScrapingMixin): # noqa: PLR0904
# Fetch published ads once from manage-ads JSON to avoid repetitive API calls during extraction
# Build lookup dict inline and pass directly to extractor (no cache abstraction needed)
LOG.info("Fetching published ads...")
LOG.info("Fetching ad metadata (status, expiry dates)...")
published_ads = await self._fetch_published_ads(strict = bool(_NUMERIC_IDS_RE.match(effective_selector)))
published_ads_by_id:dict[int, dict[str, Any]] = {}
for published_ad in published_ads:
@@ -2617,7 +2617,7 @@ class KleinanzeigenBot(WebScrapingMixin): # noqa: PLR0904
published_ads_by_id[int(ad_id)] = published_ad
except (ValueError, TypeError):
LOG.warning("Skipping ad with non-numeric id: %s", published_ad.get("id"))
LOG.info("Loaded %s published ads.", len(published_ads_by_id))
LOG.info("Loaded metadata for %s published ads.", len(published_ads_by_id))
download_dir = self._resolve_download_dir()
xdg_paths.ensure_directory(download_dir, "downloaded ads directory")
@@ -2625,9 +2625,9 @@ class KleinanzeigenBot(WebScrapingMixin): # noqa: PLR0904
ad_extractor = extract.AdExtractor(self.browser, self.config, download_dir, published_ads_by_id = published_ads_by_id)
if effective_selector in {"all", "new"}: # explore ads overview for these two modes
LOG.info("Scanning your ad overview...")
LOG.info("Scanning ad overview for navigation URLs...")
own_ad_urls = await ad_extractor.extract_own_ads_urls()
LOG.info("%s found.", pluralize("ad", len(own_ad_urls)))
LOG.info("Found %s.", pluralize("ad URL", len(own_ad_urls)))
if effective_selector == "all": # download all of your ads
LOG.info("Starting download of all ads...")

View File

@@ -566,7 +566,8 @@ class AdExtractor(WebScrapingMixin):
) from cleanup_ex
await loop.run_in_executor(None, lambda: staging_dir.mkdir(exist_ok = True))
LOG.info("New directory for ad created at %s.", staging_dir)
LOG.debug("Staging directory for ad: %s", staging_dir)
LOG.info("Downloading ad to: %s", final_dir)
try:
ad_cfg = await self._extract_ad_page_info(str(staging_dir), ad_id, ad_file_stem, active_override = active_override)

View File

@@ -259,11 +259,11 @@ kleinanzeigen_bot/__init__.py:
download_ads:
"Ads download directory: %s": "Anzeigen-Download-Verzeichnis: %s"
"Fetching published ads...": "Lade veröffentlichte Anzeigen..."
"Loaded %s published ads.": "%s veröffentlichte Anzeigen geladen."
"Scanning your ad overview...": "Scanne Anzeigenübersicht..."
"%s found.": "%s gefunden."
"ad": "Anzeige"
"Fetching ad metadata (status, expiry dates)...": "Lade Anzeigen-Metadaten (Status, Ablaufdaten)..."
"Loaded metadata for %s published ads.": "Metadaten für %s veröffentlichte Anzeigen geladen."
"Scanning ad overview for navigation URLs...": "Suche Navigations-URLs in Anzeigenübersicht..."
"Found %s.": "%s gefunden."
"ad URL": "Anzeigen-URL"
"Starting download of all ads...": "Starte den Download aller Anzeigen..."
"%d of %d ads were downloaded from your profile.": "%d von %d Anzeigen wurden aus Ihrem Profil heruntergeladen."
"Starting download of not yet downloaded ads...": "Starte den Download noch nicht heruntergeladener Anzeigen..."
@@ -350,7 +350,7 @@ kleinanzeigen_bot/extract.py:
"Removing stale staging directory: %s": "Entferne veraltetes Staging-Verzeichnis: %s"
"Could not remove stale staging directory %s: %s": "Konnte veraltetes Staging-Verzeichnis %s nicht entfernen: %s"
"Could not remove stale staging directory %s. Aborting extraction to avoid using a dirty staging directory.": "Konnte veraltetes Staging-Verzeichnis %s nicht entfernen. Extraktion wird abgebrochen, um kein verunreinigtes Staging-Verzeichnis zu verwenden."
"New directory for ad created at %s.": "Neues Verzeichnis für Anzeige erstellt unter %s."
"Downloading ad to: %s": "Lade Anzeige herunter nach: %s"
"Renaming folder from %s to %s for ad %s...": "Benenne Ordner von %s zu %s für Anzeige %s um..."
"Using existing folder for ad %s at %s.": "Verwende bestehenden Ordner für Anzeige %s unter %s."
"Could not remove staging directory %s: %s": "Konnte Staging-Verzeichnis %s nicht entfernen: %s"

View File

@@ -170,6 +170,7 @@ def pluralize(noun:str, count:int | Sized, *, prefix_with_count:bool = True) ->
"Attribute": "Attribute",
"Bild": "Bilder",
"Feld": "Felder",
"Anzeigen-URL": "Anzeigen-URLs", # Acronyms take 's' in German
}
if noun in irregular_plurals:
return f"{prefix}{irregular_plurals[noun]}"