moving to microservice client/server model
This commit is contained in:
		| @@ -1,19 +0,0 @@ | ||||
| # Data Gathering for the @ReachableCEO daily stakeholder report | ||||
|  | ||||
| ## Introduction | ||||
|  | ||||
| I'm trying to life a fully instrumented CTO/founder life and #buildInPublic. And unlike most of the founders doing so, I'm actually publishing daily reports and live streaming my workstation all dya. | ||||
|  | ||||
| I want to automate the instrumentation/reporting process as much as possible to get the highest fidelity information for stakeholders consumption. | ||||
|  | ||||
| ## Data sources | ||||
|  | ||||
| - Apple Health (exporting via AutoHealthExport) | ||||
| - Workout (evaluating a cou | ||||
| - Nutrition | ||||
| - Daily habit tracking | ||||
| - ActivityWatch | ||||
| - WakaAPI | ||||
|  | ||||
|  | ||||
| ## Scripts | ||||
| @@ -1,83 +1 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # Script to query Gitea API for a user's activity on a specific date | ||||
|  | ||||
| ######################################################################################################## | ||||
| #Obtain gitea api key from bitwarden | ||||
| ######################################################################################################## | ||||
|  | ||||
| #################################### | ||||
| ## Step 0: Set to use tsys server | ||||
| #################################### | ||||
| bw logout | ||||
|  | ||||
| echo "Setting cli to use tsys bitwarden server..." | ||||
| bw config server https://pwvault.turnsys.com | ||||
|  | ||||
| #################################### | ||||
| ## Step 1: login to bitwarden | ||||
| #################################### | ||||
|  | ||||
| # From: https://bitwarden.com/help/cli/#using-an-api-key | ||||
|  | ||||
| ### Set apikey environment varaible | ||||
|  | ||||
| echo "Sourcing clientid/apikey data..." | ||||
| source D:/tsys/secrets/bitwarden/data/apikey-bitwarden-reachableceo | ||||
|  | ||||
| ### Login to vault using apikey... | ||||
|  | ||||
| echo "Logging in..." | ||||
| bw login --apikey $BW_CLIENTID $BW_CLIENTSECRET | ||||
|  | ||||
| ### Step 1.1: unlock / save session id  | ||||
|  | ||||
| echo "Unlocking..." | ||||
| export BW_SESSION="$(bw unlock --passwordenv TSYS_BW_PASSWORD_REACHABLECEO --raw)" | ||||
|  | ||||
|  | ||||
| ### Step 2: retrive a value into an environment variable | ||||
|  | ||||
| export GITEA_APIKEY="$(bw get password APIKEY-Gitea)" | ||||
|  | ||||
| ######################################################################################################## | ||||
| # Accrss gitea data | ||||
| ######################################################################################################## | ||||
|  | ||||
| # Script to query Gitea API for a user's activity on a specific date | ||||
|  | ||||
| # Usage: ./get_gitea_user_activity.sh <username> <date> [GITEA_URL] [TOKEN] | ||||
|  | ||||
| # Set username, date, and default Gitea URL | ||||
| USERNAME="${1:-reachableceo}"                    # Default to "reachableceo" if not provided | ||||
| DATE="${2:-$(date +%Y-%m-%d)}"                   # Default to today's date if not provided | ||||
| GITEA_URL="${3:-https://git.knownelement.com}"   # Default Gitea URL if not provided | ||||
| TOKEN="${GITEA_APIKEY}"                      # Use APIKEY-GItea or passed argument | ||||
|  | ||||
| # API Endpoint for user activities | ||||
| API_ENDPOINT="$GITEA_URL/api/v1/users/$USERNAME/timeline" | ||||
|  | ||||
| # Make the API call | ||||
| if [ -n "$TOKEN" ]; then | ||||
|   # If token is provided, use it in the Authorization header | ||||
|   RESPONSE=$(curl -s -H "Authorization: token $TOKEN" "$API_ENDPOINT") | ||||
| else | ||||
|   # If no token is provided, make an unauthenticated request | ||||
|   RESPONSE=$(curl -s "$API_ENDPOINT") | ||||
| fi | ||||
|  | ||||
| # Check for API errors | ||||
| if [[ "$RESPONSE" == "Not found" || -z "$RESPONSE" ]]; then | ||||
|   echo "Error: User '$USERNAME' not found, or endpoint is incorrect." | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| # Validate JSON response | ||||
| if ! echo "$RESPONSE" | jq empty >/dev/null 2>&1; then | ||||
|   echo "Error: Invalid JSON response from Gitea API." | ||||
|   echo "Response: $RESPONSE" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| # Filter the activity by date using jq | ||||
| echo "$RESPONSE" | jq --arg date "$DATE" '[.[] | select(.created_at | startswith($date))]' | ||||
| hi | ||||
|   | ||||
| @@ -1,59 +1 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # Functions | ||||
|  | ||||
| # Search for a note by title and return its ID | ||||
| search_note() { | ||||
|     local title="$1" | ||||
|     echo "Searching for note with title: $title" | ||||
|     note_id=$(joplin search "$title" --fields id --limit 1 --json | jq -r '.[0].id') | ||||
|      | ||||
|     if [[ -z "$note_id" || "$note_id" == "null" ]]; then | ||||
|         echo "Error: Note with title '$title' not found." | ||||
|         exit 1 | ||||
|     fi | ||||
|  | ||||
|     echo "Found note with ID: $note_id" | ||||
|     echo "$note_id" | ||||
| } | ||||
|  | ||||
| # Export the note by ID to the specified directory | ||||
| export_note() { | ||||
|     local note_id="$1" | ||||
|     local output_dir="$2" | ||||
|  | ||||
|     echo "Exporting note ID: $note_id to directory: $output_dir" | ||||
|     mkdir -p "$output_dir" || { | ||||
|         echo "Error: Unable to create directory $output_dir" | ||||
|         exit 1 | ||||
|     } | ||||
|  | ||||
|     # Export the note with attachments to the specified directory | ||||
|     joplin export "$note_id" --format md --output "$output_dir" || { | ||||
|         echo "Error: Failed to export note ID $note_id" | ||||
|         exit 1 | ||||
|     } | ||||
|  | ||||
|     echo "Note exported successfully to $output_dir" | ||||
| } | ||||
|  | ||||
| # Main function | ||||
| main() { | ||||
|     if [[ $# -lt 2 ]]; then | ||||
|         echo "Usage: $0 <note-title> <output-directory>" | ||||
|         exit 1 | ||||
|     fi | ||||
|  | ||||
|     local note_title="$1" | ||||
|     local output_dir="$2" | ||||
|  | ||||
|     # Search for the note and get its ID | ||||
|     local note_id | ||||
|     note_id=$(search_note "$note_title") | ||||
|  | ||||
|     # Export the note | ||||
|     export_note "$note_id" "$output_dir" | ||||
| } | ||||
|  | ||||
| # Run the main function with all script arguments | ||||
| main "$@" | ||||
| hi | ||||
|   | ||||
| @@ -1,97 +0,0 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| # Use the Joplin CLI and create a new note for today. Let me pass in the notebook folder path. Use bash functions. | ||||
|  | ||||
| # Created by chatgpt | ||||
| # https://chatgpt.com/share/6750c7df-6b2c-8005-a91c-1bc5b3875170 | ||||
|  | ||||
|  | ||||
| # shellcheck disable=SC1090 | ||||
|  | ||||
| # Bash3 Boilerplate Setup | ||||
| set -o errexit | ||||
| set -o nounset | ||||
| set -o pipefail | ||||
| IFS=$'\n\t' | ||||
|  | ||||
| # Constants | ||||
| readonly SCRIPT_NAME=$(basename "$0") | ||||
| readonly SCRIPT_VERSION="1.0" | ||||
| readonly SCRIPT_AUTHOR="Charles N Wyble" | ||||
| readonly SCRIPT_DESC="Create a new Daily Stakeholder Report note in Joplin" | ||||
|  | ||||
| # Logging and Debugging (from bash3boilerplate) | ||||
| readonly LOG_FILE="/tmp/${SCRIPT_NAME}.log" | ||||
| readonly TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') | ||||
| info() { echo "[INFO] [$TIMESTAMP] $*"; } | ||||
| error() { echo "[ERROR] [$TIMESTAMP] $*" >&2; } | ||||
|  | ||||
| # Default Exit Codes | ||||
| readonly ERR_JOPLIN_NOT_INSTALLED=10 | ||||
| readonly ERR_NOTEBOOK_NOT_FOUND=20 | ||||
|  | ||||
| # Function: Usage Instructions | ||||
| usage() { | ||||
|     cat <<EOF | ||||
| $SCRIPT_DESC | ||||
|  | ||||
| Usage: | ||||
|   $SCRIPT_NAME <notebook_folder_path> | ||||
|  | ||||
| Example: | ||||
|   $SCRIPT_NAME "Stakeholder Reports" | ||||
|  | ||||
| Options: | ||||
|   -h, --help    Display this help message. | ||||
| EOF | ||||
| } | ||||
|  | ||||
| # Check dependencies | ||||
| require_joplin() { | ||||
|     if ! command -v joplin &>/dev/null; then | ||||
|         error "Joplin CLI is not installed or not in PATH. Please install it and try again." | ||||
|         exit $ERR_JOPLIN_NOT_INSTALLED | ||||
|     fi | ||||
| } | ||||
|  | ||||
| # Check if notebook exists in Joplin | ||||
| notebook_exists() { | ||||
|     local notebook="$1" | ||||
|     if ! joplin use "$notebook" >/dev/null 2>&1; then | ||||
|         error "Notebook '$notebook' does not exist. Please create it first." | ||||
|         exit $ERR_NOTEBOOK_NOT_FOUND | ||||
|     fi | ||||
| } | ||||
|  | ||||
| # Create a new note in the specified notebook | ||||
| create_note() { | ||||
|     local notebook="$1" | ||||
|     local today_date=$(date '+%d-%m-%Y') # Format: YYYY-MM-DD | ||||
|     local title="Daily Stakeholder Report - $date" | ||||
|     local content="## Daily Stakeholder Report\n\n**Date:** $date\n\n---\n\n### Key Updates\n\n- \n\n### Issues\n\n- \n\n### Next Steps\n\n- \n" | ||||
|  | ||||
|     joplin create note --title "$title" --body "$content" >/dev/null | ||||
|     info "Note created successfully in notebook '$notebook'." | ||||
| } | ||||
|  | ||||
| # Main Function | ||||
| main() { | ||||
|     local notebook_path="$1" | ||||
|  | ||||
|     # Ensure Joplin CLI is present | ||||
|     require_joplin | ||||
|  | ||||
|     # Verify notebook existence | ||||
|     notebook_exists "$notebook_path" | ||||
|  | ||||
|     # Create a new note | ||||
|     create_note "$notebook_path" | ||||
| } | ||||
|  | ||||
| # Argument Parsing | ||||
| if [[ $# -lt 1 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then | ||||
|     usage | ||||
|     exit 0 | ||||
| fi | ||||
|  | ||||
| main "$1" | ||||
| @@ -1,114 +0,0 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| # Written by ChatGPT | ||||
| # https://chatgpt.com/share/6750c7df-6b2c-8005-a91c-1bc5b3875170 | ||||
|  | ||||
| # Prompt: | ||||
| # Pull any issues from Redmine that have a due date of today via API | ||||
|  | ||||
| # shellcheck disable=SC1090 | ||||
|  | ||||
| # Bash3 Boilerplate Setup | ||||
| set -o errexit | ||||
| set -o nounset | ||||
| set -o pipefail | ||||
| IFS=$'\n\t' | ||||
|  | ||||
| # Constants | ||||
| readonly SCRIPT_NAME=$(basename "$0") | ||||
| readonly SCRIPT_VERSION="1.0" | ||||
| readonly SCRIPT_AUTHOR="Charles N Wyble" | ||||
| readonly SCRIPT_DESC="Pull Redmine issues with a due date of today and output in Markdown" | ||||
|  | ||||
| # Logging and Debugging | ||||
| readonly LOG_FILE="/tmp/${SCRIPT_NAME}.log" | ||||
| readonly TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') | ||||
| info() { echo "[INFO] [$TIMESTAMP] $*" | tee -a "$LOG_FILE"; } | ||||
| error() { echo "[ERROR] [$TIMESTAMP] $*" >&2 | tee -a "$LOG_FILE"; } | ||||
|  | ||||
| # Default Exit Codes | ||||
| readonly ERR_CURL_NOT_INSTALLED=10 | ||||
| readonly ERR_API_FAILURE=20 | ||||
|  | ||||
| # Configuration | ||||
| readonly REDMINE_INSTANCE="projects.knownelement.com" | ||||
| readonly REDMINE_API_URL="https://${REDMINE_INSTANCE}" | ||||
| readonly REDMINE_API_KEY="your_api_key_here" | ||||
| readonly DATE=$(date '+%Y-%m-%d') | ||||
|  | ||||
| # Function: Usage Instructions | ||||
| usage() { | ||||
|     cat <<EOF | ||||
| $SCRIPT_DESC | ||||
|  | ||||
| Usage: | ||||
|   $SCRIPT_NAME <project_id> | ||||
|  | ||||
| Options: | ||||
|   -h, --help    Display this help message. | ||||
|  | ||||
| Example: | ||||
|   $SCRIPT_NAME 123 | ||||
| EOF | ||||
| } | ||||
|  | ||||
| # Check dependencies | ||||
| require_curl() { | ||||
|     if ! command -v curl &>/dev/null; then | ||||
|         error "curl is not installed or not in PATH. Please install it and try again." | ||||
|         exit $ERR_CURL_NOT_INSTALLED | ||||
|     fi | ||||
| } | ||||
|  | ||||
| # Fetch issues from Redmine API | ||||
| fetch_issues() { | ||||
|     local project_id="$1" | ||||
|     local url="${REDMINE_API_URL}/issues.json?key=${REDMINE_API_KEY}&project_id=${project_id}&due_date=${DATE}" | ||||
|  | ||||
|     info "Fetching issues with due date ${DATE} for project ID ${project_id}..." | ||||
|     response=$(curl -s -w "%{http_code}" -o /tmp/redmine_response.json "$url") | ||||
|     http_code=$(tail -n1 <<<"$response") | ||||
|  | ||||
|     if [[ "$http_code" -ne 200 ]]; then | ||||
|         error "Failed to fetch issues from Redmine API. HTTP Code: $http_code" | ||||
|         exit $ERR_API_FAILURE | ||||
|     fi | ||||
|  | ||||
|     info "Issues fetched successfully. Parsing and converting to Markdown..." | ||||
|     generate_markdown /tmp/redmine_response.json | ||||
| } | ||||
|  | ||||
| # Generate Markdown output from JSON response | ||||
| generate_markdown() { | ||||
|     local json_file="$1" | ||||
|     local markdown_output="/tmp/redmine_issues.md" | ||||
|  | ||||
|     echo "# Redmine Issues for ${DATE}" > "$markdown_output" | ||||
|     echo "" >> "$markdown_output" | ||||
|  | ||||
|     jq -r --arg base_url "$REDMINE_API_URL" '.issues[] | "## [\(.subject)](\($base_url)/issues/\(.id))\n- **ID**: \(.id)\n- **Status**: \(.status.name)\n- **Due Date**: \(.due_date)\n\n---"' \ | ||||
|         "$json_file" >> "$markdown_output" | ||||
|  | ||||
|     info "Markdown output written to $markdown_output" | ||||
|     cat "$markdown_output" | ||||
| } | ||||
|  | ||||
| # Main Function | ||||
| main() { | ||||
|     local project_id="$1" | ||||
|  | ||||
|     # Ensure curl is installed | ||||
|     require_curl | ||||
|  | ||||
|     # Fetch issues for the project | ||||
|     fetch_issues "$project_id" | ||||
| } | ||||
|  | ||||
| # Argument Parsing | ||||
| if [[ $# -lt 1 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then | ||||
|     usage | ||||
|     exit 0 | ||||
| fi | ||||
|  | ||||
| main "$1" | ||||
|  | ||||
| @@ -1,12 +0,0 @@ | ||||
| title: ReachableCEO 2025 Plan | ||||
| titlepage: true | ||||
| toc: true | ||||
| toc-own-page: true | ||||
| header-left: "\\hspace{1cm}" | ||||
| header-center: "\\leftmark" | ||||
| header-right: "Page \\thepage" | ||||
| footer-left: "Charles N Wyble" | ||||
| footer-center: "Tenacity. Velocity. Focus." | ||||
| page-background: "./background5.pdf" | ||||
| titlepage-logo: "D:/tsys/@ReachableCEO/ReachableCEO.png" | ||||
| urlcolor: blue | ||||
| @@ -1,70 +0,0 @@ | ||||
| %PDF-1.5 | ||||
| %<25><><EFBFBD><EFBFBD> | ||||
| 3 0 obj | ||||
| << /Length 4 0 R | ||||
|    /Filter /FlateDecode | ||||
| >> | ||||
| stream | ||||
| x<EFBFBD>m<EFBFBD>;<0E>@D<>=<3D>/<2F><><EFBFBD><EFBFBD><EFBFBD>18	<14><>K삢D | ||||
| r<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ư<EFBFBD>0f<EFBFBD><EFBFBD>|%<25>߅ <20>1<EFBFBD><31><EFBFBD><EFBFBD>D<EFBFBD><44>g,7<> | ||||
| !<21>i<03>jҔ<6A>P	<09>/c<>h<06>px<70>r<72><C289><EFBFBD><EFBFBD>1W<31>^<5E><>Q<EFBFBD>d<>%q<>!<21><>9ZD<12>j<EFBFBD><6A> | ||||
| U<EFBFBD>Ѫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>p<EFBFBD><EFBFBD>r$<24>&]x_<78><5F>ʑȽ<CA91>I<EFBFBD>W<><7F>?f<>r)<1F>6EU | ||||
| endstream | ||||
| endobj | ||||
| 4 0 obj | ||||
|    168 | ||||
| endobj | ||||
| 2 0 obj | ||||
| << | ||||
|    /ExtGState << | ||||
|       /a0 << /CA 1 /ca 1 >> | ||||
|    >> | ||||
| >> | ||||
| endobj | ||||
| 5 0 obj | ||||
| << /Type /Page | ||||
|    /Parent 1 0 R | ||||
|    /MediaBox [ 0 0 595.275574 841.889771 ] | ||||
|    /Contents 3 0 R | ||||
|    /Group << | ||||
|       /Type /Group | ||||
|       /S /Transparency | ||||
|       /I true | ||||
|       /CS /DeviceRGB | ||||
|    >> | ||||
|    /Resources 2 0 R | ||||
| >> | ||||
| endobj | ||||
| 1 0 obj | ||||
| << /Type /Pages | ||||
|    /Kids [ 5 0 R ] | ||||
|    /Count 1 | ||||
| >> | ||||
| endobj | ||||
| 6 0 obj | ||||
| << /Creator (cairo 1.14.8 (http://cairographics.org)) | ||||
|    /Producer (cairo 1.14.8 (http://cairographics.org)) | ||||
| >> | ||||
| endobj | ||||
| 7 0 obj | ||||
| << /Type /Catalog | ||||
|    /Pages 1 0 R | ||||
| >> | ||||
| endobj | ||||
| xref | ||||
| 0 8 | ||||
| 0000000000 65535 f  | ||||
| 0000000582 00000 n  | ||||
| 0000000282 00000 n  | ||||
| 0000000015 00000 n  | ||||
| 0000000260 00000 n  | ||||
| 0000000354 00000 n  | ||||
| 0000000647 00000 n  | ||||
| 0000000774 00000 n  | ||||
| trailer | ||||
| << /Size 8 | ||||
|    /Root 7 0 R | ||||
|    /Info 6 0 R | ||||
| >> | ||||
| startxref | ||||
| 826 | ||||
| @@ -1,14 +0,0 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| INPUT_FILE="../dsr-build-temp/@DailyStakeholderReports/StrategicPlans/2025-ReachableCEO-Plan.md" | ||||
| OUTPUT_FILE="../dsr-build-output/ReachableCEO2025Plan.pdf" | ||||
| METADATA_FILE="2025Plan.yml" | ||||
| TEMPLATE="eisvogel" | ||||
|  | ||||
| pandoc \ | ||||
| $INPUT_FILE \ | ||||
| --template $TEMPLATE \ | ||||
| --metadata-file=$METADATA_FILE \ | ||||
| --from markdown \ | ||||
| --to=pdf \ | ||||
| --output $OUTPUT_FILE | ||||
| @@ -1,17 +0,0 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| TODAY_DATE=$(date +%m-%d-%Y) | ||||
| INPUT_FILE="DSR-$TODAY_DATE.md" | ||||
| OUTPUT_FILE="/d/tsys/@ReachableCEO/DailyStakeholderReport-Pipeline/dsr-build-output/DSR-$TODAY_DATE.pdf" | ||||
| METADATA_FILE="/d/tsys/@ReachableCEO/DailyStakeholderReport-Pipeline/dsr-publish/daily-stakeholder-report.yml" | ||||
| TEMPLATE="eisvogel" | ||||
|  | ||||
| cd /d/tsys/@ReachableCEO/DailyStakeholderReport-Pipeline/dsr-build-temp/@DailyStakeholderReports/Today || exit | ||||
|  | ||||
| pandoc \ | ||||
| $INPUT_FILE \ | ||||
| --template $TEMPLATE \ | ||||
| --metadata-file=$METADATA_FILE \ | ||||
| --from markdown \ | ||||
| --to=pdf \ | ||||
| --output $OUTPUT_FILE | ||||
| @@ -1,11 +0,0 @@ | ||||
| title: Daily Stakeholder Report - \today | ||||
| urlcolor: blue | ||||
| titlepage: true | ||||
| header-left: "\\hspace{1cm}" | ||||
| header-center: "\\leftmark" | ||||
| header-right: "Page \\thepage" | ||||
| footer-left: "Charles N Wyble" | ||||
| footer-center: "Tenacity. Velocity. Focus." | ||||
| footer-right: "[Source code](https://git.knownelement.com/reachableceo/DailyStakeholderReport-Pipeline/src/branch/main/dsr-publish/create-dsr-pdf.sh)" | ||||
| page-background: "D:/tsys/@ReachableCEO/DailyStakeholderReport-Pipeline/dsr-publish/background5.pdf" | ||||
| titlepage-logo: "D:/tsys/@ReachableCEO/ReachableCEO.png" | ||||
| @@ -1,131 +0,0 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| secrets_manager() | ||||
| { | ||||
|  | ||||
| echo "Obtaining discourse api key..." | ||||
|  | ||||
| bw logout | ||||
|  | ||||
| #################################### | ||||
| ## Step 0: Set to use tsys server | ||||
| #################################### | ||||
| bw config server https://pwvault.turnsys.com | ||||
|  | ||||
| #################################### | ||||
| ## Step 1: login to bitwarden | ||||
| #################################### | ||||
|  | ||||
| # From: https://bitwarden.com/help/cli/#using-an-api-key | ||||
|  | ||||
| ### Set apikey environment varaible | ||||
|  | ||||
| source D:/tsys/secrets/bitwarden/data/apikey-bitwarden-reachableceo | ||||
|  | ||||
| ### Login to vault using apikey... | ||||
|  | ||||
| bw login --apikey $BW_CLIENTID $BW_CLIENTSECRET | ||||
|  | ||||
| ### Step 1.1: unlock / save session id  | ||||
|  | ||||
| export BW_SESSION="$(bw unlock --passwordenv TSYS_BW_PASSWORD_REACHABLECEO --raw)" | ||||
|  | ||||
| ### Step 2: retrive a value into an environment variable | ||||
|  | ||||
| export DISCOURSE_APIKEY="$(bw get password APIKEY-discourse)" | ||||
|  | ||||
| } | ||||
|  | ||||
| post_dsr() | ||||
|  | ||||
| { | ||||
|  | ||||
| TODAY_DATE=$(date +%m-%d-%Y) | ||||
|  | ||||
| echo "Posting DSR..." | ||||
|  | ||||
| DISCOURSE_URL="https://community.turnsys.com"  # e.g., https://forum.example.com | ||||
| API_KEY="$DISCOURSE_APIKEY" # Your API key | ||||
| API_USERNAME="reachableceo" # API username or admin account | ||||
|  | ||||
| # The category ID to post to (update to match your forum's categories) | ||||
| CATEGORY_ID=61 | ||||
|  | ||||
| # The title for the post (generated here; customize as needed) | ||||
| TITLE="Daily Stakeholder Report - $TODAY_DATE" | ||||
|  | ||||
| # The content of the post | ||||
| CONTENT="Please use the link below to download today's stakeholder report." | ||||
|  | ||||
| # The file to upload (from the second argument or auto-generated based on date) | ||||
| FILE_PATH="../dsr-build-output/DSR-$TODAY_DATE.pdf" | ||||
|  | ||||
| # Check if the file exists | ||||
| if [ ! -f "$FILE_PATH" ]; then | ||||
|   echo "File not found: $FILE_PATH" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| # Upload the file | ||||
| echo "Uploading file..." | ||||
| upload_response=$(curl -s -X POST "$DISCOURSE_URL/uploads.json" \ | ||||
|   -H "Content-Type: multipart/form-data" \ | ||||
|   -H "Api-Key: $API_KEY" \ | ||||
|   -H "Api-Username: $API_USERNAME" \ | ||||
|   -F "file=@$FILE_PATH;type=application/pdf" \ | ||||
|   -F "type=composer") | ||||
|  | ||||
| echo "Upload Response: $upload_response" | ||||
|  | ||||
| # Extract the short_url from the response | ||||
| short_url=$(echo "$upload_response" | /mingw64/bin/jq -r '.short_url') | ||||
|  | ||||
| # Check if the short_url was returned | ||||
| if [ "$short_url" == "null" ]; then | ||||
|   echo "Failed to extract short_url. Response:" | ||||
|   echo "$upload_response" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| echo "File uploaded successfully. Short URL: $short_url" | ||||
|  | ||||
| # Append the file link to the post content (Markdown format) | ||||
| CONTENT="$CONTENT\n\n[Download todays report in PDF format]($short_url)" | ||||
|  | ||||
| # Create the new topic | ||||
| echo "Creating new topic..." | ||||
| post_response=$(curl -s -X POST "$DISCOURSE_URL/posts.json" \ | ||||
|   -H "Content-Type: application/json" \ | ||||
|   -H "Api-Key: $API_KEY" \ | ||||
|   -H "Api-Username: $API_USERNAME" \ | ||||
|   -d @- <<EOF | ||||
| { | ||||
|   "title": "$TITLE", | ||||
|   "raw": "$CONTENT", | ||||
|   "category": $CATEGORY_ID | ||||
| } | ||||
| EOF | ||||
| ) | ||||
|  | ||||
| echo "Post Response: $post_response" | ||||
|  | ||||
| # Check if the post creation was successful | ||||
| if echo "$post_response" | grep -q '"id":'; then | ||||
|   echo "Post created successfully!" | ||||
| else | ||||
|   echo "Failed to create post. Response:" | ||||
|   echo "$post_response" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| } | ||||
|  | ||||
| #Get discourse api key | ||||
|  | ||||
| secrets_manager  | ||||
|  | ||||
| # - Create a new topic  | ||||
| # - upload PDF to discourse | ||||
| # - attach uploaded PDF to the topic | ||||
|  | ||||
| post_dsr | ||||
| @@ -1,35 +0,0 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # Wrap up my instrumented day into a (mostly) automated report and publish to discourse | ||||
|  | ||||
| # Gather DSR assets | ||||
|  | ||||
| # My manually entered notations | ||||
| ./dsr-input/dsr-gather-joplin-log.sh | ||||
|  | ||||
| # My gitea data | ||||
| ./dsr-input/dsr-gather-gitea.sh | ||||
|  | ||||
| # My redmine data | ||||
| ./dsr-input/dsr-gather-redmine.sh | ||||
|  | ||||
| # My wakapi data | ||||
| ./dsr-input/dsr-gather-waka-api.sh | ||||
|  | ||||
| # My activity watch data | ||||
| ./dsr-input/dsr-gather-activitywatch.sh | ||||
|  | ||||
| # My habit tracker data | ||||
| ./dsr-input/dsr-gather-habits.sh | ||||
|  | ||||
| # My health/fitnes data  | ||||
| ./dsr-input/dsr-gather-fitness.sh | ||||
|  | ||||
| # My diet data | ||||
| ./dsr-input/dsr-gather-diet.sh | ||||
|  | ||||
| # Produce DSR PDF asset | ||||
| ./dsr-publish/create-dsr-pdf.sh | ||||
|  | ||||
| # Publish DSR to the world | ||||
| ./dsr-publish/publish-dsr.sh | ||||
| @@ -1,9 +0,0 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # Start my instrumented day  | ||||
|  | ||||
| # Create a new blank DSR for the day  | ||||
| ./dsr-joplin-create/dsr-new.sh | ||||
|  | ||||
| # Populate my Joplin note "Todays objectives" section based on Redmine due dates | ||||
| ./dsr-joplin-create/dsr-populate-objectives.sh | ||||
		Reference in New Issue
	
	Block a user