Release 1.1.0

This commit is contained in:
Oliver 2025-07-04 09:48:03 +02:00
parent 633f312bc7
commit 2f7f2a1eb7
8 changed files with 242 additions and 20 deletions

71
app.py
View file

@ -6,7 +6,20 @@ import os
from datetime import datetime
import pandas as pd
import openai
from openai import OpenAI
from dotenv import load_dotenv
import logging
# ==== Version ====
APP_VERSION = "1.1.0"
# ==== Logging konfigurieren ====
LOG_FILE = "app.log"
logging.basicConfig(
filename=LOG_FILE,
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
)
# ==== Konfiguration ====
ARTICLES_FILE = "articles.json"
@ -16,7 +29,8 @@ ALL_STATUSES = ["New", "Rewrite", "Process", "Online", "On Hold", "Trash"]
# ==== API Schlüssel laden ====
load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")
api_key = os.getenv("OPENAI_API_KEY")
client = OpenAI(api_key=api_key)
# ==== Hilfsfunktionen ====
def load_articles():
@ -26,6 +40,7 @@ def load_articles():
with open(ARTICLES_FILE, "r") as f:
return json.load(f)
except json.JSONDecodeError:
logging.error("Fehler beim Laden von articles.json")
return []
def save_articles(articles):
@ -39,6 +54,7 @@ def load_feeds():
with open(FEEDS_FILE, "r") as f:
return json.load(f)
except json.JSONDecodeError:
logging.error("Fehler beim Laden von feeds.json")
return []
def save_feeds(feeds):
@ -81,28 +97,31 @@ def format_date(date_str):
except Exception:
return date_str
def rewrite_article_with_gpt(original_text):
def rewrite_article_with_gpt(original_text, title):
prompt = (
"Schreibe folgenden Artikel um und formuliere ihn in journalistischem Stil neu. "
"Füge am Ende eine Liste von 23 passenden Tags hinzu (nur Schlagwörter, keine Hashtags):\n"
f"{original_text}"
)
try:
response = openai.ChatCompletion.create(
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.7
)
return response.choices[0].message.content
result = response.choices[0].message.content
logging.info(f"✅ Artikel umgeschrieben: {title}")
return result
except Exception as e:
logging.error(f"❌ Fehler beim Umschreiben von '{title}': {e}")
return f"FEHLER: {e}"
# ==== UI ====
st.set_page_config(page_title="RSS Artikel Manager", layout="wide")
st.title("📰 RSS Artikel Manager")
st.sidebar.markdown(f"🧩 Version: `{APP_VERSION}`")
# Bereich: Feed-Verwaltung
st.sidebar.header("RSS Feeds verwalten")
feeds = load_feeds()
new_feed = st.sidebar.text_input("Neuen Feed hinzufügen")
if st.sidebar.button(" Feed hinzufügen") and new_feed:
@ -126,6 +145,7 @@ if st.button("🔄 Artikel aus Feeds laden"):
all_articles = load_articles() + new
save_articles(all_articles)
st.success(f"{len(new)} neue Artikel geladen.")
logging.info(f"{len(new)} neue Artikel geladen.")
else:
st.info("Keine neuen Artikel gefunden.")
@ -134,12 +154,16 @@ rewrite_articles = [a for a in load_articles() if a["status"] == "Rewrite"]
if rewrite_articles:
if st.button("✍️ Alle Artikel mit Status 'Rewrite' umschreiben"):
all_articles = load_articles()
progress_text = st.empty()
with st.spinner("Artikel werden umgeschrieben..."):
total = len([a for a in all_articles if a["status"] == "Rewrite"])
count = 0
for a in all_articles:
if a["status"] == "Rewrite":
result = rewrite_article_with_gpt(a["content"])
count += 1
progress_text.markdown(f"➡️ Umschreibe Artikel {count} von {total}: **{a['title']}**")
result = rewrite_article_with_gpt(a["content"], a["title"])
if "FEHLER:" not in result:
# Aufteilen in Text und Tags, falls möglich
if "Tags:" in result:
rewritten, tags = result.rsplit("Tags:", 1)
a["content"] = rewritten.strip()
@ -161,12 +185,11 @@ if articles:
st.markdown("---")
st.subheader(f"Artikel mit Status '{status_filter}'")
# Checkbox-Auswahl manuell verwalten
selected_ids = []
for i, article in enumerate(articles):
cols = st.columns([0.5, 1.5, 3, 4, 1, 2, 1])
with cols[0]:
if st.checkbox("", key=article["id"]):
if st.checkbox("Auswählen", key=article["id"], label_visibility="collapsed"):
selected_ids.append(article["id"])
cols[1].markdown(format_date(article["date"]))
cols[2].markdown(f"**{article['title']}**")
@ -177,14 +200,42 @@ if articles:
st.markdown("---")
if selected_ids:
all_articles = load_articles()
selected_articles = [a for a in all_articles if a["id"] in selected_ids]
with st.expander("📋 Inhalte für WordPress kopieren"):
for a in selected_articles:
with st.container():
st.markdown("""
<div style="border: 1px solid #CCC; padding: 1rem; border-radius: 10px; background-color: #F9F9F9;">
""", unsafe_allow_html=True)
st.markdown(f"### ✏️ {a['title']}")
st.markdown(f"<button style='margin-bottom:0.5rem;' onclick=\"navigator.clipboard.writeText('{a['title']}')\">🔗 Titel kopieren</button>", unsafe_allow_html=True)
st.text_area("📝 Artikeltext", value=a["content"], height=300, key=f"content_{a['id']}", help="CMD+C zum Kopieren")
st.markdown(f"<button style='margin-bottom:0.5rem;' onclick=\"navigator.clipboard.writeText(`{a['content']}`)\">📋 Artikeltext kopieren</button>", unsafe_allow_html=True)
st.text_input("🏷️ Tags", value=", ".join(a["tags"]), key=f"tags_{a['id']}", help="CMD+C zum Kopieren")
st.markdown(f"<button style='margin-bottom:0.5rem;' onclick=\"navigator.clipboard.writeText('{', '.join(a['tags'])}')\">📎 Tags kopieren</button>", unsafe_allow_html=True)
st.markdown(f"<a href='{a['link']}' target='_blank' style='text-decoration: none;'><button style='background-color:#e8f0fe; border:none; padding:0.5rem 1rem; border-radius:5px;'>🔗 Zum Originalartikel</button></a>", unsafe_allow_html=True)
st.markdown("</div>", unsafe_allow_html=True)
new_status = st.selectbox("Neuen Status setzen für ausgewählte Artikel", ALL_STATUSES)
if st.button("✅ Status ändern"):
all_articles = load_articles()
for a in all_articles:
if a["id"] in selected_ids:
a["status"] = new_status
save_articles(all_articles)
st.success("Status aktualisiert.")
logging.info(f"Status von {len(selected_ids)} Artikel(n) auf '{new_status}' gesetzt.")
st.rerun()
else:
st.warning(f"Keine Artikel mit Status '{status_filter}' vorhanden.")