tools/polaroid.py 批量套 Instax/Polaroid 边框并加中文题字(几何取自真机规格,
题字支持中文数字、超长自动缩字、手写抖动、做旧效果)
tools/upload_to_gallery.sh 把成片上传到相册服务器(暂存区校验后才入库、默认不覆盖、
mtime 按 EXIF 拍摄时间设置)
124 lines
4.9 KiB
Bash
Executable File
124 lines
4.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# 把处理好的成片上传到相册服务器。
|
||
#
|
||
# 设计原则:先在服务器暂存区校验通过,才动相册目录;同名文件默认不覆盖。
|
||
# 用法:
|
||
# bash tools/upload_to_gallery.sh # 传 photos/polaroid 到 /home/gallery/photos
|
||
# bash tools/upload_to_gallery.sh --dry-run # 只校验本地清单并打印计划,不联网
|
||
# bash tools/upload_to_gallery.sh --dest /home/gallery/photos/polaroid # 传到子目录,绝不覆盖原图
|
||
# bash tools/upload_to_gallery.sh --overwrite # 明确允许覆盖同名文件
|
||
#
|
||
# 上传完还需要在相册后台 Settings -> Scan All 触发扫描才会出现在界面里。
|
||
|
||
set -euo pipefail
|
||
|
||
SRC="photos/polaroid"
|
||
HOST="tx-ubuntu"
|
||
DEST="/home/gallery/photos"
|
||
MANIFEST="_sha256.txt"
|
||
OVERWRITE=0
|
||
DRY_RUN=0
|
||
OWNER="gallery:gallery"
|
||
|
||
while [ $# -gt 0 ]; do
|
||
case "$1" in
|
||
--src) SRC="$2"; shift 2 ;;
|
||
--host) HOST="$2"; shift 2 ;;
|
||
--dest) DEST="$2"; shift 2 ;;
|
||
--owner) OWNER="$2"; shift 2 ;;
|
||
--overwrite) OVERWRITE=1; shift ;;
|
||
--dry-run) DRY_RUN=1; shift ;;
|
||
-h|--help) sed -n '2,15p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||
*) echo "未知参数:$1" >&2; exit 2 ;;
|
||
esac
|
||
done
|
||
|
||
cd "$SRC"
|
||
count=$(ls -1 *.jpg 2>/dev/null | wc -l | tr -d ' ')
|
||
[ "$count" -gt 0 ] || { echo "在 $SRC 里没找到 .jpg" >&2; exit 1; }
|
||
|
||
echo "== 1/6 本地校验($count 个文件)=="
|
||
if [ -f "$MANIFEST" ]; then
|
||
sha256sum -c "$MANIFEST"
|
||
else
|
||
echo "没有 $MANIFEST,现场生成一份"
|
||
sha256sum *.jpg | tee "$MANIFEST"
|
||
fi
|
||
|
||
echo
|
||
echo "== 2/6 计划 =="
|
||
echo " 源目录 $(pwd)"
|
||
echo " 目标 $HOST:$DEST"
|
||
echo " 同名处理 $( [ "$OVERWRITE" = 1 ] && echo '允许覆盖' || echo '不覆盖(发现同名就中止)' )"
|
||
if [ "$DRY_RUN" = 1 ]; then
|
||
echo
|
||
echo "(--dry-run,到此为止,没有联网)"
|
||
exit 0
|
||
fi
|
||
|
||
echo "== 3/6 连通性 =="
|
||
if ! ssh -o BatchMode=yes -o ConnectTimeout=8 "$HOST" true 2>/dev/null; then
|
||
{
|
||
echo "连不上 $HOST 的 SSH。依次排查:"
|
||
echo " 1) 当前网络是否封了出站 22 端口(酒店/办公网/部分运营商常见)。验证:"
|
||
echo " ssh -o ConnectTimeout=8 git@github.com # 也超时就说明是本机网络封了 22"
|
||
echo " 换手机热点或别的网络再跑。"
|
||
echo " 2) ~/.ssh/config 里有没有这个别名,或用 --host user@ip。"
|
||
echo " 3) 服务器是否在线:curl -sI https://gallery.fukun.net | head -1"
|
||
} >&2
|
||
exit 4
|
||
fi
|
||
|
||
stage="/tmp/pv-photos-$(date +%Y%m%d-%H%M%S)"
|
||
|
||
echo
|
||
echo "== 4/6 上传到暂存区 $stage =="
|
||
ssh "$HOST" "mkdir -p '$stage'"
|
||
if command -v rsync >/dev/null 2>&1; then
|
||
rsync -av --partial ./*.jpg "$MANIFEST" "$HOST:$stage/"
|
||
else
|
||
scp ./*.jpg "$MANIFEST" "$HOST:$stage/"
|
||
fi
|
||
|
||
echo
|
||
echo "== 5/6 服务器侧校验 =="
|
||
ssh "$HOST" "cd '$stage' && sha256sum -c '$MANIFEST'"
|
||
|
||
echo
|
||
echo "== 6/6 入库 =="
|
||
clash=$(ssh "$HOST" "cd '$stage' && for f in *.jpg; do [ -e '$DEST'/\$f ] && echo \"\$f\"; done" || true)
|
||
if [ -n "$clash" ]; then
|
||
echo "以下文件在 $DEST 里已存在:"
|
||
echo "$clash" | sed 's/^/ /'
|
||
if [ "$OVERWRITE" != 1 ]; then
|
||
echo
|
||
echo "已中止,服务器暂存区保留在 $stage(可以改 --dest 传到子目录重来)。" >&2
|
||
echo "确认要覆盖原图时加 --overwrite。" >&2
|
||
exit 3
|
||
fi
|
||
echo "(--overwrite 已开启,继续覆盖)"
|
||
fi
|
||
# 顺序很讲究,三步都不能换:
|
||
# 1) 先改暂存区(真实目录)属主。不能对 $DEST 做 chown -R:/home/gallery/photos 是指向
|
||
# /data/gallery-photos 的软链接,chown -R 默认不跟随,会「退出码 0 但什么都没做」。
|
||
# 2) 再把文件 mtime 设成 EXIF 拍摄时间。Photoview 建 media 记录时用 mtime 初始化
|
||
# date_shot,而它的 EXIF 任务有 bug(先存库后赋值 + 已关联即提前返回)不会纠正,
|
||
# 所以 mtime 就是相册里最终显示和排序的日期。
|
||
# 3) 最后用 root 的 mv 移入相册(保留属主和 mtime)。
|
||
ssh "$HOST" "sudo chown -R '$OWNER' '$stage'"
|
||
ssh "$HOST" "for f in '$stage'/*.jpg; do sudo -u '${OWNER%%:*}' exiftool -q '-FileModifyDate<DateTimeOriginal' \"\$f\" 2>/dev/null || true; done"
|
||
echo "暂存区文件的 mtime(应等于拍摄时间):"
|
||
ssh "$HOST" "ls -l --time-style=+%Y-%m-%d_%H:%M '$stage'/*.jpg | awk '{print \" \" \$6, \$7}' | head -5"
|
||
ssh "$HOST" "sudo mv '$stage'/*.jpg '$DEST'/"
|
||
owners=$(ssh "$HOST" "ls -l '$DEST'/*.jpg | awk '{print \$3\":\"\$4}' | sort | uniq -c")
|
||
echo "目标目录属主统计(应为 $OWNER):"
|
||
echo "$owners" | sed 's/^/ /'
|
||
if echo "$owners" | grep -qv "$OWNER"; then
|
||
echo "注意:上面有不属于 $OWNER 的文件,检查一下(可能是旧文件或权限漂移)。" >&2
|
||
fi
|
||
ssh "$HOST" "rm -rf '$stage'"
|
||
|
||
echo
|
||
echo "完成。还差一步:相册后台 Settings -> Scan All 触发扫描,才会出现在界面里。"
|
||
echo "公开原图地址形如 https://cdn.fukun.net/gallery/photos/<文件名>"
|