diff --git a/README.md b/README.md index f0e8e33..1cfef33 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,18 @@ Wallos Fetcher is a command-line utility designed to retrieve and export subscription data from a self-hosted [Wallos](https://github.com/WallosApp/Wallos) instanceโ€”an open-source personal subscription tracker. -This script helps you keep track of all your recurring expenses and share that information in human-readable or machine-readable formats, making it especially useful for budgeting, personal finance planning, and digital legacy preparation for family members. +This script helps you keep track of all your recurring expenses and share that information in human-readable or machine-readable formats. It's especially useful for budgeting, personal finance planning, and digital legacy preparation for family members. --- ## โœจ Features -- ๐Ÿ“„ **Markdown output by default** โ€“ easy to read, easy to share +- ๐Ÿ“„ **Markdown output by default** โ€“ clean, readable reports +- ๐Ÿ“Š **CSV output** โ€“ spreadsheet-friendly for Excel, Numbers, etc. - ๐Ÿ’พ Export as **Markdown**, **CSV**, or **JSON** - ๐Ÿ” Optionally include **full subscription details** (e.g., cycle, auto-renew, currency) - ๐Ÿ—ƒ Output to a custom file +- ๐Ÿงผ Modular, readable Bash script using secure temp file handling - ๐Ÿงฐ Lightweight, portable, and dependency-minimal (requires `curl` and `jq`) --- @@ -44,6 +46,8 @@ chmod +x wallos-fetch.sh ./wallos-fetch.sh [options] ``` +> โ„น๏ธ This script requires `curl` and `jq`. Run `./wallos-fetch.sh --help` to see all options. + ### โœ… Example Commands | Purpose | Command | @@ -90,11 +94,34 @@ Structured export for use in spreadsheets or data processing tools. - Default fields: `id,name,price,next_payment,category_name,payment_method_name` - `--full` option adds: `currency_id,cycle,auto_renew`, etc. +```csv +"id","name","price","next_payment","category_name","payment_method_name" +"1","Netflix","17.99","2025-04-21","Entertainment","Credit Card" +"2","Spotify","9.99","2025-05-01","Music","PayPal" +``` + ### ๐Ÿ“ฆ JSON -Raw response data from the Wallos APIโ€”useful for backups or integrations. +Raw response data from the Wallos APIโ€”useful for backups, custom reporting, or integrations. + +```json +{ + "subscriptions": [ + { + "id": 1, + "name": "Netflix", + "price": 17.99, + "currency_id": "USD", + "next_payment": "2025-04-21", + "category_name": "Entertainment", + "payment_method_name": "Credit Card" + } + ] +} +``` --- + ## ๐Ÿ” Authentication You can set your API key in one of two ways: @@ -125,6 +152,8 @@ API_KEY="your_api_key_here" > โš ๏ธ Be cautious: hardcoding secrets in scripts can pose a security risk if the file is shared or version-controlled. +--- + ## ๐Ÿ“œ License This project is licensed under the [GNU General Public License v3.0 or later](https://www.gnu.org/licenses/gpl-3.0.html). @@ -134,7 +163,7 @@ This project is licensed under the [GNU General Public License v3.0 or later](ht ## ๐Ÿค Contributions Feedback, bug reports, and pull requests are welcome! -Submit issues or improvements via your Gitea repository. +Submit issues or improvements via the Gitea repository. --- @@ -142,4 +171,4 @@ Submit issues or improvements via your Gitea repository. Wallos is an open-source personal subscription manager. Learn more or contribute to the main project here: -๐Ÿ”— https://github.com/WallosApp/Wallos \ No newline at end of file +๐Ÿ”— https://github.com/WallosApp/Wallos diff --git a/wallos-fetch.sh b/wallos-fetch.sh index 94b5665..24acada 100755 --- a/wallos-fetch.sh +++ b/wallos-fetch.sh @@ -1,161 +1,123 @@ #!/bin/bash -VERSION="2025.04" - -# Configuration +VERSION="2025.05" HOST="https://your-api-host.com" ENDPOINT="/api/subscriptions/get_subscriptions.php" API_KEY="${API_KEY:-$WALLOS_API_KEY}" -# Defaults MODE="md" FULL=false -OUTPUT="" # Will set default per mode later +OUTPUT="" +TMP_FILE=$(mktemp) + +# ๐Ÿšจ Dependencies check +for dep in curl jq; do + command -v "$dep" >/dev/null 2>&1 || { + echo "โŒ Missing required dependency: $dep" + exit 1 + } +done -# Show help show_help() { cat << EOF โ„น๏ธ Wallos Fetcher Script - v$VERSION Usage: ./wallos-fetch.sh [OPTIONS] -Fetch and export subscription data from a Wallos instance. - Options: --json Output raw JSON --md Output Markdown table - --full Include more fields in CSV/Markdown + --csv Output CSV table + --full Include more fields --output Custom output filename - --help Show this help message and exit - --version Show version and exit - -Default output is Markdown. + --help Show this help message + --version Show version EOF } -# Argument parser -while [[ "$#" -gt 0 ]]; do - case "$1" in - --json) MODE="json" ;; - --md) MODE="md" ;; - --full) FULL=true ;; - --output) - shift - OUTPUT="$1" - ;; - --help) show_help; exit 0 ;; - --version) echo "โ“ wallos-fetch v$VERSION"; exit 0 ;; - *) echo "Unknown option: $1" && show_help && exit 1 ;; - esac - shift -done +parse_args() { + while [[ "$#" -gt 0 ]]; do + case "$1" in + --json) MODE="json" ;; + --md) MODE="md" ;; + --csv) MODE="csv" ;; + --full) FULL=true ;; + --output) shift; OUTPUT="$1" ;; + --help) show_help; exit 0 ;; + --version) echo "๐Ÿงพ wallos-fetch v$VERSION"; exit 0 ;; + *) echo "Unknown option: $1"; show_help; exit 1 ;; + esac + shift + done -# Set default filenames if none specified -if [[ -z "$OUTPUT" ]]; then - case "$MODE" in - json) OUTPUT="subscriptions.json" ;; - md) OUTPUT="subscriptions.md" ;; - csv) OUTPUT="subscriptions.csv" ;; - esac -fi + # Set default output filename + [[ -z "$OUTPUT" ]] && OUTPUT="subscriptions.${MODE}" +} -# Construct the API URL -URL="${HOST}${ENDPOINT}?api_key=${API_KEY}" +fetch_data() { + URL="${HOST}${ENDPOINT}?api_key=${API_KEY}" + RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" "$URL") + STATUS=$(echo "$RESPONSE" | sed -n 's/^HTTP_STATUS://p') + BODY=$(echo "$RESPONSE" | sed '/^HTTP_STATUS:/d') -# Perform the request -RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" "$URL") -BODY=$(echo "$RESPONSE" | sed -n '1,/^HTTP_STATUS:/p' | sed '$d') -STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTP_STATUS://') + echo "$BODY" > "$TMP_FILE" -echo "HTTP Status: $STATUS" + if [[ "$STATUS" != "200" ]]; then + echo "โŒ API request failed with status: $STATUS" + rm -f "$TMP_FILE" + exit 1 + fi +} -if [ "$STATUS" -eq 200 ]; then - echo "$BODY" > temp_response.json +output_json() { + mv "$TMP_FILE" "$OUTPUT" + echo "๐Ÿ’พ Saved JSON to $OUTPUT" +} - if [ "$MODE" == "json" ]; then - mv temp_response.json "$OUTPUT" - echo "๐Ÿ’พ Saved JSON to $OUTPUT" - -elif [ "$MODE" == "md" ]; then - # Write markdown header and description +output_markdown() { { echo "# ๐Ÿงพ Active Subscriptions Overview" - echo "" - echo "This document lists all recurring subscriptions tied to this household or individual. It includes costs, renewal dates, categories, and payment methods. This record is provided as a reference for financial planning, digital legacy management, or to assist family members in case of emergencies or estate matters." - echo "" echo "_Last updated: $(date +'%Y-%m-%d')_" echo "" } > "$OUTPUT" - if [ "$FULL" = true ]; then + if $FULL; then echo "| ID | Name | Price | Currency | Next Payment | Cycle | Auto Renew | Category | Payment Method |" >> "$OUTPUT" echo "|----|------|-------|----------|---------------|-------|-------------|----------|----------------|" >> "$OUTPUT" - jq -r ' - .subscriptions[] | [ - .id, - .name, - (.price | tostring), - .currency_id, - .next_payment, - .cycle, - .auto_renew, - (.category_name | gsub(">"; ">") | gsub("&"; "&")), - .payment_method_name - ] | @tsv - ' temp_response.json | while IFS=$'\t' read -r id name price curr next cycle renew cat pay; do + jq -r '.subscriptions[] | [.id, .name, .price, .currency_id, .next_payment, .cycle, .auto_renew, .category_name, .payment_method_name] | @tsv' "$TMP_FILE" | + while IFS=$'\t' read -r id name price curr next cycle renew cat pay; do echo "| $id | $name | $price | $curr | $next | $cycle | $renew | $cat | $pay |" >> "$OUTPUT" done else echo "| ID | Name | Price | Next Payment | Category | Payment Method |" >> "$OUTPUT" echo "|----|------|-------|---------------|----------|----------------|" >> "$OUTPUT" - jq -r ' - .subscriptions[] | [ - .id, - .name, - (.price | tostring), - .next_payment, - (.category_name | gsub(">"; ">") | gsub("&"; "&")), - .payment_method_name - ] | @tsv - ' temp_response.json | while IFS=$'\t' read -r id name price next cat pay; do + jq -r '.subscriptions[] | [.id, .name, .price, .next_payment, .category_name, .payment_method_name] | @tsv' "$TMP_FILE" | + while IFS=$'\t' read -r id name price next cat pay; do echo "| $id | $name | $price | $next | $cat | $pay |" >> "$OUTPUT" done fi - rm -f temp_response.json - echo "๐Ÿ’พ Saved Markdown table to $OUTPUT" + echo "๐Ÿ’พ Saved Markdown to $OUTPUT" + rm -f "$TMP_FILE" +} +output_csv() { + if $FULL; then + echo '"id","name","price","currency_id","next_payment","cycle","auto_renew","category_name","payment_method_name"' > "$OUTPUT" + jq -r '.subscriptions[] | [.id, .name, .price, .currency_id, .next_payment, .cycle, .auto_renew, .category_name, .payment_method_name] | @csv' "$TMP_FILE" >> "$OUTPUT" else - if [ "$FULL" = true ]; then - echo '"id","name","price","currency_id","next_payment","cycle","auto_renew","category_name","payment_method_name"' > "$OUTPUT" - jq -r ' - .subscriptions[] | [ - .id, - .name, - .price, - .currency_id, - .next_payment, - .cycle, - .auto_renew, - .category_name, - .payment_method_name - ] | @csv - ' temp_response.json >> "$OUTPUT" - else - echo '"id","name","price","next_payment","category_name","payment_method_name"' > "$OUTPUT" - jq -r ' - .subscriptions[] | [ - .id, - .name, - .price, - .next_payment, - .category_name, - .payment_method_name - ] | @csv - ' temp_response.json >> "$OUTPUT" - fi - rm -f temp_response.json - echo "๐Ÿ’พ Saved CSV to $OUTPUT" + echo '"id","name","price","next_payment","category_name","payment_method_name"' > "$OUTPUT" + jq -r '.subscriptions[] | [.id, .name, .price, .next_payment, .category_name, .payment_method_name] | @csv' "$TMP_FILE" >> "$OUTPUT" fi -else - echo "โŒ Request failed. Response not saved." -fi + echo "๐Ÿ’พ Saved CSV to $OUTPUT" + rm -f "$TMP_FILE" +} + +# ๐Ÿ Main +parse_args "$@" +fetch_data + +case "$MODE" in + json) output_json ;; + md) output_markdown ;; + csv) output_csv ;; +esac