This is an automated email from the ASF dual-hosted git repository.
djwang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry-site.git
The following commit(s) were added to refs/heads/main by this push:
new a3bccf04 Add scripts and components for Team page integration
a3bccf04 is described below
commit a3bccf0410f78eb9e90974629de90fab9690057c
Author: Ed Espino <[email protected]>
AuthorDate: Wed Nov 27 00:22:04 2024 -0800
Add scripts and components for Team page integration
This update introduces scripts and components to mimic contrib.rocks
functionality, highlighting GitHub contributors to Apache Cloudberry
(Incubating) and active Slack community members.
Key changes:
- `fetch_contributors_and_team.py` and `fetch_slack_users.py` scripts
generate `contributors_and_team.json` and `slack_users.json`.
- `contributors.js` and `slack_users.js` React components display
contributors and Slack users, including their avatar images, on the Team page.
- Supporting CSS files (`Contributors.css` and `SlackUsers.css`) added for
styling.
- Updated `team.md` to integrate these new components dynamically.
Notes:
- Scripts are run manually, and outputs are updated in the `static`
directory.
- Only the English version is updated; the Chinese page remains unchanged.
---
scripts/active_users.json | 1 +
scripts/fetch_contributors_and_team.py | 175 +++++++++++++++++++++++++++++
scripts/fetch_slack_users.py | 136 +++++++++++++++++++++++
src/components/Contributors.css | 31 ++++++
src/components/SlackUsers.css | 31 ++++++
src/components/contributors.js | 37 +++++++
src/components/slack_users.js | 35 ++++++
src/pages/team.md | 12 +-
static/contributors_and_team.json | 86 +++++++++++++++
static/slack_users.json | 194 +++++++++++++++++++++++++++++++++
10 files changed, 734 insertions(+), 4 deletions(-)
diff --git a/scripts/active_users.json b/scripts/active_users.json
new file mode 100644
index 00000000..0637a088
--- /dev/null
+++ b/scripts/active_users.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/scripts/fetch_contributors_and_team.py
b/scripts/fetch_contributors_and_team.py
new file mode 100755
index 00000000..233edf5b
--- /dev/null
+++ b/scripts/fetch_contributors_and_team.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python3
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+# OF ANY KIND, either express or implied. See the License for
+# the specific language governing permissions and limitations
+# under the License.
+#
+"""
+fetch_contributors_and_team.py
+
+This script fetches:
+1. Contributors to the repository since a hardcoded fork date.
+2. Members of a specific GitHub team.
+
+Output:
+- contributors_and_team.json: Contains contributors and team members with the
following fields:
+ - login: GitHub username.
+ - avatar_url: URL to the user's GitHub avatar.
+
+Requirements:
+- A valid GitHub API token with `repo` and `read:org` permissions.
+ The token must be set as an environment variable `GITHUB_TOKEN`.
+
+Prerequisites:
+- Python 3.7 or later.
+- Modules: `requests`.
+
+Usage:
+1. Ensure you have `requests` installed (`pip install requests`).
+2. Set the environment variable `GITHUB_TOKEN` with a valid token:
+ - export GITHUB_TOKEN="your_github_personal_access_token"
+3. Run the script:
+ - ./fetch_contributors_and_team.py
+4. The output file `contributors_and_team.json` will be saved in the
`cloudberry-site/static` directory.
+"""
+
+import os
+import requests
+import json
+import sys
+
+# GitHub API Token from environment variable
+GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
+if not GITHUB_TOKEN:
+ raise ValueError("Please set the GITHUB_TOKEN environment variable.")
+
+# Repository and team details
+OWNER = "apache"
+REPO = "cloudberry"
+TEAM = "cloudberry-committers"
+
+# Hardcoded fork date
+FORK_DATE = "2022-02-09T22:31:43Z" # UTC timestamp for fork point.
+
+# API URLs
+COMMITS_URL = f"https://api.github.com/repos/{OWNER}/{REPO}/commits"
+TEAM_MEMBERS_URL = f"https://api.github.com/orgs/{OWNER}/teams/{TEAM}/members"
+
+# Headers for API requests
+HEADERS = {"Authorization": f"Bearer {GITHUB_TOKEN}"}
+
+# Determine absolute path to static directory
+SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
+STATIC_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "../static"))
+
+# Ensure static directory exists
+os.makedirs(STATIC_DIR, exist_ok=True)
+
+
+def fetch_committers(team_members):
+ """
+ Fetch GitHub committers from the repository since the fork date.
+ Only includes users who are part of the specified team.
+ """
+ print(f"Fetching committers since fork date: {FORK_DATE}...")
+ committers = set()
+ params = {"per_page": 100, "page": 1, "since": FORK_DATE}
+
+ while True:
+ sys.stdout.write(f"Processing page {params['page']} of
committers...\r")
+ sys.stdout.flush()
+
+ response = requests.get(COMMITS_URL, headers=HEADERS, params=params)
+ if response.status_code != 200:
+ print(f"\nError fetching committers: {response.status_code},
{response.text}")
+ break
+
+ commits = response.json()
+ if not commits:
+ break
+
+ for commit in commits:
+ committer = commit.get("committer")
+ if committer:
+ username = committer.get("login")
+ if username and username in team_members:
+ committers.add(username)
+
+ params["page"] += 1
+
+ sys.stdout.write("\n")
+ print(f"Found {len(committers)} unique committers.")
+ return committers
+
+
+def fetch_team_members():
+ """
+ Fetch members of the GitHub team specified in the TEAM variable.
+ """
+ print("Fetching team members...")
+ team_members = set()
+ params = {"per_page": 100, "page": 1}
+
+ while True:
+ response = requests.get(TEAM_MEMBERS_URL, headers=HEADERS,
params=params)
+ if response.status_code != 200:
+ print(f"Error fetching team members: {response.status_code},
{response.text}")
+ break
+
+ members = response.json()
+ if not members:
+ break
+
+ for member in members:
+ username = member.get("login")
+ if username:
+ team_members.add(username)
+
+ params["page"] += 1
+
+ print(f"Found {len(team_members)} unique team members.")
+ return team_members
+
+
+def save_combined_data(committers, team_members):
+ """
+ Combine committers and team members and save as JSON.
+ The output is written to the `contributors_and_team.json` file in the
`static` directory.
+ """
+ combined_users = committers.union(team_members)
+ user_data = [
+ {
+ "login": user,
+ "avatar_url": f"https://avatars.githubusercontent.com/{user}"
+ }
+ for user in sorted(combined_users)
+ ]
+
+ output_path = os.path.join(STATIC_DIR, "contributors_and_team.json")
+ with open(output_path, "w") as file:
+ json.dump(user_data, file, indent=4)
+
+ print(f"Combined data saved to {output_path}")
+
+
+if __name__ == "__main__":
+ print("Starting GitHub user processing...")
+
+ team_members = fetch_team_members()
+ committers = fetch_committers(team_members)
+ save_combined_data(committers, team_members)
+
+ print("Processing complete.")
diff --git a/scripts/fetch_slack_users.py b/scripts/fetch_slack_users.py
new file mode 100755
index 00000000..50b0a447
--- /dev/null
+++ b/scripts/fetch_slack_users.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python3
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+# OF ANY KIND, either express or implied. See the License for
+# the specific language governing permissions and limitations
+# under the License.
+#
+"""
+fetch_slack_users.py
+
+This script fetches Slack users and filters them based on a hardcoded list of
names.
+Duplicate names are excluded by keeping only the first occurrence.
+
+Output:
+- `slack_users.json`: Contains matched users with the following fields:
+ - name: Slack user's real name.
+ - profile_image: URL to the user's Slack profile image.
+
+Requirements:
+- A valid Slack API token with the `users:read` permission.
+ The token must be set as an environment variable `SLACK_TOKEN`.
+
+Notes:
+- The hardcoded list of user names is manually retrieved from the Slack
workspace
+ members area, where it is possible to filter active users.
+- This script is designed to work at the free API level, as Slack APIs do not
provide
+ sufficient information to programmatically determine active users in
free-tier workspaces.
+
+Prerequisites:
+- Python 3.7 or later.
+- Modules: `requests`.
+
+Usage:
+1. Ensure you have `requests` installed (`pip install requests`).
+2. Set the environment variable `SLACK_TOKEN` with a valid token:
+ - export SLACK_TOKEN="your_slack_api_token"
+3. Run the script:
+ - ./fetch_slack_users.py
+4. The output file `slack_users.json` will be saved in the `static` directory.
+"""
+
+import os
+import requests
+import json
+
+# Slack API Token from environment variable
+SLACK_TOKEN = os.getenv("SLACK_TOKEN")
+if not SLACK_TOKEN:
+ raise ValueError("Please set the SLACK_TOKEN environment variable.")
+
+# Slack API URL
+SLACK_USERS_URL = "https://slack.com/api/users.list"
+
+# Headers for API request
+HEADERS = {"Authorization": f"Bearer {SLACK_TOKEN}"}
+
+# Hardcoded list of user names
+USER_NAMES = [
+ "Abhi", "Albert C", "Albert Dong", "Alwin", "Amy Levine", "Andreas
Eschbacher",
+ "Antonio Petrole", "Bernard", "Brad Howerter", "Chuck Renaud", "David",
+ "Dianjin Wang", "Eddie Espino", "franck sidi", "Greg Spiegelberg", "Hao
Wu",
+ "Himanshu Pandey", "Jacque Istok", "Jakub Sicner", "jiaqizho", "Joaquim
Oliveira",
+ "John Huang", "kalo", "kris", "Leon Cheng", "Leonid Borchuk", "Liang Chen",
+ "Lirong Jian", "Louis Mugnano", "Luis Macedo", "Max Yang", "Nadir Pervez",
+ "Nikolay", "Nixon Daniel Hutahaean", "roseduan", "Ryan Wei", "sai",
"Sharon",
+ "Shine Zhang 张辛", "Tony Wasson", "Travis L", "Tushar Pednekar", "Way Dev",
+ "Xuebin", "Yuriy", "Zhang Mingli", "ZhangBaowen", "Айдарханов Даурен"
+]
+
+# Determine absolute path to static directory
+SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
+STATIC_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "../static"))
+
+# Ensure static directory exists
+os.makedirs(STATIC_DIR, exist_ok=True)
+
+
+def fetch_slack_users():
+ """
+ Fetch Slack users and filter by a hardcoded list of names.
+ Exclude duplicates by keeping the first occurrence.
+ Save their names and profile images to a JSON file.
+ """
+ print("Fetching Slack users from API...")
+ slack_users = {}
+ matched_users = []
+
+ # Fetch users from Slack API
+ response = requests.get(SLACK_USERS_URL, headers=HEADERS)
+ if response.status_code != 200:
+ print(f"Error fetching Slack users: {response.status_code},
{response.text}")
+ return
+
+ data = response.json()
+ if not data.get("ok"):
+ print(f"Slack API error: {data.get('error')}")
+ return
+
+ # Process users and match against the hardcoded list
+ slack_user_data = data.get("members", [])
+ for user in slack_user_data:
+ # Skip bots and deleted users
+ if user.get("is_bot") or user.get("deleted"):
+ continue
+
+ # Extract user name and profile image
+ real_name = user.get("real_name", "").strip()
+ profile_image = user.get("profile", {}).get("image_512")
+
+ # Check if name is in USER_NAMES and not already recorded
+ if real_name in USER_NAMES and real_name not in slack_users:
+ slack_users[real_name] = {"name": real_name, "profile_image":
profile_image}
+ matched_users.append(slack_users[real_name])
+ print(f"Matched user: {real_name}")
+
+ # Save matched users to JSON
+ output_path = os.path.join(STATIC_DIR, "slack_users.json")
+ with open(output_path, "w") as file:
+ json.dump(matched_users, file, indent=4)
+ print(f"Slack users saved to {output_path} ({len(matched_users)} matched
users)")
+
+
+if __name__ == "__main__":
+ fetch_slack_users()
diff --git a/src/components/Contributors.css b/src/components/Contributors.css
new file mode 100644
index 00000000..7b6baf95
--- /dev/null
+++ b/src/components/Contributors.css
@@ -0,0 +1,31 @@
+.grid {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 20px;
+ justify-content: center;
+ margin-top: 20px;
+}
+
+.card {
+ text-align: center;
+ width: 120px;
+ font-family: Arial, sans-serif;
+}
+
+.avatar {
+ width: 100px;
+ height: 100px;
+ border-radius: 50%;
+ box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
+ margin-bottom: 10px;
+}
+
+p {
+ margin: 0;
+ font-size: 14px;
+ color: #333;
+}
+
+p strong {
+ font-weight: bold;
+}
diff --git a/src/components/SlackUsers.css b/src/components/SlackUsers.css
new file mode 100644
index 00000000..7b6baf95
--- /dev/null
+++ b/src/components/SlackUsers.css
@@ -0,0 +1,31 @@
+.grid {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 20px;
+ justify-content: center;
+ margin-top: 20px;
+}
+
+.card {
+ text-align: center;
+ width: 120px;
+ font-family: Arial, sans-serif;
+}
+
+.avatar {
+ width: 100px;
+ height: 100px;
+ border-radius: 50%;
+ box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
+ margin-bottom: 10px;
+}
+
+p {
+ margin: 0;
+ font-size: 14px;
+ color: #333;
+}
+
+p strong {
+ font-weight: bold;
+}
diff --git a/src/components/contributors.js b/src/components/contributors.js
new file mode 100644
index 00000000..c88c3884
--- /dev/null
+++ b/src/components/contributors.js
@@ -0,0 +1,37 @@
+import React, { useEffect, useState } from 'react';
+import './Contributors.css';
+
+const Contributors = () => {
+ const [contributors, setContributors] = useState([]);
+
+ useEffect(() => {
+ // Fetch data from contributors_and_team.json
+ fetch('/contributors_and_team.json')
+ .then((response) => response.json())
+ .then((data) => {
+ setContributors(data);
+ })
+ .catch((error) => {
+ console.error('Error loading contributors:', error);
+ });
+ }, []);
+
+ return (
+ <div>
+ <div className="grid">
+ {contributors.map((contributor) => (
+ <div key={contributor.login} className="card">
+ <img
+ src={contributor.avatar_url || 'https://via.placeholder.com/100'}
+ alt={contributor.login}
+ className="avatar"
+ />
+ <p><strong>{contributor.login}</strong></p>
+ </div>
+ ))}
+ </div>
+ </div>
+ );
+};
+
+export default Contributors;
diff --git a/src/components/slack_users.js b/src/components/slack_users.js
new file mode 100644
index 00000000..342873df
--- /dev/null
+++ b/src/components/slack_users.js
@@ -0,0 +1,35 @@
+import React, { useEffect, useState } from 'react';
+import './SlackUsers.css';
+
+const SlackUsers = () => {
+ const [users, setUsers] = useState([]);
+
+ useEffect(() => {
+ fetch('/slack_users.json')
+ .then((response) => response.json())
+ .then((data) => setUsers(data))
+ .catch((error) => {
+ console.error('Error loading Slack users:', error);
+ });
+ }, []);
+
+ return (
+ <div>
+ <div className="grid">
+ {users.map((user) => (
+ <div key={user.id} className="card">
+ <img
+ src={user.profile_image || 'https://via.placeholder.com/100'}
+ alt={user.name}
+ className="avatar"
+ />
+ <p><strong>{user.name}</strong></p>
+ <p>{user.email}</p>
+ </div>
+ ))}
+ </div>
+ </div>
+ );
+};
+
+export default SlackUsers;
diff --git a/src/pages/team.md b/src/pages/team.md
index 9ad283af..b1f4925a 100644
--- a/src/pages/team.md
+++ b/src/pages/team.md
@@ -37,10 +37,14 @@ Each Podling Project Management Committee (PPMC) helps its
Podling learn how to
Our journey began in 2022, and we have built our foundation on PostgreSQL and
Greenplum Database. We would not be where we are today without the invaluable
contributions of the two project contributors. We extend our heartfelt thanks
to them.
-# Become a contributor
+import Contributors from '@site/src/components/contributors';
+import SlackUsers from '@site/src/components/slack_users';
-The Apache Cloudberry community welcomes everyone to contribute, regardless of
their level of experience. We encourage all types of contributions, no matter
how small. Our [contribution guide](/contribute) is available to help you get
started with the process.
+# Contributors wall
+## GitHub Committers and PPMC members
-In addition, we offer various channels for community members to discuss, seek
help, provide feedback, and chat. You can find [support](/support) here. Let us
know if you have any questions or feedback - we're always here to help.
+<Contributors />
-Join us and be part of us!
\ No newline at end of file
+## Slack Community
+
+<SlackUsers />
diff --git a/static/contributors_and_team.json
b/static/contributors_and_team.json
new file mode 100644
index 00000000..bdd6dded
--- /dev/null
+++ b/static/contributors_and_team.json
@@ -0,0 +1,86 @@
+[
+ {
+ "login": "HuSen8891",
+ "avatar_url": "https://avatars.githubusercontent.com/HuSen8891"
+ },
+ {
+ "login": "Smyatkin-Maxim",
+ "avatar_url": "https://avatars.githubusercontent.com/Smyatkin-Maxim"
+ },
+ {
+ "login": "WillemJiang",
+ "avatar_url": "https://avatars.githubusercontent.com/WillemJiang"
+ },
+ {
+ "login": "antoniopetrole",
+ "avatar_url": "https://avatars.githubusercontent.com/antoniopetrole"
+ },
+ {
+ "login": "avamingli",
+ "avatar_url": "https://avatars.githubusercontent.com/avamingli"
+ },
+ {
+ "login": "edespino",
+ "avatar_url": "https://avatars.githubusercontent.com/edespino"
+ },
+ {
+ "login": "fanfuxiaoran",
+ "avatar_url": "https://avatars.githubusercontent.com/fanfuxiaoran"
+ },
+ {
+ "login": "gaoxueyu",
+ "avatar_url": "https://avatars.githubusercontent.com/gaoxueyu"
+ },
+ {
+ "login": "gfphoenix78",
+ "avatar_url": "https://avatars.githubusercontent.com/gfphoenix78"
+ },
+ {
+ "login": "jiaqizho",
+ "avatar_url": "https://avatars.githubusercontent.com/jiaqizho"
+ },
+ {
+ "login": "my-ship-it",
+ "avatar_url": "https://avatars.githubusercontent.com/my-ship-it"
+ },
+ {
+ "login": "oppenheimer01",
+ "avatar_url": "https://avatars.githubusercontent.com/oppenheimer01"
+ },
+ {
+ "login": "reshke",
+ "avatar_url": "https://avatars.githubusercontent.com/reshke"
+ },
+ {
+ "login": "rvs",
+ "avatar_url": "https://avatars.githubusercontent.com/rvs"
+ },
+ {
+ "login": "tuhaihe",
+ "avatar_url": "https://avatars.githubusercontent.com/tuhaihe"
+ },
+ {
+ "login": "weinan003",
+ "avatar_url": "https://avatars.githubusercontent.com/weinan003"
+ },
+ {
+ "login": "x4m",
+ "avatar_url": "https://avatars.githubusercontent.com/x4m"
+ },
+ {
+ "login": "xinzweb",
+ "avatar_url": "https://avatars.githubusercontent.com/xinzweb"
+ },
+ {
+ "login": "xtangcode",
+ "avatar_url": "https://avatars.githubusercontent.com/xtangcode"
+ },
+ {
+ "login": "yaooqinn",
+ "avatar_url": "https://avatars.githubusercontent.com/yaooqinn"
+ },
+ {
+ "login": "yjhjstz",
+ "avatar_url": "https://avatars.githubusercontent.com/yjhjstz"
+ }
+]
\ No newline at end of file
diff --git a/static/slack_users.json b/static/slack_users.json
new file mode 100644
index 00000000..c4dd713e
--- /dev/null
+++ b/static/slack_users.json
@@ -0,0 +1,194 @@
+[
+ {
+ "name": "Ryan Wei",
+ "profile_image":
"https://avatars.slack-edge.com/2023-06-16/5449454763825_0ae253a51a5d524fe93a_512.jpg"
+ },
+ {
+ "name": "Dianjin Wang",
+ "profile_image":
"https://avatars.slack-edge.com/2024-04-23/7029674500336_cda6b2ff4aae5ac12188_512.png"
+ },
+ {
+ "name": "Max Yang",
+ "profile_image":
"https://secure.gravatar.com/avatar/0b093e09789280920dabda5e27102a26.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0020-512.png"
+ },
+ {
+ "name": "Zhang Mingli",
+ "profile_image":
"https://avatars.slack-edge.com/2023-07-12/5557615873222_37922453b37b3ab89bf2_512.png"
+ },
+ {
+ "name": "Xuebin",
+ "profile_image":
"https://secure.gravatar.com/avatar/c207a8faaaea4a8d25c2dbddeaf11044.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0012-512.png"
+ },
+ {
+ "name": "Nikolay",
+ "profile_image":
"https://secure.gravatar.com/avatar/32743e2065b79dbc9c30c6ce69901318.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0006-512.png"
+ },
+ {
+ "name": "Louis Mugnano",
+ "profile_image":
"https://avatars.slack-edge.com/2024-05-30/7185480733959_09d8f9d7b48f16f3c56e_512.jpg"
+ },
+ {
+ "name": "Sharon",
+ "profile_image":
"https://secure.gravatar.com/avatar/8d5b2e76166c4cf50ad304dac77b1c29.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0025-512.png"
+ },
+ {
+ "name": "Eddie Espino",
+ "profile_image":
"https://avatars.slack-edge.com/2024-06-05/7243045768017_c4eb6614509041758d97_512.jpg"
+ },
+ {
+ "name": "Tushar Pednekar",
+ "profile_image":
"https://secure.gravatar.com/avatar/f22d0b4cd39f864aec2f0d90117fa933.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-512.png"
+ },
+ {
+ "name": "Nadir Pervez",
+ "profile_image":
"https://secure.gravatar.com/avatar/bd9d9cb2f48691616bd6a20b5be21a43.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0019-512.png"
+ },
+ {
+ "name": "David",
+ "profile_image":
"https://secure.gravatar.com/avatar/457887abf01f295c98f6a5f0e97daee5.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0009-512.png"
+ },
+ {
+ "name": "Antonio Petrole",
+ "profile_image":
"https://avatars.slack-edge.com/2024-07-12/7429103314481_c65557e3b1ed7beed763_512.jpg"
+ },
+ {
+ "name": "Joaquim Oliveira",
+ "profile_image":
"https://secure.gravatar.com/avatar/3e36e8ffb3a043fbf6971f616d8f7bab.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-512.png"
+ },
+ {
+ "name": "Leon Cheng",
+ "profile_image":
"https://secure.gravatar.com/avatar/b2eb7911503867e44720570fa5e20413.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0013-512.png"
+ },
+ {
+ "name": "Andreas Eschbacher",
+ "profile_image":
"https://avatars.slack-edge.com/2024-08-30/7656572199444_9930f59434ad90f98d88_512.jpg"
+ },
+ {
+ "name": "franck sidi",
+ "profile_image":
"https://avatars.slack-edge.com/2024-06-28/7347197911938_c6d58b6a2b1818805ab4_512.png"
+ },
+ {
+ "name": "jiaqizho",
+ "profile_image":
"https://secure.gravatar.com/avatar/5c06c1e58ab16a4f01b0a8533ca35132.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0024-512.png"
+ },
+ {
+ "name": "ZhangBaowen",
+ "profile_image":
"https://secure.gravatar.com/avatar/b2bf10918d9fe845cbfb5f075b026cb1.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0004-512.png"
+ },
+ {
+ "name": "Greg Spiegelberg",
+ "profile_image":
"https://avatars.slack-edge.com/2024-07-04/7399744955184_cc6d9fbd541670e89710_512.jpg"
+ },
+ {
+ "name": "Tony Wasson",
+ "profile_image":
"https://avatars.slack-edge.com/2024-07-03/7395668799520_9e41a4e982117b173cae_512.png"
+ },
+ {
+ "name": "Bernard",
+ "profile_image":
"https://secure.gravatar.com/avatar/44c0e409ff5883f10d43aa12fe36ca2f.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0025-512.png"
+ },
+ {
+ "name": "Liang Chen",
+ "profile_image":
"https://secure.gravatar.com/avatar/cb2cfd8b82fb649cb0987f9cd9159bde.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-512.png"
+ },
+ {
+ "name": "Lirong Jian",
+ "profile_image":
"https://avatars.slack-edge.com/2024-07-18/7437673719478_aea62ef15cee46a82d3f_512.jpg"
+ },
+ {
+ "name": "Albert Dong",
+ "profile_image":
"https://avatars.slack-edge.com/2024-10-17/7894298916531_cb8bee080789cf918f86_512.jpg"
+ },
+ {
+ "name": "\u0410\u0439\u0434\u0430\u0440\u0445\u0430\u043d\u043e\u0432
\u0414\u0430\u0443\u0440\u0435\u043d",
+ "profile_image":
"https://avatars.slack-edge.com/2024-08-24/7622859611941_950bf7e47b98a13d6d92_512.jpg"
+ },
+ {
+ "name": "Jacque Istok",
+ "profile_image":
"https://avatars.slack-edge.com/2024-09-04/7679909438834_3547956376770d3dbcca_512.png"
+ },
+ {
+ "name": "roseduan",
+ "profile_image":
"https://avatars.slack-edge.com/2024-08-30/7654152866067_12c367633cc72be748e5_512.png"
+ },
+ {
+ "name": "Chuck Renaud",
+ "profile_image":
"https://avatars.slack-edge.com/2024-09-05/7689455648308_44287f728297ae34283e_512.png"
+ },
+ {
+ "name": "Amy Levine",
+ "profile_image":
"https://avatars.slack-edge.com/2024-09-09/7703764836516_e525e915b0a37dbdeb23_512.png"
+ },
+ {
+ "name": "Hao Wu",
+ "profile_image":
"https://secure.gravatar.com/avatar/b8142e43a413ce1ed2589e501819ac0c.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-512.png"
+ },
+ {
+ "name": "Luis Macedo",
+ "profile_image":
"https://secure.gravatar.com/avatar/b18d6db60aab1d18fa48070c58e4660b.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0014-512.png"
+ },
+ {
+ "name": "Shine Zhang \u5f20\u8f9b",
+ "profile_image":
"https://avatars.slack-edge.com/2024-09-17/7740011265522_399356ac2af6767aada7_512.jpg"
+ },
+ {
+ "name": "Travis L",
+ "profile_image":
"https://secure.gravatar.com/avatar/0b5057a246e7d5401acd1f2317ca44d2.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-512.png"
+ },
+ {
+ "name": "Albert C",
+ "profile_image":
"https://secure.gravatar.com/avatar/b0e3d09f3163c55f9902f38e35f8a948.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0026-512.png"
+ },
+ {
+ "name": "Leonid Borchuk",
+ "profile_image":
"https://secure.gravatar.com/avatar/918649609a3908a4c486dafb44f5e3fd.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0014-512.png"
+ },
+ {
+ "name": "sai",
+ "profile_image":
"https://secure.gravatar.com/avatar/4080a5f227c5d7987df5e6400b3f8dcf.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-512.png"
+ },
+ {
+ "name": "Way Dev",
+ "profile_image":
"https://secure.gravatar.com/avatar/7c25270474e5589e87a6587ca077a1da.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0000-512.png"
+ },
+ {
+ "name": "Alwin",
+ "profile_image":
"https://secure.gravatar.com/avatar/b5287400b65b0b7d786882ef5e238f12.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-512.png"
+ },
+ {
+ "name": "Jakub Sicner",
+ "profile_image":
"https://secure.gravatar.com/avatar/4a5f13ccc598fc3ea5fd69ace00e3c88.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0017-512.png"
+ },
+ {
+ "name": "Nixon Daniel Hutahaean",
+ "profile_image":
"https://avatars.slack-edge.com/2024-10-17/7884697754599_61f6eed6b476ca3aee4d_512.jpg"
+ },
+ {
+ "name": "Brad Howerter",
+ "profile_image":
"https://secure.gravatar.com/avatar/7b8608bfadec4140f88c736b0210f481.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0009-512.png"
+ },
+ {
+ "name": "kris",
+ "profile_image":
"https://secure.gravatar.com/avatar/1bf4d4a7c79824be35d0e3bd319c9f76.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0019-512.png"
+ },
+ {
+ "name": "Yuriy",
+ "profile_image":
"https://secure.gravatar.com/avatar/6862d222fd715e3846df3fa3dc783dbb.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0021-512.png"
+ },
+ {
+ "name": "John Huang",
+ "profile_image":
"https://secure.gravatar.com/avatar/5129dccaaeb548023b7f119eaacee1ef.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0010-512.png"
+ },
+ {
+ "name": "kalo",
+ "profile_image":
"https://secure.gravatar.com/avatar/3697c0a59c688b73911c8301fdf949f4.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-512.png"
+ },
+ {
+ "name": "Himanshu Pandey",
+ "profile_image":
"https://secure.gravatar.com/avatar/a9ecad82f6d530ff0cdca5d18ccd7f8d.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0004-512.png"
+ },
+ {
+ "name": "Abhi",
+ "profile_image":
"https://secure.gravatar.com/avatar/74b2cef4a56cb73d2c6e7ddb476efb9f.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0018-512.png"
+ }
+]
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]