2019年7月 Google 更新政策,Google Photos 与 Google Drive 不会双向同步,之前通过 Google Drive,使用 rclone 备份 Google Photos 这个方法就失效了。在博友那里看到了新工具:gphotos-sync · GitHub
折腾一圈,发现 gphotos-sync 无法直接保存照片到使用 rclone 挂载的 OneDrive 上(2019.10.14,后记,博友 @NSFW 缓解了这个问题,加--db-path参数,把数据库文件保存在本地即可运行2分钟左右)。放弃……
安装 Python 3
gphotos-sync 需要 Python 3,CentOS 自带 Python 2,得安装,方法参考:CentOS 7 编译安装 Python 3.7.4
嫌麻烦的话还是一键脚本安装吧,比如:Python 3.6一键安装脚本 for CentOS/Debian
#CentOS系统
wget https://www.moerats.com/usr/shell/Python3/CentOS_Python3.6.sh && sh CentOS_Python3.6.sh
#Debian系统
wget https://www.moerats.com/usr/shell/Python3/Debian_Python3.6.sh && sh Debian_Python3.6.sh
安装 gphotos-sync
官网:Google Photos Sync,目前版本 2.9.2。执行下面命令安装即可:
pip3 install gphotos-sync
安装完成,执行 gphotos-sync --help 就能看到帮助信息▼展开
# gphotos-sync --help
usage: gphotos-sync [-h] [--album ALBUM] [--logfile LOGFILE]
[--compare-folder COMPARE_FOLDER] [--favourites-only]
[--flush-index] [--rescan] [--retry-download]
[--skip-video] [--skip-shared-albums]
[--start-date START_DATE] [--end-date END_DATE]
[--log-level LOG_LEVEL] [--db-path DB_PATH]
[--albums-path ALBUMS_PATH] [--photos-path PHOTOS_PATH]
[--use-flat-path] [--new-token] [--index-only]
[--skip-index] [--do-delete] [--skip-files]
[--skip-albums] [--get-locations] [--use-hardlinks]
[--no-album-index]
root_folder
Google Photos download tool
positional arguments:
root_folder root of the local folders to download into
optional arguments:
-h, --help show this help message and exit
--album ALBUM only synchronize the contents of a single album.use
quotes e.g. "album name" for album names with spaces
--logfile LOGFILE full path to debug level logfile, default:
<root>/gphotos.log.If a directory is specified then a
unique filename will begenerated.
--compare-folder COMPARE_FOLDER
root of the local folders to compare to the Photos
Library
--favourites-only only download media marked as favourite (star)
--flush-index delete the index db, re-scan everything
--rescan rescan entire library, ignoring last scan date. Use
this if you have added photos to the library that
predate the last sync, or you have deleted some of the
local files
--retry-download check for the existence of files marked as already
downloaded and re-download any missing ones. Use this
if you have deleted some local files
--skip-video skip video types in sync
--skip-shared-albums skip albums that only appear in 'Sharing'
--start-date START_DATE
Set the earliest date of files to syncformat YYYY-MM-
DD
--end-date END_DATE Set the latest date of files to syncformat YYYY-MM-DD
--log-level LOG_LEVEL
Set log level. Options: critical, error, warning,
info, debug
--db-path DB_PATH Specify a pre-existing folder for the index database.
Defaults to the root of the local download folders
--albums-path ALBUMS_PATH
Specify a folder for the albums Defaults to the
'albums' in the local download folders
--photos-path PHOTOS_PATH
Specify a folder for the photo files. Defaults to the
'photos' in the local download folders
--use-flat-path mandate use of a flat directory structure ('YYYY-MMM')
and not a nested one ('YYYY/MM') .
--new-token Request new token
--index-only Only build the index of files in .gphotos.db - no
downloads
--skip-index Use index from previous run and start download
immediately
--do-delete Remove local copies of files that were deleted. Must
be used with --flush-index since the deleted items
must be removed from the index
--skip-files Dont download files, just refresh the album links (for
testing)
--skip-albums Dont download albums (for testing)
--get-locations Scrape the Google Photos website for location metadata
and add it to the local files' EXIF metadata
--use-hardlinks Use hardlinks instead of symbolic links in albums and
comparison folders
--no-album-index only index the photos library - skip indexing of
folder contents (for testing)
version: 2.9.2, database schema version 5.6
申请 Google Photos 访问 API client id
创建项目
打开 Google Developer Console 控制台,创建一个新项目,如:google-photos-sync
在 google-photos-sync 项目中激活 Photos Library API
进入 API 库,搜索 Google Photos,激活 Photos Library API。
创建 OAuth 同意屏幕
填写应用名称,然后保存即可。(其余信息不用理会)
创建 OAuth 客户端 ID
凭据(Credentials)菜单,创建「OAuth 客户端 ID」(OAuth client ID)凭证。
「应用类型」一定要选择「其他(Other)」,点击创建。
创建完成,点击凭证右侧下载按钮把 json 格式凭证信息下载并重命名为:client_secret.json
client_secret.json 上传到指定路径
这个文件,不同操作系统类型,放置到不同目录:
- Mac OS X:~/Library/Application Support/gphotos-sync/
- Linux:~/.config/gphotos-sync/
- Windows:C:\Users\
\AppData\Local\gphotos-sync\gphotos-sync\
rclone 挂载 OneDrive 到 VPS
如果先备份到大硬盘 VPS,则不需要将 OneDrive 挂载到 VPS,rclone sync 同步到 OneDrive 更稳定。rclone 安装、配置挺简单,可参看旧文:
rclone mount 挂载 OneDrive
可能会报错:
Fatal error: failed to mount FUSE fs: fusermount: exec: "fusermount": executable file not found in $PATH
解决办法:
yum -y install fuse ##Centos
apt-get -y install fuse ##Debian/Ubuntu
挂载命令
/usr/bin/rclone mount OneDrive:GooglePhotos /root/GooglePhotos --allow-other --allow-non-empty --buffer-size 256M --vfs-cache-mode writes --write-back-cache -v &
参考文章:解决Rclone挂载Google Drive时上传失败和内存占用高等问题
卸载磁盘
fusermount -qzu /root/GooglePhotos
开机自动挂载
参考文章:在Debian/Ubuntu上使用rclone挂载Google Drive网盘
代码:▼展开
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
NAME_BIN="rclone"
### BEGIN INIT INFO
# Provides: rclone
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start rclone at boot time
# Description: Enable rclone by daemon.
### END INIT INFO
NAME="OneDrive" #rclone name名
REMOTE="GooglePhotos" #远程文件夹
LOCAL="/root/GooglePhotos" #挂载地址
Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m"
Info="${Green_font_prefix}[信息]${Font_color_suffix}"
Error="${Red_font_prefix}[错误]${Font_color_suffix}"
RETVAL=0
check_running(){
PID="$(ps -C $NAME_BIN -o pid= |head -n1 |grep -o '[0-9]\{1,\}')"
if [[ ! -z ${PID} ]]; then
return 0
else
return 1
fi
}
do_start(){
check_running
if [[ $? -eq 0 ]]; then
echo -e "${Info} $NAME_BIN (PID ${PID}) 正在运行..." && exit 0
else
fusermount -zuq $LOCAL >/dev/null 2>&1
mkdir -p $LOCAL
sudo /usr/bin/rclone mount $NAME:$REMOTE $LOCAL --allow-other --allow-non-empty --buffer-size 256M --vfs-cache-mode writes --write-back-cache -v >/dev/null 2>&1 &
sleep 2s
check_running
if [[ $? -eq 0 ]]; then
echo -e "${Info} $NAME_BIN 启动成功 !"
else
echo -e "${Error} $NAME_BIN 启动失败 !"
fi
fi
}
do_stop(){
check_running
if [[ $? -eq 0 ]]; then
kill -9 ${PID}
RETVAL=$?
if [[ $RETVAL -eq 0 ]]; then
echo -e "${Info} $NAME_BIN 停止成功 !"
else
echo -e "${Error} $NAME_BIN 停止失败 !"
fi
else
echo -e "${Info} $NAME_BIN 未运行"
RETVAL=1
fi
fusermount -zuq $LOCAL >/dev/null 2>&1
}
do_status(){
check_running
if [[ $? -eq 0 ]]; then
echo -e "${Info} $NAME_BIN (PID $(echo ${PID})) 正在运行..."
else
echo -e "${Info} $NAME_BIN 未运行 !"
RETVAL=1
fi
}
do_restart(){
do_stop
do_start
}
case "$1" in
start|stop|restart|status)
do_$1
;;
*)
echo "使用方法: $0 { start | stop | restart | status }"
RETVAL=1
;;
esac
exit $RETVAL
请根据实际修改下面三个参数:
NAME="" #配置 rclone 时输入的 Name REMOTE="" #远程网盘里的文件夹 LOCAL="" #VPS 本地挂载目录
然后保存为 startrclone 文件,上传到 VPS,/root 目录下。
执行下面命令添加开机自启:
mv startrclone /etc/init.d/startrclone
chmod +x /etc/init.d/startrclone
chkconfig --add startrclone
chkconfig startrclone on
update-rc.d -f startrclone defaults #Debian/Ubuntu
bash /etc/init.d/startrclone start
重启一下 VPS,然后 df -h 即可检查有没有自动加载。
启动 gphotos-sync 备份 GooglePhotos 相册
两个方法:一是 gphotos-sync 直接备份到前面挂载到 VPS 上的 OneDrive 目录,优点是几乎不占用 VPS 空间(不需要大硬盘 VPS);二是 gphotos-sync 把 GooglePhotos 相册下载到 VPS 本地,然后 rclone sync 同步到 OneDrive,优点是更稳定,缺点需要大硬盘 VPS。
gphotos-sync 直接备份到挂载到 VPS 上的 OneDrive 目录
/usr/local/bin/gphotos-sync /root/GooglePhotos/ --db-path /root/gpsync --flush-index --use-hardlinks
其中 /root/GooglePhotos/ 是 OneDrive 挂载到 VPS 的目录(保存 Google 照片),/root/gpsync 为数据库保存目录,自己指定一个就行。
首次启动,会提示 Google 账号授权,根据提示信息的网址,复制到浏览器打开后进行授权,把生成的 token 填写到命令窗口即可。
如无意外,gphotos-sync 就开始进行索引、下载、备份照片,以年月的形式来保存照片。第一次同步时间会比较长,数据大,容易出错,最好配合 --skip-index 参数以及 crontab 定时自动运行,否则 Google API 很容易超额(Google API 额度查询)。
比如运行一次:
/usr/local/bin/gphotos-sync /root/GooglePhotosAPI/ --db-path /root/gpsync --flush-index --use-hardlinks --max-retries 12 --max-threads 16
索引完,自动挂掉,然后 crontab 定时根据第一次索引自动重试下载
*/30 * * * * /usr/local/bin/gphotos-sync /root/GooglePhotosAPI/ --db-path /root/gpsync --skip-index --use-hardlinks --max-retries 12 --max-threads 16 >/dev/null 2>&1 &
初次同步完成,可以修改定时任务,自动备份,比如,每天凌晨4点执行备份:
crontab -e
0 4 * * * /usr/local/bin/gphotos-sync /root/GooglePhotos/ --db-path /root/gpsync --flush-index --use-hardlinks --max-retries 12 --max-threads 16 > /dev/null 2>&1 &
亲测,次方法不稳定,一般跑两分钟左右,脚本就会出错([Errno 5] Input/output error、ETag does not match current item’s value 等)挂掉,需要不断重启进程。
gphotos-sync 把 GooglePhotos 相册下载到 VPS 本地,然后 rclone sync 同步到 OneDrive
这方法除了需要大硬盘 VPS,暂时没有其它问题。亲测,BuyVM 大硬盘 VPS,跑了4个多小时,Downloaded 83253 Items, Failed 8……一次跑完 133G……
gphotos-sync 把 GooglePhotos 相册下载到 VPS 本地:
screen -S gphotos-sync
/usr/local/bin/gphotos-sync /mnt/256/ --use-hardlinks --flush-index --max-retries 10 --max-threads 16
/mnt/256/ 为 VPS 本地存放 GooglePhotos 数据目录,容量需要够大。
rclone sync 定时把数据同步到 OneDrive:
crontab -e
11 */1 * * * /usr/bin/rclone sync /mnt/256/ OneDrive:GooglePhotos >/dev/null 2>&1 &
参考资料
Google Photos Sync 项目:gphotos-sync
Logix - How To Backup Google Photos To Your Computer With gphotos-sync(英文)
后记、更新
2019.8.27:Windows 下同步效果不理想,相册一个都没有同步下来,照片也只下载了很少一部分。(估计是 gbk 编码原因)
2019.10.14:博友 @NSFW 解决了 gphotos-sync 无法直接保存照片到使用 rclone 挂载的 OneDrive 这个问题,加 --db-path 参数,把数据库文件保存在本地即可。(效果不大好,没有大盘鸡的话还是直接 rclone 方法稳定点)