Bugfix: Tag-Duplikate, Post-Duplikate und Veröffentlichungsdatum
Fixes: - Tag/Kategorie-Erstellung: Bessere Fehlerbehandlung für bereits existierende Tags - Post-Duplikatsprüfung: Verbesserte Suche mit status='any' und case-insensitive Vergleich - Veröffentlichungsdatum: datePublished aus Frontmatter wird als WordPress-Datum gesetzt - Erweiterte Datumsextraktion aus verschiedenen Frontmatter-Strukturen Neue Datei: - USAGE_MODES.md: Übersicht der drei Verwendungsmodi
This commit is contained in:
parent
7a234be652
commit
9ba1aa7b10
4 changed files with 169 additions and 8 deletions
94
USAGE_MODES.md
Normal file
94
USAGE_MODES.md
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
# Verwendungs-Modi
|
||||
|
||||
## Modus 1: Einzelne URL (Empfohlen für Tests)
|
||||
|
||||
```bash
|
||||
python workflow.py "https://example.com/artikel.md"
|
||||
```
|
||||
|
||||
oder lokale Datei:
|
||||
|
||||
```bash
|
||||
python workflow.py "content/beispiel-beitrag.md"
|
||||
```
|
||||
|
||||
**Vorteile:**
|
||||
- Schnellster Weg zum Testen
|
||||
- Keine YAML-Konfiguration nötig
|
||||
- Alle Metadaten aus Frontmatter
|
||||
|
||||
## Modus 2: YAML-Batch (Für kuratierte Listen)
|
||||
|
||||
Erstellen Sie `posts.yaml`:
|
||||
|
||||
```yaml
|
||||
posts:
|
||||
- url: "https://example.com/artikel1.md"
|
||||
- url: "https://example.com/artikel2.md"
|
||||
- file: "content/artikel3.md"
|
||||
|
||||
settings:
|
||||
default_status: "draft"
|
||||
```
|
||||
|
||||
Dann:
|
||||
|
||||
```bash
|
||||
python workflow.py posts.yaml
|
||||
```
|
||||
|
||||
**Vorteile:**
|
||||
- Kontrollierte Liste von Beiträgen
|
||||
- Metadaten können überschrieben werden
|
||||
- Wiederverwendbar
|
||||
|
||||
## Modus 3: Forgejo-Repository (Für Bulk-Import)
|
||||
|
||||
```bash
|
||||
python workflow.py --repo "https://codeberg.org/user/repo" main
|
||||
```
|
||||
|
||||
**Vorteile:**
|
||||
- Alle Markdown-Dateien eines Repos auf einmal
|
||||
- Perfekt für bestehende Dokumentationen
|
||||
- Automatische Erkennung aller .md-Dateien
|
||||
|
||||
## Kombinationen
|
||||
|
||||
### Test → Produktion Workflow
|
||||
|
||||
1. **Einzelne URL testen:**
|
||||
```bash
|
||||
python workflow.py "https://example.com/test-artikel.md"
|
||||
```
|
||||
|
||||
2. **Bei Erfolg: YAML für mehrere erstellen**
|
||||
3. **Bei Erfolg: Status auf "publish" setzen**
|
||||
|
||||
### Repository → Kuratierte Liste
|
||||
|
||||
1. **Repository scannen:**
|
||||
```bash
|
||||
python workflow.py --repo "https://codeberg.org/user/repo" main
|
||||
```
|
||||
|
||||
2. **Prüfen welche Beiträge erstellt wurden**
|
||||
3. **Gewünschte in YAML übertragen für Feinabstimmung**
|
||||
|
||||
## Empfohlener Workflow
|
||||
|
||||
1. ✅ Test mit Beispiel-Beitrag:
|
||||
```bash
|
||||
python workflow.py "content/beispiel-beitrag.md"
|
||||
```
|
||||
|
||||
2. ✅ Test mit eigener URL:
|
||||
```bash
|
||||
python workflow.py "https://ihre-url.de/artikel.md"
|
||||
```
|
||||
|
||||
3. ✅ Bei Erfolg: Batch oder Repo-Import
|
||||
|
||||
4. ✅ In WordPress überprüfen
|
||||
|
||||
5. ✅ Status auf "publish" setzen (in .yaml oder Frontmatter)
|
||||
|
|
@ -146,14 +146,19 @@ def extract_wordpress_metadata(frontmatter: Dict[str, Any],
|
|||
metadata['status'] = 'draft'
|
||||
|
||||
# Datum extrahieren (falls vorhanden)
|
||||
# Priorität: date > datePublished > (aus commonMetadata) > (aus staticSiteGenerator)
|
||||
if 'date' in frontmatter:
|
||||
metadata['date'] = frontmatter['date']
|
||||
metadata['date'] = str(frontmatter['date'])
|
||||
elif 'datePublished' in frontmatter:
|
||||
metadata['date'] = frontmatter['datePublished']
|
||||
metadata['date'] = str(frontmatter['datePublished'])
|
||||
elif isinstance(frontmatter.get('#commonMetadata'), dict):
|
||||
common = frontmatter['#commonMetadata']
|
||||
if 'datePublished' in common:
|
||||
metadata['date'] = common['datePublished']
|
||||
metadata['date'] = str(common['datePublished'])
|
||||
elif isinstance(frontmatter.get('#staticSiteGenerator'), dict):
|
||||
static_gen = frontmatter['#staticSiteGenerator']
|
||||
if 'datePublished' in static_gen:
|
||||
metadata['date'] = str(static_gen['datePublished'])
|
||||
|
||||
return metadata
|
||||
|
||||
|
|
|
|||
|
|
@ -57,13 +57,31 @@ class WordPressAPI:
|
|||
Post-ID wenn gefunden, sonst None
|
||||
"""
|
||||
try:
|
||||
response = self._get('posts', params={'search': title, 'per_page': 10})
|
||||
# Suche mit verschiedenen Parametern
|
||||
response = self._get('posts', params={
|
||||
'search': title,
|
||||
'per_page': 100, # Erhöht für bessere Suche
|
||||
'status': 'any' # Alle Status (draft, publish, etc.)
|
||||
})
|
||||
posts = response.json()
|
||||
|
||||
# Normalisiere Titel für Vergleich
|
||||
title_lower = title.lower().strip()
|
||||
|
||||
# Exakte Übereinstimmung prüfen
|
||||
for post in posts:
|
||||
if post.get('title', {}).get('rendered', '') == title:
|
||||
# Prüfe rendered Titel
|
||||
rendered_title = post.get('title', {}).get('rendered', '').strip()
|
||||
if rendered_title.lower() == title_lower:
|
||||
print(f" → Beitrag gefunden (ID: {post['id']}, Status: {post['status']})")
|
||||
return post['id']
|
||||
|
||||
# Prüfe auch raw Titel falls vorhanden
|
||||
raw_title = post.get('title', {}).get('raw', '').strip()
|
||||
if raw_title and raw_title.lower() == title_lower:
|
||||
print(f" → Beitrag gefunden (ID: {post['id']}, Status: {post['status']})")
|
||||
return post['id']
|
||||
|
||||
return None
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Fehler bei der Suche nach Beitrag: {e}")
|
||||
|
|
@ -241,7 +259,21 @@ class WordPressAPI:
|
|||
response = self._post('categories', data={'name': name})
|
||||
return response.json()['id']
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Fehler beim Erstellen der Kategorie: {e}")
|
||||
# Prüfe ob Fehler durch bereits existierende Kategorie
|
||||
if e.response is not None and e.response.status_code == 400:
|
||||
# Kategorie könnte durch Race Condition gerade erstellt worden sein
|
||||
# Erneut suchen
|
||||
categories = self.get_categories()
|
||||
for cat in categories:
|
||||
if cat['name'].lower() == name.lower():
|
||||
return cat['id']
|
||||
print(f"Fehler beim Erstellen der Kategorie '{name}': {e}")
|
||||
if hasattr(e, 'response') and e.response is not None:
|
||||
try:
|
||||
error_data = e.response.json()
|
||||
print(f"Details: {error_data}")
|
||||
except:
|
||||
print(f"Response: {e.response.text}")
|
||||
return None
|
||||
|
||||
def get_tags(self) -> List[Dict[str, Any]]:
|
||||
|
|
@ -265,7 +297,21 @@ class WordPressAPI:
|
|||
response = self._post('tags', data={'name': name})
|
||||
return response.json()['id']
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Fehler beim Erstellen des Tags: {e}")
|
||||
# Prüfe ob Fehler durch bereits existierenden Tag
|
||||
if e.response is not None and e.response.status_code == 400:
|
||||
# Tag könnte durch Race Condition gerade erstellt worden sein
|
||||
# Erneut suchen
|
||||
tags = self.get_tags()
|
||||
for tag in tags:
|
||||
if tag['name'].lower() == name.lower():
|
||||
return tag['id']
|
||||
print(f"Fehler beim Erstellen des Tags '{name}': {e}")
|
||||
if hasattr(e, 'response') and e.response is not None:
|
||||
try:
|
||||
error_data = e.response.json()
|
||||
print(f"Details: {error_data}")
|
||||
except:
|
||||
print(f"Response: {e.response.text}")
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
|||
18
workflow.py
18
workflow.py
|
|
@ -232,6 +232,21 @@ def process_post(wp_api: WordPressAPI, post_config: Dict[str, Any],
|
|||
# Autor
|
||||
author_name = metadata.get('author') or post_config.get('author') or default_author
|
||||
|
||||
# Veröffentlichungsdatum
|
||||
# WordPress erwartet ISO 8601 Format: 2025-09-02T12:00:00
|
||||
publish_date = metadata.get('date') or post_config.get('date')
|
||||
|
||||
# Zusätzliche WordPress-Felder vorbereiten
|
||||
extra_fields = {}
|
||||
if publish_date:
|
||||
# Datum formatieren falls nötig
|
||||
if isinstance(publish_date, str):
|
||||
# Wenn nur Datum (YYYY-MM-DD), füge Uhrzeit hinzu
|
||||
if len(publish_date) == 10: # Format: 2025-09-02
|
||||
publish_date = f"{publish_date}T00:00:00"
|
||||
extra_fields['date'] = publish_date
|
||||
print(f"Veröffentlichungsdatum: {publish_date}")
|
||||
|
||||
# Beitrag erstellen
|
||||
skip_duplicates = global_settings.get('skip_duplicates', True)
|
||||
post_id = wp_api.create_post(
|
||||
|
|
@ -242,7 +257,8 @@ def process_post(wp_api: WordPressAPI, post_config: Dict[str, Any],
|
|||
categories=category_ids if category_ids else None,
|
||||
tags=tag_ids if tag_ids else None,
|
||||
excerpt=excerpt,
|
||||
check_duplicate=skip_duplicates
|
||||
check_duplicate=skip_duplicates,
|
||||
**extra_fields # Datum und andere Felder
|
||||
)
|
||||
|
||||
return post_id
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue