add avatar download rb plugin to download images
diff --git a/_src/_includes/themes/apache/partials/_head.html b/_src/_includes/themes/apache/partials/_head.html
index 12ca572..3617b68 100644
--- a/_src/_includes/themes/apache/partials/_head.html
+++ b/_src/_includes/themes/apache/partials/_head.html
@@ -49,9 +49,4 @@
<!-- favicons -->
<link rel="shortcut icon" href="/assets/img/favicon.png">
-
- {% if page.path contains "community" %}
- <!-- allow github profile images, only in community page -->
- <meta http-equiv="Content-Security-Policy" content="img-src 'self' data: blob: https://avatars.githubusercontent.com/;">
- {% endif %}
</head>
\ No newline at end of file
diff --git a/_src/_plugins/avatar_downloader.rb b/_src/_plugins/avatar_downloader.rb
new file mode 100644
index 0000000..5dfe170
--- /dev/null
+++ b/_src/_plugins/avatar_downloader.rb
@@ -0,0 +1,168 @@
+# Avatar Downloader Plugin for Jekyll
+# ==================================
+#
+# This plugin automates the process of downloading GitHub avatar images for
+# contributors listed in the site's data file. It downloads the images during
+# the Jekyll build process and stores them in the assets/img/avatars directory.
+#
+# Process Flow:
+# ------------
+# ```
+# +-----------------+ +------------------+ +-----------------------+
+# | Read contributor| | For each | | Check if avatar exists|
+# | data from |--->| contributor with |--->|or check ETag/Modified |
+# | site.data | | GitHub ID | | headers for changes |
+# +-----------------+ +------------------+ +-----------------------+
+# |
+# v
+# +-----------------+ +------------------+ +-----------------------+
+# | Update site | | Save avatar | | Download avatar only |
+# | configuration |<---| to assets/img/ |<---| if changed or new |
+# | with avatar path| | avatars | | (using HTTP headers) |
+# +-----------------+ +------------------+ +-----------------------+
+# ```
+#
+# Benefits:
+# --------
+# 1. No manual downloading of avatar images required
+# 2. Images stay fresh but are only downloaded when actually changed
+# 3. Images are included in the built site automatically
+# 4. Faster page loads since images are served from the same domain
+#
+# Usage:
+# ------
+# In templates: <img src="/assets/img/avatars/{{ github_username }}.jpg">
+# The plugin automatically runs during Jekyll build process.
+#
+# Configuration:
+# --------------
+# - Requires contributor data with 'githubId' field
+# - Uses HTTP ETag/Last-Modified headers to only download changed images
+
+require 'net/http'
+require 'fileutils'
+require 'digest'
+require 'yaml'
+
+module Jekyll
+ class AvatarDownloader < Generator
+ safe true
+ priority :high
+
+ def generate(site)
+ # Store avatars in the source assets directory so they're included in the build
+ avatar_dir = File.join(site.source, 'assets', 'img', 'avatars')
+ FileUtils.mkdir_p(avatar_dir) unless Dir.exist?(avatar_dir)
+
+ # Create metadata directory for ETag/Last-Modified storage
+ metadata_dir = File.join(site.source, 'assets', 'img', 'avatars', '.metadata')
+ FileUtils.mkdir_p(metadata_dir) unless Dir.exist?(metadata_dir)
+
+ # Load previous metadata if it exists
+ metadata_file = File.join(metadata_dir, 'metadata.yml')
+ avatar_metadata = {}
+ if File.exist?(metadata_file)
+ begin
+ avatar_metadata = YAML.load_file(metadata_file) || {}
+ rescue => e
+ puts "Error loading avatar metadata: #{e.message}"
+ avatar_metadata = {}
+ end
+ end
+
+ # Get contributors from site data
+ contributors = site.data['contributors'] || []
+
+ # Download each avatar
+ contributors.each do |contributor|
+ next unless contributor['githubId']
+
+ github_id = contributor['githubId']
+ avatar_url = "https://avatars.githubusercontent.com/#{github_id}"
+ local_path = File.join(avatar_dir, "#{github_id}.jpg")
+
+ # Get stored ETag and Last-Modified values if they exist
+ user_metadata = avatar_metadata[github_id] || {}
+ stored_etag = user_metadata['etag']
+ stored_last_modified = user_metadata['last_modified']
+
+ download_needed = false
+ headers = {}
+
+ # Add conditional headers if we have previous values
+ if stored_etag
+ headers['If-None-Match'] = stored_etag
+ end
+
+ if stored_last_modified
+ headers['If-Modified-Since'] = stored_last_modified
+ end
+
+ # Check if we need to download: file doesn't exist or we need to check if it's changed
+ if !File.exist?(local_path) || stored_etag || stored_last_modified
+ begin
+ uri = URI(avatar_url)
+
+ # Make a HEAD request first to check headers
+ Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
+ request = Net::HTTP::Head.new(uri, headers)
+ response = http.request(request)
+
+ case response.code
+ when '200'
+ # Resource changed or first download
+ download_needed = true
+ # Store new ETag and Last-Modified for future requests
+ avatar_metadata[github_id] = {
+ 'etag' => response['ETag'],
+ 'last_modified' => response['Last-Modified']
+ }
+ when '304'
+ # Resource not modified
+ puts "Avatar for #{github_id} is up-to-date (HTTP 304)"
+ download_needed = false
+ else
+ puts "Unexpected response for #{github_id}: #{response.code}"
+ download_needed = false
+ end
+ end
+
+ # Only download if needed
+ if download_needed
+ puts "Downloading avatar for #{github_id}..."
+ Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
+ request = Net::HTTP::Get.new(uri)
+ response = http.request(request)
+
+ if response.code == '200'
+ File.open(local_path, 'wb') do |file|
+ file.write(response.body)
+ end
+ puts "Avatar saved for #{github_id}"
+
+ # Update metadata
+ avatar_metadata[github_id] = {
+ 'etag' => response['ETag'],
+ 'last_modified' => response['Last-Modified']
+ }
+ else
+ puts "Failed to download avatar for #{github_id}: #{response.code}"
+ end
+ end
+ end
+ rescue => e
+ puts "Error processing avatar for #{github_id}: #{e.message}"
+ end
+ end
+ end
+
+ # Save metadata for next build
+ File.open(metadata_file, 'w') do |file|
+ file.write(avatar_metadata.to_yaml)
+ end
+
+ # Add site.avatar_path for use in templates
+ site.config['avatar_path'] = '/assets/img/avatars'
+ end
+ end
+end
\ No newline at end of file
diff --git a/_src/assets/img/avatars/.metadata/metadata.yml b/_src/assets/img/avatars/.metadata/metadata.yml
new file mode 100644
index 0000000..214b5bd
--- /dev/null
+++ b/_src/assets/img/avatars/.metadata/metadata.yml
@@ -0,0 +1,100 @@
+---
+ae2015:
+ etag: '"88e86f61b57d6d3109510ffbc34976bc694b34cb5fc661ec14f94ef023ec592b"'
+ last_modified: Sat, 02 May 2015 15:01:36 GMT
+phaniarnab:
+ etag: '"06fceca82aba23e83d6c661b3d09b1d81d918f0d83e66c8caad93c948873081b"'
+ last_modified: Fri, 12 Jul 2024 21:06:09 GMT
+asurve:
+ etag: '"503aeffe134d57975ee975d093338ee2a9268127ccbb9aca5d0b4c06cfa82bc6"'
+ last_modified: Wed, 28 Oct 2015 17:41:20 GMT
+BACtaki:
+ etag: '"cd95e29deefa0ff63c67b6a1247f90c0f5a9ef3899e04ef376154332ef40d86a"'
+ last_modified: Sat, 02 May 2015 15:01:36 GMT
+bertholdreinwald:
+ etag: '"8642d7447dd2b2d365bc4acc72f86e4e7db0b902d7da04d40c86299f482e916b"'
+ last_modified: Sun, 23 Oct 2016 05:37:40 GMT
+ywcb00:
+ etag: '"0405526ff14518ab62d44a56637050ea1592906681464a48911b60bb98f15c22"'
+ last_modified: Sat, 02 May 2015 15:01:36 GMT
+dbtsai:
+ etag: '"09ff9dc128b12ce2afd5c732390bd0bdb9407fd2fdd9a65da1a2d95603811aa9"'
+ last_modified: Tue, 10 Jun 2014 22:42:13 GMT
+deroneriksson:
+ etag: '"70b78cfb1cd7a54c2ca8d23081ab84e6dc45a2c666b54a0f01eb4677cd5e8c28"'
+ last_modified: Wed, 01 Jul 2015 18:42:34 GMT
+fmakari:
+ etag: '"4451d0e84bed47fb139c508e1b5e4a08e051fe45439ae952b67bbdcb87cf0ff2"'
+ last_modified: Fri, 28 Apr 2017 12:15:44 GMT
+fschueler:
+ etag:
+ last_modified: Tue, 24 Sep 2013 14:46:00 GMT
+frreiss:
+ etag: '"1674414a6a0c7949af322ba32f28de49d5002a9ff3d6c9f9bc1b2839e2b16a96"'
+ last_modified: Mon, 24 Jun 2024 20:14:27 GMT
+gweidner:
+ etag: '"cf9f5a2d267c350f1ae7bf681dd20e7354e87ba6fcf7a0ce9f8609432d3bc81e"'
+ last_modified: Wed, 30 Sep 2015 20:39:05 GMT
+EdgarLGB:
+ etag: '"276581349793b598f5535fa6fe150546aeef0e97b805414cf13ce08953a49140"'
+ last_modified: Mon, 13 Nov 2017 14:15:06 GMT
+hsaputra:
+ etag: '"9a3fcfa4a9944c4c377376c84f325c3a5795776a6f07ecf05f908e6ab2833919"'
+ last_modified: Mon, 02 Feb 2015 20:49:52 GMT
+holdenk:
+ etag:
+ last_modified: Tue, 04 Dec 2012 02:21:02 GMT
+j143:
+ etag: '"56d0b022238cbd3a259721f3aa44bbfa40a45ee9e9e81ba279b1cc04867cff0b"'
+ last_modified: Fri, 29 Oct 2021 18:24:34 GMT
+jkbradley:
+ etag: '"3235eed8302c7ffd77fd3f32ec3963d193c9cd1fb227045a05894bd9c45a4e47"'
+ last_modified: Sat, 02 May 2015 15:01:36 GMT
+kev-inn:
+ etag: '"90c32cb4953463f0bb061dce46b4e319c4caf9d8baddb2829d2903da6ce4a4fe"'
+ last_modified: Mon, 21 Nov 2022 14:52:57 GMT
+krishnakalyan3:
+ etag: '"8d66a63baf5ace0ef349fe9f46d0a9341942c7eee1959b1d3591074ecbbf9a2e"'
+ last_modified: Sat, 18 Jun 2022 23:27:02 GMT
+lresende:
+ etag: '"ddb2be794e75e36a7003c98a8ba03e18e5ef909102f7ce9f4a3c4dcb23728f8e"'
+ last_modified: Wed, 09 Dec 2020 04:19:15 GMT
+corepointer:
+ etag: '"dec4d54e940328ea97ca7d39811a8da89ca662b2f9102b95016224563c1c18d3"'
+ last_modified: Mon, 26 Jun 2023 14:33:55 GMT
+mboehm7:
+ etag: '"b9ad82d205557c7a10af2ed4f2bbb2bc4d8e67b4d863c1cc1323cfb93670c343"'
+ last_modified: Sun, 09 Aug 2015 20:58:15 GMT
+dusenberrymw:
+ etag: '"8214346a3edb810790c12d4f4b26ca91300c37a7d40724acecf7d3500fa0960f"'
+ last_modified: Tue, 02 Aug 2016 17:09:50 GMT
+nakul02:
+ etag: '"3a4ee7985ef9fe366e0f3ca4af9d1e2f5bcaf9ebb2b247e1c05f29168fbee4a6"'
+ last_modified: Fri, 08 Jan 2016 02:21:34 GMT
+niketanpansare:
+ etag:
+ last_modified: Sun, 15 Jun 2014 16:05:04 GMT
+OlgaOvcharenko:
+ etag: '"870478e44146c49681f269297b5ec813271a55c836d06e7efb24b722a04b5fd6"'
+ last_modified: Sun, 03 Jan 2021 18:31:42 GMT
+pwendell:
+ etag: '"6ac4d173092d13c36578b3f5e4bed1d461a29113244c19d5e08729597d3a4c2e"'
+ last_modified: Mon, 14 Sep 2015 21:46:02 GMT
+prithvirajsen:
+ etag: '"e588c1ebcfa09f07e218f024425885c49078b44928e735ef577a04586357d0ae"'
+ last_modified: Sat, 02 May 2015 15:01:36 GMT
+rxin:
+ etag: '"3afacc3d9641230c1a0b4a0041e3022ef74c996bab569011d30cbb2e78bad917"'
+ last_modified: Mon, 03 Mar 2025 01:28:38 GMT
+Baunsgaard:
+ etag: '"7f11c27c7e27b0077e5eddfdc9358c1faea74525620d9902299d5d46ae2d5b8c"'
+ last_modified: Sun, 05 Nov 2023 13:18:42 GMT
+shirisht:
+ etag: '"952fbc91eeff8f58bfdb0cd068c82ed323c7bf8c8fdd1ae21848144d1b0fe225"'
+ last_modified: Sat, 02 May 2015 15:01:36 GMT
+Shafaq-Siddiqi:
+ etag: '"3e8f6474b0ddf35f090546871e2a462e39cacf4953ffdae996b916f2684f820b"'
+ last_modified: Sat, 02 May 2015 15:01:36 GMT
+mengxr:
+ etag: '"3024504bf3d26f3e5b0e9b9d7cd094dc23c19d7802aba428c8603e0d8deb526a"'
+ last_modified: Mon, 16 Feb 2015 21:10:39 GMT
diff --git a/_src/assets/img/avatars/BACtaki.jpg b/_src/assets/img/avatars/BACtaki.jpg
new file mode 100644
index 0000000..50ecfaa
--- /dev/null
+++ b/_src/assets/img/avatars/BACtaki.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/Baunsgaard.jpg b/_src/assets/img/avatars/Baunsgaard.jpg
new file mode 100644
index 0000000..006404a
--- /dev/null
+++ b/_src/assets/img/avatars/Baunsgaard.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/EdgarLGB.jpg b/_src/assets/img/avatars/EdgarLGB.jpg
new file mode 100644
index 0000000..2bf4b04
--- /dev/null
+++ b/_src/assets/img/avatars/EdgarLGB.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/OlgaOvcharenko.jpg b/_src/assets/img/avatars/OlgaOvcharenko.jpg
new file mode 100644
index 0000000..151f38b
--- /dev/null
+++ b/_src/assets/img/avatars/OlgaOvcharenko.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/Shafaq-Siddiqi.jpg b/_src/assets/img/avatars/Shafaq-Siddiqi.jpg
new file mode 100644
index 0000000..e8b28b4
--- /dev/null
+++ b/_src/assets/img/avatars/Shafaq-Siddiqi.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/ae2015.jpg b/_src/assets/img/avatars/ae2015.jpg
new file mode 100644
index 0000000..2b35bec
--- /dev/null
+++ b/_src/assets/img/avatars/ae2015.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/asurve.jpg b/_src/assets/img/avatars/asurve.jpg
new file mode 100644
index 0000000..b741747
--- /dev/null
+++ b/_src/assets/img/avatars/asurve.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/bertholdreinwald.jpg b/_src/assets/img/avatars/bertholdreinwald.jpg
new file mode 100644
index 0000000..4682f34
--- /dev/null
+++ b/_src/assets/img/avatars/bertholdreinwald.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/corepointer.jpg b/_src/assets/img/avatars/corepointer.jpg
new file mode 100644
index 0000000..879b7f1
--- /dev/null
+++ b/_src/assets/img/avatars/corepointer.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/dbtsai.jpg b/_src/assets/img/avatars/dbtsai.jpg
new file mode 100644
index 0000000..fd6eed4
--- /dev/null
+++ b/_src/assets/img/avatars/dbtsai.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/deroneriksson.jpg b/_src/assets/img/avatars/deroneriksson.jpg
new file mode 100644
index 0000000..3274a66
--- /dev/null
+++ b/_src/assets/img/avatars/deroneriksson.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/dusenberrymw.jpg b/_src/assets/img/avatars/dusenberrymw.jpg
new file mode 100644
index 0000000..7fe7977
--- /dev/null
+++ b/_src/assets/img/avatars/dusenberrymw.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/fmakari.jpg b/_src/assets/img/avatars/fmakari.jpg
new file mode 100644
index 0000000..b718e0e
--- /dev/null
+++ b/_src/assets/img/avatars/fmakari.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/frreiss.jpg b/_src/assets/img/avatars/frreiss.jpg
new file mode 100644
index 0000000..2d4b49a
--- /dev/null
+++ b/_src/assets/img/avatars/frreiss.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/fschueler.jpg b/_src/assets/img/avatars/fschueler.jpg
new file mode 100644
index 0000000..d2eab7f
--- /dev/null
+++ b/_src/assets/img/avatars/fschueler.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/gweidner.jpg b/_src/assets/img/avatars/gweidner.jpg
new file mode 100644
index 0000000..8b8adb9
--- /dev/null
+++ b/_src/assets/img/avatars/gweidner.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/holdenk.jpg b/_src/assets/img/avatars/holdenk.jpg
new file mode 100644
index 0000000..0310de5
--- /dev/null
+++ b/_src/assets/img/avatars/holdenk.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/hsaputra.jpg b/_src/assets/img/avatars/hsaputra.jpg
new file mode 100644
index 0000000..1a3f70f
--- /dev/null
+++ b/_src/assets/img/avatars/hsaputra.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/j143.jpg b/_src/assets/img/avatars/j143.jpg
new file mode 100644
index 0000000..a2352f2
--- /dev/null
+++ b/_src/assets/img/avatars/j143.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/jkbradley.jpg b/_src/assets/img/avatars/jkbradley.jpg
new file mode 100644
index 0000000..5a61ca9
--- /dev/null
+++ b/_src/assets/img/avatars/jkbradley.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/kev-inn.jpg b/_src/assets/img/avatars/kev-inn.jpg
new file mode 100644
index 0000000..66101bf
--- /dev/null
+++ b/_src/assets/img/avatars/kev-inn.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/krishnakalyan3.jpg b/_src/assets/img/avatars/krishnakalyan3.jpg
new file mode 100644
index 0000000..4a1a14e
--- /dev/null
+++ b/_src/assets/img/avatars/krishnakalyan3.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/lresende.jpg b/_src/assets/img/avatars/lresende.jpg
new file mode 100644
index 0000000..e9d1c56
--- /dev/null
+++ b/_src/assets/img/avatars/lresende.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/mboehm7.jpg b/_src/assets/img/avatars/mboehm7.jpg
new file mode 100644
index 0000000..a31b73d
--- /dev/null
+++ b/_src/assets/img/avatars/mboehm7.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/mengxr.jpg b/_src/assets/img/avatars/mengxr.jpg
new file mode 100644
index 0000000..e274a44
--- /dev/null
+++ b/_src/assets/img/avatars/mengxr.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/nakul02.jpg b/_src/assets/img/avatars/nakul02.jpg
new file mode 100644
index 0000000..1a025e7
--- /dev/null
+++ b/_src/assets/img/avatars/nakul02.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/niketanpansare.jpg b/_src/assets/img/avatars/niketanpansare.jpg
new file mode 100644
index 0000000..890aeb8
--- /dev/null
+++ b/_src/assets/img/avatars/niketanpansare.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/phaniarnab.jpg b/_src/assets/img/avatars/phaniarnab.jpg
new file mode 100644
index 0000000..fb05c9f
--- /dev/null
+++ b/_src/assets/img/avatars/phaniarnab.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/phaniarnab_new.jpg b/_src/assets/img/avatars/phaniarnab_new.jpg
new file mode 100644
index 0000000..fb05c9f
--- /dev/null
+++ b/_src/assets/img/avatars/phaniarnab_new.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/prithvirajsen.jpg b/_src/assets/img/avatars/prithvirajsen.jpg
new file mode 100644
index 0000000..21f68b3
--- /dev/null
+++ b/_src/assets/img/avatars/prithvirajsen.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/pwendell.jpg b/_src/assets/img/avatars/pwendell.jpg
new file mode 100644
index 0000000..4dba9a2
--- /dev/null
+++ b/_src/assets/img/avatars/pwendell.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/rxin.jpg b/_src/assets/img/avatars/rxin.jpg
new file mode 100644
index 0000000..07d415f
--- /dev/null
+++ b/_src/assets/img/avatars/rxin.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/shirisht.jpg b/_src/assets/img/avatars/shirisht.jpg
new file mode 100644
index 0000000..edc9f36
--- /dev/null
+++ b/_src/assets/img/avatars/shirisht.jpg
Binary files differ
diff --git a/_src/assets/img/avatars/ywcb00.jpg b/_src/assets/img/avatars/ywcb00.jpg
new file mode 100644
index 0000000..28d9ce6
--- /dev/null
+++ b/_src/assets/img/avatars/ywcb00.jpg
Binary files differ
diff --git a/_src/community.html b/_src/community.html
index ba7bd6b..3537537 100644
--- a/_src/community.html
+++ b/_src/community.html
@@ -73,7 +73,7 @@
<div class="profile">
<a href="http://github.com/{{ member.githubId }}">
<img class="profile--img"
- src="{% unless c.avatar %}https://avatars.githubusercontent.com/{{ member.githubId }}{% else %}{{ member.avatar }}{% endunless %}">
+ src="{% unless member.avatar %}https://avatars.githubusercontent.com/{{ member.githubId }}{% else %}{{ member.avatar }}{% endunless %}">
</a>
<div class="profile--info">
<a class="profile--name" href="http://github.com/{{ member.githubId }}">{{member.name}}</a>