194 lines
5.1 KiB
Bash
194 lines
5.1 KiB
Bash
|
#!/bin/bash
|
||
|
|
||
|
FEED_TITLE="My RSS Feed"
|
||
|
FEED_LINK="https://example.com"
|
||
|
FEED_DESC="Example RSS Feed Description"
|
||
|
FEED_LANG="en-us"
|
||
|
|
||
|
ITEMS_FILE="rss_items.json"
|
||
|
RSS_FILE="rss_feed.xml"
|
||
|
|
||
|
if ! command -v jq &> /dev/null; then
|
||
|
echo "Error: jq is required but not installed. Please install jq first."
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
[ ! -f "$ITEMS_FILE" ] && echo "[]" > "$ITEMS_FILE"
|
||
|
|
||
|
function generate_rss() {
|
||
|
local lastBuildDate
|
||
|
lastBuildDate=$(date -R)
|
||
|
|
||
|
{
|
||
|
echo '<?xml version="1.0" encoding="UTF-8"?>'
|
||
|
echo '<rss version="2.0">'
|
||
|
echo ' <channel>'
|
||
|
echo " <title>$FEED_TITLE</title>"
|
||
|
echo " <link>$FEED_LINK</link>"
|
||
|
echo " <description>$FEED_DESC</description>"
|
||
|
echo " <language>$FEED_LANG</language>"
|
||
|
echo " <lastBuildDate>$lastBuildDate</lastBuildDate>"
|
||
|
|
||
|
jq -c '.[]' "$ITEMS_FILE" | while read -r item; do
|
||
|
title=$(echo "$item" | jq -r '.title')
|
||
|
description=$(echo "$item" | jq -r '.description')
|
||
|
body=$(echo "$item" | jq -r '.body')
|
||
|
link=$(echo "$item" | jq -r '.link')
|
||
|
pubDate=$(echo "$item" | jq -r '.pubDate')
|
||
|
guid=$(echo "$item" | jq -r '.guid')
|
||
|
|
||
|
echo " <item>"
|
||
|
echo " <title><![CDATA[$title]]></title>"
|
||
|
if [ -n "$link" ]; then
|
||
|
echo " <link>$link</link>"
|
||
|
fi
|
||
|
echo " <description><![CDATA[$description<br><br>$body]]></description>"
|
||
|
echo " <pubDate>$pubDate</pubDate>"
|
||
|
echo " <guid isPermaLink=\"false\">$guid</guid>"
|
||
|
echo " </item>"
|
||
|
done
|
||
|
|
||
|
echo ' </channel>'
|
||
|
echo '</rss>'
|
||
|
} > "$RSS_FILE"
|
||
|
}
|
||
|
|
||
|
function list_items() {
|
||
|
local count
|
||
|
count=$(jq length "$ITEMS_FILE")
|
||
|
if [ "$count" -eq 0 ]; then
|
||
|
echo "No items found."
|
||
|
return
|
||
|
fi
|
||
|
echo "Current RSS items:"
|
||
|
jq -r '.[] | "\(.title)"' "$ITEMS_FILE" | nl
|
||
|
}
|
||
|
|
||
|
function read_input() {
|
||
|
local prompt=$1
|
||
|
local default=$2
|
||
|
local result
|
||
|
|
||
|
if [ -z "$default" ]; then
|
||
|
read -rp "$prompt: " result
|
||
|
else
|
||
|
read -rp "$prompt [$default]: " result
|
||
|
result=${result:-$default}
|
||
|
fi
|
||
|
echo "$result"
|
||
|
}
|
||
|
|
||
|
function add_item() {
|
||
|
local title description body link pubDate guid
|
||
|
|
||
|
title=$(read_input "Enter Title")
|
||
|
description=$(read_input "Enter Description")
|
||
|
body=$(read_input "Enter Body")
|
||
|
link=$(read_input "Enter Link (full URL, or leave empty for no link)" "")
|
||
|
|
||
|
|
||
|
if [ -n "$link" ] && [[ ! "$link" =~ ^https?:// ]]; then
|
||
|
echo "Warning: Link should start with http:// or https://"
|
||
|
fi
|
||
|
|
||
|
pubDate=$(date -R)
|
||
|
guid=$(echo -n "$title$pubDate" | md5sum | cut -d ' ' -f1)
|
||
|
|
||
|
jq --arg t "$title" --arg d "$description" --arg b "$body" --arg l "$link" --arg p "$pubDate" --arg g "$guid" \
|
||
|
'. + [{"title": $t, "description": $d, "body": $b, "link": $l, "pubDate": $p, "guid": $g}]' "$ITEMS_FILE" > tmp.json && mv tmp.json "$ITEMS_FILE"
|
||
|
|
||
|
generate_rss
|
||
|
echo "Item added successfully."
|
||
|
}
|
||
|
|
||
|
function update_item() {
|
||
|
list_items
|
||
|
local count index new_title new_desc new_body new_link pubDate guid
|
||
|
|
||
|
count=$(jq length "$ITEMS_FILE")
|
||
|
if [ "$count" -eq 0 ]; then
|
||
|
return
|
||
|
fi
|
||
|
|
||
|
read -rp "Enter item number to update: " num
|
||
|
if ! [[ "$num" =~ ^[0-9]+$ ]] || [ "$num" -lt 1 ] || [ "$num" -gt "$count" ]; then
|
||
|
echo "Invalid item number."
|
||
|
return
|
||
|
fi
|
||
|
index=$((num - 1))
|
||
|
|
||
|
local old_title old_desc old_body old_link
|
||
|
old_title=$(jq -r ".[${index}].title" "$ITEMS_FILE")
|
||
|
old_desc=$(jq -r ".[${index}].description" "$ITEMS_FILE")
|
||
|
old_body=$(jq -r ".[${index}].body" "$ITEMS_FILE")
|
||
|
old_link=$(jq -r ".[${index}].link" "$ITEMS_FILE")
|
||
|
|
||
|
new_title=$(read_input "New Title" "$old_title")
|
||
|
new_desc=$(read_input "New Description" "$old_desc")
|
||
|
new_body=$(read_input "New Body" "$old_body")
|
||
|
new_link=$(read_input "New Link (full URL, or leave empty for no link)" "$old_link")
|
||
|
|
||
|
if [ -n "$new_link" ] && [[ ! "$new_link" =~ ^https?:// ]]; then
|
||
|
echo "Warning: Link should start with http:// or https://"
|
||
|
fi
|
||
|
|
||
|
pubDate=$(date -R)
|
||
|
guid=$(echo -n "$new_title$pubDate" | md5sum | cut -d ' ' -f1)
|
||
|
|
||
|
jq ".[${index}] |= {title: \"$new_title\", description: \"$new_desc\", body: \"$new_body\", link: \"$new_link\", pubDate: \"$pubDate\", guid: \"$guid\"}" "$ITEMS_FILE" > tmp.json && mv tmp.json "$ITEMS_FILE"
|
||
|
|
||
|
generate_rss
|
||
|
echo "Item updated successfully."
|
||
|
}
|
||
|
|
||
|
function delete_item() {
|
||
|
list_items
|
||
|
local count index
|
||
|
|
||
|
count=$(jq length "$ITEMS_FILE")
|
||
|
if [ "$count" -eq 0 ]; then
|
||
|
return
|
||
|
fi
|
||
|
|
||
|
read -rp "Enter item number to delete: " num
|
||
|
if ! [[ "$num" =~ ^[0-9]+$ ]] || [ "$num" -lt 1 ] || [ "$num" -gt "$count" ]; then
|
||
|
echo "Invalid item number."
|
||
|
return
|
||
|
fi
|
||
|
index=$((num - 1))
|
||
|
|
||
|
jq "del(.[${index}])" "$ITEMS_FILE" > tmp.json && mv tmp.json "$ITEMS_FILE"
|
||
|
|
||
|
generate_rss
|
||
|
echo "Item deleted successfully."
|
||
|
}
|
||
|
|
||
|
function main_menu() {
|
||
|
echo
|
||
|
echo "===== RSS Feed Manager ====="
|
||
|
echo "1) List items"
|
||
|
echo "2) Add item"
|
||
|
echo "3) Update item"
|
||
|
echo "4) Delete item"
|
||
|
echo "5) Generate RSS XML now"
|
||
|
echo "6) Exit"
|
||
|
read -rp "Choose an option: " opt
|
||
|
case $opt in
|
||
|
1) list_items ;;
|
||
|
2) add_item ;;
|
||
|
3) update_item ;;
|
||
|
4) delete_item ;;
|
||
|
5) generate_rss; echo "RSS XML generated at $RSS_FILE" ;;
|
||
|
6) exit 0 ;;
|
||
|
*) echo "Invalid option." ;;
|
||
|
esac
|
||
|
}
|
||
|
|
||
|
if [ ! -s "$RSS_FILE" ]; then
|
||
|
generate_rss
|
||
|
fi
|
||
|
|
||
|
while true; do
|
||
|
main_menu
|
||
|
done
|