mirror of
				https://github.com/privacyguides/privacyguides.org.git
				synced 2025-11-04 05:17:57 +00:00 
			
		
		
		
	feat: Generate member list (#3133)
Signed-off-by: Daniel Gray <dngray@privacyguides.org> Signed-off-by: Niek de Wilde <niek@privacyguides.org>
This commit is contained in:
		
							
								
								
									
										4
									
								
								.github/workflows/build-pr.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/build-pr.yml
									
									
									
									
										vendored
									
									
								
							@@ -72,8 +72,6 @@ jobs:
 | 
			
		||||
      continue-on-error: false
 | 
			
		||||
      privileged: ${{ fromJSON(needs.metadata.outputs.privileged) }}
 | 
			
		||||
      strict: true
 | 
			
		||||
    secrets:
 | 
			
		||||
      RO_DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
 | 
			
		||||
 | 
			
		||||
  build_i18n:
 | 
			
		||||
    if: ${{ contains(github.event.pull_request.labels.*.name, 'ci:build i18n') }}
 | 
			
		||||
@@ -108,8 +106,6 @@ jobs:
 | 
			
		||||
    with:
 | 
			
		||||
      ref: ${{github.event.pull_request.head.ref}}
 | 
			
		||||
      repo: ${{github.event.pull_request.head.repo.full_name}}
 | 
			
		||||
    secrets:
 | 
			
		||||
      RO_DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
 | 
			
		||||
 | 
			
		||||
  combine_build:
 | 
			
		||||
    needs: [build_english, build_i18n, build_blog]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								.github/workflows/build-zimfile.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.github/workflows/build-zimfile.yml
									
									
									
									
										vendored
									
									
								
							@@ -9,9 +9,6 @@ on:
 | 
			
		||||
      repo:
 | 
			
		||||
        required: true
 | 
			
		||||
        type: string
 | 
			
		||||
    secrets:
 | 
			
		||||
      RO_DISCOURSE_API_KEY:
 | 
			
		||||
        required: false
 | 
			
		||||
 | 
			
		||||
permissions:
 | 
			
		||||
  contents: read
 | 
			
		||||
@@ -82,8 +79,6 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Generate Donating Members List
 | 
			
		||||
        continue-on-error: true
 | 
			
		||||
        env:
 | 
			
		||||
          DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
 | 
			
		||||
        run: |
 | 
			
		||||
          pip install requests
 | 
			
		||||
          python tools/generate-members.py > includes/members.md
 | 
			
		||||
@@ -222,8 +217,6 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Generate Donating Members List
 | 
			
		||||
        continue-on-error: true
 | 
			
		||||
        env:
 | 
			
		||||
          DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
 | 
			
		||||
        run: |
 | 
			
		||||
          pip install requests
 | 
			
		||||
          python tools/generate-members.py > includes/members.md
 | 
			
		||||
@@ -471,8 +464,6 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Generate Donating Members List
 | 
			
		||||
        continue-on-error: true
 | 
			
		||||
        env:
 | 
			
		||||
          DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
 | 
			
		||||
        run: |
 | 
			
		||||
          pip install requests
 | 
			
		||||
          python tools/generate-members.py > includes/members.md
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							@@ -30,9 +30,6 @@ on:
 | 
			
		||||
      cache:
 | 
			
		||||
        type: boolean
 | 
			
		||||
        default: true
 | 
			
		||||
    secrets:
 | 
			
		||||
      RO_DISCOURSE_API_KEY:
 | 
			
		||||
        required: false
 | 
			
		||||
 | 
			
		||||
permissions:
 | 
			
		||||
  contents: read
 | 
			
		||||
@@ -176,8 +173,6 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Generate Donating Members List
 | 
			
		||||
        continue-on-error: true
 | 
			
		||||
        env:
 | 
			
		||||
          DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
 | 
			
		||||
        run: |
 | 
			
		||||
          pip install requests
 | 
			
		||||
          python tools/generate-members.py > includes/members.md
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								.github/workflows/publish-release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/publish-release.yml
									
									
									
									
										vendored
									
									
								
							@@ -63,8 +63,6 @@ jobs:
 | 
			
		||||
      context: production
 | 
			
		||||
      continue-on-error: false
 | 
			
		||||
      cache: false
 | 
			
		||||
    secrets:
 | 
			
		||||
      RO_DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
 | 
			
		||||
 | 
			
		||||
  build_blog:
 | 
			
		||||
    needs: submodule
 | 
			
		||||
@@ -85,8 +83,6 @@ jobs:
 | 
			
		||||
    with:
 | 
			
		||||
      repo: ${{ github.repository }}
 | 
			
		||||
      ref: ${{ github.ref }}
 | 
			
		||||
    secrets:
 | 
			
		||||
      RO_DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
 | 
			
		||||
 | 
			
		||||
  release:
 | 
			
		||||
    name: Create release notes
 | 
			
		||||
 
 | 
			
		||||
@@ -1,102 +1,20 @@
 | 
			
		||||
import requests
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
GITHUB_API_URL = "https://api.github.com/graphql"
 | 
			
		||||
GITHUB_TOKEN = os.getenv("GH_TOKEN")
 | 
			
		||||
ORG_NAME = "privacyguides"
 | 
			
		||||
 | 
			
		||||
# Fetch members from the API
 | 
			
		||||
members_api_url = "https://discuss.privacyguides.net/g/members/members.json?offset=0&order=added_at&asc=true"
 | 
			
		||||
headers = {
 | 
			
		||||
  "Api-Key": os.getenv("DISCOURSE_API_KEY"),
 | 
			
		||||
  "Api-Username": "system"
 | 
			
		||||
}
 | 
			
		||||
members_response = requests.get(members_api_url, headers=headers)
 | 
			
		||||
members_data = members_response.json()
 | 
			
		||||
 | 
			
		||||
if 'members' not in members_data:
 | 
			
		||||
  raise KeyError("Response JSON does not contain 'members' key")
 | 
			
		||||
members_api_url = os.getenv('MEMBERS_API_URL', 'https://ghost.privacyguides.org/cache/members.json')
 | 
			
		||||
members_response = requests.get(members_api_url)
 | 
			
		||||
members_data = members_response.json()[0]
 | 
			
		||||
 | 
			
		||||
members = members_data['members']
 | 
			
		||||
public_members_count = 0
 | 
			
		||||
private_members_count = 0
 | 
			
		||||
 | 
			
		||||
html_output = ""
 | 
			
		||||
for member in members:
 | 
			
		||||
  flair_name = member.get('flair_name')
 | 
			
		||||
  title = member.get('title')
 | 
			
		||||
  if flair_name == "members" or title == "Member":
 | 
			
		||||
    username = member['username']
 | 
			
		||||
    avatar_template = member['avatar_template']
 | 
			
		||||
    avatar_url = f"https://discuss.privacyguides.net{avatar_template.replace('{size}', '128')}"
 | 
			
		||||
    profile_url = f"https://discuss.privacyguides.net/u/{username}"
 | 
			
		||||
    html_output += f'<a href="{profile_url}" target="_blank" title="@{username}" class="mdx-donors__item"><img loading="lazy" src="{avatar_url}"></a>'
 | 
			
		||||
    public_members_count += 1
 | 
			
		||||
 | 
			
		||||
# print(html_output)
 | 
			
		||||
 | 
			
		||||
query = """
 | 
			
		||||
{
 | 
			
		||||
  organization(login: "%s") {
 | 
			
		||||
    sponsorshipsAsMaintainer(first: 100) {
 | 
			
		||||
      nodes {
 | 
			
		||||
        sponsorEntity {
 | 
			
		||||
          ... on User {
 | 
			
		||||
            login
 | 
			
		||||
            avatarUrl
 | 
			
		||||
            url
 | 
			
		||||
          }
 | 
			
		||||
          ... on Organization {
 | 
			
		||||
            login
 | 
			
		||||
            avatarUrl
 | 
			
		||||
            url
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        createdAt
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
""" % ORG_NAME
 | 
			
		||||
 | 
			
		||||
headers = {
 | 
			
		||||
    "Authorization": f"Bearer {GITHUB_TOKEN}",
 | 
			
		||||
    "Content-Type": "application/json"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
response = requests.post(GITHUB_API_URL, json={'query': query}, headers=headers)
 | 
			
		||||
data = response.json()
 | 
			
		||||
 | 
			
		||||
if 'errors' in data:
 | 
			
		||||
    raise Exception(f"GraphQL query failed with errors: {data['errors']}")
 | 
			
		||||
if 'data' not in data:
 | 
			
		||||
    raise KeyError(f"Response JSON does not contain 'data' key: {data}")
 | 
			
		||||
 | 
			
		||||
sponsors = data['data']['organization']['sponsorshipsAsMaintainer']['nodes']
 | 
			
		||||
 | 
			
		||||
# Sort sponsors by the date they began their sponsorship
 | 
			
		||||
sponsors.sort(key=lambda x: x['createdAt'])
 | 
			
		||||
 | 
			
		||||
for sponsor in sponsors:
 | 
			
		||||
    sponsor_entity = sponsor['sponsorEntity']
 | 
			
		||||
    login = sponsor_entity['login']
 | 
			
		||||
    avatar_url = sponsor_entity['avatarUrl']
 | 
			
		||||
    url = sponsor_entity['url']
 | 
			
		||||
    html_output += f'<a href="{url}" title="@{login}" rel="ugc nofollow" target="_blank" class="mdx-donors__item"><img loading="lazy" src="{avatar_url}&size=120"></a>'
 | 
			
		||||
 | 
			
		||||
# Fetch the number of active members from the Magic Grants API
 | 
			
		||||
magic_grants_url = "https://donate.magicgrants.org/api/active-members?fund=privacyguides"
 | 
			
		||||
magic_grants_response = requests.get(magic_grants_url)
 | 
			
		||||
magic_grants_data = magic_grants_response.json()
 | 
			
		||||
 | 
			
		||||
if 'members_count' not in magic_grants_data:
 | 
			
		||||
  raise KeyError("Response JSON does not contain 'members_count' key")
 | 
			
		||||
 | 
			
		||||
private_members_count += magic_grants_data['members_count']
 | 
			
		||||
private_members_count -= public_members_count
 | 
			
		||||
  username = member['username']
 | 
			
		||||
  html_output += f'<a href="{member['url']}" target="_blank" title="@{member['username']}" class="mdx-donors__item"><img loading="lazy" src="{member['avatar']}"></a>'
 | 
			
		||||
 | 
			
		||||
# Append the count of private members
 | 
			
		||||
if private_members_count > 0:
 | 
			
		||||
  html_output += f'<a href="https://donate.magicgrants.org/privacyguides" class="mdx-donors__item mdx-donors__item--private">+{private_members_count}</a>'
 | 
			
		||||
if members_data['unaccounted'] > 0:
 | 
			
		||||
  html_output += f'<a href="https://donate.magicgrants.org/privacyguides" class="mdx-donors__item mdx-donors__item--private">+{members_data["unaccounted"]}</a>'
 | 
			
		||||
 | 
			
		||||
print(html_output)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user