diff options
context:
space:
mode:
Diffstat (limited to 'custom/extensions/email-libravatar.lua')
-rw-r--r--custom/extensions/email-libravatar.lua114
1 file changed, 114 insertions, 0 deletions
diff --git a/custom/extensions/email-libravatar.lua b/custom/extensions/email-libravatar.lua
new file mode 100644
index 0000000..812bef5
--- /dev/null
+++ b/custom/extensions/email-libravatar.lua
@@ -0,0 +1,114 @@
+-- cgit email-filter that shows a Libravatar icon next to author names. Use it
+-- with the email-filter or repo.email-filter setting and the lua: prefix.
+--
+-- email-filter=lua:/path/to/email-libravatar.lua
+--
+-- SUPPORTED LUA
+--
+-- Lua 5.1, 5.2, 5.3, 5.4 and LuaJIT. Lua 5.5 is not supported, because luaossl
+-- has no 5.5 build.
+--
+-- DEPENDENCY
+--
+-- luaossl OpenSSL binding, provides openssl.digest
+-- <https://github.com/wahern/luaossl>
+--
+-- # Debian and Ubuntu
+-- sudo apt install luarocks libssl-dev
+-- sudo luarocks --lua-version 5.1 install luaossl
+--
+-- # Fedora
+-- sudo dnf install luarocks openssl-devel
+-- sudo luarocks --lua-version 5.1 install luaossl
+--
+-- # macOS with Homebrew
+-- brew install luarocks openssl
+-- luarocks install luaossl OPENSSL_DIR="$(brew --prefix openssl)"
+--
+-- PRIVACY
+--
+-- Every page view sends the visitor's IP address and a hash of each
+-- committer's email to a third-party service. Leave this filter off if that is
+-- not acceptable for your instance.
+--
+-- The secure CDN is always used, so the icon loads over https and is never
+-- blocked as mixed content. Addresses are hashed with MD5.
+
+local digest = require("openssl.digest")
+
+--
+-- ===== CONFIGURATION =====
+--
+
+-- Pixel size of the avatar.
+local avatar_size = 13
+
+-- Fallback style for an address with no avatar. See the Libravatar docs for
+-- the choices, for example retro, identicon, monsterid or mm.
+local default_image = "retro"
+
+-- Avatar endpoint. The secure CDN is used so the image loads over https.
+local base_url = "https://seccdn.libravatar.org/avatar/"
+
+-- Text for the image alt attribute.
+local alt_text = "Libravatar"
+
+--
+-- =========================
+--
+
+-- State shared across the open, write and close calls of one invocation.
+local buffer = ""
+local avatar = nil
+
+local function hash_hex(input)
+ local b = digest.new("md5"):final(input)
+ local x = ""
+ for i = 1, #b do
+ x = x .. string.format("%.2x", string.byte(b, i))
+ end
+ return x
+end
+
+-- Take the address, strip the angle brackets if present, then trim and
+-- lowercase as the avatar services expect. Returns nil for a missing or empty
+-- address.
+local function normalize_email(email)
+ if email == nil then
+ return nil
+ end
+ local inner = email:match("<(.*)>")
+ if inner ~= nil then
+ email = inner
+ end
+ email = (email:gsub("^%s*(.-)%s*$", "%1")):lower()
+ if email == "" then
+ return nil
+ end
+ return email
+end
+
+function filter_open(email, page)
+ buffer = ""
+ local addr = normalize_email(email)
+ if addr == nil then
+ avatar = nil
+ else
+ avatar = hash_hex(addr)
+ end
+end
+
+function filter_close()
+ if avatar == nil then
+ -- No usable address, render the name without an icon.
+ html(buffer)
+ else
+ html("<img src='" .. base_url .. avatar .. "?s=" .. avatar_size .. "&amp;d=" .. default_image ..
+ "' width='" .. avatar_size .. "' height='" .. avatar_size .. "' alt='" .. alt_text .. "' /> " .. buffer)
+ end
+ return 0
+end
+
+function filter_write(str)
+ buffer = buffer .. str
+end