From a9f34be3eb2e9ff21bca6027fc961e2fccf53f16 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Sun, 26 Oct 2025 12:39:22 +0000 Subject: [PATCH 1/8] Add flow to update the patreon data --- .github/workflows/main.yaml | 5 + FetchPatreons/action.yml | 11 + FetchPatreons/fetch_patreon_members.sh | 175 ++++++++ website/_data/patreons.json | 571 ++++++++++++++++++++----- 4 files changed, 649 insertions(+), 113 deletions(-) create mode 100644 FetchPatreons/action.yml create mode 100755 FetchPatreons/fetch_patreon_members.sh diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 8c5247ee..cba3f690 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -36,6 +36,11 @@ jobs: GH_TOKEN: ${{ secrets.SPONSORS_TOKEN }} GH_LOGIN: MonoGame + - name: Fetch Patreons + uses: ./FetchPatreons + env: + PATREON_ACCESS_TOKEN: ${{ secrets.PATREON_ACCESS_TOKEN }} + - name: Setup .NET Core SDK uses: actions/setup-dotnet@v4 with: diff --git a/FetchPatreons/action.yml b/FetchPatreons/action.yml new file mode 100644 index 00000000..4088aae1 --- /dev/null +++ b/FetchPatreons/action.yml @@ -0,0 +1,11 @@ +name: Fetch Patreons +description: 'Updates the Patreon list for the Monogame website' +author: 'MonoGame Foundation' +runs: + using: "composite" + steps: + - name: Fetch + if: runner.os == 'Linux' + run: | + ./fetch_patreon_memberships.sh + shell: bash \ No newline at end of file diff --git a/FetchPatreons/fetch_patreon_members.sh b/FetchPatreons/fetch_patreon_members.sh new file mode 100755 index 00000000..22445dae --- /dev/null +++ b/FetchPatreons/fetch_patreon_members.sh @@ -0,0 +1,175 @@ +#!/bin/bash +# filepath: fetch_patreon_members.sh + +set -e + +# Check for required environment variable +if [ -z "$PATREON_ACCESS_TOKEN" ]; then + echo "Error: PATREON_ACCESS_TOKEN environment variable is not set" + echo "Usage: export PATREON_ACCESS_TOKEN='your_token_here' && ./fetch_patreon_members.sh" + exit 1 +fi + +# Get campaign ID first (you'll need to get your campaign ID) +# If you know your campaign ID, you can hardcode it here +CAMPAIGN_ID="${PATREON_CAMPAIGN_ID:-}" + +if [ -z "$CAMPAIGN_ID" ]; then + echo "Fetching campaign ID..." + CAMPAIGN_RESPONSE=$(curl -s -X GET \ + "https://www.patreon.com/api/oauth2/v2/campaigns" \ + -H "Authorization: Bearer $PATREON_ACCESS_TOKEN" \ + -H "Content-Type: application/json") + + CAMPAIGN_ID=$(echo "$CAMPAIGN_RESPONSE" | jq -r '.data[0].id') + + if [ -z "$CAMPAIGN_ID" ] || [ "$CAMPAIGN_ID" = "null" ]; then + echo "Error: Could not fetch campaign ID" + echo "Response: $CAMPAIGN_RESPONSE" + exit 1 + fi + + echo "Campaign ID: $CAMPAIGN_ID" +fi + +# Fetch members with pagination support +OUTPUT_FILE="../website/_data/patreons.json" +TEMP_FILE=$(mktemp) +ALL_MEMBERS="[]" +NEXT_CURSOR="" + +echo "Fetching Patreon members..." + +while true; do + # Build the URL with cursor for pagination + if [ -z "$NEXT_CURSOR" ]; then + URL="https://www.patreon.com/api/oauth2/v2/campaigns/${CAMPAIGN_ID}/members?include=currently_entitled_tiers,user&fields%5Bmember%5D=full_name,patron_status&fields%5Btier%5D=title&fields%5Buser%5D=full_name,url" + else + URL="https://www.patreon.com/api/oauth2/v2/campaigns/${CAMPAIGN_ID}/members?include=currently_entitled_tiers,user&fields%5Bmember%5D=full_name,patron_status&fields%5Btier%5D=title&fields%5Buser%5D=full_name,url&page%5Bcursor%5D=${NEXT_CURSOR}" + fi + + RESPONSE=$(curl -s -X GET "$URL" \ + -H "Authorization: Bearer $PATREON_ACCESS_TOKEN" \ + -H "Content-Type: application/json") + + # Check for errors + if echo "$RESPONSE" | jq -e '.errors' > /dev/null 2>&1; then + echo "Error from API:" + echo "$RESPONSE" | jq '.errors' + exit 1 + fi + + # Process the response + echo "$RESPONSE" > "$TEMP_FILE" + + # Debug: Show structure of response + echo "DEBUG: Response data count: $(echo "$RESPONSE" | jq '.data | length')" + echo "DEBUG: First member structure:" + echo "$RESPONSE" | jq '.data[0]' || echo "No data found" + echo "DEBUG: Included items count: $(echo "$RESPONSE" | jq '.included | length')" + + # Extract members from this page + PAGE_MEMBERS=$(jq '[ + .data[] | + . as $member | + { + member_id: .id, + name: (.attributes.full_name // ""), + tier_id: (.relationships.currently_entitled_tiers.data[0].id // ""), + patron_status: .attributes.patron_status + } + ]' "$TEMP_FILE") + + echo "DEBUG: All members (including inactive): $(echo "$PAGE_MEMBERS" | jq 'length')" + echo "DEBUG: First filtered member:" + echo "$PAGE_MEMBERS" | jq '.[0]' || echo "No filtered members" + + # Extract included data (tiers and users) + INCLUDED=$(jq '.included // []' "$TEMP_FILE") + + echo "DEBUG: Included types:" + echo "$INCLUDED" | jq '[group_by(.type) | .[] | {type: .[0].type, count: length}]' + echo "DEBUG: First tier:" + echo "$INCLUDED" | jq '[.[] | select(.type == "tier")][0]' + + # Simplified merge - include all patrons with active status, excluding free tier + PAGE_RESULT=$(jq -n \ + --argjson members "$PAGE_MEMBERS" \ + --argjson included "$INCLUDED" \ + '$members | map( + . as $m | + ($included[] | select(.type == "tier" and .id == $m.tier_id)) as $tier | + { + name: $m.name, + tier: ($tier.attributes.title // "Unknown"), + active: ($m.patron_status == "active_patron") + } + ) | map(select(.tier != "Unknown" and .tier != "" and .tier != "Free")) | sort_by(.tier) | reverse') + + echo "DEBUG: Page result count (after filtering): $(echo "$PAGE_RESULT" | jq 'length')" + echo "DEBUG: First few results:" + echo "$PAGE_RESULT" | jq '.[0:2]' + + # Merge with all members + ALL_MEMBERS=$(jq -n \ + --argjson all "$ALL_MEMBERS" \ + --argjson page "$PAGE_RESULT" \ + '$all + $page') + + echo "Fetched $(echo "$PAGE_RESULT" | jq 'length') members..." + + # Check for next page + NEXT_CURSOR=$(jq -r '.meta.pagination.cursors.next // ""' "$TEMP_FILE") + + if [ -z "$NEXT_CURSOR" ] || [ "$NEXT_CURSOR" = "null" ]; then + break + fi +done + +# Merge with existing data to preserve custom fields and historical data +if [ -f "$OUTPUT_FILE" ]; then + echo "Merging with existing data to preserve custom fields and historical patrons..." + EXISTING_DATA=$(cat "$OUTPUT_FILE") + + # Merge strategy: + # 1. Update existing members with new data from API (name, tier, active status) + # 2. Keep old members that aren't in the new data (they've left but we keep them for history) + # 3. Add new members from API + # 4. Preserve custom fields like 'url' from existing data + MERGED_DATA=$(jq -n \ + --argjson new "$ALL_MEMBERS" \ + --argjson old "$EXISTING_DATA" \ + ' + # Create lookup maps + ($new | map({(.name): .}) | add) as $newMap | + ($old | map({(.name): .}) | add) as $oldMap | + + # Get all unique names from both old and new + (($new | map(.name)) + ($old | map(.name)) | unique) as $allNames | + + # For each name, merge appropriately + $allNames | map( + . as $name | + if $newMap[$name] and $oldMap[$name] then + # Member exists in both - merge, keeping custom fields from old but updating tier/active from new + $oldMap[$name] + $newMap[$name] + elif $newMap[$name] then + # New member - use from API + $newMap[$name] + else + # Old member not in new data - keep as is (they left but we preserve history) + $oldMap[$name] + end + ) + ') + + echo "$MERGED_DATA" | jq '.' > "$OUTPUT_FILE" +else + # No existing file, just save new data + echo "$ALL_MEMBERS" | jq '.' > "$OUTPUT_FILE" +fi + +echo "Successfully saved $(jq 'length' "$OUTPUT_FILE") patrons to $OUTPUT_FILE" + +# Clean up +rm -f "$TEMP_FILE" \ No newline at end of file diff --git a/website/_data/patreons.json b/website/_data/patreons.json index 2bcea6e4..83e7586d 100644 --- a/website/_data/patreons.json +++ b/website/_data/patreons.json @@ -1,115 +1,460 @@ [ - { - "name": "James Silva", - "tier": "EnvironmentMapEffect", - "url": "https://ska-studios.com/" - }, - { - "name": "D. Ezra Sidran, PhD", - "tier": "DrawUserPrimitives" - }, - { - "name": "Pirota Pirozou", - "tier": "Cornflower Blue" - }, - { - "name": "macabrett", - "tier": "Cornflower Blue" - }, - { - "name": "Michal Škoula", - "tier": "Cornflower Blue", - "url": "https://skoula.cz/" - }, - { - "name": "Ben", - "tier": "SpriteBatch" - }, - { - "name": "ajian_nedo", - "tier": "SpriteBatch" - }, - { - "name": "Ellpeck Games", - "tier": "DrawUserPrimitives", - "url": "https://games.ellpeck.de/" - }, - { - "name": "Csharpskolan", - "tier": "Cornflower Blue" - }, - { - "name": "Donny Beals", - "tier": "SpriteBatch" - }, - { - "name": "Rui Holdorf", - "tier": "SpriteBatch" - }, - { - "name": "Alex Campbell-Black", - "tier": "Cornflower Blue" - }, - { - "name": "NotExplosive", - "tier": "SpriteBatch" - }, - { - "name": "Jake Kirkbride", - "tier": "DrawUserPrimitives" - }, - { - "name": "Oblotzky", - "tier": "DrawUserPrimitives" - }, - { - "name": "Gerald Unterrainer", - "tier": "SpriteBatch" - }, - { - "name":"Aaron Langille", - "tier": "SpriteBatch", - "url": "https://welcomebraveadventurer.ca" - }, - { - "name": "MoonFarmGame", - "tier": "SpriteBatch", - "url": "https://x.com/MoonFarmGame" - }, - { - "name": "MrValentine", - "tier": "SpriteBatch" - }, - { - "name": "aristurtledev", - "tier": "EnvironmentMapEffect", - "url": "https://aristurtledev.github.io/" - }, - { - "name": "Christopher Hanna", - "tier": "SpriteBatch" - }, - { - "name": "RenewEarth", - "tier": "SpriteBatch" - }, - { - "name": "Andrew Powell", - "tier": "SpriteBatch" - }, - { - "name": "Cynthia McMahon", - "tier": "SpriteBatch", - "url": "https://cynthiamcmahon.ca/blog/" - }, - { - "name": "Austin Sojka", - "tier": "Model.Draw", - "url": "https://romansixvigaming.com/" - }, - { - "name": "Dominik Gotojuch", - "tier": "DrawUserPrimitives", - "url": "https://gotojuch.com/" - } + { + "name": "Aaron Langille", + "tier": "SpriteBatch", + "url": "https://welcomebraveadventurer.ca", + "active": true + }, + { + "name": "Alex Campbell-Black", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Anastasia Lyra Calico", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Anders Pantzar", + "tier": "DrawUserPrimitives", + "active": true + }, + { + "name": "Andrew Powell", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Austin Sojka", + "tier": "Model.Draw", + "url": "https://romansixvigaming.com/", + "active": true + }, + { + "name": "Ben", + "tier": "SpriteBatch", + "active": false + }, + { + "name": "Ben Ritter", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Benjamin Sprakel", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Brandon Edgar", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Brett", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "BrizzleBrip", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Broken Stick", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Charles Pratt", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Christopher Hanna", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Christopher Schillinger", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Crizzhd ", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Csharpskolan", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Cynthia McMahon", + "tier": "SpriteBatch", + "url": "https://cynthiamcmahon.ca/blog/", + "active": true + }, + { + "name": "D. Ezra Sidran, PhD", + "tier": "DrawUserPrimitives", + "active": false + }, + { + "name": "Daddel Dattel Games", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Dave Pergola", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Den ", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Devin", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Dominik Gotojuch", + "tier": "DrawUserPrimitives", + "url": "https://gotojuch.com/", + "active": true + }, + { + "name": "Dominique Lacombe", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Donny Beals", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Eduardo Costa Rodrigues", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Efrain Vega Jr", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Ellpeck ", + "tier": "DrawUserPrimitives", + "active": true + }, + { + "name": "Ellpeck Games", + "tier": "DrawUserPrimitives", + "url": "https://games.ellpeck.de/", + "active": false + }, + { + "name": "Fabian Jakobsson", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Florian", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Gerald Unterrainer", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Hunter Krieger", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Jake Kirkbride", + "tier": "DrawUserPrimitives", + "active": true + }, + { + "name": "James Silva", + "tier": "EnvironmentMapEffect", + "url": "https://ska-studios.com/", + "active": true + }, + { + "name": "Joe Nicholson", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "John", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Joshua Favo", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Kelsam ", + "tier": "DrawUserPrimitives", + "active": true + }, + { + "name": "Landon", + "tier": "EnvironmentMapEffect", + "active": true + }, + { + "name": "Laurie Bose", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Lee Tran", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "MATTHEW PURCHESE", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Magnus Haaland", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Marcel Van Drunen", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Max Piskunov", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Maxime Caignart", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Melvin Bos", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Michal Škoula", + "tier": "Cornflower Blue", + "url": "https://skoula.cz/", + "active": false + }, + { + "name": "Mitchel Disveld", + "tier": "DrawUserPrimitives", + "active": true + }, + { + "name": "MoonFarmGame", + "tier": "SpriteBatch", + "url": "https://x.com/MoonFarmGame", + "active": false + }, + { + "name": "MrValentine", + "tier": "SpriteBatch", + "active": false + }, + { + "name": "NashFlow", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Nicola ", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Nicolò Montalesi", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Noam Chapnik", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "NotExplosive", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Oblotzky", + "tier": "DrawUserPrimitives", + "active": false + }, + { + "name": "Oculon Prime", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Paul Demers", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Pirota Pirozou", + "tier": "Cornflower Blue", + "active": false + }, + { + "name": "Primebie1", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Raleigh Showalter", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "RenewEarth", + "tier": "SpriteBatch" + }, + { + "name": "Retrodad0001", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Rui Holdorf", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "SagaSeeker", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Sanders Lauture", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Sandra Lénárdová", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Sharpe ", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Skye Maidstone", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Spacemyname", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Stephan Oberhoff", + "tier": "DrawUserPrimitives", + "active": true + }, + { + "name": "Takeshi Maruyama", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Tom Ogburn", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Tyler Lutz", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "V R", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "Zeram", + "tier": "SpriteBatch", + "active": true + }, + { + "name": "ajian_nedo", + "tier": "SpriteBatch", + "active": false + }, + { + "name": "aristurtledev", + "tier": "EnvironmentMapEffect", + "url": "https://aristurtledev.github.io/", + "active": false + }, + { + "name": "capsulecity ", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "chromatic_cobra", + "tier": "DrawUserPrimitives", + "active": true + }, + { + "name": "foobar1307", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "macabrett", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "madsdj", + "tier": "DrawUserPrimitives", + "active": true + }, + { + "name": "paloobi", + "tier": "Cornflower Blue", + "active": true + }, + { + "name": "Łukasz", + "tier": "DrawUserPrimitives", + "active": true + }, + { + "name": "これは 聡明 な文章だ", + "tier": "SpriteBatch", + "active": true + } ] From fcf9cd7242b7f6ad9c6dc11ecfef6aeb909c5da9 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Sun, 26 Oct 2025 13:04:44 +0000 Subject: [PATCH 2/8] Fix path? --- FetchPatreons/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FetchPatreons/action.yml b/FetchPatreons/action.yml index 4088aae1..77ffde0c 100644 --- a/FetchPatreons/action.yml +++ b/FetchPatreons/action.yml @@ -7,5 +7,5 @@ runs: - name: Fetch if: runner.os == 'Linux' run: | - ./fetch_patreon_memberships.sh + ./FetchPatreons/fetch_patreon_memberships.sh shell: bash \ No newline at end of file From ab3e93426798b0c1a5fb1acf2474978b48123e52 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Sun, 26 Oct 2025 13:09:44 +0000 Subject: [PATCH 3/8] run it in PR's also --- .github/workflows/pullrequest.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/pullrequest.yaml b/.github/workflows/pullrequest.yaml index 30d44809..872c4562 100644 --- a/.github/workflows/pullrequest.yaml +++ b/.github/workflows/pullrequest.yaml @@ -32,6 +32,11 @@ jobs: GH_TOKEN: ${{ secrets.SPONSORS_TOKEN }} GH_LOGIN: MonoGame + - name: Fetch Patreons + uses: ./FetchPatreons + env: + PATREON_ACCESS_TOKEN: ${{ secrets.PATREON_ACCESS_TOKEN }} + - name: Setup .NET Core SDK uses: actions/setup-dotnet@v4 with: From f537e8ff4e7a0f007e5068d642cd7251523bbe2e Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Sun, 26 Oct 2025 13:11:19 +0000 Subject: [PATCH 4/8] Fix issue --- FetchPatreons/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FetchPatreons/action.yml b/FetchPatreons/action.yml index 77ffde0c..98ddb22f 100644 --- a/FetchPatreons/action.yml +++ b/FetchPatreons/action.yml @@ -7,5 +7,5 @@ runs: - name: Fetch if: runner.os == 'Linux' run: | - ./FetchPatreons/fetch_patreon_memberships.sh + ./FetchPatreons/fetch_patreon_members.sh shell: bash \ No newline at end of file From 98d7113648c287001dc1e553fc8d6b0b50c7df71 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Sun, 26 Oct 2025 13:15:17 +0000 Subject: [PATCH 5/8] Remove debug output --- FetchPatreons/fetch_patreon_members.sh | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/FetchPatreons/fetch_patreon_members.sh b/FetchPatreons/fetch_patreon_members.sh index 22445dae..ebaf6ca5 100755 --- a/FetchPatreons/fetch_patreon_members.sh +++ b/FetchPatreons/fetch_patreon_members.sh @@ -33,7 +33,7 @@ if [ -z "$CAMPAIGN_ID" ]; then fi # Fetch members with pagination support -OUTPUT_FILE="../website/_data/patreons.json" +OUTPUT_FILE="website/_data/patreons.json" TEMP_FILE=$(mktemp) ALL_MEMBERS="[]" NEXT_CURSOR="" @@ -62,12 +62,6 @@ while true; do # Process the response echo "$RESPONSE" > "$TEMP_FILE" - # Debug: Show structure of response - echo "DEBUG: Response data count: $(echo "$RESPONSE" | jq '.data | length')" - echo "DEBUG: First member structure:" - echo "$RESPONSE" | jq '.data[0]' || echo "No data found" - echo "DEBUG: Included items count: $(echo "$RESPONSE" | jq '.included | length')" - # Extract members from this page PAGE_MEMBERS=$(jq '[ .data[] | @@ -80,18 +74,9 @@ while true; do } ]' "$TEMP_FILE") - echo "DEBUG: All members (including inactive): $(echo "$PAGE_MEMBERS" | jq 'length')" - echo "DEBUG: First filtered member:" - echo "$PAGE_MEMBERS" | jq '.[0]' || echo "No filtered members" - # Extract included data (tiers and users) INCLUDED=$(jq '.included // []' "$TEMP_FILE") - echo "DEBUG: Included types:" - echo "$INCLUDED" | jq '[group_by(.type) | .[] | {type: .[0].type, count: length}]' - echo "DEBUG: First tier:" - echo "$INCLUDED" | jq '[.[] | select(.type == "tier")][0]' - # Simplified merge - include all patrons with active status, excluding free tier PAGE_RESULT=$(jq -n \ --argjson members "$PAGE_MEMBERS" \ @@ -106,10 +91,6 @@ while true; do } ) | map(select(.tier != "Unknown" and .tier != "" and .tier != "Free")) | sort_by(.tier) | reverse') - echo "DEBUG: Page result count (after filtering): $(echo "$PAGE_RESULT" | jq 'length')" - echo "DEBUG: First few results:" - echo "$PAGE_RESULT" | jq '.[0:2]' - # Merge with all members ALL_MEMBERS=$(jq -n \ --argjson all "$ALL_MEMBERS" \ From 1f1427ca2791a09fbdcb0391f2b04cf367247c8a Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Sun, 26 Oct 2025 19:16:40 +0000 Subject: [PATCH 6/8] Add a Past section --- website/content/donate.njk | 45 +++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/website/content/donate.njk b/website/content/donate.njk index 7a2a442a..a2547cb3 100644 --- a/website/content/donate.njk +++ b/website/content/donate.njk @@ -61,9 +61,9 @@ title: Donate
-

Monthly Sponsors

+

Past Monthly Sponsors

- The following is a partial list of individuals and studios that support us through Patreon. + The following is a list of individuals and studios that support us through Patreon.


@@ -87,7 +87,46 @@ title: Donate {% for tier in tiers %}
{% for patreon in patreons %} - {% if patreon.tier == tier.name %} + {% if patreon.tier == tier.name and patreon.active %} + {% if patreon.url %}{% endif %} + {{patreon.name}} + {% if patreon.url %}{% endif %} +
+ {% endif %} + {% endfor %} +
+ {% endfor%} +
+ +
+
+

Past Monthly Sponsors

+

+ The following is a partial list of individuals and studios that have support us through Patreon in the past. +

+
+
+ {% set tiers = [ + { name: "EnvironmentMapEffect", url: "https://www.patreon.com/checkout/MonoGame?rid=9142452" }, + { name: "Model.Draw", url: "https://www.patreon.com/checkout/MonoGame?rid=9142450" }, + { name: "DrawUserPrimitives", url: "https://www.patreon.com/checkout/MonoGame?rid=1916865" }, + { name: "SpriteBatch", url: "https://www.patreon.com/checkout/MonoGame?rid=1867475" }, + { name: "Cornflower Blue", url: "https://www.patreon.com/checkout/MonoGame?rid=1867471" } + ] %} +
+ {% for tier in tiers %} +
+ {{tier.name}} +
+
+
+ {% endfor %} +
+
+ {% for tier in tiers %} +
+ {% for patreon in patreons %} + {% if patreon.tier == tier.name and not patreon.active %} {% if patreon.url %}{% endif %} {{patreon.name}} {% if patreon.url %}{% endif %} From 3253d4458c627caf93b09c4d901744288bfe3b2c Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Sun, 26 Oct 2025 19:51:59 +0000 Subject: [PATCH 7/8] fixed text --- website/content/donate.njk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/content/donate.njk b/website/content/donate.njk index a2547cb3..c9e41332 100644 --- a/website/content/donate.njk +++ b/website/content/donate.njk @@ -102,7 +102,7 @@ title: Donate

Past Monthly Sponsors

- The following is a partial list of individuals and studios that have support us through Patreon in the past. + The following is a list of individuals and studios that have supported us through Patreon in the past.


From 6ab8bad593ec6c8fe31eec3cc4b3183a49e2193a Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Sun, 26 Oct 2025 20:26:44 +0000 Subject: [PATCH 8/8] fixed title --- website/content/donate.njk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/content/donate.njk b/website/content/donate.njk index c9e41332..03a0aefe 100644 --- a/website/content/donate.njk +++ b/website/content/donate.njk @@ -61,7 +61,7 @@ title: Donate
-

Past Monthly Sponsors

+

Monthly Sponsors

The following is a list of individuals and studios that support us through Patreon.