Compare commits
10 Commits
7a50a7541a
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63467ce25f | ||
|
|
a65638b1f3 | ||
|
|
816ae727f3 | ||
|
|
296ce3c0e6 | ||
|
|
c41e908ed5 | ||
|
|
a0a120b31e | ||
|
|
7b769b3e1f | ||
|
|
778cae07b9 | ||
|
|
2ca66ed400 | ||
|
|
4d0c65dcef |
14
.build.yml
14
.build.yml
@@ -37,11 +37,19 @@ tasks:
|
|||||||
|
|
||||||
# Start Ruby server for dithering images
|
# Start Ruby server for dithering images
|
||||||
- dither: |
|
- dither: |
|
||||||
true
|
cd bin/dither
|
||||||
|
sudo bundle install
|
||||||
|
ROOT=~/davideisinger.com/content \
|
||||||
|
KEY=~/secret.key \
|
||||||
|
bundle exec rackup -p 4567 -D
|
||||||
|
|
||||||
# Build site
|
# Build site
|
||||||
- hugo: |
|
- hugo: |
|
||||||
./bin/build
|
HUGO_PARAMS_GIT_COMMIT=$(git rev-parse HEAD) \
|
||||||
|
DITHER_SERVER=http://localhost:4567 \
|
||||||
|
hugo --minify
|
||||||
|
find public -name "*.enc" -type f -delete
|
||||||
|
find public/elsewhere -name "*.gmi" -type f -delete
|
||||||
|
|
||||||
# Sync files to production server
|
# Sync files to production server
|
||||||
- deploy: |
|
- deploy: |
|
||||||
@@ -55,7 +63,7 @@ tasks:
|
|||||||
-v \
|
-v \
|
||||||
-r \
|
-r \
|
||||||
--delete \
|
--delete \
|
||||||
public/ \
|
public/* \
|
||||||
www-data@$SERVER_IP:/var/www/davideisinger.com \
|
www-data@$SERVER_IP:/var/www/davideisinger.com \
|
||||||
2>/dev/null
|
2>/dev/null
|
||||||
set -x
|
set -x
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ on:
|
|||||||
env:
|
env:
|
||||||
HUGO_VERSION: 0.160.1
|
HUGO_VERSION: 0.160.1
|
||||||
DEPLOY_DIR: /var/www/davideisinger.com
|
DEPLOY_DIR: /var/www/davideisinger.com
|
||||||
|
DITHER_CACHE_DIR: /workspace-cache/dither
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
@@ -18,6 +19,11 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22
|
||||||
|
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
apt-get update
|
||||||
@@ -33,11 +39,10 @@ jobs:
|
|||||||
printf '%s' "$SECRET_KEY" > secret.key
|
printf '%s' "$SECRET_KEY" > secret.key
|
||||||
|
|
||||||
- name: Verify RSS template diff
|
- name: Verify RSS template diff
|
||||||
run: |
|
run: ./bin/check-rss-template
|
||||||
curl -s https://raw.githubusercontent.com/gohugoio/hugo/refs/tags/v${HUGO_VERSION}/tpl/tplimpl/embedded/templates/rss.xml \
|
|
||||||
| diff - ./themes/v2/layouts/_default/rss.xml \
|
- name: Spellcheck Markdown
|
||||||
| wc -l \
|
run: npx -y cspell "content/**/*.md"
|
||||||
| grep 7
|
|
||||||
|
|
||||||
- name: Build site
|
- name: Build site
|
||||||
run: ./bin/build
|
run: ./bin/build
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
.hugo_build.lock
|
.hugo_build.lock
|
||||||
|
.cache
|
||||||
public
|
public
|
||||||
resources/_gen
|
resources/_gen
|
||||||
secret.key
|
secret.key
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -2,18 +2,6 @@
|
|||||||
|
|
||||||
[1]: https://davideisinger.com
|
[1]: https://davideisinger.com
|
||||||
|
|
||||||
## Deployment
|
|
||||||
|
|
||||||
SourceHut still uses [`.build.yml`](/Users/dce/code/davideisinger.com/.build.yml).
|
|
||||||
|
|
||||||
Gitea uses [`.gitea/workflows/deploy.yaml`](/Users/dce/code/davideisinger.com/.gitea/workflows/deploy.yaml), which mirrors the same build steps and deploys directly into `/var/www/davideisinger.com`.
|
|
||||||
|
|
||||||
For that workflow to succeed, the Gitea runner needs:
|
|
||||||
|
|
||||||
- a `SECRET_KEY` Actions secret containing the contents of `secret.key`
|
|
||||||
- write access to `/var/www/davideisinger.com`
|
|
||||||
- that path mounted into the job environment if the runner is containerized
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
© [CC BY 4.0 License][2]
|
© [CC BY 4.0 License][2]
|
||||||
|
|||||||
@@ -3,10 +3,13 @@ set -euo pipefail
|
|||||||
|
|
||||||
repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||||
dither_dir="${repo_root}/bin/dither"
|
dither_dir="${repo_root}/bin/dither"
|
||||||
|
cache_dir="${DITHER_CACHE_DIR:-${repo_root}/.cache/dither}"
|
||||||
|
|
||||||
|
mkdir -p "${cache_dir}"
|
||||||
|
|
||||||
pushd "${dither_dir}" >/dev/null
|
pushd "${dither_dir}" >/dev/null
|
||||||
bundle install
|
bundle install
|
||||||
ROOT="${repo_root}/content" KEY="${repo_root}/secret.key" bundle exec rackup -p 4567 &
|
ROOT="${repo_root}/content" KEY="${repo_root}/secret.key" DITHER_CACHE_DIR="${cache_dir}" bundle exec rackup -p 4567 &
|
||||||
dither_pid=$!
|
dither_pid=$!
|
||||||
popd >/dev/null
|
popd >/dev/null
|
||||||
|
|
||||||
|
|||||||
29
bin/check-rss-template
Executable file
29
bin/check-rss-template
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||||
|
tmp_dir=$(mktemp -d)
|
||||||
|
trap 'rm -rf "${tmp_dir}"' EXIT
|
||||||
|
|
||||||
|
hugo_version="${HUGO_VERSION:?HUGO_VERSION must be set}"
|
||||||
|
upstream_template="${tmp_dir}/rss.xml"
|
||||||
|
diff_output="${tmp_dir}/rss.diff"
|
||||||
|
|
||||||
|
curl -fsSL "https://raw.githubusercontent.com/gohugoio/hugo/refs/tags/v${hugo_version}/tpl/tplimpl/embedded/templates/rss.xml" \
|
||||||
|
-o "${upstream_template}"
|
||||||
|
|
||||||
|
set +e
|
||||||
|
diff "${upstream_template}" "${repo_root}/themes/v2/layouts/_default/rss.xml" >"${diff_output}"
|
||||||
|
diff_status=$?
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [[ "${diff_status}" -gt 1 ]]; then
|
||||||
|
exit "${diff_status}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
line_count=$(wc -l <"${diff_output}" | tr -d ' ')
|
||||||
|
if [[ "${line_count}" != "7" ]]; then
|
||||||
|
echo "Unexpected RSS template diff line count: ${line_count}" >&2
|
||||||
|
cat "${diff_output}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
require "sinatra"
|
require "sinatra"
|
||||||
require "mini_magick"
|
require "mini_magick"
|
||||||
|
require "digest"
|
||||||
|
require "fileutils"
|
||||||
|
require "tempfile"
|
||||||
|
|
||||||
MiniMagick.logger.level = Logger::DEBUG
|
MiniMagick.logger.level = Logger::DEBUG
|
||||||
|
|
||||||
@@ -7,6 +10,24 @@ ROOT = ENV.fetch("ROOT")
|
|||||||
KEY = ENV.fetch("KEY")
|
KEY = ENV.fetch("KEY")
|
||||||
DITHER = ENV["DITHER"] != "0"
|
DITHER = ENV["DITHER"] != "0"
|
||||||
FORMAT = "png"
|
FORMAT = "png"
|
||||||
|
CACHE_DIR = ENV["DITHER_CACHE_DIR"]
|
||||||
|
|
||||||
|
def cache_path_for(path, geometry)
|
||||||
|
return unless CACHE_DIR
|
||||||
|
|
||||||
|
source_path = "#{ROOT}/#{path}.enc"
|
||||||
|
cache_key = Digest::SHA256.hexdigest([
|
||||||
|
path,
|
||||||
|
Digest::SHA256.file(source_path).hexdigest,
|
||||||
|
geometry,
|
||||||
|
DITHER,
|
||||||
|
FORMAT,
|
||||||
|
1
|
||||||
|
].join("\0"))
|
||||||
|
|
||||||
|
FileUtils.mkdir_p(CACHE_DIR)
|
||||||
|
File.join(CACHE_DIR, "#{cache_key}.#{FORMAT}")
|
||||||
|
end
|
||||||
|
|
||||||
get "/*" do |path|
|
get "/*" do |path|
|
||||||
halt 404, {"Content-Type" => "text/plain"}, "not found" unless File.exist?("#{ROOT}/#{path}.enc")
|
halt 404, {"Content-Type" => "text/plain"}, "not found" unless File.exist?("#{ROOT}/#{path}.enc")
|
||||||
@@ -16,37 +37,63 @@ get "/*" do |path|
|
|||||||
geometry = params["geo"] unless params["geo"] == ""
|
geometry = params["geo"] unless params["geo"] == ""
|
||||||
geometry.gsub!(/\d+/) { |n| n.to_i * 2 } if geometry && !DITHER
|
geometry.gsub!(/\d+/) { |n| n.to_i * 2 } if geometry && !DITHER
|
||||||
|
|
||||||
decrypted = %x(
|
cached_path = cache_path_for(path, geometry)
|
||||||
openssl \
|
if cached_path && File.exist?(cached_path)
|
||||||
aes-256-cbc \
|
return File.binread(cached_path)
|
||||||
-d \
|
end
|
||||||
-in #{ROOT}/#{path}.enc \
|
|
||||||
-pass file:#{KEY} \
|
|
||||||
-iter 1000000
|
|
||||||
)
|
|
||||||
|
|
||||||
convert = MiniMagick::Tool::Convert.new
|
decrypted = Tempfile.new(["dither", File.extname(path)])
|
||||||
convert.stdin
|
decrypted.binmode
|
||||||
convert.background("white")
|
decrypted.close
|
||||||
convert.layers("flatten")
|
|
||||||
convert.strip
|
|
||||||
convert.auto_orient
|
|
||||||
|
|
||||||
if geometry
|
begin
|
||||||
if geometry.match?(/^\d+x\d+$/)
|
openssl_ok = system(
|
||||||
convert.resize "#{geometry}^"
|
"openssl",
|
||||||
convert.gravity "center"
|
"aes-256-cbc",
|
||||||
convert.extent geometry
|
"-d",
|
||||||
else
|
"-in", "#{ROOT}/#{path}.enc",
|
||||||
convert.resize geometry
|
"-out", decrypted.path,
|
||||||
|
"-pass", "file:#{KEY}",
|
||||||
|
"-iter", "1000000"
|
||||||
|
)
|
||||||
|
halt 500, {"Content-Type" => "text/plain"}, "decrypt failed" unless openssl_ok
|
||||||
|
|
||||||
|
convert = MiniMagick::Tool::Convert.new
|
||||||
|
convert.limit("memory", "128MiB")
|
||||||
|
convert.limit("map", "256MiB")
|
||||||
|
convert.limit("disk", "1GiB")
|
||||||
|
convert << decrypted.path
|
||||||
|
convert.background("white")
|
||||||
|
convert.layers("flatten")
|
||||||
|
convert.strip
|
||||||
|
convert.auto_orient
|
||||||
|
|
||||||
|
if geometry
|
||||||
|
if geometry.match?(/^\d+x\d+$/)
|
||||||
|
convert.resize "#{geometry}^"
|
||||||
|
convert.gravity "center"
|
||||||
|
convert.extent geometry
|
||||||
|
else
|
||||||
|
convert.resize geometry
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
if DITHER
|
if DITHER
|
||||||
convert.ordered_dither "o8x8"
|
convert.ordered_dither "o8x8"
|
||||||
convert.monochrome
|
convert.monochrome
|
||||||
end
|
end
|
||||||
|
|
||||||
convert << "#{FORMAT.upcase}:-"
|
convert << "#{FORMAT.upcase}:-"
|
||||||
convert.call(stdin: decrypted)
|
output = convert.call
|
||||||
|
|
||||||
|
if cached_path
|
||||||
|
temp_cache_path = "#{cached_path}.tmp-#{Process.pid}"
|
||||||
|
File.binwrite(temp_cache_path, output)
|
||||||
|
FileUtils.mv(temp_cache_path, cached_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
output
|
||||||
|
ensure
|
||||||
|
decrypted.unlink
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,9 +3,12 @@ set -euo pipefail
|
|||||||
|
|
||||||
repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||||
dither_dir="${repo_root}/bin/dither"
|
dither_dir="${repo_root}/bin/dither"
|
||||||
|
cache_dir="${DITHER_CACHE_DIR:-${repo_root}/.cache/dither}"
|
||||||
|
|
||||||
|
mkdir -p "${cache_dir}"
|
||||||
|
|
||||||
pushd "${dither_dir}" >/dev/null
|
pushd "${dither_dir}" >/dev/null
|
||||||
ROOT="${repo_root}/content" KEY="${repo_root}/secret.key" bundle exec ruby dither.rb &
|
ROOT="${repo_root}/content" KEY="${repo_root}/secret.key" DITHER_CACHE_DIR="${cache_dir}" bundle exec ruby dither.rb &
|
||||||
dither_pid=$!
|
dither_pid=$!
|
||||||
popd >/dev/null
|
popd >/dev/null
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ Finally warming up around here (though we did get hit by the [largest 24-hour te
|
|||||||
{{<dither IMG_0004.jpeg "782x600">}}Face-first into the color chaos.{{</dither>}}
|
{{<dither IMG_0004.jpeg "782x600">}}Face-first into the color chaos.{{</dither>}}
|
||||||
{{<dither IMG_0009.jpeg "782x600">}}Blue faces, red popsicles, and the kind of chaos that means the afternoon went well.{{</dither>}}
|
{{<dither IMG_0009.jpeg "782x600">}}Blue faces, red popsicles, and the kind of chaos that means the afternoon went well.{{</dither>}}
|
||||||
|
|
||||||
Then we drove up to DC, left the kids with my folks, and took the train to Baltimore to catch [my friend's][3] show and spend a little bit of time in the city. We stayed at the [Pendry][4] which was super nice -- we'll be back. Sold the old car while were up there -- 🪦 legend.
|
Then we drove up to DC, left the kids with my folks, and took the train to Baltimore to catch [my friend's][3] show and spend a little bit of time in the city. We stayed at the [Pendry][4] which was super nice. We'll be back. Sold the old car while were up there -- 🪦 legend.
|
||||||
|
|
||||||
[3]: https://www.instagram.com/__carillon/
|
[3]: https://www.instagram.com/__carillon/
|
||||||
[4]: https://www.pendry.com/baltimore/
|
[4]: https://www.pendry.com/baltimore/
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
Rendered {{ now | dateFormat "2006-01-02 15:04:05 MST" }}
|
Rendered {{ now | dateFormat "2006-01-02 15:04:05 MST" }}
|
||||||
{{- with site.Params.git.commit }}
|
{{- with site.Params.git.commit }}
|
||||||
=> https://git.sr.ht/~dce/davideisinger.com/commit/{{ . }} {{ . }}
|
=> https://git.davideisinger.com/dce/davideisinger.com/commit/{{ . }} {{ . }}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
|
|
||||||
=> https://creativecommons.org/licenses/by/4.0/deed.en © CC BY 4.0
|
=> https://creativecommons.org/licenses/by/4.0/deed.en © CC BY 4.0
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<div class="mobile-hidden">
|
<div class="mobile-hidden">
|
||||||
Rendered {{ now | dateFormat "2006-01-02 15:04:05 MST" }}
|
Rendered {{ now | dateFormat "2006-01-02 15:04:05 MST" }}
|
||||||
{{ with site.Params.git.commit }}
|
{{ with site.Params.git.commit }}
|
||||||
• <a href="https://git.sr.ht/~dce/davideisinger.com/commit/{{ . }}">{{ substr . 0 7}}</a>
|
• <a href="https://git.davideisinger.com/dce/davideisinger.com/commit/{{ . }}">{{ substr . 0 7}}</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,11 @@
|
|||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
{{- /* Photo processing */ -}}
|
{{- /* Photo processing */ -}}
|
||||||
|
{{- range findRE `(?s){{<dither[^>]*>}}.*?{{</dither>}}` $content -}}
|
||||||
|
{{- $rendered := $page.RenderString . -}}
|
||||||
|
{{- $url := $rendered | replaceRE `(?s).*src="([^"]+)".*` "=> $1" -}}
|
||||||
|
{{- $content = replace $content . $url -}}
|
||||||
|
{{- end -}}
|
||||||
{{- range findRE `{{<(dither|thumbnail) [^/]+/>}}` $content -}}
|
{{- range findRE `{{<(dither|thumbnail) [^/]+/>}}` $content -}}
|
||||||
{{- $rendered := $page.RenderString . -}}
|
{{- $rendered := $page.RenderString . -}}
|
||||||
{{- $url := $rendered | replaceRE `(?s).*src="([^"]+)".*` "=> $1" -}}
|
{{- $url := $rendered | replaceRE `(?s).*src="([^"]+)".*` "=> $1" -}}
|
||||||
|
|||||||
Reference in New Issue
Block a user