import requests
from bs4 import BeautifulSoup
from urllib.parse import urlparse
import os
BOOKSTACK_URL = os.getenv("BOOKSTACK_URL","https://my-book-stack.com")
BOOKSTACK_TOKEN_ID = os.getenv("BOOKSTACK_TOKEN_ID", "TOKEN-ID")
BOOKSTACK_TOKEN_SECRET = os.getenv("BOOKSTACK_TOKEN_SECRET", "TOKEN-SECRET")
PAGE_SLUG = os.getenv("PAGE_SLUG","page-name-of-book")
BOOK_SLUG = os.getenv("BOOK_SLUG","book-name")
INSERT_MARKER_LINK = os.getenv("INSERT_MARKER_LINK", "## Unsortierte Links")
INSERT_MARKER_TEXT = os.getenv("INSERT_MARKER_TEXT", "## Textmerker")
HEADERS = {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": f"Token {BOOKSTACK_TOKEN_ID}:{BOOKSTACK_TOKEN_SECRET}"
}
def is_valid_url(url):
parsed = urlparse(url)
return all([parsed.scheme in ("http", "https"), parsed.netloc])
def get_page_id_by_slug(book_slug, page_slug):
res = requests.get(f"{BOOKSTACK_URL}/api/pages", headers=HEADERS)
print(HEADERS)
print(res)
pages = res.json().get("data", [])
for p in pages:
if p["book_slug"] == book_slug and p["slug"] == page_slug:
return p["id"]
raise("Book not found")
def get_page_title_from_url(url):
try:
response = requests.get(url, timeout=10)
soup = BeautifulSoup(response.text, "html.parser")
title_tag = soup.find("title")
return title_tag.text.strip() if title_tag else url
except Exception as e:
print(f"Fehler beim Abrufen des Titels: {e}")
return url
def get_clean_title_from_url(url, max_len=80):
try:
res = requests.get(url, timeout=10)
res.raise_for_status()
soup = BeautifulSoup(res.text, "html.parser")
# 1. og:title
og_title = soup.find("meta", property="og:title")
if og_title and og_title.get("content"):
title = og_title["content"]
# 2.
elif soup.find("meta", attrs={"name": "title"}):
title = soup.find("meta", attrs={"name": "title"}).get("content", "")
# 3.
elif soup.title and soup.title.string:
title = soup.title.string
# 4. Fallback: Domain
else:
return urlparse(url).netloc
title = title.strip()
# Optional: Aufteilen an Trennzeichen wie " | " oder " – "
for sep in ["|", "–", "-", "•"]:
if sep in title:
title = title.split(sep)[0].strip()
break
# Länge kürzen
if len(title) > max_len:
title = title[:max_len].rstrip() + "…"
return title
except Exception as e:
print(f"Fehler beim Abrufen oder Parsen des Titels: {e}")
return urlparse(url).netloc # Fallback auf Domain
def append_link_to_bookstack_page(url):
strPageId = get_page_id_by_slug(BOOK_SLUG, PAGE_SLUG)
# Hole aktuellen Seiteninhalt
page = requests.get(f"{BOOKSTACK_URL}/api/pages/{strPageId}", headers=HEADERS).json()
current_content = page["markdown"]
if url in current_content:
print("Text bereits vorhanden.")
return
title = get_page_title_from_url(url)
new_entry = f"- [{title}]({url})
{url}"
# Füge Link unterhalb von INSERT_MARKER_LINK ein
if INSERT_MARKER_LINK in current_content:
parts = current_content.split(INSERT_MARKER_LINK)
updated_content = parts[0] + INSERT_MARKER_LINK + "\n" + new_entry + parts[1]
else:
# Falls Marker nicht vorhanden, füge ihn am Ende hinzu
updated_content = current_content + "\n\n## Unsortierte Links\n\n" + new_entry
# Seite aktualisieren
update_data = {
"name": page["name"],
"markdown": updated_content
}
response = requests.put(
f"{BOOKSTACK_URL}/api/pages/{strPageId}",
headers=HEADERS,
json=update_data
)
if response.status_code == 200:
print("Link erfolgreich hinzugefügt.")
else:
print("Fehler beim Aktualisieren der Seite:", response.text)
def append_text_to_bockstack_page(strText):
strPageId = get_page_id_by_slug(BOOK_SLUG, PAGE_SLUG)
# Hole aktuellen Seiteninhalt
page = requests.get(f"{BOOKSTACK_URL}/api/pages/{strPageId}", headers=HEADERS).json()
current_content = page["markdown"]
if strText in current_content:
print("Text bereits vorhanden.")
return
new_entry = strText + "\n\n"
# Füge Text unterhalb von INSERT_MARKER_TEXT ein
if INSERT_MARKER_TEXT in current_content:
parts = current_content.split(INSERT_MARKER_TEXT)
updated_content = parts[0] + INSERT_MARKER_TEXT + "\n\n" + new_entry + "\n" + parts[1]
else:
# Falls Marker nicht vorhanden, füge ihn am Ende hinzu
updated_content = current_content + "\n\n## Textmerker\n\n" + new_entry
# Seite aktualisieren
update_data = {
"name": page["name"],
"markdown": updated_content
}
response = requests.put(
f"{BOOKSTACK_URL}/api/pages/{strPageId}",
headers=HEADERS,
json=update_data
)
if response.status_code == 200:
print("Link erfolgreich hinzugefügt.")
else:
print("Fehler beim Aktualisieren der Seite:", response.text)
def add_link_or_text(strText):
if (is_valid_url(strText)):
append_link_to_bookstack_page(strText)
else:
append_text_to_bockstack_page(strText)
pass