rss-center

rss-center schreibt RSS-Daten in ein JPEG. Dieses Script läuft permanent aller 5 Minuten auf einem Raspberry und zwar mit mehreren Instanzen für diverse Feeds. Die 10 neuesten Nachrichten werden aus der RSS-Datei extraiert (Ordner „rss_data“), danach werden diese 10 Nachrichten plus Zeit in eine txt-Datei geschrieben (Ordner „rss_final“). Diese Datei wird dann in imagemagick geladen und gerendert. Die Resultate (Ordner „output“) werden bei mir per rsync auf meinen Mac übertragen und dienen dort als Quellordner für den Bildschirmschoner (Bild 2), der mir also vollkommen passiv die entsprechenden Schlagzeilen liefert. Das Logo oben rechts (optional) dient zur Unterscheidung der Quellen, also „S“ für „Spiegel“, „T“ für „Tagesschau“ usw.


#!/bin/bash
set -e
echo "Requires Imagemagick 7.0"
convert --version | grep "Version:"
magick --version | grep "Version:"
# ---------------- VARIABLES ----------------
BASE_DIR="/home/pi/test"
cd "$BASE_DIR" || exit 1

rss_url="https://www.spiegel.de/schlagzeilen/index.rss"
IN_DIR="./rss_data"
OUT_DIR="./rss_final"
FINAL_DIR="./output"
FONT="/usr/share/fonts/truetype/noto/NotoMono-Regular.ttf"

WIDTH=1280
HEIGHT=832
COLOR="#FFFFFF"
BACKGROUND="black"

LEFT_MARGIN=50   # distance from left edge
TOP_MARGIN=50    # distance from top edge
FONT_SIZE=35     # ✅ fixed font size

mkdir -p "$IN_DIR" "$OUT_DIR" "$FINAL_DIR"

echo "📡 Downloading RSS feed from: $rss_url"
wget -q "$rss_url" -O "$BASE_DIR/rss.txt"

if [[ ! -s "$BASE_DIR/rss.txt" ]]; then
  echo "❌ Error: Failed to download RSS feed"
  exit 1
fi

domain=$(echo "$rss_url" | sed -E 's@https?://(www\.)?([^/]+).*@\2@' | cut -d'.' -f1)
today=$(date +"%Y-%m-%d")

# ---------------- CLEANUP ----------------
rm -f "$IN_DIR"/title_*.txt "$IN_DIR"/date_*.txt "$OUT_DIR"/message_*.txt "$OUT_DIR"/all_messages.txt
rm -f "$FINAL_DIR"/*.jpg

# ---------------- EXTRACT TITLES + DATES ----------------
pairs=$(awk '
  BEGIN { RS="</item>"; FS="\n" }
  {
    title=""; date="";
    for (i=1; i<=NF; i++) {
      if ($i ~ /<title>/) {
        line=$i
        gsub(/<title><!\[CDATA\[/, "", line)
        gsub(/\]\]><\/title>/, "", line)
        gsub(/<title>/, "", line)
        gsub(/<\/title>/, "", line)
        title=line
      }
      if ($i ~ /<pubDate>/) {
        gsub(/.*<pubDate>/, "", $i)
        gsub(/<\/pubDate>.*/, "", $i)
        date=$i
      }
    }
    if (title != "" && date != "") print title "\x1f" date;
  }
' "$BASE_DIR/rss.txt" | head -n 10)

index=1
echo "$pairs" | while IFS=$'\x1f' read -r title pubdate; do
  formatted_date=$(date -d "$pubdate" "+%d.%m.%Y, %H:%M Uhr")

  formatted_title=$(echo "$title" | sed \
    -e 's/\\/\\\\/g' \
    -e 's/&quot;/"/g' \
    -e 's/&amp;/\&/g' \
    -e 's/&#[0-9]*;//g' \
    -e 's/:/ /g' \
    -e 's/,/ /g' \
    -e "s/'/'/g" \
    -e 's/?/ /g' \
    -e 's/\"/\"/g')

  wrapped_title=$(echo "$formatted_title" | fold -s -w 120)
  echo "$wrapped_title" > "$IN_DIR/title_${index}.txt"
  echo "$domain - $formatted_date" > "$IN_DIR/date_${index}.txt"

  ((index++))
done

# ---------------- CREATE MESSAGES ----------------
wordcount1=20
for i in {1..10}; do
  date_part=$(cut -c23-27 "$IN_DIR/date_$i.txt" 2>/dev/null || echo "")
  title_part=$(awk -v n="$wordcount1" '{for(i=1;i<=n && i<=NF;i++) printf "%s%s",$i,(i<n && i<NF?OFS:""); print ""}' "$IN_DIR/title_$i.txt" 2>/dev/null || echo "")
  printf "%s %s\n\n" "$date_part" "$title_part" >> "$OUT_DIR/all_messages.txt"
done

# ---------------- IMAGEMAGICK PART ----------------
TMP_DIR=$(mktemp -d)
OUT_FILE="${FINAL_DIR}/news-spiegel.jpg"
#OUT_FILE="${FINAL_DIR}/$(date +%s).jpg"
LINE_SPACING=8     # ← adjust this value for line height

# 1️⃣ Create background
magick -size ${WIDTH}x${HEIGHT} canvas:$BACKGROUND -colorspace sRGB "$TMP_DIR/base.png"

# 2️⃣ Generate caption image (auto-wrap width minus margins)
magick -size $((WIDTH - LEFT_MARGIN * 2))x${HEIGHT} \
  -background none -fill "$COLOR" -font "$FONT" -pointsize "$FONT_SIZE" -interline-spacing $LINE_SPACING \
  caption:@"$OUT_DIR/all_messages.txt" "$TMP_DIR/text.png"

# 3️⃣ Composite caption image with top/left margins
magick "$TMP_DIR/base.png" "$TMP_DIR/text.png" \
  -geometry +${LEFT_MARGIN}+${TOP_MARGIN} -compose over -composite "$OUT_FILE"

# 4️⃣ Overlay logo - optional
#LOGO_PATH="./logos/logo.png"
#LOGO_WIDTH=130
#MARGIN=0
#TMP_LOGO="$TMP_DIR/logo_resized.png"
#magick "$LOGO_PATH" -resize ${LOGO_WIDTH} "$TMP_LOGO"
#magick "$OUT_FILE" "$TMP_LOGO" -colorspace sRGB \

magick "$OUT_FILE" -colorspace sRGB "$OUT_FILE"

rm -rf "$TMP_DIR"
echo "✅ Created image: $OUT_FILE"

/) {<br /><br> line=$i<br /><br> gsub(/<title><!\[CDATA\[/, „“, line)<br> gsub(/\]\]><\/title>/, „“, line)<br /><br> gsub(/<title>/, „“, line)<br /><br> gsub(/<\/title>/, „“, line)<br /><br> title=line<br /><br> }<br /><br> if ($i ~ /<pubDate>/) {<br /><br> gsub(/.*<pubDate>/, „“, $i)<br /><br> gsub(/<\/pubDate>.*/, „“, $i)<br /><br> date=$i<br /><br> }<br /><br> }<br /><br> if (title != „“ && date != „“) print title „\x1f“ date;<br /><br> }<br /><br>‘ „$BASE_DIR/rss.txt“ | head -n 10)</p><br><p>index=1<br /><br>echo „$pairs“ | while IFS=$’\x1f‘ read -r title pubdate; do<br /><br> formatted_date=$(date -d „$pubdate“ „+%d.%m.%Y, %H:%M Uhr“)</p><br><p> formatted_title=$(echo „$title“ | sed \<br /><br> -e ’s/\\/\\\\/g‘ \<br /><br> -e ’s/“/“/g‘ \<br /><br> -e ’s/&/\&/g‘ \<br /><br> -e ’s/&#[0-9]*;//g‘ \<br /><br> -e ’s/:/ /g‘ \<br /><br> -e ’s/,/ /g‘ \<br /><br> -e „s/’/’/g“ \<br /><br> -e ’s/?/ /g‘ \<br /><br> -e ’s/\“/\“/g‘)</p><br><p> wrapped_title=$(echo „$formatted_title“ | fold -s -w 120)<br /><br> echo „$wrapped_title“ > „$IN_DIR/title_${index}.txt“<br /><br> echo „$domain – $formatted_date“ > „$IN_DIR/date_${index}.txt“</p><br><p> ((index++))<br /><br>done</p><br><p># —————- CREATE MESSAGES —————-<br /><br>wordcount1=20<br /><br>for i in {1..10}; do<br /><br> date_part=$(cut -c23-27 „$IN_DIR/date_$i.txt“ 2>/dev/null || echo „“)<br /><br> title_part=$(awk -v n=“$wordcount1″ ‚{for(i=1;i<=n && i<=NF;i++) printf „%s%s“,$i,(i<n && i<NF?OFS:““); print „“}‘ „$IN_DIR/title_$i.txt“ 2>/dev/null || echo „“)<br /><br> printf „%s %s\n\n“ „$date_part“ „$title_part“ >> „$OUT_DIR/all_messages.txt“<br /><br>done</p><br><p># —————- IMAGEMAGICK PART —————-<br /><br>TMP_DIR=$(mktemp -d)<br /><br>OUT_FILE=“${FINAL_DIR}/news-spiegel.jpg“<br /><br>#OUT_FILE=“${FINAL_DIR}/$(date +%s).jpg“<br /><br>LINE_SPACING=8 # ← adjust this value for line height</p><br><p># 1️⃣ Create background<br /><br>magick -size ${WIDTH}x${HEIGHT} canvas:$BACKGROUND -colorspace sRGB „$TMP_DIR/base.png“</p><br><p># 2️⃣ Generate caption image (auto-wrap width minus margins)<br /><br>magick -size $((WIDTH – LEFT_MARGIN * 2))x${HEIGHT} \<br /><br> -background none -fill „$COLOR“ -font „$FONT“ -pointsize „$FONT_SIZE“ -interline-spacing $LINE_SPACING \<br /><br> caption:@“$OUT_DIR/all_messages.txt“ „$TMP_DIR/text.png“</p><br><p># 3️⃣ Composite caption image with top/left margins<br /><br>magick „$TMP_DIR/base.png“ „$TMP_DIR/text.png“ \<br /><br> -geometry +${LEFT_MARGIN}+${TOP_MARGIN} -compose over -composite „$OUT_FILE“</p><br><p># 4️⃣ Overlay logo – optional<br /><br>#LOGO_PATH=“./logos/logo.png“<br /><br>#LOGO_WIDTH=130<br /><br>#MARGIN=0<br /><br>#TMP_LOGO=“$TMP_DIR/logo_resized.png“<br /><br>#magick „$LOGO_PATH“ -resize ${LOGO_WIDTH} „$TMP_LOGO“<br /><br>#magick „$OUT_FILE“ „$TMP_LOGO“ -colorspace sRGB \</p><br><p>magick „$OUT_FILE“ -colorspace sRGB „$OUT_FILE“</p><br><p>rm -rf „$TMP_DIR“<br /><br>echo „✅ Created image: $OUT_FILE“</p>