# TrailSnap documentation for AI agents This file combines the official TrailSnap user guide, deployment guide, agent guide, and core developer documentation. Updated: 2026-10-23. # AI Agent 文档入口 - Source: https://trailsnap.cn/docs/guide/ai-access.html - Markdown: https://trailsnap.cn/docs/guide/ai-access.md - Category: AI Agent 文档入口 - Language: zh-CN # AI Agent 文档入口 TrailSnap 官网在面向人类的页面之外,还提供了一组面向 AI Agent 的稳定文本入口。Agent 不需要解析页面导航、搜索框或渲染后的 HTML,可以直接读取纯文本文档。 ## 推荐入口 | 入口 | 地址 | 用途 | | --- | --- | --- | | 文档索引 | [/llms.txt](/llms.txt) | 按分类查看全部文档,链接直接指向 Markdown 原文 | | 全量文档 | [/llms-full.txt](/llms-full.txt) | 一次性读取用户指南、部署指南、Agent 指南和核心开发文档 | | 结构化索引 | [/ai-docs.json](/ai-docs.json) | 程序化读取标题、描述、分类、语言、HTML 与 Markdown 地址 | | CLI 安装提示 | [/install.md](https://trailsnap.cn/install.md) | 面向 Agent 的 `trailsnap-cli` 安装与配置流程 | | 站点地图 | [/sitemap.xml](/sitemap.xml) | 发现官网所有可索引页面 | ## Markdown 原文规则 官网教程会同时输出 HTML 与 Markdown 两种格式: - 人类阅读页面:`/docs/guide/install.html` - AI 阅读原文:`/docs/guide/install.md` - 目录页:`/docs/guide/agent/` 与 `/docs/guide/agent/index.md` - 英文文档:`/en/docs/guide/install.html` 与 `/en/docs/guide/install.md` 因此,Agent 可以把文档 URL 中的 `.html` 替换为 `.md`,直接读取原始 Markdown。 ## 推荐读取顺序 1. 先读取 [/llms.txt](/llms.txt),确定需要哪篇文档。 2. 单个主题只读取对应 `.md` 文件,减少上下文占用。 3. 需要完整背景时读取 [/llms-full.txt](/llms-full.txt)。 4. 需要程序化处理文档列表时读取 [/ai-docs.json](/ai-docs.json)。 5. 安装或调用 TrailSnap CLI 时读取 [/install.md](https://trailsnap.cn/install.md),并参考 [TrailSnap CLI 工具](/docs/guide/agent/trailsnap-cli.md)。 ## Agent 使用建议 - **先读索引,再按需读全文**:`llms.txt` 能帮助 Agent 快速定位教程,避免把官网首页和导航噪音带入上下文。 - **优先读取 Markdown 原文**:Markdown 没有页面脚本和渲染噪音,链接结构也更接近源文件。 - **保持语言一致**:中文用户优先使用中文文档;英文用户使用 `/en/docs/...` 下的对应文档。 - **注意区分人类流程与 Agent 流程**:涉及浏览器登录、Token 创建或照片目录授权时,应提示用户手动完成,不要代替用户猜测凭据。 - **CLI 操作先确认配置**:执行 `trailsnap` 命令前,先确认 API URL 与 Token 已通过 `trailsnap config set` 配置。 --- # AI Agent Documentation Access - Source: https://trailsnap.cn/en/docs/guide/ai-access.html - Markdown: https://trailsnap.cn/en/docs/guide/ai-access.md - Category: AI Agent access - Language: en # AI Agent Documentation Access Besides the human-oriented website, TrailSnap publishes stable text entry points for AI agents. Agents can read plain-text documentation without parsing navigation, search UI, or rendered HTML. ## Recommended entry points | Entry point | URL | Use it for | | --- | --- | --- | | Documentation index | [/llms.txt](/llms.txt) | Browse all docs by category; links point to Markdown source | | Full documentation | [/llms-full.txt](/llms-full.txt) | Read the user guide, deployment guide, agent guide, and core developer docs in one file | | Structured index | [/ai-docs.json](/ai-docs.json) | Programmatically read titles, descriptions, categories, languages, HTML URLs, and Markdown URLs | | CLI installation prompt | [/install.md](https://trailsnap.cn/install.md) | Agent-oriented installation and configuration flow for `trailsnap-cli` | | Sitemap | [/sitemap.xml](/sitemap.xml) | Discover all indexable website pages | ## Markdown mirror rule Every selected documentation page is published in both HTML and Markdown: - Human page: `/en/docs/guide/install.html` - AI-friendly source: `/en/docs/guide/install.md` - Directory page: `/en/docs/guide/agent/` and `/en/docs/guide/agent/index.md` - Chinese documentation: `/docs/guide/install.html` and `/docs/guide/install.md` An agent can therefore replace `.html` with `.md` in a documentation URL and read the original Markdown directly. ## Recommended reading order 1. Read [/llms.txt](/llms.txt) first to identify the relevant document. 2. For a single topic, read only its `.md` file to preserve context. 3. Read [/llms-full.txt](/llms-full.txt) when broader background is required. 4. Read [/ai-docs.json](/ai-docs.json) when processing the documentation list programmatically. 5. To install or call TrailSnap CLI, read [/install.md](https://trailsnap.cn/install.md) and the [TrailSnap CLI guide](/en/docs/guide/agent/trailsnap-cli.md). ## Guidance for agents - **Read the index first, then the needed document.** `llms.txt` avoids homepage and navigation noise. - **Prefer Markdown source.** Markdown has no page scripts or rendering noise and preserves source structure. - **Keep language consistent.** Use Chinese docs for Chinese users and `/en/docs/...` for English users. - **Separate human-only steps.** Ask users to complete browser login, token creation, or photo-directory authorization manually; never guess credentials. - **Verify CLI configuration.** Before running `trailsnap`, confirm the API URL and token with `trailsnap config set`. --- # 桌面版内置 AI - Source: https://trailsnap.cn/docs/guide/desktop-ai-extension.html - Markdown: https://trailsnap.cn/docs/guide/desktop-ai-extension.md - Category: 安装部署 - Language: zh-CN # 桌面版内置 AI 行影集桌面安装包已包含人脸、OCR、票据识别、分类、语义检索和本地大模型所需的 AI 程序,无需另行安装扩展或配置本地服务地址。 1. 安装并打开行影集。 2. 在“设置 → AI 模型管理”查看所需模型。模型按需下载,下载完成后相关任务自动继续。 3. 在“关于行影集”统一检查和安装应用更新。已下载模型和照片保留。 AI 程序首次使用时自动启动,空闲后释放资源。本地大模型所需推理依赖也由应用自动准备;首次使用需要联网,体积较大的模型需要等待下载。 旧版本用户直接升级完整应用即可,已有模型继续使用。无需先卸载旧 AI 扩展,也无需重新导入扩展压缩包。 Docker 独立部署继续使用其原有服务和地址配置。 --- # 安装指南 - Source: https://trailsnap.cn/docs/guide/install.html - Markdown: https://trailsnap.cn/docs/guide/install.md - Category: 安装部署 - Language: zh-CN # 安装 TrailSnap TrailSnap 同时提供桌面安装包和 Docker 自托管部署。先根据使用场景选择版本: | 方式 | 适合场景 | 支持平台 | AI 能力 | | --- | --- | --- | --- | | 桌面版 | 单台个人电脑、希望快速开始 | Windows、macOS、Linux | 已内置 AI 运行环境,模型按需下载 | | Docker | NAS、家庭服务器、多设备访问 | 支持 Docker Compose 的设备 | AI 服务随 Compose 部署,可选 CPU/GPU/OpenVINO | ::: tip 不确定怎么选? 只在当前电脑使用,选择桌面版;需要手机、平板和多台电脑通过局域网访问同一图库,选择 Docker。 ::: ## 桌面版 前往[下载页面](/download),官网会优先标出当前系统的安装包: - Windows 10/11(x64):下载 `.exe` 并按向导安装。 - macOS(Apple Silicon):下载 `.dmg`,将 TrailSnap 拖入“应用程序”。首次打开若被系统拦截,请在“隐私与安全性”中确认允许。 - Linux(x64):Debian/Ubuntu 建议下载 `.deb`;其他发行版可使用 `.AppImage`,并为文件添加执行权限。 桌面安装包已包含 AI 运行环境,安装和更新统一完成。人脸识别、OCR、图片分类、语义检索和本地大模型的模型文件按需下载,参见 [内置 AI 使用说明](/docs/guide/desktop-ai-extension)。 安装完成后: 1. 启动 TrailSnap。 2. 在设置中添加照片目录。 3. 先用少量照片完成一次扫描,确认目录权限与运行状态。 4. 在“AI 模型管理”查看所需模型并创建分析任务。 ::: warning 数据安全 桌面版不会替代你的照片备份。首次使用批量整理、重命名或清理功能前,请先备份图库。 ::: ## Docker 部署 Docker 适合 NAS 和常驻服务器,会同时运行前端、后端、PostgreSQL 与 AI 服务。开始前请先完成[部署前检查](/docs/guide/preflight)。 ### 一键安装脚本 Windows PowerShell: ```powershell irm https://trailsnap.cn/install.ps1 -OutFile install.ps1 powershell -ExecutionPolicy Bypass -File .\install.ps1 ``` Linux / macOS / WSL2: ```bash curl -fsSL https://trailsnap.cn/install.sh | bash ``` 脚本会收集照片目录、一个 TrailSnap 访问端口、时区和 AI 模式,生成 `.env` 与 `docker-compose.yml`,拉取镜像并完成健康检查。AI 模式支持通用 CPU、NVIDIA GPU(CUDA)和适合 Intel CPU/核显/NPU 的 OpenVINO。默认地址为 `http://<服务器 IP>:3180`,网页、App 和 CLI 都使用这个地址。 常用管理命令(在安装目录执行): ```bash docker compose --env-file .env ps docker compose --env-file .env logs -f docker compose --env-file .env restart docker compose --env-file .env down ``` Android App 的“自动查找 TrailSnap”会直接探测宿主机发布的默认 `3180` 入口,普通 Docker bridge 部署无需额外配置。Linux 服务器还可以选择启用宿主机 mDNS 广播: ```bash docker compose --env-file .env --profile lan-discovery up -d ``` 该 profile 仅增强 mDNS,不影响网页和 App 正常连接。Docker Desktop、手机热点、访客 Wi-Fi 或启用了 AP 隔离的网络仍建议使用“设置 → 连接手机 App”中的二维码。 升级和卸载: ```bash ./install.sh --upgrade ./install.sh --uninstall # 保留数据 ./install.sh --uninstall --purge # 删除数据,谨慎使用 ``` PowerShell 脚本使用对应的 `-Upgrade`、`-Uninstall` 参数;运行 `Get-Help .\install.ps1 -Detailed` 可查看完整参数。 ### 切换 AI 加速模式 再次运行安装脚本时,已有安装菜单会显示当前模式。选择“切换 AI 模式”后,可以在 CPU、GPU 和 OpenVINO 之间切换;数据库、模型缓存和照片目录不会被删除。 也可以直接通过命令切换并升级 AI 镜像: ::: code-group ```powershell [Windows PowerShell] # NVIDIA GPU / CUDA .\install.ps1 -Upgrade -AiMode gpu # 通用 CPU .\install.ps1 -Upgrade -AiMode cpu # Intel OpenVINO .\install.ps1 -Upgrade -AiMode openvino ``` ```bash [Linux / macOS / WSL2] # NVIDIA GPU / CUDA ./install.sh --upgrade --ai-mode gpu # 通用 CPU ./install.sh --upgrade --ai-mode cpu # Intel OpenVINO ./install.sh --upgrade --ai-mode openvino ``` ::: GPU 模式要求 NVIDIA 驱动和 NVIDIA Container Toolkit 可用,安装器会在切换前检查环境。服务启动后,安装器还会自动进入 AI 容器验收推理后端:GPU 模式必须检测到 `CUDAExecutionProvider`,OpenVINO 模式必须检测到 `OpenVINOExecutionProvider`。验收失败不会删除数据或中止其他服务,脚本会显示诊断命令和本教程地址。 也可以手动验证 ONNX Runtime: ```bash docker compose --env-file .env exec ai python -c "import onnxruntime as ort; print(ort.get_device()); print(ort.get_available_providers())" ``` GPU 模式的输出应包含 `GPU` 和 `CUDAExecutionProvider`;只有 `AzureExecutionProvider` 与 `CPUExecutionProvider` 表示当前仍是 CPU 运行时。OpenVINO 模式应包含 `OpenVINOExecutionProvider`。 ### 手动部署与 NAS 教程 - [Docker 通用部署与 GPU 配置](/docs/guide/docker/) - [Windows Docker 部署](/docs/guide/docker/windows) - [绿联 NAS](/docs/guide/docker/ugreen) - [极空间](/docs/guide/docker/zspace) - [飞牛 OS](/docs/guide/docker/fnos) ## 下一步 - [添加外部图库](/docs/guide/settings/directories) - [内置 AI 使用说明](/docs/guide/desktop-ai-extension) - [AI 大模型连接配置](/docs/guide/settings/aisetting) - [数据、隐私与备份](/docs/guide/data-safety) - [开始使用](/docs/guide/user) --- # 移动 App 使用指南 - Source: https://trailsnap.cn/docs/guide/mobile-app.html - Markdown: https://trailsnap.cn/docs/guide/mobile-app.md - Category: 安装部署 - Language: zh-CN # 移动 App 使用指南 TrailSnap App 是 Web 版的移动端原生容器,使用 Capacitor 构建。它不会提供公共云端服务, 而是连接你自己部署的 TrailSnap。因此,在安装 App 前需要先完成 [TrailSnap 服务部署](/docs/guide/install)。 ::: warning 预览版本 移动 App 目前优先适配登录、相册浏览、搜索、设置等基础功能。部分原生能力仍在开发中, 建议保留浏览器访问方式作为备用。 ::: ## Android 安装 如果已经部署并打开 TrailSnap,也可以在电脑网页进入 **设置 → 连接手机 App**。页面会显示当前版本的 APK 直接下载地址和下载二维码,用手机相机扫码即可下载;安装完成后,再用 App 扫描同一页面中的服务器连接二维码。 1. 打开项目的 [GitHub Releases](https://github.com/LC044/TrailSnap/releases)。 2. 找到所需的正式版本(标签格式为 `v*.*.*`,例如 `v0.9.1`)。 3. 在 **Assets** 中下载 APK。早期测试包的文件名可能带有 `debug`。 4. 在手机上打开 APK,并按系统提示允许浏览器或文件管理器“安装未知应用”。 5. 安装完成后打开 TrailSnap。 请只从 TrailSnap 官方 GitHub 仓库下载;如果 Release 页面提供了 SHA-256 校验值,请在安装前进行核对。 如果 Android 显示 Play Protect 提示,请先确认下载来源和校验值,不要从第三方网盘安装来源不明的包。 ## 首次连接服务器 App 首次启动会打开“连接 TrailSnap”页面。这里填写的地址与浏览器访问地址完全相同,不需要添加 `/api`: ```text http://192.168.1.10:3180 ``` 其中: - `192.168.1.10` 替换为部署 TrailSnap 的电脑或 NAS 的局域网 IP; - `3180` 是一键安装脚本默认的 TrailSnap 访问端口; - 不要填写 `localhost` 或 `127.0.0.1`,它们在手机上指向手机自身; - 不要在地址末尾添加 `/api`。 点击“测试并保存”。连接成功后,App 会保存该地址并跳转到登录页面。账号、照片和相册数据仍保存在你的 TrailSnap 服务器上。 还可以使用以下免输入方式: - 在电脑浏览器中打开 TrailSnap,进入“设置 → 连接手机 App”,然后用 App 的“扫描二维码”扫描电脑网页上的二维码; - 点击“自动查找 TrailSnap”。App 会先使用 DNS-SD/mDNS,再自动探测当前局域网中使用默认访问地址的 Docker 部署; - 在手机上打开 `trailsnap://connect?url=...` 连接深链。 二维码应显示在电脑网页上,再由手机 App 扫描;手机连接页不会为自己生成二维码。如果电脑网页使用的是 `localhost` 或 `127.0.0.1`,请在“连接手机 App”页面改成电脑的局域网 IP。 自动查找不再只依赖组播:mDNS 没有结果时,Android App 会通过 TCP 查找当前私有网段中使用默认 `3180` 入口的 TrailSnap,因此普通 Docker bridge 部署也可以被找到。自定义了访问端口、使用 iPhone/iPad,或者热点、访客 Wi-Fi、AP 隔离禁止设备互访时,请改用二维码或手动输入。 ### 连接前检查 让手机与服务器连接到同一局域网,然后用手机浏览器访问: ```text http://192.168.1.10:3180/api/health-check ``` 如果无法打开,请检查: - TrailSnap 的 `frontend` 与 `server` 容器是否正常运行; - Docker 是否将统一访问端口映射为 `3180:80`; - 服务器防火墙是否允许手机访问 TCP `3180`; - Wi-Fi 是否启用了 AP 隔离或访客网络隔离; - 地址中的 IP 和端口是否正确。 局域网内可以使用 HTTP。通过公网访问时,请配置域名和有效的 HTTPS 证书,避免账号、令牌和照片请求通过明文网络传输。 ## 更换服务器 进入: ```text 设置 → 关于 → 更改服务器 ``` 输入新地址并点击“测试并保存”。切换服务器后,App 会清除当前登录状态,需要使用新服务器上的账号重新登录;服务器端的照片和配置不会因此被删除。 ## Android 返回操作 Android 的实体返回键或返回手势遵循以下顺序: 1. 当前有弹窗时关闭弹窗; 2. 当前有上一页时返回上一页; 3. 已在首页或没有可返回页面时,将 App 切换到后台,而不是直接结束 App。 ## 更新 App Android App 会自行检查更新:启动数秒后向所连接的 TrailSnap 服务器查询最新版本,发现新版时弹出更新提示,展示更新内容并提供“立即更新”。点击后 App 会直接下载官方安装包,显示下载进度,完成后自动打开系统安装界面,确认即可覆盖安装。 - 首次更新时 Android 会要求允许 TrailSnap“安装未知应用”。App 会引导跳转到该授权页,授权后回到 App 再点一次“安装”。 - 下载过程中可以点击“取消下载”;也可以点击“跳过此版本”,该版本不再自动提醒(仍可手动检查)。 - 自动检查每天最多提醒一次。需要立即检查时,进入 **设置 → 关于 → 检查更新**。 - 安装包会先下载到 App 缓存目录,安装完成或下次更新时自动清理。 - 更新检查依赖服务器能访问外网版本清单。服务器处于纯内网时,App 无法获取新版本信息,请按下面的手动方式更新。 也可以手动更新:从 GitHub Releases 下载新版本 APK,并直接安装覆盖旧版本。覆盖更新要求: - 应用 ID 相同; - 新旧 APK 使用同一发布密钥签名; - 新版本号高于已安装版本。 正常覆盖安装会保留服务器地址和登录信息。如果系统提示“签名不一致”,不要直接卸载:先确认 APK 是否来自官方 Release。卸载 App 会清除手机端保存的服务器地址和登录令牌,但不会删除服务器上的照片和数据库。 ## iPhone 和 iPad iOS 原生工程已经接入,但公开 IPA 仍需要 Apple 开发者签名。目前推荐使用 PWA: 1. 用 Safari 打开 TrailSnap Web 地址,例如 `http://192.168.1.10:3180`; 2. 点击 Safari 的“分享”按钮; 3. 选择“添加到主屏幕”; 4. 从主屏幕打开 TrailSnap。 PWA、Android App、iOS App 和浏览器都使用同一个 TrailSnap 地址。 ## 隐私和安全 - App 连接的是用户指定的服务器,项目维护者不会因为使用 App 而自动获得你的照片或账号数据; - 服务器运营者仍需自行保护数据库、照片目录、备份和访问凭证; - 公网访问务必优先使用 HTTPS,并设置强密码; - 只对外开放 TrailSnap 统一访问端口,不要暴露 Server、AI 或数据库内部端口; - 安装包、服务器和 Web 前端应尽量使用同一版本,以避免接口不兼容。 --- # 概览 - Source: https://trailsnap.cn/docs/guide/overview.html - Markdown: https://trailsnap.cn/docs/guide/overview.md - Category: 安装部署 - Language: zh-CN ::: info 前言 TrailSnap 是一个智能化的 **AI 相册**应用,致力于帮助用户轻松记录、整理和回顾自己的出行经历。通过强大的 AI 处理能力,让每一张照片和每一段旅程都成为值得珍藏的记忆。 未来每个人(至少每个家庭)都有一个属于自己的 AI 数据中心,而相册是数据中心的一个重要数据来源,它留存了你生活中的很多瞬间,而 AI 相册则是将这些瞬间转化为有价值的记忆,它可以帮你默默地记录下相册里的车票、景点门票,可以帮你记录旅行中的所见所闻,可以帮你自动整理出可以发朋友圈的照片(甚至帮你准备好文案),可以帮你剪一段15s的短视频······。 ::: ## 特色功能 - **AI助手**(支持与Agent进行对话,智能检索相册内容,AI比你更懂相册) - **SKILL**(支持在不同AI平台使用TrailSnap CLI,如Claude Code、OpenClaw、Hermes Agent等) 直接通过自然语言让`龙虾`查询相册: > "帮我使用 trailsnap-cli skill,查一下最近在西安拍的照片有哪些?" > "我去年国庆节去了哪些地方,帮我写一个HTML格式的旅游日记。" - **内置 AI 连接**(开箱即用的多模态模型,无需额外配置;也支持本地 LLM 托管,数据不出本机) - **足迹相册**(支持查看自己在不同时间点的足迹,将不同地点串联成线) - **票据管理**(自动识别照片中票据信息,如火车票、飞机票等) - **那年今日**(AI推荐往年今天最具回忆价值的照片) ![alt text](/images/wechat_longscreenshot_2026-04-27_224237_662.jpg) ## ✨ 主要功能 ### 🖼️ 普通相册 - 传统的相册功能,支持上传、管理、查看照片 - 丝滑的时间轴滚动效果 - 支持iPhone、vivo、小米、OPPO等手机的**live photo** ![](https://blog.siyuan.ink/static/img/7f3995c1fa22ded5a26506194a516da4.timeline.webp) ### 🤖 智能相册 - OCR识别、人脸识别、智能场景分类 - 智能搜索(支持搜索图片中的文字、人脸、分类、画面内容) - 条件相册(支持按时间、地点、人物、分类、画面内容等条件自动生成相册) - 那年今日(电子画廊,AI推荐往年今天最具回忆的照片) ![](https://blog.siyuan.ink/static/img/943063875ecd4ff82543e0ae3a21a4a4.AI-narrative.webp) ![](https://blog.siyuan.ink/static/img/d20dabc7c273d8f8d763f6251f1ec03e.AI-analyize.webp) ### 🗺️ 足迹相册 - 在地图上查看照片 - 记录点亮的城市(支持省、市、区县) - 显示去过的5A级景区(支持添加自定义景区或地点) ![](https://blog.siyuan.ink/static/img/38bd45b7c69fe79457e74109dbba8683.map.webp) ### 🎫 票据管理 - 自动识别照片中票据信息(如火车票、飞机票等) - 支持添加、管理、查看旅行票据 - 支持查看、导出纸质仿真火车票(支持导出为png格式,可选红票和蓝票两种样式) ### 📊 [年度报告](https://siyuan.ink/annual-report) - 照片墙、照片日历、去过的城市、走过最远的城市及拍摄的照片、春夏秋冬不同的照片、年度最佳照片等 ![](https://blog.siyuan.ink/static/img/720c50509ca349f40b1e8038371b7bcf.年度报告.webp) ### 🔧 工具箱 - 照片批量转移(将照片批量移动或复制到指定目录) - 照片自动整理(按时间、人物自动归类,支持平铺或递归目录结构) - 修改照片元数据(根据文件名修改拍摄时间) - 批量重命名照片 - 清理重复、相似照片 - AI大模型识别并清理低质量、无意义的照片 ![](/images/toolbox.webp) ## 🛠️ 待开发功能 - AI功能增强 - 接入AI大模型,实现更智能的图片分类、搜索和推荐功能 - 自动生成旅行日志(支持根据照片自动生成旅行记录,包括行程、住宿、美食、人物、美景等) - 将相册作为本地数据库进行智能对话 - 今年国庆节去了哪些地方 - 整理一下周末的照片,帮我准备一个朋友圈九宫格图片和文案 - 图片编辑(支持裁剪、旋转、添加文字、添加标签等) --- # 部署前检查 - Source: https://trailsnap.cn/docs/guide/preflight.html - Markdown: https://trailsnap.cn/docs/guide/preflight.md - Category: 安装部署 - Language: zh-CN # 部署前检查 在运行安装脚本前,用这一页确认环境和预期。这样可以避免“容器启动了,但照片无法扫描或手机无法访问”的常见问题。 ## 你需要准备什么 | 项目 | 最低要求 | 建议 | | --- | --- | --- | | 系统 | Windows、macOS、Linux 或支持 Docker 的 NAS | 64 位 x86 或 ARM 系统,保持系统与 Docker 为受支持版本 | | Docker | Docker Engine / Desktop 与 Docker Compose | 先运行 `docker compose version` 确认可用 | | 存储 | 能容纳原始照片、缩略图和数据库 | 预留额外空间,并为备份准备独立位置 | | 网络 | 服务器可被浏览器访问 | 手机使用时,手机与服务器处于同一局域网或配置 HTTPS 公网访问 | | AI | CPU 可运行基础流程 | 大图库或本地模型建议使用更充足的内存和 GPU;GPU 不是安装前提 | ## 照片目录检查 - 使用一个真实存在的绝对路径,不要填写临时盘、网络断开的映射盘或容器内路径。 - 确认 Docker 有读取该目录的权限;如果需要上传、整理或重命名,也需要相应写入权限。 - 第一次导入前先备份照片。批量整理、重命名和清理功能会影响文件,建议先在小目录试用。 - 首次扫描时间取决于照片数量、文件大小、硬盘速度和是否启用 AI;扫描可在后台进行,不代表网页不可用。 ## 网络与端口检查 - 一键安装只对外开放一个 TrailSnap 访问端口;网页、App 和 CLI 使用相同地址,以安装完成后的终端输出为准。 - Android/iOS App 可以扫描连接二维码、发现同一局域网中的服务,或手动填写该地址;不要填写 `localhost`。 - 如果局域网访问失败,先检查 Docker 端口映射、防火墙和 Wi-Fi 的 AP / 访客网络隔离。 ## 开始前的选择 1. **只想试用**:先选择一个少量照片的测试目录,使用 CPU 模式部署。 2. **导入家庭图库**:先完成照片和数据库备份,再在空闲时间开始首次扫描。 3. **使用公网或移动端**:先规划域名与 HTTPS,只开放 TrailSnap 统一入口,不要把 Server、AI 或数据库内部端口暴露到公网。 4. **使用外部 AI 服务或 Agent**:先阅读[数据、隐私与备份](/docs/guide/data-safety),为 Token 设定最小权限。 确认无误后,继续阅读[安装指南](/docs/guide/install)。 --- # Built-in desktop AI - Source: https://trailsnap.cn/en/docs/guide/desktop-ai-extension.html - Markdown: https://trailsnap.cn/en/docs/guide/desktop-ai-extension.md - Category: Installation - Language: en # Built-in desktop AI The desktop installer includes the AI runtime for faces, OCR, tickets, classification, semantic search and local language models. No separate extension installation or local service address is required. 1. Install and open TrailSnap. 2. Open Settings → AI Models to view model downloads. Models are downloaded as needed; waiting tasks resume when ready. 3. Update the complete application from About TrailSnap. Downloaded models and photos are preserved. AI starts on demand and exits when idle. Local language model inference dependencies are prepared automatically. Initial model preparation requires an internet connection. Existing users can upgrade directly. Keep existing models; there is no need to uninstall or import an AI extension. Independently deployed Docker services retain their existing configuration. --- # Installation - Source: https://trailsnap.cn/en/docs/guide/install.html - Markdown: https://trailsnap.cn/en/docs/guide/install.md - Category: Installation - Language: en # Install TrailSnap TrailSnap is available as a desktop app and as a self-hosted Docker stack. | Option | Best for | Platforms | AI features | | --- | --- | --- | --- | | Desktop | One personal computer and the quickest setup | Windows, macOS, Linux | AI runtime included; models downloaded as needed | | Docker | NAS, home server, and access from multiple devices | Any Docker Compose host | AI service is deployed with the stack; CPU, GPU, and OpenVINO modes are available | ::: tip Which should I choose? Choose the desktop app for use on the current computer. Choose Docker when phones, tablets, and computers need to access one shared library over your LAN. ::: ## Desktop app Open the [download page](/en/download) and choose the installer for your system: - Windows 10/11 (x64): download and run the `.exe` installer. - macOS (Apple Silicon): download the `.dmg` and drag TrailSnap into Applications. If macOS blocks the first launch, allow it under Privacy & Security. - Linux (x64): use `.deb` on Debian/Ubuntu, or make the `.AppImage` executable on other distributions. The desktop installer includes AI and updates it with the application. Models for faces, OCR, classification, semantic search and local LLMs are downloaded as needed. See the [built-in desktop AI guide](/en/docs/guide/desktop-ai-extension). After installation: 1. Start TrailSnap. 2. Add a photo directory in Settings. 3. Scan a small folder first to verify permissions and runtime behavior. 4. Check the required models in AI Models and start an analysis task. ## Docker deployment Docker runs the frontend, backend, PostgreSQL, and AI service together. Complete the [preflight checklist](/en/docs/guide/preflight) first. Windows PowerShell: ```powershell irm https://trailsnap.cn/install.ps1 -OutFile install.ps1 powershell -ExecutionPolicy Bypass -File .\install.ps1 ``` Linux / macOS / WSL2: ```bash curl -fsSL https://trailsnap.cn/install.sh | bash ``` The installer collects the photo path, one TrailSnap access port, time zone, and AI mode; generates `.env` and `docker-compose.yml`; pulls the images; and runs health checks. Available modes are generic CPU, NVIDIA GPU (CUDA), and OpenVINO for Intel CPUs, integrated graphics, and NPUs. Browsers, apps, and the CLI all use `http://:3180` by default. Common commands from the installation directory: ```bash docker compose --env-file .env ps docker compose --env-file .env logs -f docker compose --env-file .env restart docker compose --env-file .env down ``` ### Switch the AI acceleration mode Run the installer again to see the current mode and select **Switch AI mode** from the existing-installation menu. Switching preserves the database, model cache, and photo-directory mounts. You can also switch the AI image directly from the command line: ::: code-group ```powershell [Windows PowerShell] # NVIDIA GPU / CUDA .\install.ps1 -Upgrade -AiMode gpu # Generic CPU .\install.ps1 -Upgrade -AiMode cpu # Intel OpenVINO .\install.ps1 -Upgrade -AiMode openvino ``` ```bash [Linux / macOS / WSL2] # NVIDIA GPU / CUDA ./install.sh --upgrade --ai-mode gpu # Generic CPU ./install.sh --upgrade --ai-mode cpu # Intel OpenVINO ./install.sh --upgrade --ai-mode openvino ``` ::: GPU mode requires a working NVIDIA driver and NVIDIA Container Toolkit. The installer checks them before switching. After the service starts, the installer also verifies the runtime inside the AI container: GPU mode must expose `CUDAExecutionProvider`, while OpenVINO mode must expose `OpenVINOExecutionProvider`. A failed verification does not remove data or stop the other services; the installer prints diagnostic commands and a link to this guide. You can also verify ONNX Runtime manually: ```bash docker compose --env-file .env exec ai python -c "import onnxruntime as ort; print(ort.get_device()); print(ort.get_available_providers())" ``` GPU mode should report `GPU` and include `CUDAExecutionProvider`. If only `AzureExecutionProvider` and `CPUExecutionProvider` are shown, the container is still using the CPU runtime. OpenVINO mode should include `OpenVINOExecutionProvider`. For manual configuration, GPU setup, and NAS-specific steps, see the [Docker deployment guide](/en/docs/guide/docker/). ## Next steps - [Built-in desktop AI](/en/docs/guide/desktop-ai-extension) - [AI model connections](/en/docs/guide/settings/aisetting) - [Data, privacy, and backups](/en/docs/guide/data-safety) - [User manual](/en/docs/guide/user) --- # Mobile App Guide - Source: https://trailsnap.cn/en/docs/guide/mobile-app.html - Markdown: https://trailsnap.cn/en/docs/guide/mobile-app.md - Category: Installation - Language: en # Mobile App Guide The TrailSnap app is a Capacitor-based native container for the web application. It does not connect to a public TrailSnap cloud service. Instead, it connects to the TrailSnap backend that you deploy and control. Complete the [server installation](/en/docs/guide/install) before installing the app. ::: warning Preview version The mobile app currently focuses on essential features such as sign-in, album browsing, search, and settings. Some native integrations are still under development, so keeping browser access available is recommended. ::: ## Install on Android If TrailSnap is already deployed, open **Settings → Connect Mobile App** in the desktop browser. The page shows the current APK download link and a download QR code. Scan it with the phone camera to install the App, then use the App to scan the separate server connection QR code on the same page. 1. Open the project's [GitHub Releases](https://github.com/LC044/TrailSnap/releases). 2. Find the required stable release (tags use the `v*.*.*` format, for example `v0.9.1`). 3. Download the APK from **Assets**. Early test packages may include `debug` in the file name. 4. Open the APK and allow your browser or file manager to install unknown apps when Android asks. 5. Open TrailSnap after installation. Only download packages from the official TrailSnap GitHub repository. If a SHA-256 checksum is published on the Release page, compare it before installation. If Play Protect displays a warning, verify the source and any published checksum before continuing. ## Connect to Your Server On first launch, enter the same TrailSnap address that you use in a browser, without `/api`: ```text http://192.168.1.10:3180 ``` - Replace `192.168.1.10` with the LAN IP address of the computer or NAS running TrailSnap. - `3180` is the default unified TrailSnap access port. - Do not use `localhost` or `127.0.0.1`; on a phone, those addresses refer to the phone itself. - Do not append `/api` to the URL. Tap **Test and Save**. After a successful connection, the app stores the address and opens the sign-in page. Accounts, photos, and albums remain on your TrailSnap server. For a QR connection, open TrailSnap in a desktop browser, go to **Settings → Connect Mobile App**, and scan the QR code shown on the computer with the app. The phone connection page does not generate a QR code for itself. If the desktop page uses `localhost` or `127.0.0.1`, replace it with the computer's LAN address on the **Connect Mobile App** page. You can also tap **Find TrailSnap Automatically** or open a `trailsnap://connect?url=...` deep link. Automatic discovery tries DNS-SD/mDNS first. If it returns no result, the Android App uses TCP to look for TrailSnap on the current private subnet at the default `3180` entry point, which works with ordinary Docker bridge deployments. Use QR scanning or manual entry for custom ports, iPhone/iPad, or networks where hotspots, guest Wi-Fi, or AP isolation prevent devices from talking. ### Connection Checklist Connect the phone and server to the same LAN, then open this URL in the phone's browser: ```text http://192.168.1.10:3180/api/health-check ``` If it does not open, check that: - the TrailSnap `frontend` and `server` containers are running; - Docker maps the unified access port as `3180:80`; - the server firewall allows inbound TCP traffic on port `3180`; - Wi-Fi client/AP isolation is disabled; - the IP address and port are correct. HTTP can be used on a trusted LAN. For access over the public internet, configure a domain and a valid HTTPS certificate to protect credentials, tokens, and photo requests in transit. ## Change Servers Open: ```text Settings → About → Change Server ``` Enter the new address and tap **Test and Save**. Switching servers clears the current sign-in state, so you must sign in with an account on the new server. It does not delete photos or settings stored on either server. ## Android Back Navigation The Android hardware button or back gesture behaves in this order: 1. close the current dialog; 2. return to the previous page when available; 3. move TrailSnap to the background at the root page instead of terminating the app. ## Update the App The Android app checks for updates on its own: a few seconds after launch it asks the connected TrailSnap server for the latest version. When a newer version exists, the app shows an update prompt with the release notes and an **Update now** action. Tapping it downloads the official package, shows download progress, and opens the system installer so you can confirm the in-place update. - The first update requires Android's "install unknown apps" permission. The app opens that settings page for you; grant it, return to the app, and tap **Install** again. - You can cancel an in-flight download, or choose **Skip this version** to stop automatic reminders for it (manual checks still work). - Automatic checks prompt at most once a day. To check immediately, go to **Settings → About → Check for updates**. - The package is downloaded into the app cache directory and cleaned up after installation or on the next update. - Update checks require the server to reach the public version manifest. On a fully isolated network the app cannot discover new versions, so use the manual path below. You can also update manually: download the newer APK from GitHub Releases and install it over the existing version. An in-place update requires the same application ID and signing key, plus a newer version number. A normal update keeps the saved server address and sign-in state. If Android reports a signature mismatch, do not uninstall immediately; first verify that the APK came from the official Release. Uninstalling clears the server address and token stored on the phone, but it does not delete server-side photos or databases. ## iPhone and iPad The native iOS project is available, but a public IPA still requires Apple developer signing. For now, use TrailSnap as a PWA: 1. Open the TrailSnap web URL in Safari, for example `http://192.168.1.10:3180`. 2. Tap Safari's **Share** button. 3. Select **Add to Home Screen**. 4. Open TrailSnap from the Home Screen. The PWA, native apps, browser, and CLI all use the same TrailSnap address. ## Privacy and Security - The app connects to the server selected by the user; using the app does not automatically give project maintainers access to photos or account data. - The server operator remains responsible for protecting the database, photo directories, backups, and credentials. - Prefer HTTPS and strong passwords for public internet access. - Expose only the unified TrailSnap entry point; keep Server, AI, and database ports private. - Keep the app, server, and web frontend on compatible versions to avoid API incompatibilities. --- # Overview 🚀 - Source: https://trailsnap.cn/en/docs/guide/overview.html - Markdown: https://trailsnap.cn/en/docs/guide/overview.md - Category: Installation - Language: en # Overview 🚀 TrailSnap is an intelligent **AI photo album** app. It helps you record, organize, and review your travel experiences, turning photos into memories worth cherishing. In the future, every family will have its own AI data center. Your photo album is one of the most important data sources: it keeps the moments of your life, and AI can turn them into searchable, structured, and shareable memories. ## Highlights - **AI Assistant**: chat with your album and search by natural language. - **Built-in AI**: out-of-the-box multimodal model with no extra setup; also supports local LLM hosting for full data privacy. - **Sidebar Navigation**: collapsible sidebar with global search for quick access. - **Theme Customization**: 5 brand colors (Sky, Emerald, Violet, Rose, Amber) that apply globally with one click. - **Footprints**: connect places into a travel trail on the map. - **On This Day**: AI recommends the most memorable photos from past years. ## ✨ Main Features ### 🖼️ Standard Album - Upload, manage, and browse photos and videos - Smooth timeline browsing experience - Supports **Live Photos** (iPhone, vivo, Xiaomi, OPPO, etc.) ![](https://blog.siyuan.ink/static/img/7f3995c1fa22ded5a26506194a516da4.timeline.webp) ### 🤖 Smart Album - OCR, face recognition, smart scene classification - Smart search (text, faces, tags, and semantic content) - Smart/conditional albums generated by time, location, people, categories, and content - On This Day (AI-curated memories) ![](https://blog.siyuan.ink/static/img/943063875ecd4ff82543e0ae3a21a4a4.AI-narrative.webp) ![](https://blog.siyuan.ink/static/img/d20dabc7c273d8f8d763f6251f1ec03e.AI-analyize.webp) ### 🗺️ Footprint Album - View photos on the map - Track lit-up cities (province/city/district) - Show visited 5A scenic spots (supports custom scenic spots/locations) ![](https://blog.siyuan.ink/static/img/38bd45b7c69fe79457e74109dbba8683.map.webp) ### 🎫 Ticket Management - Automatically recognize ticket information (train/flight/scenic spot tickets, etc.) - Add, manage, and browse tickets - Export simulated paper-style train tickets (PNG, red/blue styles) ### 📊 [Annual Report](https://siyuan.ink/annual-report) - Photo wall, photo calendar, visited cities, farthest trip, seasonal photos, best photos of the year, etc. ![](https://blog.siyuan.ink/static/img/720c50509ca349f40b1e8038371b7bcf.年度报告.webp) ### 🔧 Toolbox - Batch photo transfer (move/copy to specified directories) - Auto-organize photos by time or person (flat or recursive directory structure) - Modify photo metadata (set capture time from filename) - Batch rename photos - Clean duplicate/similar photos - Use AI to identify and clean low-quality photos ## 🛠️ Planned Features - AI enhancements - Better classification, search, and recommendations - Auto-generated travel journals (itinerary, hotels, food, people, scenery) - Chat with your album as a local database ## 🔗 Next Steps - Want to see it in action: [Feature Demo](/en/docs/guide/demo) - Want to learn daily usage: [User Guide](/en/docs/guide/user) - Want technical details: [Developer Guide](/en/docs/dev/guide) --- # Pre-deployment checklist - Source: https://trailsnap.cn/en/docs/guide/preflight.html - Markdown: https://trailsnap.cn/en/docs/guide/preflight.md - Category: Installation - Language: en # Pre-deployment checklist Use this page before running the installer. It helps avoid the common case where containers start successfully but photos cannot be scanned or a phone cannot reach the server. ## What you need | Item | Minimum | Recommended | | --- | --- | --- | | System | Windows, macOS, Linux, or a Docker-capable NAS | A supported 64-bit x86 or ARM system with current Docker | | Docker | Docker Engine / Desktop and Docker Compose | Confirm with `docker compose version` first | | Storage | Space for original photos, thumbnails, and the database | Reserve headroom and a separate backup destination | | Network | A browser can reach the server | Use the same LAN for phones, or configure HTTPS public access | | AI | CPU is enough for the basic flow | Larger libraries or local models benefit from more memory and a GPU; a GPU is not required to install | ## Check your photo directory - Use an existing absolute host path, not a temporary drive, disconnected network mapping, or a container path. - Ensure Docker can read the directory. Upload, organize, rename, and cleanup features also require appropriate write access. - Back up photos before the first import. Test file-changing tools on a small directory first. - Initial scanning time depends on photo count, file sizes, disk speed, and enabled AI. It runs in the background and does not mean the web app is unavailable. ## Network and ports - The installer exposes one TrailSnap address; browsers, native apps, and the CLI all use it. - The app can scan a connection QR code, discover a service on the same LAN, or accept the address manually. Do not use `localhost` from another device. - If LAN access fails, inspect Docker port mapping, the firewall, and Wi-Fi AP / guest-network isolation. ## Choose your starting path 1. **Trying TrailSnap**: deploy in CPU mode with a small test folder. 2. **Importing a family library**: back up the photos and database, then run the first scan during an idle period. 3. **Using mobile or public access**: plan a domain and HTTPS first; keep Server, AI, and database ports private. 4. **Using third-party AI or an Agent**: read [Data, privacy, and backups](/en/docs/guide/data-safety) and grant tokens the minimum scope. When ready, continue to the [installation guide](/en/docs/guide/install). --- # 飞牛OS(fnOS)部署 - Source: https://trailsnap.cn/docs/guide/docker/fnos.html - Markdown: https://trailsnap.cn/docs/guide/docker/fnos.md - Category: Docker 部署 - Language: zh-CN # 飞牛OS(fnOS)部署 本教程用于在飞牛OS(fnOS)上通过 Docker Compose 部署 TrailSnap。不同版本界面可能略有差异,但关键点一致:应用数据持久化、照片目录挂载、端口规划与权限校验。 建议先阅读通用章节:[/docs/guide/docker/](/docs/guide/docker/) --- # Docker 部署(通用) - Source: https://trailsnap.cn/docs/guide/docker/ - Markdown: https://trailsnap.cn/docs/guide/docker/index.md - Category: Docker 部署 - Language: zh-CN # Docker 部署(通用) 本章面向 NAS/家庭服务器场景:用 Docker Compose 一次性启动 TrailSnap 的前端、后端、数据库与 AI 服务,并把你的照片目录挂载进来。 ## 一键安装脚本 Windows PowerShell: ```powershell irm https://trailsnap.cn/install.ps1 -OutFile install.ps1 powershell -ExecutionPolicy Bypass -File .\install.ps1 ``` Linux / macOS / WSL2: ```bash curl -fsSL https://trailsnap.cn/install.sh | bash ``` 脚本会收集照片目录、一个 TrailSnap 访问端口、时区和 CPU/GPU 模式,生成 `.env` 与 `docker-compose.yml`,拉取镜像并完成健康检查。默认访问地址为 `http://<服务器 IP>:3180`。网页、App 和 CLI 都使用这个地址。 常用管理命令(在安装目录执行): ```bash docker compose --env-file .env ps docker compose --env-file .env logs -f docker compose --env-file .env restart docker compose --env-file .env down ``` 升级和卸载: ```bash ./install.sh --upgrade ./install.sh --uninstall # 保留数据 ./install.sh --uninstall --purge # 删除数据,谨慎使用 ``` PowerShell 脚本使用对应的 `-Upgrade`、`-Uninstall` 参数;运行 `Get-Help .\install.ps1 -Detailed` 可查看完整参数。 ## 手动部署 ### 1. 目录规划 在 NAS 上先准备一个空白文件夹作为 TrailSnap 的项目目录,例如:`/docker/trailsnap`。 ### 2. Docker Compose 在上面的目录下新建一个docker-compose.yaml文档,写入以下内容: 下面的 compose 与安装指南保持一致,你只需要修改两处: - `server.volumes` 里照片目录的宿主机路径 - 如有端口冲突,修改 `frontend.ports` 中唯一的访问端口 ```yaml version: '3.8' services: postgres: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/pgvector:pg18-trixie container_name: postgres_container restart: always environment: POSTGRES_DB: trailsnap POSTGRES_USER: trailsnap POSTGRES_PASSWORD: trailsnap POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=C --lc-ctype=C" PGDATA: /var/lib/postgresql/data/pgdata networks: [ app-network ] volumes: - ./pg_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U trailsnap -d trailsnap -p 5432"] interval: 5s timeout: 5s retries: 5 start_period: 10s server: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-server:latest restart: always expose: [ "8000" ] networks: [ app-network ] volumes: - ./data:/app/data - /path/to/your/photos:/app/Photos environment: - TZ=Asia/Shanghai - DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/trailsnap - RAILWAY_DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/railway - AI_API_URL=http://ai:8001 - TRAILSNAP_ROOT_PATH=/api # 请替换为这台主机的局域网 IP,供 App 自动发现 - TRAILSNAP_PUBLIC_URL=http://192.168.1.10:3180 depends_on: postgres: condition: service_healthy ai: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-ai:latest restart: always stop_grace_period: 15s expose: [ "8001" ] networks: [ app-network ] volumes: - ./data:/app/data environment: - TZ=Asia/Shanghai healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8001/health-check', timeout=3)"] interval: 30s timeout: 5s retries: 3 start_period: 30s frontend: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-frontend:latest restart: always ports: [ "3180:80" ] depends_on: [ server ] networks: [ app-network ] networks: app-network: driver: bridge ``` ### 3. 启动与验证 在 `docker-compose.yml` 所在目录执行: ```bash docker-compose up -d ``` 启动后访问: - TrailSnap:`http://:3180` ## GPU 加速支持 (可选) 如果您拥有 NVIDIA 显卡,可以启用 GPU 加速来提升 AI 处理速度。 ### 前置条件 1. 宿主机已安装 NVIDIA 显卡驱动。 2. 已安装 [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)。 **【Windows 安装步骤】**(其他系统请自行搜索教程): **步骤 1**:打开 WSL 2 的 Linux 终端 在 Windows 开始菜单中找到你安装的 Linux 发行版(比如 Ubuntu),打开其终端(不是 Windows 的 PowerShell)。 **步骤 2**:在 WSL 2 中安装 nvidia-docker2 以 Ubuntu 为例,执行以下命令: ```bash sudo apt update sudo apt install -y lsb-release curl gpg # 1. 设置NVIDIA软件源 distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list # 2. 更新软件源并安装nvidia-docker2 sudo apt-get update sudo apt-get install -y nvidia-docker2 # 3. 重启Docker服务 sudo systemctl restart docker ``` ### 修改 docker-compose.yml 请对 `ai` 服务进行如下修改: 1. 将镜像标签修改为 `-gpu` 后缀(例如 `latest-gpu`)。 2. 添加 `deploy` 节点以请求 GPU 资源。 ```yaml ai: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-ai:latest-gpu restart: always stop_grace_period: 15s expose: [ "8001" ] networks: [ app-network ] volumes: - ./data:/app/data environment: - TZ=Asia/Shanghai healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8001/health-check', timeout=3)"] interval: 30s timeout: 5s retries: 3 start_period: 30s deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## NAS 场景常见问题 ### 路径怎么写才正确? 在 NAS 上请以“文件夹的真实路径”为准。不同系统的路径显示方式不同,但原则只有一个:确保容器内的 `/app/Photos/` 能看到你的照片文件。 如果有多个文件夹需要挂载,推荐使用下面的格式,/app/Photos子目录下会简化后续的一些操作: ```yaml volumes: - ./data:/app/data - /你的照片文件夹真实路径1:/app/Photos/旅行 - /你的照片文件夹真实路径2:/app/Photos/航拍 - /你的照片文件夹真实路径3:/app/Photos/家庭 ``` ### 权限不足导致扫描不到照片 如果照片目录是只读共享或权限隔离,容器可能无法读取。建议: - 给容器运行账号授予该共享文件夹的读取权限 - 或把照片目录挂载为只读并确保宿主机侧权限允许读取 ### 端口冲突 NAS 上常见 80/443/8080 等端口容易被占用。TrailSnap 默认只开放 3180;如冲突可修改唯一的映射,例如: ```yaml ports: [ "13180:80" ] ``` ## NAS 具体教程 - [绿联 NAS 部署](/docs/guide/docker/ugreen) - [极空间部署](/docs/guide/docker/zspace) - [飞牛OS 部署](/docs/guide/docker/fnos) --- # 绿联 NAS(UGREEN)部署 - Source: https://trailsnap.cn/docs/guide/docker/ugreen.html - Markdown: https://trailsnap.cn/docs/guide/docker/ugreen.md - Category: Docker 部署 - Language: zh-CN # 绿联 NAS(UGREEN)部署 ## 使用 Docker Compose 部署容器 在 UGOS Pro 系统上,推荐使用项目 Docker Compose 快速部署容器,适合需同时管理多个容器的场景,这种方法简化了容器的部署与管理工作。以下是使用 Docker Compose 部署 TrailSnap 的详细步骤。 如果你还没部署过,建议先读通用章节:[/docs/guide/docker/](/docs/guide/docker/) ### 1. 进入 Docker 项目界面 在 UGOS Pro 系统中,打开 Docker 应用,点击【项目】 > 【创建】,启动项目创建向导。 项目名称填为 `trailsnap`,其他默认即可。 ![Alt text](/images/ugos.webp) ## 2. 配置 Docker Compose 文件 填入[/docs/guide/docker/](/docs/guide/docker/)中的 Docker Compose 模板。 1. 修改 `server` 服务的照片目录挂载: ```yaml volumes: - ./data:/app/data - /你的照片文件夹真实路径:/app/Photos ``` 绿联的默认照片路径通常为:`/home/用户名/Photos` 如果有多个文件夹需要挂载,推荐使用下面的格式,/app/Photos子目录下会简化后续的一些操作: ```yaml volumes: - ./data:/app/data - /你的照片文件夹真实路径1:/app/Photos/旅行 - /你的照片文件夹真实路径2:/app/Photos/航拍 - /你的照片文件夹真实路径3:/app/Photos/家庭 ``` 如果你希望最大化安全性,可以把照片目录挂载为只读,但这样会导致删除功能和其他一些修改本地文件的工具不可用: ```yaml - /你的照片文件夹真实路径:/app/Photos/:ro ``` ## 3. 设置端口与网络 TrailSnap 默认只开放一个访问端口:`3180`。网页、App 和 CLI 都使用该地址;后端、AI 与数据库端口仅在 Docker 内部使用。 如与 NAS 上其他服务冲突,只需修改 `frontend.ports` 映射(例如改为 13180)。 ## 4. 启动与验证 启动后在浏览器访问: - `http://:3180` ![Alt text](/images/ugos-start.webp) 打开设置->外部图库,填入容器内的照片路径:`/app/Photos`,添加外部图库之后会自动扫描并在后台运行任务(可以在设置->任务管理查看任务详情)。 API 文档位于 `http://:3180/api/docs`。 ## 5. 权限与扫描问题排查 若 TrailSnap 扫描不到照片,通常是权限或路径问题: - 先进入 `server` 容器的终端/控制台,确认 `/app/Photos` 目录下能看到照片文件。 - 确认 NAS 侧共享文件夹权限允许 Docker/容器服务读取。 - 如照片目录在外接存储或特定存储池,确认该存储池对容器可见。 --- # Windows 部署 - Source: https://trailsnap.cn/docs/guide/docker/windows.html - Markdown: https://trailsnap.cn/docs/guide/docker/windows.md - Category: Docker 部署 - Language: zh-CN ### 第一步:安装Docker Desktop Docker Compose已经集成在Docker Desktop中,所以先安装它: 1. 访问Docker官网下载:https://www.docker.com/products/docker-desktop/ 2. 双击下载的安装包,一路点击「Next」(勾选「Use WSL 2 instead of Hyper-V」) 3. 安装完成后,重启一下电脑 4. 启动Docker Desktop(首次启动可能需要几分钟,右下角会显示Docker图标) 5. 如果是第一次使用,启动之后会弹出一个黑框,提示你下载“适用于 Linux 的 Windows 子系统”,根据要求下载即可 6. 配置加速器:打开setting->Docker Engine,写入以下内容: ```json { "builder": { "gc": { "defaultKeepStorage": "20GB", "enabled": true } }, "experimental": false, "registry-mirrors": ["https://docker.1ms.run"] } ``` 点击「Apply & Restart」,重启Docker Desktop。 7. 验证安装:按下`Win + R`,输入`cmd`打开命令提示符,执行: ```bash docker --version docker-compose --version ``` 如果能显示版本号,说明安装成功。 ### 第二步:准备docker-compose.yml文件 1. 新建一个空白文件夹,例如`D:\TrailSnap` 2. 在文件夹中新建一个文件,命名为`docker-compose.yml` 3. 用文本编辑器打开`docker-compose.yml`文件,复制粘贴以下内容: ```yaml version: '3.8' services: postgres: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/pgvector:pg18-trixie container_name: postgres_container restart: always environment: POSTGRES_DB: trailsnap POSTGRES_USER: trailsnap POSTGRES_PASSWORD: trailsnap POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=C --lc-ctype=C" PGDATA: /var/lib/postgresql/data/pgdata networks: [ app-network ] volumes: - ./pg_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U trailsnap -d trailsnap -p 5432"] interval: 5s timeout: 5s retries: 5 start_period: 10s server: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-server:latest restart: always expose: [ "8000" ] networks: [ app-network ] volumes: - ./data:/app/data - ./photos:/app/Photos environment: - DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/trailsnap - RAILWAY_DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/railway - AI_API_URL=http://ai:8001 - TRAILSNAP_ROOT_PATH=/api - TRAILSNAP_PUBLIC_URL=http://192.168.1.10:3180 depends_on: postgres: condition: service_healthy ai: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-ai:latest restart: always stop_grace_period: 15s expose: [ "8001" ] networks: [ app-network ] volumes: - ./data:/app/data environment: - TZ=Asia/Shanghai healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8001/health-check', timeout=3)"] interval: 30s timeout: 5s retries: 3 start_period: 30s frontend: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-frontend:latest restart: always ports: [ "3180:80" ] depends_on: [ server ] networks: [ app-network ] networks: app-network: driver: bridge ``` 修改文件挂载目录: 找到`docker-compose.yml`文件中`server`的`volumes`配置,修改挂载目录`./photos:/app/Photos`为你自己的照片目录。 例如,我的照片目录是`D:\TrailSnap\photos`,则修改为: ```yml server: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-server:latest restart: always expose: [ "8000" ] networks: [ app-network ] volumes: - ./data:/app/data - D:\TrailSnap\photos:/app/Photos environment: - DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/trailsnap - RAILWAY_DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/railway - AI_API_URL=http://ai:8001 depends_on: postgres: condition: service_healthy ``` 如果你有多个照片目录,例如`D:\TrailSnap\photos1`、`D:\TrailSnap\photos2`,则可以在`docker-compose.yml`中添加多个挂载目录: ```yml server: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-server:latest restart: always expose: [ "8000" ] networks: [ app-network ] volumes: - ./data:/app/data - C:\TrailSnap\photos1:/app/Photos/photos1 - D:\TrailSnap\photos2:/app/Photos/photos2 - E:\TrailSnap\photos3:/app/Photos/photos3 ``` 冒号前面是本地目录,冒号后面是TrailSnap用到的目录。 ### 第三步:执行部署命令 1. 打开命令提示符(`Win + R` → `cmd`),切换到`docker-compose.yml`所在的文件夹: ```bash # 示例:如果文件在D盘的TrailSnap文件夹,执行 cd /d D:\TrailSnap ``` 2. 启动服务(核心命令): ```bash docker-compose up -d ``` - `up`:启动配置文件中的所有服务 - `-d`:后台运行(不占用当前命令行窗口) 3. 等待执行完成:Docker会自动下载所需的镜像、创建容器并启动服务、完成之后显示以下内容: ```bash PS C:\ProgramData\TrailSnap> docker-compose up -d time="2026-03-06T17:42:03+08:00" level=warning msg="C:\\ProgramData\\TrailSnap\\docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion" [+] up 51/51 ✔ Image crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-frontend:latest Pulled 38.2ss ✔ Image crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-ai:latest Pulled 155.8s ✔ Image crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/pgvector:pg18-trixie Pulled 76.8ss ✔ Image crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-server:latest Pulled 112.8s ✔ Network trailsnap_app-network Created 0.1s ✔ Container postgres_container Healthy 28.0s ✔ Container trailsnap-ai-1 Created 1.1s ✔ Container trailsnap-server-1 Created 0.1s ✔ Container trailsnap-frontend-1 Created 0.1s ``` ### 第四步:验证部署是否成功 打开浏览器,访问 `http://localhost:3180`,即可看到 TrailSnap。移动 App 与 CLI 也使用同一个地址。 然后点击更多->设置->外部图库,添加`/app/Photos`。 ### 常见问题解决 1. **启动时提示“找不到docker-compose.yml”**:确认命令行当前目录是文件所在目录,或执行`docker-compose -f 完整路径/文件名.yml up -d`。 2. **端口被占用**:查看`docker-compose.yml`中的`ports`配置(比如`8080:80`),修改前面的端口(如`8081:80`),再重新执行`docker-compose up -d`。 --- ### 总结 1. **核心前提**:安装Docker Desktop并验证成功(`docker --version`)。 2. **关键步骤**:将`docker-compose.yml`放在单独文件夹,用`cd`切换到该目录,执行`docker-compose up -d`启动服务。 3. **验证/维护**:用`docker-compose ps`查看状态,`docker-compose logs`排查问题,`docker-compose down`停止并删除容器。 --- # 极空间部署 - Source: https://trailsnap.cn/docs/guide/docker/zspace.html - Markdown: https://trailsnap.cn/docs/guide/docker/zspace.md - Category: Docker 部署 - Language: zh-CN # 极空间部署 本教程基于 TrailSnap 的 Docker Compose 部署方式,适合在极空间设备上部署并长期运行。目标是让 TrailSnap 作为家庭服务稳定运行,同时把照片库挂载到容器中用于扫描与索引。 建议先阅读通用章节:[/docs/guide/docker/](/docs/guide/docker/) --- # Fnos Deployment - Source: https://trailsnap.cn/en/docs/guide/docker/fnos.html - Markdown: https://trailsnap.cn/en/docs/guide/docker/fnos.md - Category: Docker deployment - Language: en # Fnos Deployment This tutorial is for deploying TrailSnap on Fnos via Docker Compose. Interfaces may vary slightly between versions, but the key points are consistent: application data persistence, photo directory mounting, port planning, and permission verification. It is recommended to read the generic chapter first: [/en/docs/guide/docker/](/en/docs/guide/docker/) --- # Docker Deployment (Generic) - Source: https://trailsnap.cn/en/docs/guide/docker/ - Markdown: https://trailsnap.cn/en/docs/guide/docker/index.md - Category: Docker deployment - Language: en # Docker Deployment (Generic) This chapter targets NAS/Home Server scenarios: Start TrailSnap's frontend, backend, database, and AI services at once using Docker Compose, and mount your photo directory. If you haven't read the installation guide, it is recommended to read first: [/en/docs/guide/install](/en/docs/guide/install) ## 1. Directory Planning (Suggested) Prepare a shared folder on the NAS as TrailSnap's "project directory", preferably containing two types of data: - **Application Data**: Database and application runtime data (needs long-term persistence) - **Photo Directory**: Your own photo library (recommended read-only mount) Example structure (for illustration only): ``` trailsnap/ docker-compose.yml data/ pg_data/ ``` ## 2. Docker Compose (Recommended Template) The compose below is consistent with the installation guide, you only need to modify two places: - Host path for photo directory in `server.volumes` - Modify the single `frontend.ports` mapping if there is a port conflict ```yaml version: '3.8' services: postgres: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/pgvector:pg18-trixie container_name: postgres_container restart: always environment: POSTGRES_DB: trailsnap POSTGRES_USER: trailsnap POSTGRES_PASSWORD: trailsnap POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=C --lc-ctype=C" PGDATA: /var/lib/postgresql/data/pgdata networks: [ app-network ] volumes: - ./pg_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U trailsnap -d trailsnap -p 5432"] interval: 5s timeout: 5s retries: 5 start_period: 10s server: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-server:latest restart: always expose: [ "8000" ] networks: [ app-network ] volumes: - ./data:/app/data - /path/to/your/photos:/app/Photos/ environment: - TZ=Asia/Shanghai - DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/trailsnap - RAILWAY_DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/railway - AI_API_URL=http://ai:8001 - TRAILSNAP_ROOT_PATH=/api # Replace this with the host LAN address to enable App discovery - TRAILSNAP_PUBLIC_URL=http://192.168.1.10:3180 depends_on: postgres: condition: service_healthy ai: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-ai:latest restart: always expose: [ "8001" ] networks: [ app-network ] volumes: - ./data:/app/data frontend: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-frontend:latest restart: always ports: [ "3180:80" ] depends_on: [ server ] networks: [ app-network ] networks: app-network: driver: bridge ``` ## 3. Startup and Verification Execute in the directory where `docker-compose.yml` is located: ```bash docker-compose up -d ``` TrailSnap has one user-facing address after startup: - TrailSnap: `http://:3180` - API docs: `http://:3180/api/docs` The browser, mobile app, PWA, and CLI all use this same address. Server, AI, and PostgreSQL remain private on the Compose network. ## 4. GPU Acceleration Support (Optional) If you have an NVIDIA GPU, you can enable GPU acceleration to speed up AI processing. ### Prerequisites 1. NVIDIA graphics driver installed on the host. 2. [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) installed. **[Windows Installation Steps]** (for other systems, please search for tutorials): **Step 1**: Open a WSL 2 Linux terminal Find your installed Linux distribution (e.g. Ubuntu) in the Windows Start Menu and open its terminal (not Windows PowerShell). **Step 2**: Install nvidia-docker2 in WSL 2 For Ubuntu, run: ```bash # 1. Set up NVIDIA software source distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list # 2. Update and install nvidia-docker2 sudo apt-get update sudo apt-get install -y nvidia-docker2 # 3. Restart Docker sudo systemctl restart docker ``` ### Modify docker-compose.yml Make the following changes to the `ai` service: 1. Change the image tag to the `-gpu` suffix (e.g. `latest-gpu`). 2. Add a `deploy` section to request GPU resources. ```yaml ai: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-ai:latest-gpu restart: always expose: [ "8001" ] networks: [ app-network ] volumes: - ./data:/app/data deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] ``` ## 5. NAS Scenario FAQ ### 4.1 How to write the path correctly? On NAS, please refer to the "real path of the shared folder". Different systems display paths differently, but there is only one principle: ensure that `/app/Photos/` inside the container can see your photo files. ### 4.2 Insufficient permissions causing scan failure If the photo directory is read-only shared or permission isolated, the container may not be able to read it. Suggestions: - Grant read permission of the shared folder to the container running account - Or mount the photo directory as read-only and ensure host side permissions allow reading ### 4.3 Port Conflict Common ports like 80/443/8080 are easily occupied on NAS. TrailSnap exposes only port 3180 by default. If there is a conflict, modify the single mapping, for example: ```yaml ports: [ "13180:80" ] ``` ## 6. NAS Specific Tutorials - [Ugreen NAS Deployment](/en/docs/guide/docker/ugreen) - [Zspace Deployment](/en/docs/guide/docker/zspace) - [Fnos Deployment](/en/docs/guide/docker/fnos) --- # Ugreen NAS Deployment - Source: https://trailsnap.cn/en/docs/guide/docker/ugreen.html - Markdown: https://trailsnap.cn/en/docs/guide/docker/ugreen.md - Category: Docker deployment - Language: en # Ugreen NAS Deployment ## Deploy Container using Docker Compose On the UGOS Pro system, it is recommended to use the project Docker Compose to quickly deploy containers, suitable for scenarios where multiple containers need to be managed simultaneously. This method simplifies container deployment and management. The following are the detailed steps to deploy TrailSnap using Docker Compose. If you haven't deployed before, it is recommended to read the generic chapter first: [/en/docs/guide/docker/](/en/docs/guide/docker/) ### 1. Enter Docker Project Interface In the UGOS Pro system, open the Docker application, click [Project] > [Create], and start the project creation wizard. Fill in the project name as `trailsnap`, and leave others as default. ## 2. Configure Docker Compose File Fill in the Docker Compose template from [/en/docs/guide/docker/](/en/docs/guide/docker/). 1. Modify the photo directory mount for the `server` service: ```yaml volumes: - ./data:/app/data - /real/path/to/your/photos:/app/Photos/ ``` If you want to maximize security, you can mount the photo directory as read-only: ```yaml - /real/path/to/your/photos:/app/Photos/:ro ``` ## 3. Set Ports and Network TrailSnap exposes one access port by default: `3180`. The browser, App, and CLI use this address; Server, AI, and database ports stay inside Docker. If it conflicts with another NAS service, modify only `frontend.ports` (for example, use 13180). ## 4. Startup and Verification Access in browser after startup: - `http://:3180` Open Settings -> External Libraries, fill in the photo path inside the container: `/app/Photos/`, adding an external library will automatically scan and run tasks in the background (task details can be viewed in Settings -> Task Management). API documentation is available at `http://:3180/api/docs`. ## 5. Permission and Scan Troubleshooting If TrailSnap cannot scan photos, it is usually a permission or path problem: - First enter the terminal/console of the `server` container and confirm that photo files can be seen in the `/app/Photos/` directory. - Confirm that the NAS side shared folder permissions allow Docker/container service reading. - If the photo directory is on external storage or a specific storage pool, confirm that the storage pool is visible to the container. --- # Step 1: Install Docker Desktop - Source: https://trailsnap.cn/en/docs/guide/docker/windows.html - Markdown: https://trailsnap.cn/en/docs/guide/docker/windows.md - Category: Docker deployment - Language: en # Step 1: Install Docker Desktop Docker Compose is already integrated into Docker Desktop, so install it first: 1. Go to the Docker official website to download: https://www.docker.com/products/docker-desktop/ 2. Double-click the downloaded installer and keep clicking **Next** (check **Use WSL 2 instead of Hyper-V**). 3. Restart your computer after installation. 4. Launch Docker Desktop (the first startup may take a few minutes; a Docker icon will appear in the system tray). 5. If this is your first use, a command prompt window will pop up asking you to install **Windows Subsystem for Linux**. Follow the instructions to install it. 6. Configure a registry mirror: Open **Settings → Docker Engine**, and paste the following JSON: ```json { "builder": { "gc": { "defaultKeepStorage": "20GB", "enabled": true } }, "experimental": false, "registry-mirrors": ["https://docker.1ms.run"] } ``` Click **Apply & Restart** to restart Docker Desktop. 7. Verify installation: Press `Win + R`, type `cmd` to open Command Prompt, then run: ```bash docker --version docker-compose --version ``` If version numbers are displayed, the installation is successful. --- # Step 2: Prepare the `docker-compose.yml` File 1. Create a new empty folder, e.g., `D:\TrailSnap`. 2. Inside the folder, create a file named `docker-compose.yml`. 3. Open it with a text editor and paste the content below: ```yaml version: '3.8' services: postgres: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/pgvector:pg18-trixie container_name: postgres_container restart: always environment: POSTGRES_DB: trailsnap POSTGRES_USER: trailsnap POSTGRES_PASSWORD: trailsnap POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=C --lc-ctype=C" PGDATA: /var/lib/postgresql/data/pgdata networks: [ app-network ] volumes: - ./pg_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U trailsnap -d trailsnap -p 5432"] interval: 5s timeout: 5s retries: 5 start_period: 10s server: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-server:latest restart: always expose: [ "8000" ] networks: [ app-network ] volumes: - ./data:/app/data - ./photos:/app/Photos/ environment: - DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/trailsnap - RAILWAY_DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/railway - AI_API_URL=http://ai:8001 - TRAILSNAP_ROOT_PATH=/api - TRAILSNAP_PUBLIC_URL=http://192.168.1.10:3180 depends_on: postgres: condition: service_healthy ai: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-ai:latest restart: always expose: [ "8001" ] networks: [ app-network ] volumes: - ./data:/app/data frontend: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-frontend:latest restart: always ports: [ "3180:80" ] depends_on: [ server ] networks: [ app-network ] networks: app-network: driver: bridge ``` ## Modify Photo Volume Mounts Find the `volumes` section under the `server` service and change `./photos:/app/Photos/` to your **local photo directory**. Example (if your photos are in `D:\TrailSnap\photos`): ```yml server: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-server:latest restart: always expose: [ "8000" ] networks: [ app-network ] volumes: - ./data:/app/data - D:\TrailSnap\photos:/app/Photos/ environment: - DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/trailsnap - RAILWAY_DB_URL=postgresql://trailsnap:trailsnap@postgres:5432/railway - AI_API_URL=http://ai:8001 depends_on: postgres: condition: service_healthy ``` If you have **multiple photo folders** (e.g., `D:\TrailSnap\photos1`, `D:\TrailSnap\photos2`): ```yml server: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-server:latest restart: always expose: [ "8000" ] networks: [ app-network ] volumes: - ./data:/app/data - D:\TrailSnap\photos:/app/Photos/ - D:\TrailSnap\photos1:/app/Photos1/ - D:\TrailSnap\photos2:/app/Photos2/ ``` - Left side of `:` = local folder path - Right side of `:` = path used inside TrailSnap --- # Step 3: Run Deployment Commands 1. Open Command Prompt (`Win + R` → `cmd`), then navigate to the folder containing `docker-compose.yml`: ```bash # Example: if the file is in D:\TrailSnap cd /d D:\TrailSnap ``` 2. Start all services (core command): ```bash docker-compose up -d ``` - `up`: start all services defined in the compose file - `-d`: run in detached/background mode 3. Wait for completion. Docker will automatically pull images, create containers, and start services. Sample success output: ```bash PS C:\ProgramData\TrailSnap> docker-compose up -d time="2026-03-06T17:42:03+08:00" level=warning msg="C:\\ProgramData\\TrailSnap\\docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion" [+] up 51/51 ✔ Image crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-frontend:latest Pulled 38.2s ✔ Image crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-ai:latest Pulled 155.8s ✔ Image crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/pgvector:pg18-trixie Pulled 76.8s ✔ Image crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-server:latest Pulled 112.8s ✔ Network trailsnap_app-network Created 0.1s ✔ Container postgres_container Healthy 28.0s ✔ Container trailsnap-ai-1 Created 1.1s ✔ Container trailsnap-server-1 Created 0.1s ✔ Container trailsnap-frontend-1 Created 0.1s ``` --- # Step 4: Verify Deployment Open your browser at `http://localhost:3180`. The mobile app and CLI use the same TrailSnap address. You will see the TrailSnap web interface. Go to **More → Settings → External Library** and add: `/app/Photos/` If you have multiple volumes, add: `/app/Photos1/`, `/app/Photos2/`, etc. --- # Troubleshooting (For Beginners) 1. **“docker-compose.yml not found”** Make sure your Command Prompt is in the same folder as the file. Or run: ```bash docker-compose -f "full\path\to\docker-compose.yml" up -d ``` 2. **Port conflict / Port in use** Change the **host port** (the number before `:`) in the `ports` section of `docker-compose.yml`, then run `docker-compose up -d` again. --- # Summary 1. **Prerequisite**: Install Docker Desktop and verify with `docker --version`. 2. **Key step**: Place `docker-compose.yml` in a folder, `cd` into it, then run `docker-compose up -d`. 3. **Management commands**: - `docker-compose ps` – view running services - `docker-compose logs` – check logs for errors - `docker-compose down` – stop and remove containers --- # Zspace Deployment - Source: https://trailsnap.cn/en/docs/guide/docker/zspace.html - Markdown: https://trailsnap.cn/en/docs/guide/docker/zspace.md - Category: Docker deployment - Language: en # Zspace Deployment This tutorial is based on TrailSnap's Docker Compose deployment method, suitable for deployment and long-term operation on Zspace devices. The goal is to let TrailSnap run stably as a home service while mounting the photo library into the container for scanning and indexing. It is recommended to read the generic chapter first: [/en/docs/guide/docker/](/en/docs/guide/docker/) --- # AI 大模型设置 - Source: https://trailsnap.cn/docs/guide/settings/aisetting.html - Markdown: https://trailsnap.cn/docs/guide/settings/aisetting.md - Category: 设置指南 - Language: zh-CN # AI 大模型设置 ::: tip 桌面版用户 本页配置对话与图片理解使用的大模型连接。桌面版已内置 AI 运行环境,识别模型按需下载,参见[桌面版内置 AI](/docs/guide/desktop-ai-extension)。 ::: ## 内置连接 TrailSnap 内置了 AI 连接功能,开箱即用。内置连接使用 MiniCPM-V-4_6-Q4_K_M 多模态模型,支持图片内容理解、标签生成等视觉任务。 内置连接在 `设置-基础设置-AI相关配置-大模型连接配置` 页面中显示,带有"内置"标识。**内置连接不可编辑、不可删除**。 如果需要使用第三方 API,可以添加新的连接。 ## 添加连接 点击 `设置-基础设置-AI相关配置-大模型连接配置` 可以添加新的大模型连接。 - 选择api接口类型,例如`OpenAI`、`Ollama`等。 - 填写base url和api key。 - 填写模型名称(可选,不填则可以使用该api key的所有模型),例如`gpt-3.5-turbo`、`qwen3.5:4b`等。 - 点击验证按钮,验证成功后会显示连接成功。 ![alt text](/images/aisettings.webp) ## AI对话配置 点击 `设置-基础设置-AI相关配置-AI对话配置` 可以配置AI对话(右下角AI小助手)默认使用的模型。 ## 大模型智能分析配置 点击 `设置-基础设置-AI相关配置-大模型智能分析配置` 选择要使用的连接和模型,用于图片内容理解、标签生成等视觉任务。该任务比较简单,使用小模型即可完成。 涉及隐私问题需谨慎使用各个平台提供的云模型,推荐使用ollama本地部署qwen3.5:4b模型,或者使用`vllm`等本地大模型服务。 ```bash ollama run qwen3.5:4b ``` - Base URL: 视觉大模型的API基础URL,例如 `http://127.0.0.1:11434/v1` - API Key: 视觉大模型的API密钥,本地ollama可以填写:`empty` - Model Name: 视觉大模型的名称,例如 `qwen3.5:4b` ### 创建处理任务 设置完成之后可以点击"任务管理-大模型智能分析",选择`强制重做此项`或者`执行缺失任务`,开始分析照片(为了节省资源,分析的时候会自动略过**截图**)。 ### 查看分析结果 1. 点击"工具箱-低分清理",之后会显示所有AI分析完成的照片,按评分排序。 2. 点击照片,会弹出照片详情页,点击右上角选择"查看AI分析结果"即可显示该照片的AI分析结果。 3. 首页的"那年今日"模块,用户可以查看往年今天的照片(如果有的话),按图片评分排序并显示AI生成的照片文案。 --- # 设置外部图库 - Source: https://trailsnap.cn/docs/guide/settings/directories.html - Markdown: https://trailsnap.cn/docs/guide/settings/directories.md - Category: 设置指南 - Language: zh-CN # 设置外部图库 添加外部文件夹路径,系统将扫描这些文件夹中的图片。外部文件夹中的图片不会被移动或修改,生成的缩略图将存储在主目录中。 查看docker-compose.yml文件,确认photos文件夹的挂载路径。 ```yml server: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-server:latest restart: always expose: [ "8000" ] networks: [ app-network ] volumes: - ./data:/app/data - D:\TrailSnap\photos:/app/Photos/ ``` 冒号前面是电脑上的文件夹路径,冒号后面是容器内的路径。外部图库要添加的目录为冒号后面的路径,也就是`/app/Photos/`。 你也可以挂载多个文件夹,只需要在volumes中添加多个挂载路径即可。修改之后要重启docker容器,使配置生效。 ```yml - D:\TrailSnap\photos1:/app/Photos1/ - E:\TrailSnap\photos2:/app/Photos2/ ``` 也可以添加外部文件夹的某个子文件夹,例如只想添加`D:\TrailSnap\photos1\2025\`中的图片,那么外部图库为`/app/Photos1/2025/`。 --- # 设置指南 - Source: https://trailsnap.cn/docs/guide/settings/ - Markdown: https://trailsnap.cn/docs/guide/settings/index.md - Category: 设置指南 - Language: zh-CN # 设置指南 TrailSnap 提供了丰富的自定义选项,帮助您打造个性化的智能相册。 ## 主要配置项 - **基础设置**:外观主题、存储路径、AI 参数配置等。 - **地图设置**:[地图 API Key 配置](./mapsetting.md),用于开启足迹地图功能。 - **Token 设置**:[访问令牌配置](./tokensetting.md),用于第三方应用访问后端 API。 - **任务管理**:查看后台任务状态(索引重建、人脸识别等)。 ## 配置文件 除了通过 Web 界面修改设置外,高级用户也可以直接修改配置文件(通常位于数据目录下的 `config.json`)。但为了避免格式错误,建议优先使用 Web 界面进行操作。 --- # 地图设置指南 - Source: https://trailsnap.cn/docs/guide/settings/mapsetting.html - Markdown: https://trailsnap.cn/docs/guide/settings/mapsetting.md - Category: 设置指南 - Language: zh-CN # 地图设置指南 TrailSnap 使用地图服务来展示照片的地理位置分布(足迹地图)。为了正常使用地图功能,您需要自行申请并配置地图服务的 API Key。 ## 为什么需要配置 API Key? 地图服务商(如天地图、高德、百度)通常要求开发者申请独立的 API Key (或 Token) 才能调用其服务。自行配置 Key 有以下好处: 1. **稳定性保障**:拥有独立的每日调用配额,避免因共享 Key 达到限额而导致地图无法加载。 2. **合规与安全**:符合地图服务商的使用条款,且 Key 由您自己管理,更加安全。 ## 1. 天地图 (推荐) [天地图](https://www.tianditu.gov.cn/) 是国家地理信息公共服务平台,数据权威、覆盖全,且对个人开发者提供较为宽裕的免费配额,是 TrailSnap 的**默认及推荐**地图服务商。 ::: warning 旧版本升级用户必须更换 Key 旧版 TrailSnap 配置的是天地图**浏览器端 Key**。升级后原 Key 不会自动转换为服务端类型,请在天地图控制台创建新的**服务端 Key**,并到“设置 → 基础设置 → 地图配置”替换原 Key。继续使用浏览器端 Key 可能导致网页或手机 App 加载地图时返回 403。 如果服务端 Key 启用了 IP 白名单,请填写 **TrailSnap Server 的公网出口 IP**,不要填写访问网页或手机 App 的设备 IP。 ::: ### 获取 API Key (Tk) 步骤 1. **注册账号** 访问 [天地图官网](https://www.tianditu.gov.cn/),点击右上角的“注册”,完成个人账号注册。如果已有账号,直接[登录](https://oauth.tianditu.gov.cn/login)。 2. **进入控制台** 登录后,点击页面顶部的“开发资源”,选择“控制台”,或者直接访问 [天地图控制台](https://cloudcenter.tianditu.gov.cn/center/development/myApp)。 3. **申请成为开发者** 如果是首次使用,可能需要点击“申请成为个人开发者”并完成简单的实名认证。 4. **创建应用** - 点击左侧菜单栏的 **“应用管理”**。 - 点击 **“创建新应用”** 按钮。 - 填写应用信息: - **应用名称**:填写 `TrailSnap` 或任意您喜欢的名称。 - **行业类别**:根据实际情况选择(如“生活服务”)。 - **应用类型**:选择 **“服务端”**。TrailSnap 的网页、桌面端和手机 App 都通过自部署 Server 调用天地图,Key 不会发送给浏览器或 WebView。 - **IP 白名单**(非必须):如需启用,请填写 TrailSnap Server 访问互联网时使用的公网出口 IP,而不是手机或浏览器的 IP。 ![Alt text](/images/tianditu.webp) 5. **获取 Key** 创建成功后,您会在应用列表中看到刚才创建的应用。复制 **Key** 列对应的一串字符(通常称为 `tk`)。 6. **填入设置** 回到 TrailSnap 系统: - 进入 **设置** -> **基础设置**。 - 找到 **地图配置** 区域。 - 确保地图提供商选择为 **天地图 (Tianditu)**。 - 将复制的 Key 粘贴到 **API Key** 输入框中。 - 点击保存。 7. **获取多个 Key 并配置** - 天地图允许您为不同的应用或场景创建多个 Key,每个 Key 有独立的调用配额。 - 防止调用次数过多,您可以在 TrailSnap 中配置多个 Key,系统会随机选择一个用于加载地图。 - 这在您需要在不同环境(如本地开发、测试环境、生产环境)使用不同 Key 时非常有用。 ## 2. 高德地图 (Amap)(暂不支持) ### 获取 API Key 步骤 1. **注册开发者** 访问 [高德开放平台](https://console.amap.com/dev/index),注册账号并完成开发者认证(个人开发者即可)。 2. **创建应用** - 进入 **应用管理** -> **我的应用**。 - 点击 **创建新应用**,输入名称(如 `TrailSnap`)和类型(如 `工具`)。 3. **添加 Key** - 在刚才创建的应用下,点击 **添加 Key**。 - **服务平台**:选择 **Web端 (JSAPI)**。 - **域名白名单**:本地测试可不填,线上部署请填写域名。 - 勾选同意协议并提交。 4. **获取 Key** 复制生成的 **Key**。注意:高德地图 JSAPI 2.0 可能还需要配置安全密钥 (jscode),目前 TrailSnap 暂未通过界面支持配置安全密钥,建议优先使用天地图。 ## 3. 百度地图 (Baidu) > **注意**:百度地图的支持正在规划中。 ### 获取 API Key (AK) 步骤 1. **注册开发者** 访问 [百度地图开放平台](https://lbsyun.baidu.com/apiconsole/center),注册并认证。 2. **创建应用** - 进入 **应用管理** -> **我的应用**。 - 点击 **创建应用**。 3. **配置应用** - **应用类型**:选择 **浏览器端**。 - **Referer白名单**:填写 `*` (本地测试) 或您的域名。 - **启用服务**:默认全选即可。 4. **获取 AK** 提交后,列表中的 **访问应用(AK)** 即为 API Key。 ## 4. 离线地图数据 (Offline Map Data) TrailSnap 支持离线反向地理编码功能,即使在没有网络连接的情况下,也能根据照片的 GPS 坐标解析出所在的城市和地区。该功能依赖于离线城市数据文件。 ### 功能说明 在 **设置** -> **基础设置** -> **地图配置** 下方,您可以找到 **离线地图数据** 管理区域。 ### 下载国家数据 1. 在 **下载国家数据** 区域,从下拉框中选择您需要的国家(例如“China”)。 2. 点击 **下载** 按钮。 3. 系统将在后台自动下载该国的城市数据并进行处理。下载完成后,该国的数据将显示在下方的 **已下载数据** 列表中。 ### 上传自定义数据 如果您无法通过系统直接下载,或者有自定义的城市数据文件,可以通过此功能手动上传。 1. 准备 CSV 格式的城市数据文件。文件必须包含以下表头字段: - `longitude`: 经度 - `latitude`: 纬度 - `country`: 国家代码 (如 CN, US) - `admin_1`: 一级行政区 (如 省/州) - `admin_2`: 二级行政区 (如 市) - `admin_3`: 三级行政区 (如 区/县) - `admin_4`: 四级行政区 (可选) 2. 点击 **点击上传 CSV 文件** 按钮,选择您的文件。 3. 上传成功后,数据将立即生效并显示在列表中。 ### 管理已下载数据 在 **已下载数据** 列表中,您可以: - 查看当前已安装的所有国家/地区数据。 - 点击文件名旁边的 **下载图标**,将服务器上的 CSV 数据文件下载到本地电脑进行备份或查看。 ## 常见问题 **Q: 地图加载显示空白或网格?** A: 1. 请检查 API Key 是否正确复制,注意不要带有空格。 2. 确认申请 Key 时选择的**应用类型**是否正确(天地图必须是**服务端**)。 3. 如果设置了 IP 白名单,请确认填写的是 TrailSnap Server 的公网出口 IP。 4. 回到设置页点击“测试”,测试请求会由 TrailSnap Server 发起。 **Q: 天地图配额不够用怎么办?** A: 个人开发者的免费配额通常足以满足个人相册的日常浏览需求。如果确实超限,可以考虑注册多个账号或升级企业认证。 **Q: 离线地图数据下载失败?** A: 可能是由于网络连接问题导致无法连接到数据源 (GeoNames)。您可以尝试稍后重试,或者手动下载数据并使用“上传自定义数据”功能进行导入。 --- # 设置访问令牌 - Source: https://trailsnap.cn/docs/guide/settings/tokensetting.html - Markdown: https://trailsnap.cn/docs/guide/settings/tokensetting.md - Category: 设置指南 - Language: zh-CN # 设置访问令牌 ::: info Token 设置 使用token可以让第三方应用访问TrailSnap的后端API,你可以从TrailSnap后端获取一个Token。 ::: ## 获取 Token 打开 “设置” -> “令牌管理” -> “新增令牌”,输入令牌名称和过期时间,验证账号登录密码之后即可获取到Token。 token示例:`ts_hV5nsCZJDheBvvmcd5L248IiAUnIwwZAn` ## API URL 第三方客户端填写统一的 TrailSnap 地址,例如 `http://:3180`。CLI 会自动通过该地址下的 `/api` 访问接口。 ```yaml frontend: ports: [ "3180:80" ] ``` 这里的 `3180` 是唯一的用户访问端口;不需要额外开放后端、AI 或数据库端口。 ## 使用token Agent Token 支持按用途选择最小权限。只读查询可选择照片、相册和人物读取权限;需要外部 Agent 整理照片时,可以额外授予“提出相册方案”权限。该权限只能创建待确认计划,不能直接修改相册。 - MCP 客户端:参考 [配置 TrailSnap MCP](/docs/guide/agent/mcp) - 命令行工具:参考 [TrailSnap CLI 工具](/docs/guide/agent/trailsnap-cli) --- # AI / LLM Settings - Source: https://trailsnap.cn/en/docs/guide/settings/aisetting.html - Markdown: https://trailsnap.cn/en/docs/guide/settings/aisetting.md - Category: Settings - Language: en # AI / LLM Settings ::: tip Desktop users This page configures model connections for chat and image understanding. Desktop AI is included in the application; models are downloaded as needed. See [built-in desktop AI](/en/docs/guide/desktop-ai-extension). ::: ## Built-in Connection TrailSnap includes a built-in AI connection that works out of the box. It uses the MiniCPM-V-4_6-Q4_K_M multimodal model, supporting image content understanding, tag generation, and other visual tasks. The built-in connection is shown on the **Settings → General → AI Configuration → LLM Connection** page with a "Built-in" badge. **Built-in connections cannot be edited or deleted.** If you need to use a third-party API, you can add a new connection. ## Adding a Connection Go to **Settings → General → AI Configuration → LLM Connection** to add a new LLM connection. - Select the API type, e.g. `OpenAI`, `Ollama`, etc. - Fill in the base URL and API key. - Fill in the model name (optional — if left empty, all models available with that API key can be used), e.g. `gpt-3.5-turbo`, `qwen3.5:4b`, etc. - Click the verify button; a success message will appear if the connection works. ![alt text](/images/aisettings.webp) ## AI Chat Configuration Go to **Settings → General → AI Configuration → AI Chat** to configure the default model used by the AI assistant (bottom-right corner). ## Smart Analysis Configuration Go to **Settings → General → AI Configuration → Smart Analysis** to select the connection and model for image content understanding and tag generation. This is a relatively simple task, so a small model is sufficient. Due to privacy concerns, be cautious when using cloud models from various platforms. Using a locally deployed model is recommended, such as Ollama with `qwen3.5:4b`, or a local LLM service like `vllm`. ```bash ollama run qwen3.5:4b ``` - Base URL: The API base URL for the vision model, e.g. `http://127.0.0.1:11434/v1` - API Key: The API key for the vision model. For local Ollama, you can use: `empty` - Model Name: The vision model name, e.g. `qwen3.5:4b` ### Creating a Processing Task After configuration, go to **Task Management → Smart Analysis**, select `Force Redo` or `Run Missing Tasks` to start analyzing photos (to save resources, screenshots are automatically skipped during analysis). ### Viewing Analysis Results 1. Go to **Toolbox → Quality Cleanup** — this shows all AI-analyzed photos sorted by score. 2. Click a photo to open the detail panel, then click the top-right button and select "View AI Analysis Results". 3. On the home page, the "On This Day" module shows photos from past years (if available), sorted by score with AI-generated captions. --- # External Libraries - Source: https://trailsnap.cn/en/docs/guide/settings/directories.html - Markdown: https://trailsnap.cn/en/docs/guide/settings/directories.md - Category: Settings - Language: en # External Libraries Add external folder paths and the system will scan images in those folders. Images in external folders will not be moved or modified; generated thumbnails will be stored in the main directory. Check the `docker-compose.yml` file to confirm the mount path of the photos folder. ```yml server: image: crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-server:latest restart: always expose: [ "8000" ] networks: [ app-network ] volumes: - ./data:/app/data - D:\TrailSnap\photos:/app/Photos/ ``` The part before the colon is the folder path on your computer; the part after the colon is the path inside the container. The directory to add as an external library is the path after the colon, i.e. `/app/Photos/`. You can also mount multiple folders by adding multiple mount paths in the `volumes` section. After modifying, restart the Docker container for the changes to take effect. ```yml - D:\TrailSnap\photos1:/app/Photos1/ - E:\TrailSnap\photos2:/app/Photos2/ ``` You can also add a subfolder of an external folder. For example, if you only want to add images from `D:\TrailSnap\photos1\2025\`, the external library path would be `/app/Photos1/2025/`. --- # Settings Guide - Source: https://trailsnap.cn/en/docs/guide/settings/ - Markdown: https://trailsnap.cn/en/docs/guide/settings/index.md - Category: Settings - Language: en # Settings Guide TrailSnap provides rich customization options to help you build a personalized intelligent photo album. ## Main Configurations - **Basic Settings**: Appearance theme, storage path, AI parameter configuration, etc. - **Map Settings**: [Map API Key Configuration](./mapsetting.md), used to enable the footprint map function. - **Token Settings**: [API access token](./tokensetting.md), used for third-party apps to access backend APIs. - **Task Management**: View background task status (index rebuilding, face recognition, etc.). ## Configuration Files In addition to modifying settings via the Web interface, advanced users can also directly modify configuration files (usually located in `config.json` under the data directory). However, to avoid format errors, it is recommended to prioritize using the Web interface for operations. --- # Map Settings Guide - Source: https://trailsnap.cn/en/docs/guide/settings/mapsetting.html - Markdown: https://trailsnap.cn/en/docs/guide/settings/mapsetting.md - Category: Settings - Language: en # Map Settings Guide TrailSnap uses map services to display the geographical distribution of photos (Footprint Map). In order to use the map function normally, you need to apply for and configure the API Key of the map service yourself. ## Why configure an API Key? Map service providers (such as Tianditu, Amap, Baidu) usually require developers to apply for an independent API Key (or Token) to call their services. Configuring your own Key has the following benefits: 1. **Stability Guarantee**: Have an independent daily call quota to avoid map loading failure due to shared Key reaching the limit. 2. **Compliance and Security**: Comply with the terms of use of the map service provider, and the Key is managed by yourself, which is more secure. --- ## 1. Tianditu (Recommended) [Tianditu](https://www.tianditu.gov.cn/) is a national geographic information public service platform with authoritative data and full coverage. It provides a relatively generous free quota for individual developers and is the **default and recommended** map service provider for TrailSnap. ### Steps to Get API Key (Tk) 1. **Register Account** Visit the [Tianditu Official Website](https://www.tianditu.gov.cn/), click "Register" in the upper right corner, and complete personal account registration. If you already have an account, [log in](https://sso.tianditu.gov.cn/login) directly. 2. **Enter Console** After logging in, click "Development Resources" at the top of the page, select "Console", or visit the [Tianditu Console](http://lbs.tianditu.gov.cn/server/kz.html) directly. 3. **Apply to be a Developer** If it is your first time using it, you may need to click "Apply to become an individual developer" and complete simple real-name authentication. 4. **Create Application** - Click **"Application Management"** in the left menu bar. - Click the **"Create New Application"** button. - Fill in application information: - **Application Name**: Fill in `TrailSnap` or any name you like. - **Industry Category**: Select according to the actual situation (e.g., "Life Service"). - **Application Type**: **Must select "Browser Side"** (because TrailSnap loads the map directly on the browser frontend). - **IP Whitelist/Domain Whitelist**: - If you use it locally (`localhost`), you can fill in `*` (meaning no restriction). - If you use TrailSnap Desktop, leave it unrestricted; the desktop WebView's internal origin is not suitable for a fixed domain whitelist. - If you deploy on the public network, it is recommended to fill in your domain name or IP address to improve security. 5. **Get Key** After successful creation, you will see the application just created in the application list. Copy the string of characters corresponding to the **Key** column (usually called `tk`). 6. **Fill in Settings** Return to the TrailSnap system: - Go to **Settings** -> **Basic Settings**. - Find the **Map Configuration** area. - Ensure the map provider is selected as **Tianditu**. - Paste the copied Key into the **API Key** input box. - Click Save. 7. **Get Multiple Keys and Configure** - Tianditu allows you to create multiple Keys for different applications or scenarios, and each Key has an independent call quota. - To prevent excessive calls, you can configure multiple Keys in TrailSnap, and the system will randomly select one to load the map. - This is very useful when you need to use different Keys in different environments (such as local development, test environment, production environment). --- ## 2. Amap (Gaode Map) > **Note**: TrailSnap currently mainly supports Tianditu. Support for Amap is under development, and configuration may not take effect temporarily or only some functions may be available. ### Steps to Get API Key 1. **Register Developer** Visit the [Amap Open Platform](https://console.amap.com/dev/index), register an account and complete developer authentication (individual developer is sufficient). 2. **Create Application** - Enter **Application Management** -> **My Applications**. - Click **Create New Application**, enter name (e.g., `TrailSnap`) and type (e.g., `Tool`). 3. **Add Key** - Under the application just created, click **Add Key**. - **Service Platform**: Select **Web Side (JSAPI)**. - **Domain Whitelist**: Can be left blank for local testing, please fill in the domain name for online deployment. - Check agree to the agreement and submit. 4. **Get Key** Copy the generated **Key**. Note: Amap JSAPI 2.0 may also require configuring a security key (jscode). Currently, TrailSnap does not support configuring security keys through the interface. It is recommended to prioritize using Tianditu. --- ## 3. Baidu Map > **Note**: Support for Baidu Map is being planned. ### Steps to Get API Key (AK) 1. **Register Developer** Visit the [Baidu Map Open Platform](https://lbsyun.baidu.com/apiconsole/center), register and authenticate. 2. **Create Application** - Enter **Application Management** -> **My Applications**. - Click **Create Application**. 3. **Configure Application** - **Application Type**: Select **Browser Side**. - **Referer Whitelist**: Fill in `*` (local testing) or your domain name. - **Enable Services**: Default select all. 4. **Get AK** After submission, the **Access Application (AK)** in the list is the API Key. --- ## 4. Offline Map Data TrailSnap supports offline reverse geocoding. Even without an internet connection, it can resolve the city and region based on the GPS coordinates of photos. This feature relies on offline city data files. ### Feature Description You can find the **Offline Map Data** management area under **Settings** -> **Basic Settings** -> **Map Configuration**. ### Download Country Data 1. In the **Download Country Data** area, select the country you need (e.g., "China") from the dropdown menu. 2. Click the **Download** button. 3. The system will automatically download and process the city data for that country in the background. Once completed, the country's data will appear in the **Downloaded Data** list below. ### Upload Custom Data If you cannot download directly through the system, or have custom city data files, you can manually upload them using this feature. 1. Prepare a city data file in CSV format. The file must include the following header fields: - `longitude`: Longitude - `latitude`: Latitude - `country`: Country Code (e.g., CN, US) - `admin_1`: Admin Level 1 (e.g., Province/State) - `admin_2`: Admin Level 2 (e.g., City) - `admin_3`: Admin Level 3 (e.g., District/County) - `admin_4`: Admin Level 4 (Optional) 2. Click the **Click to Upload CSV File** button and select your file. 3. After successful upload, the data will take effect immediately and appear in the list. ### Manage Downloaded Data In the **Downloaded Data** list, you can: - View all currently installed country/region data. - Click the **Download Icon** next to the filename to download the CSV data file from the server to your local computer for backup or inspection. --- ## FAQ **Q: Map loads blank or grid?** A: 1. Please check if the API Key is copied correctly, be careful not to include spaces. 2. Confirm if the **Application Type** selected when applying for the Key is correct (Tianditu must be **Browser Side**). 3. If a whitelist is set, please confirm whether the current access address (such as `localhost` or `127.0.0.1`) is in the whitelist. 4. For TrailSnap Desktop, remove the domain restriction and validate the Key again from Settings. **Q: What if the Tianditu quota is not enough?** A: The free quota for individual developers is usually sufficient for daily browsing needs of personal albums. If it really exceeds the limit, you can consider registering multiple accounts or upgrading to enterprise certification. **Q: Offline map data download failed?** A: It may be due to network connection issues preventing connection to the data source (GeoNames). You can try again later, or manually download the data and import it using the "Upload Custom Data" feature. --- # Token Settings - Source: https://trailsnap.cn/en/docs/guide/settings/tokensetting.html - Markdown: https://trailsnap.cn/en/docs/guide/settings/tokensetting.md - Category: Settings - Language: en # Token Settings ::: info Token Using a token allows third-party apps (such as TrailSnap CLI or Agent Skills) to access TrailSnap Backend APIs. ::: ## Get a Token Open **Settings** → **Token Management** → **New Token**, then set a name and expiration time. After verifying your account password, you will get a token. Example token: `ts_hV5nsCZJDheBvvmcd5L248IiAUnIwwZAn` ## API URL Third-party clients use the unified TrailSnap address, for example `http://:3180`. The CLI automatically uses its `/api` path. ```yaml frontend: ports: [ "3180:80" ] ``` Here, `3180` is the only user-facing port. Server, AI, and database ports stay inside the Docker network. ## Use the Token Agent Tokens support least-privilege scopes. Select photo, album, and people read scopes for queries. Grant **Propose albums** only when an external agent needs to organize selected photos; this scope creates a pending plan and cannot modify an album directly. - MCP clients: see [Configure TrailSnap MCP](/en/docs/guide/agent/mcp). - Command-line access: see [TrailSnap CLI](/en/docs/guide/agent/trailsnap-cli). --- # 功能清单 - Source: https://trailsnap.cn/docs/guide/features.html - Markdown: https://trailsnap.cn/docs/guide/features.md - Category: 使用指南 - Language: zh-CN # 功能清单 本文档列出 TrailSnap(行影集)的完整功能列表,帮助你快速了解应用的所有能力。 ::: tip 如何理解功能状态 下方功能以当前项目能力为准。需要 AI 服务、外部模型或较高硬件资源的功能,会在说明中标出;路线图中的能力请以“待开发功能”为准,不应视为当前版本承诺。 ::: ## 当前能力与使用条件 | 能力 | 当前状态 | 使用条件 / 注意事项 | | --- | --- | --- | | 照片浏览、相册、时间轴、元数据 | 可用 | 需先完成照片导入或扫描 | | 人脸、OCR、场景分类、相似/重复检测 | 可用 | 需要 AI 服务;处理时间受图库规模和硬件影响 | | 地图、足迹、5A 景区 | 可用 | 依赖照片定位信息和地图配置 | | 火车票、飞机票等票据能力 | 可用 | 识别效果依赖照片清晰度与票据类型 | | AI 助手、外部模型、Agent CLI | 可选 | 需配置模型或 Token;外部模型可能传输数据到服务商 | | 自动 Vlog、智能精修等增强创作 | 规划中 | 不应作为当前版本的可用能力 | --- ## 1. 相册管理 ### 1.1 基础功能 | 功能 | 说明 | | --- | --- | | 照片上传 | 支持多文件上传,自动生成缩略图 | | 照片浏览 | 瀑布流/网格视图,支持筛选和过滤 | | 照片灯箱 | 全屏照片查看器,带导航功能 | | 照片元数据 | EXIF 数据提取与展示 | | Live Photo | 支持 iPhone、Vivo、OPPO、小米等手机的实况照片 | | 回收站 | 软删除功能,支持恢复已删除的照片 | ### 1.2 智能分类 | 功能 | 说明 | | --- | --- | | 人脸识别 | 基于 InsightFace 的人物识别与聚类 | | 场景分类 | 自动分类为夜景、宠物、美食、自拍等场景 | | OCR 识别 | 从照片中提取文字信息 | | 相似照片检测 | 查找视觉上相似的照片 | | 重复照片清理 | 基于哈希值的重复照片检测与清理 | | AI 照片分析 | AI 生成照片描述和评分 | --- ## 2. AI 能力 | 功能 | 说明 | | --- | --- | | AI 助手对话 | 与 AI 大模型对话,智能检索相册内容 | | 智能相册生成 | 根据描述自动生成相册(如"我在海边的自拍") | | 那年今日 | AI 推荐往年今天最具回忆价值的照片 | | 智能搜索 | 支持按人物、内容、时间、地点等维度搜索 | | 内置 AI 连接 | 开箱即用的内置多模态模型(MiniCPM-V-4_6),无需额外配置 | | 本地 LLM 托管 | 支持通过 llama.cpp 托管自定义模型,数据不出本机 | | 多模型支持 | 支持连接多个 AI 大模型(OpenAI、Ollama 等) | --- ## 3. 足迹与地图 | 功能 | 说明 | | --- | --- | | 足迹地图 | 在交互式地图上查看所有照片 | | 点亮的城市 | 统计并展示去过的城市,支持省/市/区县级别 | | 去过的景区 | 追踪去过的 5A 级景区,支持添加自定义景区 | | 足迹时间轴 | 按时间轴展示不同地点的照片 | | 轨迹视图 | 将一段时间内的地点连接起来,展示移动轨迹 | | 离线地图 | 支持下载多国离线地图数据 | --- ## 4. 行程票据 ### 4.1 火车票 | 功能 | 说明 | | --- | --- | | 火车票识别 | OCR 自动识别照片中的火车票信息 | | 火车票管理 | 增删改查火车票记录 | | 纸质票样式 | 仿真火车票展示(红票/蓝票样式) | | 火车票导出 | 支持导出为 PNG、CSV、JSON 格式 | ### 4.2 飞机票 | 功能 | 说明 | | --- | --- | | 飞机票识别 | 识别照片中的行程单截图 | | 飞机票管理 | 增删改查飞机票记录 | | 机票统计 | 按城市、距离、时长等维度统计 | ### 4.3 票据统计 | 功能 | 说明 | | --- | --- | | 年度票据报告 | 出行统计摘要 | | 城市统计 | 去过的城市及照片数量 | | 距离统计 | 旅行总里程 | | 乘客筛选 | 按乘客筛选票据记录 | --- ## 5. 相册类型 | 相册类型 | 说明 | | --- | --- | | 普通相册 | 传统相册功能,按时间线组织 | | 智能相册 | AI 根据描述自动生成 | | 人物相册 | 人脸识别后的人物照片集合 | | 位置相册 | 按地理位置组织的照片 | | 场景分类相册 | 按场景类型(夜景、美食等)分类 | | 条件相册 | 支持按标签、场景、人物、地点等条件筛选生成 | --- ## 6. 年度报告 | 功能 | 说明 | | --- | --- | | 照片墙 | 年度照片拼图展示 | | 照片日历 | 按日期展示年度照片 | | 城市榜单 | 去过的城市排名 | | 景区榜单 | 去过的景点排名 | | 行程时间轴 | 年度行程时间线 | | 线路里程 | 旅行线路与总里程 | | 季节分析 | 春夏秋冬各季节照片统计 | | 消费统计 | 机票、火车票消费统计 | | 最佳照片 | 年度 AI 评分最高的照片 | --- ## 7. 工具箱 | 功能 | 说明 | | --- | --- | | 照片批量转移 | 将照片批量移动或复制到指定目录 | | 照片自动整理 | 按时间(年/月/日)、人物、类别、地点整理到对应目录,支持平铺或递归目录结构 | | 修改照片元数据 | 支持根据文件名修改图片的拍摄时间 | | 相似照片清理 | 查找并清理视觉相似的照片 | | 重复照片清理 | 清理完全重复的照片 | | 质量清理 | 根据 AI 评分清理低质量照片 | --- ## 8. 用户管理 | 功能 | 说明 | | --- | --- | | 用户认证 | 登录、注册、密码重置 | | 多用户支持 | 用户之间数据隔离 | | 外部图库 | 添加外部文件夹作为数据源 | | 令牌管理 | API 令牌配置,支持免登录访问 | | 任务管理 | 后台任务监控与管理 | --- ## 9. 系统特性 | 功能 | 说明 | | --- | --- | | 侧边栏导航 | 可折叠的侧边栏,支持全局搜索 | | 主题色自定义 | 天空蓝、翡翠绿、紫罗兰、玫瑰红、琥珀橙 5 种主题色,全局一键切换 | | 深色模式 | 支持深色/浅色模式切换 | | 响应式设计 | 移动端友好的界面 | | Docker 部署 | 一键部署前端、后端、数据库、AI 服务 | | SKILL 支持 | 可接入 OpenClaw、Claude Code、Hermes Agent 等平台 | | ONNX Runtime | AI 服务全部迁移至 ONNX Runtime,移除冗余依赖 | --- ## 10. 待开发功能 | 功能 | 说明 | | --- | --- | | 图片编辑 | 裁剪、旋转、添加文字、添加标签等 | | 自动旅行日志 | 根据照片自动生成旅行记录 | | 朋友圈九宫格 | 自动生成可分享的九宫格图片和文案 | | MCP 协议支持 | MCP 协议通信 | --- # TrailSnap 用户指南 - Source: https://trailsnap.cn/docs/guide/user.html - Markdown: https://trailsnap.cn/docs/guide/user.md - Category: 使用指南 - Language: zh-CN # TrailSnap 用户指南 ## 1. 快速开始 ### 主界面概览 登录后,您将看到系统主页(Dashboard),其中包含了: - **数据概览**:展示照片总数、相册数、足迹点等统计信息。 - **最近回忆**:时间轴形式展示最近上传的照片或活动。 - **功能快捷入口**:快速访问相册、票据、地图足迹等功能。 ### 添加外部图库 1. 点击导航栏的“设置->外部图库” 2. 输入外部图库的地址,例如 /app/photos (注意docker挂载路径) - 例如你的docker挂载路径是:`/home/user/photos:/app/Photos/` - 如果你想添加原路径为:`/home/user/photos/海边`,则在TrailSnap中添加的路径为:`/app/Photos/海边` - 如果你想把整个 `/home/user/photos` 目录都作为外部图库,则在TrailSnap中添加的路径为:`/app/Photos/` 3. 点击确认,系统会自动扫描该目录下的所有照片(任务进度可以在“设置->任务管理”中查看)。 4. 有问题可以参考[目录设置](./settings/directories.md) ### 使用地图服务 如果你需要使用地图服务(在地图上显示照片、自定义景区位置等),请确保在“设置->地图服务”中配置了正确的地图 API 密钥。[查看配置教程](./settings/mapsetting.md) ![](/images/map.png) ## 2. 相册管理 ### 创建相册 1. 点击导航栏的“相册”或“新建相册”按钮。 2. 输入相册名称、描述,并选择相册封面(可选)。 3. 点击确认即可创建。 ### 上传照片 1. 进入任意相册或点击全局“上传”按钮。 2. 支持拖拽上传或点击选择文件。 3. 支持批量上传,系统会自动读取照片的 EXIF 信息(拍摄时间、地点等)。 ### 照片浏览 - **时间轴视图**:按拍摄时间顺序排列照片,适合回顾旅程。 - **地图视图**:在地图上显示照片拍摄地点,点亮你的足迹。 - **详情查看**:点击照片可查看大图及详细元数据(ISO、快门、设备型号等)。 ## 3. 智能功能 TrailSnap 内置了强大的 AI 服务,为您提供以下智能体验: ### 人脸识别与聚类 - 系统会自动分析上传的照片,识别其中的人脸。 - 自动将同一人物的照片归类到“人物相册”中。 - 您可以为识别出的人物命名,系统会自动关联该人物的所有照片。 ### 智能搜索 (OCR & 内容识别) - **文字搜索**:支持搜索照片中的文字(如路牌、菜单、票据上的文字)。 - **语义搜索**:直接描述照片内容进行搜索,例如“海边的日落”、“滑雪的朋友”,AI 能理解您的自然语言描述。 ## 4. 行程与票据 这是 TrailSnap 专为旅行者设计的特色功能。 ### 票据管理 - **自动识别**:上传火车票、飞机票、景区门票或演唱会门票的照片。 - **OCR 提取**:系统会自动提取票据上的关键信息(出发地、目的地、时间、车次/航班号、座位号等)。 - **手动录入**:如果识别有误,支持手动修改或补充信息。 ### 行程时间轴 - 系统会根据您的票据时间和照片时间,自动生成一条完整的“旅行时间轴”。 - 您可以清晰地看到从出发到返程的完整轨迹。 ## 5. 系统设置 在设置页面,您可以进行以下配置: - **个人信息**:修改头像、昵称、密码。 - **主题设置**:切换浅色/深色模式,或跟随系统自动切换。 - **存储设置**:查看存储空间使用情况。 - **任务管理**:查看后台任务进度(如正在进行的 AI 识别任务、缩略图生成任务)。 如有任何使用问题,请联系[我们](./feedback.md)或查阅 [开发者文档](../dev/guide.md)。 --- # Feature List - Source: https://trailsnap.cn/en/docs/guide/features.html - Markdown: https://trailsnap.cn/en/docs/guide/features.md - Category: User guide - Language: en # Feature List This document lists the complete feature set of TrailSnap, helping you quickly understand all its capabilities. ::: tip Reading feature status The list below describes current project capabilities. Features that need the AI service, an external model, or more hardware are called out; roadmap items should not be treated as a promise for the current release. ::: ## Current capabilities and requirements | Capability | Status | Requirements / notes | | --- | --- | --- | | Photo browsing, albums, timeline, metadata | Available | Import or scan photos first | | Faces, OCR, scene classification, similar/duplicate detection | Available | Requires the AI service; duration depends on library size and hardware | | Maps, footprints, 5A scenic spots | Available | Depends on photo location metadata and map configuration | | Train, flight, and other ticket features | Available | Recognition quality depends on photo clarity and ticket type | | AI assistant, external models, Agent CLI | Optional | Requires model or token configuration; external models may transmit data to their provider | | Auto Vlogs and smart retouching | Planned | Not a current release capability | --- ## 1. Album Management ### 1.1 Basics | Feature | Description | | --- | --- | | Photo upload | Multi-file upload with automatic thumbnail generation | | Photo browsing | Waterfall/grid view with filtering and sorting | | Photo lightbox | Full-screen photo viewer with navigation | | Photo metadata | EXIF data extraction and display | | Live Photo | Supports iPhone, Vivo, OPPO, Xiaomi and more | | Recycle bin | Soft delete with photo recovery | ### 1.2 Smart Classification | Feature | Description | | --- | --- | | Face recognition | InsightFace-based person identification and clustering | | Scene classification | Auto-classify into night view, pets, food, selfie, etc. | | OCR | Extract text from photos | | Similar photo detection | Find visually similar photos | | Duplicate photo cleanup | Hash-based duplicate detection and cleanup | | AI photo analysis | AI-generated photo descriptions and scores | --- ## 2. AI Capabilities | Feature | Description | | --- | --- | | AI assistant chat | Chat with LLMs to intelligently search album content | | Smart album generation | Auto-generate albums from descriptions (e.g. "my selfies at the beach") | | On This Day | AI recommends the most memorable photos from past years | | Smart search | Search by person, content, time, location, and more | | Built-in AI connection | Out-of-the-box multimodal model (MiniCPM-V-4_6), no extra configuration needed | | Local LLM hosting | Host custom models via llama.cpp — data never leaves your machine | | Multi-model support | Connect to multiple LLMs (OpenAI, Ollama, etc.) | --- ## 3. Footprints & Maps | Feature | Description | | --- | --- | | Footprint map | View all photos on an interactive map | | Lit-up cities | Track visited cities at province/city/district level | | Visited scenic spots | Track visited 5A scenic spots; supports custom spots | | Footprint timeline | Browse photos by time across different locations | | Trajectory view | Connect locations across a time range to show travel routes | | Offline maps | Download offline map data for multiple countries | --- ## 4. Itinerary Tickets ### 4.1 Train Tickets | Feature | Description | | --- | --- | | Ticket recognition | OCR auto-recognition of train ticket info from photos | | Ticket management | CRUD for train ticket records | | Paper-style tickets | Simulated train ticket display (red/blue styles) | | Ticket export | Export as PNG, CSV, or JSON | ### 4.2 Flight Tickets | Feature | Description | | --- | --- | | Ticket recognition | Recognize itinerary screenshots from photos | | Ticket management | CRUD for flight ticket records | | Flight statistics | Statistics by city, distance, duration, etc. | ### 4.3 Ticket Statistics | Feature | Description | | --- | --- | | Annual ticket report | Travel statistics summary | | City statistics | Visited cities and photo counts | | Distance statistics | Total travel mileage | | Passenger filtering | Filter tickets by passenger | --- ## 5. Album Types | Album Type | Description | | --- | --- | | Standard album | Traditional album organized by timeline | | Smart album | AI auto-generated from descriptions | | People album | Person-grouped photo collection from face recognition | | Location album | Photos organized by geographic location | | Scene album | Photos classified by scene type (night view, food, etc.) | | Conditional album | Auto-generated by filtering on tags, scenes, people, locations, etc. | --- ## 6. Annual Report | Feature | Description | | --- | --- | | Photo wall | Yearly photo collage display | | Photo calendar | Browse photos by date | | City rankings | Top visited cities | | Scenic spot rankings | Top visited scenic spots | | Travel timeline | Yearly travel timeline | | Route mileage | Travel routes and total mileage | | Seasonal analysis | Photo stats across spring/summer/fall/winter | | Spending stats | Flight and train ticket spending | | Best photos | Top AI-scored photos of the year | --- ## 7. Toolbox | Feature | Description | | --- | --- | | Batch photo transfer | Move or copy photos to a specified directory in bulk | | Auto-organize photos | Organize by time (year/month/day), person, category, or location; flat or recursive directory structure | | Modify photo metadata | Set capture time from filename | | Similar photo cleanup | Find and clean visually similar photos | | Duplicate photo cleanup | Clean exact duplicate photos | | Quality cleanup | Clean low-quality photos based on AI scores | --- ## 8. User Management | Feature | Description | | --- | --- | | User authentication | Login, registration, password reset | | Multi-user support | Data isolation between users | | External libraries | Add external folders as data sources | | Token management | API token configuration for login-free access | | Task management | Background task monitoring and management | --- ## 9. System Features | Feature | Description | | --- | --- | | Sidebar navigation | Collapsible sidebar with global search | | Theme customization | 5 brand colors (Sky, Emerald, Violet, Rose, Amber) that apply globally with one click | | Dark mode | Light/dark mode toggle | | Responsive design | Mobile-friendly interface | | Docker deployment | One-click deployment of frontend, backend, database, and AI services | | SKILL support | Integrate with OpenClaw, Claude Code, Hermes Agent, and more | | ONNX Runtime | All AI services migrated to ONNX Runtime with redundant dependencies removed | --- ## 10. Planned Features | Feature | Description | | --- | --- | | Image editing | Crop, rotate, add text, add tags, etc. | | Auto travel journal | Auto-generate travel records from photos | | Social media 9-grid | Auto-generate shareable 9-grid images with captions | | MCP protocol support | MCP protocol communication | --- # TrailSnap User Guide - Source: https://trailsnap.cn/en/docs/guide/user.html - Markdown: https://trailsnap.cn/en/docs/guide/user.md - Category: User guide - Language: en # TrailSnap User Guide Welcome to TrailSnap! This guide covers the main features and how to use them. ## 1. Quick Start ### Dashboard Overview After logging in, you will see the system dashboard, which includes: - **Data Overview**: Displays statistics such as total photos, albums, and footprint points. - **Recent Memories**: Displays recently uploaded photos or activities in a timeline format. - **Feature Shortcuts**: Quick access to albums, tickets, map footprints, and other features. ### Add External Library 1. Click "Settings -> External Libraries" in the navigation bar. 2. Enter the path of the external library (this is the Docker container path). - Example Docker mount: `/home/user/photos:/app/Photos/` - If you want to add the original folder `/home/user/photos/sea`, then add `/app/Photos/sea` in TrailSnap - If you want to add the whole `/home/user/photos` directory, then add `/app/Photos/` 3. Click Confirm, and the system will automatically scan all photos in that directory (task progress can be viewed in "Settings -> Task Management"). 4. See [Directories](/en/docs/guide/settings/directories) for common issues. ### Map Service If you want map features (view photos on map, edit custom scenic spots, etc.), make sure you configured your map provider in **Settings → Map Service**. See [Map Settings](/en/docs/guide/settings/mapsetting). ![](/images/map.png) ## 2. Album Management ### Create Album 1. Click "Albums" or the "New Album" button in the navigation bar. 2. Enter the album name, description, and select an album cover (optional). 3. Click Confirm to create. ### Upload Photos 1. Enter any album or click the global "Upload" button. 2. Supports drag-and-drop upload or click to select files. 3. Supports batch upload; the system will automatically read the photo's EXIF information (shooting time, location, etc.). ### Photo Browsing - **Timeline View**: Arranges photos in chronological order of shooting, suitable for reviewing journeys. - **Map View**: Displays photo shooting locations on the map, lighting up your footprints. - **Detail View**: Click on a photo to view the large image and detailed metadata (ISO, shutter, device model, etc.). ## 3. Smart Features TrailSnap has built-in powerful AI services to provide you with the following intelligent experiences: ### Face Recognition & Clustering - The system automatically analyzes uploaded photos and identifies faces. - Automatically groups photos of the same person into "People Albums". - You can name the identified people, and the system will automatically associate all photos of that person. ### Smart Search (OCR & Content Recognition) - **Text Search**: Supports searching for text in photos (such as street signs, menus, text on tickets). - **Semantic Search**: Search by directly describing the photo content, such as "sunset by the sea", "friends skiing", AI can understand your natural language description. ## 4. Itinerary & Tickets This is a featured function of TrailSnap designed for travelers. ### Ticket Management - **Automatic Recognition**: Upload photos of train tickets, flight tickets, scenic spot tickets, or concert tickets. - **OCR Extraction**: The system automatically extracts key information from tickets (departure, destination, time, train/flight number, seat number, etc.). - **Manual Entry**: If recognition is incorrect, manual modification or supplementation of information is supported. ### Itinerary Timeline - The system automatically generates a complete "Travel Timeline" based on your ticket times and photo times. - You can clearly see the complete trajectory from departure to return. ## 5. System Settings On the settings page, you can configure the following: - **Personal Information**: Modify avatar, nickname, password. - **Theme Settings**: Switch between light/dark modes, or follow the system automatically. - **Storage Settings**: View storage space usage. - **Task Management**: View background task progress (such as ongoing AI recognition tasks, thumbnail generation tasks). If you have any questions, see [Feedback](/en/docs/guide/feedback) or the [Developer Guide](/en/docs/dev/guide). --- # 更新日志 - Source: https://trailsnap.cn/docs/guide/changelog.html - Markdown: https://trailsnap.cn/docs/guide/changelog.md - Category: 参考信息 - Language: zh-CN # 更新日志 ## 2026-10-19 (0.18.1) ### 优化功能 - 火车票截图识别更准:支持无「站」字后缀的站名、新增车站和繁简车厢座位,缺车次时自动补充整图识别,日期不再受广告和状态栏干扰。 - 桌面端手机连接端口被占用时自动换用新端口并提示重新扫码;设置页新增自动或自定义端口选择,启动失败页可直接修改。 - 旧图库升级校验只核对本次实际复制的照片,外部原照片被修改或磁盘离线不再阻止升级;校验结果按启动复用,验证更快。 - 支持单张照片重新提取元数据,导入时缓存的 EXIF 可强制刷新。 - 统一所有下载安装包命名(版本-组件-平台-架构),官网下载页拆分 NAS 部署与桌面端安装,Docker 模板更换国内镜像源。 ### Bug 修复 - 修复全量任务重做无法执行的问题,任务管理可重新执行缩略图、元数据、票据等全量任务。 - 修复 AI 模型下载等待状态未清理导致的任务积压,模型就绪后自动继续。 - 修复桌面端退出后任务进程残留占用照片文件的问题。 - 修复火车票与机票类型误判,广告年份不再覆盖真实行程日期。 ## 2026-10-19 (0.18.0) ### 新增功能 - 支持 360° 全景照片:识别带有效 GPano 元数据的全景图,支持拖动环视、缩放、全屏与画质切换,并可筛选图库中的全景照片。 - Windows 桌面端统一安装版与便携版:各文件夹可使用独立图库,支持 ZIP 便携包、应用内更新和旧版本图库自动迁移。 - 照片查看设置新增「自动查看原图」,普通照片与全景照片统一遵循画质偏好。 ### 优化功能 - Windows 旧图库升级展示检查、复制、校验和启动验证进度;可在安全阶段暂停、重试,设置页统一展示实际的「行影集文件夹」。 - 完善图库找回、独立备份、搬迁及失败恢复体验,同版本重新安装可修复程序文件。 - 照片查看器优化鼠标定位缩放、拖动边界和原图加载过渡,调整桌面工具栏、手机底栏与菜单动效。 - 页面切换增加加载反馈,按网络状况预加载;优化记忆、地点查询和相册网格浏览。 - AI 模型未就绪时,照片分析任务显示具体等待原因,模型准备完成后自动继续。 - 需求平台完善 Agent 规格编写与编码交付流程,并支持 OpenAI 作为交付 Provider。 ### Bug 修复 - 修复桌面升级、导入和照片整理过程中路径不一致及失败恢复问题,完善安装与卸载时的图库保留。 - 修复异常 GPS 数值和任务元数据导致处理失败的问题。 - 修复原图加载期间的照片显示、全景查看及移动端菜单交互问题。 ## 2026-10-12 (0.17.4) ### 新增功能 - 桌面端 AI 扩展更新体验完善:设置页可检查更新、查看与 Server 的兼容状态和当前平台,支持手动下载与离线导入;已安装扩展达到最低兼容版本即可继续使用,不会强制重复下载 - 共享照片选择弹窗全新升级:支持搜索定位照片,人物封面、相册封面、头像等场景统一复用;手机端新增字母条快速滚动定位 - 人物编辑支持直接从图库多选照片作为封面候选 ### 优化功能 - 人脸识别性能大幅提升:优化桌面端人脸匹配查询与批次并发,修复推理结果异常时的 CPU 自动重试,识别吞吐和 CPU 利用率明显改善 - 后台任务调度更聪明:出现更高优先级任务(如扫描、缩略图)时 AI 任务主动让位,等待在途批次完成后自动切换,整理照片不再被后台 AI 分析卡住 - 任务队列新增调度索引并关联照片,照片删除时自动清理关联任务;旧库升级时自动补齐关联并回收 SQLite 空间 - 元数据提取复用缓存结果,颜色分析改用缩略图,减少重复读取原图,扫描整理更快 - 磁盘读写按操作粒度限流,视频元数据、动图提取等媒体处理不再长时间占用 IO ### Bug 修复 - 修复桌面年度报告照片和头像加载失败的问题 - 修复视频元数据把封面图等二进制数据写入 EXIF 导致数据膨胀的问题,并提供 SQLite 清理工具 - 修复 PostgreSQL 首次部署时向量类型导入失败的问题 - 修复人物封面、相册封面、头像更换时选择照片的入口与交互问题 ## 2026-10-11 (0.17.3) ### 新增功能 - 桌面端新增「数据目录」设置:可将照片库整体迁移到其他磁盘(如 D 盘或移动硬盘),迁移前自动等待任务和上传完成,失败自动回退,原目录保留为备份 - 桌面端新增「连接手机 App」:提供局域网地址与二维码,手机扫码即可备份照片到同一图库;端口固定沿用,电脑 IP 变化时可重新扫码 - 照片查看器新增「在文件管理器中定位原文件」入口 ### 优化功能 - 桌面端冷启动大幅提速:双击图标到可用约 18 秒缩短至 4 秒左右,手机局域网自动探测等功能不受影响 - 手机备份与上传提速明显:原文件保存确认时间缩短约 88%,缩略图与元数据交给后台处理;分块上传支持断点续传,失败文件不阻塞后续备份 - 后台任务调度更可靠:AI 任务按类型批量执行、减少模型切换;磁盘读写按卷限流,扫描和整理期间界面更流畅 - HEIC/HEIF 照片在浏览器中直接显示为预览图,无需下载即可查看 - 上传队列挂载到应用层,收起窗口或切换页面不中断上传 ### Bug 修复 - 修复后台任务完成后照片页整页闪烁刷新的问题 - 修复桌面端 AI 对话流式响应中断(502)与 Windows 下闪现黑色控制台窗口的问题 - 修复加密 AppData 环境下桌面端配置保存失败的问题 - 修复手机端照片查看器中缩略图被操作栏遮挡的问题 - Windows 安装包升级时自动关闭正在运行的 TrailSnap,不再需要手动退出 ## 2026-10-09 (0.17.2) ### 新增功能 - 票据夹全新升级:车票与机票统一浏览,支持将票据关联到相册和照片,票据详情可查看关联内容,从照片回忆也能找回当时的行程 ### 优化功能 - 统一移动端日期与时间选择器,支持日期、时间、月份、范围等多种模式,操作更顺手 - 优化移动端相册与回收站交互,支持长按批量选择;导航切换时自动关闭多余浮层 - 朋友圈式回忆布局优化,高亮照片撑开更合理的展示高度 - 「那年今日」移动端支持滑动切换,误触不再触发点击 - 弹层层级统一管理,新弹窗始终显示在已打开面板之上 ### Bug 修复 - 修复照片时间轴排序卡顿,修复 EXIF 方向导致的照片宽高显示错误 - 修复首次安装注册账号时被铁路数据初始化阻塞的问题 - 修复偶发的读取请求失败,瞬时网络错误自动重试,重复连接错误不再重复提示 ## 2026-10-04 (0.17.1) ### 新增功能 - 移动端照片日记支持单页阅读、文字自动分页、日期选择和手势翻页 ### 优化功能 - 统一照片、相册和记忆页面的液体玻璃工具栏与响应式操作菜单,小屏使用底部弹出面板 - 调整首页、相册与记忆页面的标题层级、卡片和留白,改善移动端浏览体验 - 精简 Server Docker 镜像:本地实测 AMD64 / ARM64 压缩层总量减少约 61% / 59%,保留常见视频读取、缩略图与一日一帧影片生成能力 ### Bug 修复 - 修复 Android 系统栏安全区与键盘弹出时的布局避让问题,改善照片封面与工具栏显示 - 改进 Server 多架构镜像构建与国内镜像仓库同步的稳定性 ## 2026-10-03 (0.17.0) ### 新增功能 - 人生章节:将一段时期的照片与记忆整理为章节,支持章节发现、手动编辑、日记阅读与故事浏览,让旅行、成长和生活阶段有清晰的脉络 - 记忆关系图:探索人物、地点和事件之间的关联,从一个熟悉的人或地点出发,找到相连的经历 - 人物时光线:按年份回顾单人或双人合影,支持隐藏与恢复片段、AI 解读,更方便查看家人、朋友的变化 - 一日一帧:通过日历挑选每日照片或视频片段,支持补齐空缺、编辑字幕、制作每天一秒的静音影片,并可预览、导出和管理作品 - 照片日记布局:按天阅读照片,展开查看当天更多画面 - 地图轨迹连线:在地图中连接拍摄地点,更直观地回看旅行路线 - 照片色彩重分析:支持后台批量重新分析照片颜色,更新色彩检索数据 ### 优化功能 - 本地大语言模型支持线程数配置,便于按设备性能调整运行资源 - 优化人物详情页布局,相册详情标题在滚动时保持可见 - 整理系统设置与常用操作界面,提升页面体验的一致性 - 更新多项依赖,改进安装构建稳定性 ### Bug 修复 - 修复人物和相册照片画廊虚拟滚动计算异常 - 修复地图拖动后坐标未同步,以及保存位置后行政区划未更新的问题 - 修复 HTTPS 反向代理部署下的混合内容请求问题 - 修复部分样式与 AI 并发处理问题 ### 升级说明 - 建议 Server、AI 服务与客户端同时更新;Server 启动时自动执行数据库迁移,升级前请备份数据库 - 一日一帧影片生成需要 FFmpeg、FFprobe、H.264 编码支持及可用中文字体;缺少这些组件时仍可选择每日瞬间,页面会提示影片生成不可用 ## 2026-09-24 (0.16.0) ### 新增功能 - 记忆片段:系统自动从照片的人物、地点、票据线索中发现候选记忆并在首页呈现,确认后成为正式记忆;支持从相册、多选照片或 AI 助手对话手动创建,每段记忆包含封面、事件时间线与关联照片、人物、地点、票据,支持编辑故事、合并拆分,AI 可根据照片生成记忆故事 - 地点时光对照:同一地点跨年份照片拖动分割线对比今昔,地点详情页与照片灯箱(「这里以前」)均可进入,支持年份轨道、更换对比照片、生成今昔对比作品,分享默认隐藏精确位置 - 人物相册新增合影组合视图:按同框人物组合聚合合影照片,「我和爸爸」「一家三口」各自成册,封面取组合内最新合影 - 人物封面自定义:人物详情页支持从本人照片挑选封面,编辑弹窗移动端升级为全屏 - 批量修时间工具新增相册模式:可直接选择指定相册作为处理范围,只处理相册内照片,存储位置不变 ### 优化功能 - 全站视觉升级:桌面侧边栏圆角按钮与主题色渐变激活态,移动端悬浮液体玻璃底栏与气泡指示器,统一设计令牌体系,导航分组收敛为照片/探索/更多并支持折叠记忆 - 智能相册总览升级:人物、地点、分类卡片直接展示真实内容封面,配合数据库索引优化加载更快 - 移动端相册操作:自定义相册长按弹出编辑/删除菜单,相册详情页新增更多菜单(编辑/更换封面/删除) - 移动端位置相册筛选改为底部弹出面板,地图信息抽屉支持三档拖拽吸附,3D 足迹地球移动端渲染分辨率提升 - AI 助手对话优化:模型选择弹窗重构,生成中显示加载动画并禁用重复操作 - 照片页数据管理治理:状态拆分解决跨页面数据污染,刷新后保留滚动位置,时间轴统计增加竞态保护 - 任务管理增强:任务状态 SSE 实时推送,支持分类状态筛选,全部完成给出提示;移动端备份通知可直达备份设置 - 登录注册页重构,统一认证页布局与视觉风格 ### Bug 修复 - 修复照片画廊在错误状态下误显示「空相册」占位提示的问题 - 修复去重/相似照片清理页面在部分浏览器下无法滚动的问题 - 恢复人物编辑弹窗打开后自动聚焦姓名输入框 - 修复视频预览时遮挡元素导致的交互干扰 ### 升级说明 - 可从 0.15.x 直接升级,升级时自动完成数据库迁移;建议 Server 与客户端同时更新 ## 2026-09-18 (0.15.0) ### 新增功能 - 位置相册新增 3D 足迹地图:沉浸式三维地球展示去过的城市与旅行连线,支持 2D/3D/地球三种视角、年份筛选、城市搜索、旅程回放与年份巡游,图层菜单可控制照片热力、省份边界与三维地形 - 需求平台 Web 管理界面支持管理员修改需求状态:目标状态按常用流转推荐,变更原因必填并记入时间线 - 需求平台新增 Agent 交付工作流:批准后的规格成为 Agent 唯一执行依据,交付任务、执行记录、PR 关联与澄清问答全程可视化,AI 分析过程支持流式反馈 - 需求平台支持导入 cc-switch 备份统计 Token 用量:按统一口径统计真实消耗与成本,提供趋势图、模型与设备分布及请求明细 ### 优化功能 - AI 需求分析支持为不同模型分别设置推理强度,可选更合适的模型档位 - 修复足迹年份边界问题,年底拍摄的照片不会因毫秒进位被算到下一年 ### Bug 修复 - 修复手机 App 天地图瓦片裂图:地图 SDK 默认图层不再绕过服务器代理直连,照片标记恢复正常渲染,升级后残留坏缓存自动失效 - 修复手机 App 连接新服务器失败的问题:扫码或手动输入新地址不再报 Failed to fetch,登录过期静默清除失效凭据,消除「扫码或自动查找」被踢回的死循环 ## 2026-09-11 (0.14.2) ### 新增功能 - 行影集需求平台上线:支持匿名提交需求与问题,查看审核结论、开发状态和版本计划,总览看板提供趋势与分布图表;应用内问题反馈入口同步切换 - 官网新增开发者博客,收录独立开发者 vibecoding 可靠性实践文章 ### 优化功能 - 天地图全面改用服务端 Key:网页、桌面端和手机 App 统一通过 TrailSnap Server 加载地图,真实 Key 不再进入地图资源 URL,Key 保存前由 Server 自动验证 - 地图设置页新增旧版 Key 更换提示,配套文档同步更新 ### Bug 修复 - 修复手机 App 地图大面积空白的问题:地图代理转发设备真实 User-Agent,避免天地图返回 403,失败响应不再被 WebView 缓存 24 小时 - 修复位置相册轨迹图、新建景区弹窗在部分环境下底图加载失败的问题 ### 升级说明 - 旧版本使用「浏览器端」天地图 Key 的用户需要前往天地图控制台创建「服务端」Key 并在设置中替换;如启用 IP 白名单,请填写 TrailSnap Server 的公网出口 IP ## 2026-09-08 (0.14.1) ### 新增功能 - 大模型配置支持为每个模型设置显示名称、上下文窗口和推理强度,照片分析与聊天对话可以分别选择更合适的模型 - Server 端 App 安装包缓存会自动清理旧版本与下载残留文件,应用内更新在弱网中断后可自动重试 ### 优化功能 - 手机备份并行计算文件校验值,并根据局域网状况自适应调整媒体与分片并发,减少小文件请求,大幅提升备份吞吐 - 移动端相册列表重新排版,信息更集中,浏览和操作更顺手 - 优化导航栏视觉与照片浏览体验,删除照片后可保持当前浏览位置 ### Bug 修复 - 修复手机备份增量扫描重复、实况照片 JPG+MP4 配对上传、落盘校验与类型识别问题,并保留手机端拍摄时间 - 修复大模型连接编辑保存异常,候选模型现在在连接编辑器中获取,聊天窗口只显示已保存模型 - 修复移动端扫码切换服务器被网络策略拦截的问题 - 优化实况图加载体验,减少等待和闪烁 ## 2026-09-07 (0.14.0) ### 新增功能 - 相册 Agent 正式上线:支持自然语言检索照片、发现旅行线索、生成人物时光机和回忆侦探故事,并可基于真实照片证据整理相册 - 新增 Agent 任务中心,集中查看待确认、执行中、失败和已完成的方案,支持失败重试、取消、继续、执行确认和撤销 - 新增相册医生修复闭环,可诊断相册计数、封面、描述、文件哈希、照片时间与地点,并生成可预览、可确认、可撤销的修复方案 - 新增安全清理方案:精确重复照片会移入回收站,空相册删除前需要文字确认,所有清理操作保留审计与撤销能力 - AI 旅行日志支持生成个性化 HTML 页面,可直接预览、导出、分享、生成长图或通过浏览器打印为 PDF - 新增只读 MCP 服务、Pi Agent 扩展和受限访问令牌,方便 Claude Code、OpenClaw、Codex 等外部 AI 安全查询相册数据 - 位置相册新增沉浸式足迹地图与分层 GPS 旅行轨迹,可按时间与距离查看行程脉络 ### 优化功能 - Android App 网络请求统一通过自部署 Server 转发,地图瓦片改由 Server 代理,减少混合网络与跨域问题 - 缩略图读取不再依赖数据库会话,并增加启动期存储缓存预热,大型相册浏览更流畅 - 主动回忆会生成可直接进入 Agent 对话的推荐卡片,从“提醒你去看”升级为“陪你去回忆” - 默认服务端口调整为 3180,官网安装脚本与 Docker 文档同步更新 ### Bug 修复 - 修复 Android 地图瓦片直连失败的问题,并优化应用图标视觉居中与单色细节 - 修复已取消任务可能从预取队列继续执行的问题,任务取消现在会立即生效 - 修复 Agent 流式输出、作品记录和后台任务辅助逻辑中的多处边界问题,提高长任务稳定性 ## 2026-09-04 (0.13.1) ### 新增功能 - 回收站支持跨页全选、清空回收站和全部恢复,大型图库无需逐页加载或传输全部照片 ID - 大批量清空任务支持后台执行并展示实时进度,避免长时间请求超时 ### 优化功能 - 重写回收站批量删除流程并补充数据库索引,万张照片清理实测由约 22 秒缩短至约 0.9 秒,同时减少对其他操作的阻塞 - 人脸聚类拆分为独立后台任务,不再阻塞识别队列;大型人脸库采用流式读取,峰值内存显著降低 - 自动人脸聚类会跳过短时间内无明显变化的重复计算,手动聚类仍会立即执行 - 统一全站滚动条样式,并优化桌面端与移动端页面的滚动区域 - 官网增强 AI 文档索引提示,便于 AI 助手定位并核对 TrailSnap 文档 ### Bug 修复 - 修复回收站存在缺失删除时间的数据时列表加载失败的问题 - 修复批量删除同一聚类中的多张照片时,聚类计数更新不准确的问题 - 修复人脸相似匹配可能跨用户扫描的问题,并确保采用当前用户的人脸聚类阈值 ## 2026-09-03 (0.13.0) ### 新增功能 - Android App 支持自动检查并下载新版本,可在应用内完成 APK 更新,支持进度展示、失败重试和跳过指定版本 - 新增视频元数据解析,支持从 MP4、MOV 等常见格式读取拍摄时间、位置和机型,让视频更准确进入时间线与地图 - AI 助手新增语义记忆检索,可在长对话中优先引用与当前问题相关的照片记忆 - AI 助手支持上下文自动压缩,长对话保留重点摘要和近期内容,减少上下文超限 - AI 助手输入框支持多行输入,Enter 发送、Shift+Enter 换行,并兼容中文输入法 ### 优化功能 - 移动端照片查看器改用三联轨道滑动,连续快切更顺滑,并补齐搜索结果、回收站、文件夹等页面的左右切换 - 移动端照片查看器参考系统相册重排信息与操作区,操作更集中,顶部信息更清晰 - 手机 App 重新设计备份与设置导航,优化照片多选与查看体验 - 人脸聚类算法向量化提速,大型照片库整理更快 - 官网新增 AI 友好文档与二维码入口,更新演示图片 ### Bug 修复 - 修复移动端备份中实况照片配对、失败任务重复上传、自适应相册备份速度和后台数据库连接隔离问题 - 修复移动端照片查看器轨道偏移、Android 启动图标安全区比例等问题 - 修复桌面端本地 API 前缀握手失败的问题 ## 2026-09-01 (0.12.1) ### Bug 修复 - 修复 Docker 部署从 0.11.0 升级时,数据库迁移提前读取尚未创建的 `backup_key` 字段,导致 Server 容器持续重启的问题 - 已经升级失败的实例可直接更新到 0.12.1,迁移会安全重试并继续完成;尚未升级的实例也可直接升级,无需手动修改数据库 ## 2026-08-31 (0.12.0) ### 新增功能 - Android App 新增系统相册增量备份,可选择目标文件夹、查看进度、暂停或继续任务,并保留原始媒体与成对的实况照片 - 外部图库新增桌面端管理能力与上传目标配置,支持把照片导入指定的外部目录 - 相似照片工具新增并排对比视图,筛选和清理相近画面时更直观 - “断舍离”照片筛选会保存处理决定与进度,离线操作可在恢复连接后同步 - 桌面端安装器支持按设备切换 AI 运行环境 ### 优化功能 - 统一桌面端、手机 App 与浏览器的连接入口,优化手机端服务器配置引导和 Docker 局域网服务发现 - 优化桌面端启动、登录会话与自动更新流程,减少重复配置和升级中断 - AI 任务可根据运行压力自适应调整并发并自动重试,模型下载完成后会恢复等待中的任务 - 简化 AI 性能选项,优化全站响应式布局、深色模式与键盘可访问性 - 调整多用户存储目录结构,强化用户文件隔离,并支持更长的照片路径 ### Bug 修复 - 修复移动端备份可能转码原始媒体、遗漏实况照片配对文件或错误处理可选字段的问题 - 修复视觉模型输出异常导致任务失败、模型下载后任务不恢复以及分析请求超时的问题 - 修复 Windows 下被占用的用户目录清理失败和部分移动端导航、时间线交互问题 ## 2026-08-22 (0.11.0) ### 新增功能 - AI 助手新增照片记忆能力,可从与具体照片相关的对话中沉淀重要回忆,并在后续交流中结合真实照片提供更连贯的回应 - AI 助手新增主动回忆,可在“那年今日”有照片时送上个性化问候,并通过侧边栏红点提醒查看 - 条件相册新增文件夹筛选,可多选文件夹并自动包含其全部子文件夹中的照片 - AI 模型管理新增多档 PP-OCRv6 文字识别模型与 Buffalo M 人脸模型,方便根据设备性能选择速度或效果 ### 优化功能 - 统一 AI 模型的查看、下载、切换与删除体验,模型切换更快,异常删除可自动回退到可用配置 - 优化 AI 助手照片搜索结果:探索性问题提供精简样本和聚合摘要,多图结果自动使用网格展示 - 更新 Web、PWA、Android 与 iOS 应用图标,统一各端品牌视觉 ### Bug 修复 - 修复 AI 助手侧边栏提醒影响无障碍名称、未登录时主动请求导致登录状态异常的问题 - 修复模型资源在桌面构建中的准备与地址配置问题,提升桌面 AI 扩展安装和启动稳定性 ## 2026-08-18 (0.10.2) ### 新增功能 - 照片查看器新增“重新识别”,可对单张照片重新执行人脸识别、文字识别、场景分类、视觉描述和图片向量分析,并实时查看处理进度与结果 ### 优化功能 - 手动发起的照片处理任务采用交互式优先级,可在后台分类暂停时继续执行,减少等待 - 优化官网下载按钮的容错,在 GitHub API 暂时不可用时仍可进入对应版本下载页 - 同步 Android 与 iOS 客户端版本信息,方便识别和覆盖安装新版本 ### Bug 修复 - 修复 Android App 连接 HTTP 自托管服务器时,照片、相册封面、头像和“那年今日”等图片被 WebView 安全策略拦截的问题 - 修复首次扫描大量照片时数据库连接耗尽,导致缩略图生成失败并引发后续任务连续失败的问题 ## 2026-08-16 (0.10.1) ### 新增功能 - 桌面端 AI 扩展补全完整服务能力,新增 AI 模型管理页面,可按需查看与管理识图模型;稳定 AI 运行时启动并内置人脸识别所需依赖 - 桌面端外链改为在系统浏览器中打开,邮箱与电话链接交由系统应用处理 ### 优化功能 - Windows MSI 安装包语言改为简体中文,安装界面与进度提示与应用保持一致 - 优化应用图标资源体积,安装包更小 - 优化官网下载与部署文档,新增 Docker 一键安装说明,修复下载页平台资源匹配规则 ### Bug 修复 - 修复桌面端天地图瓦片加载问题,相册位置页地图与轨迹视图可正常显示 - 修复桌面端打包后地图边界与位置数据 404,地图接口不再因工作目录不同而失效 ## 2026-08-15 (0.10.0) ### 新增功能 - 新增基于 Tauri 2 的跨平台桌面端,内置 SQLite 数据库,可在 Windows、macOS 和 Linux 上独立运行 - 桌面端新增可选 AI 扩展,支持按需安装运行环境并下载识图模型 - 手机 App 登录页支持切换服务器地址,并保存最近使用的服务器历史 - 外部图库支持通过桌面目录选择器或服务端目录浏览器选择照片文件夹 - 移动端照片网格支持双指缩放调整密度,并保持当前照片附近的浏览位置 - 地图设置支持管理和逐个验证多个天地图 Key,并可直接检测 AI 服务连通性 ### 优化功能 - 优化照片增量加载、跨页面状态同步、相册详情和移动端时间线导航 - 优化照片查看器、弹窗与 Android 返回键行为,返回操作会优先关闭当前浮层 - 精简侧边栏与移动端导航,重新组织旅程相关入口 - AI 助手消息支持显示用户自定义头像,移动端模型选择器布局更紧凑 - 一键安装脚本新增重装备份流程,可选择保留配置升级或清空重装 - 优化国内镜像兼容性、前端多架构镜像构建和发布产物命名 ### Bug 修复 - 修复桌面端 SQLite 日期统计、向量检索、启动和 AI 扩展运行问题 - 修复普通相册移除照片、回收站永久删除和机票更新反馈异常 - 修复单个照片目录挂载错误和 Android 调试包重复安装时的签名冲突 ## 2026-08-08 (0.9.2) ### 新增功能 - 已审核人物身份支持重新扫描,便于在人脸数据更新后重新识别照片 - 离线地图数据下载新增进度提示 - 离线逆地理编码数据持久化保存,减少重复下载与查询 - 演示模式支持自动填充登录账号和密码 ### 优化功能 - 国内部署可使用阿里云镜像仓库 - 优化前端首屏加载速度与 Nginx 传输 - 新增部署前检查与数据安全说明,并完善首页和 FAQ - 扩充照片、设置、媒体、人脸、相册等模块的自动化测试覆盖 ### Bug 修复 - 修复 AI 服务运行环境缺少 `libgomp1` 导致 llama-server 无法启动的问题 ## 2026-08-02 (0.9.1) ### 新增功能 - 新增基于 Capacitor 的 Android/iOS App 工程,支持在首次启动时填写并保存自托管 TrailSnap Server 地址 - 新增 Android APK 自动构建,推送 `v*.*.*` 标签后会将安装包与 CLI 产物上传到同一个 GitHub Release - Web 前端新增 PWA 支持,可安装到桌面或手机主屏幕,并优化离线资源与刷新体验 - 朋友圈 AI 文案生成支持实时展示思考过程 ### 优化功能 - 优化 Android 返回键和返回手势:优先关闭弹窗或返回上一级,在首页时切换到后台而不是直接退出 - 统一 App 与 CLI 发布规则:手动构建只保留 Actions Artifacts,正式版本标签才创建或更新 Release - 官网新增移动 App 安装、Server 地址配置、更新与隐私安全说明 ### Bug 修复 - 修复 Linux GitHub Runner 无法执行 Android Gradle Wrapper 的权限问题 - 修复 PWA 刷新和分支镜像标签相关问题 ## 2026-08-02 (0.9.0) ### 新增功能 - 新增**朋友圈日记**,支持按天生成、编辑和清除 AI 朋友圈文案,并展示每日主要地点与照片高光 - 新增**位置相册拼图视图**,支持全国/省份浏览、自动与手动选片、格子替换和相似照片去重 - 地图区块支持双击下钻,拼图视图支持回忆价值、画质、最新拍摄、随机等选片策略 - 移动端新增底部 Tab 导航、地图/拼图手势操作与 Agent 抽屉 - 用户信息持久化到本地,刷新页面后不再短暂显示默认昵称 ### 优化功能 - 优化 Server、AI 服务镜像构建,减少部署体积与启动开销 - AI 服务增加优雅停止与健康监控 - 优化朋友圈图片比例、移动端布局和拼图渲染性能 ### Bug 修复 - 修复朋友圈本地时区聚合、流式生成和单图比例显示问题 - 修复移动端真机拼图视图空白、位置编辑逆地理字段解析和最近去过层级跳转问题 - 修复人物相册空壳身份排序、图库选择器滚动空白、外部图库校验与任务跳转问题 - 修复部分后端校验错误显示为 `[object Object]` 的问题 ## 2026-07-28 (0.8.1) ### 新增功能 - 新增**外部图库一键接入向导**,可在设置中完成目录选择、路径映射与扫描配置;安装后也能继续追加照片目录 - 新增**全局通知中心**,桌面端铃铛集中展示后台任务和系统消息,并实时同步最新状态 - 新增定时版本更新检查,便于及时发现新版本 ### 优化功能 - 优化 AI 助手上下文裁剪与照片检索,在长对话和复杂图库中查询更稳定 - 演示模式支持 AI 助手对话,并完善示例照片补足、访问频率和上传限制 - 合并文件夹视图操作入口,修复弹层主题色和助手悬浮按钮半隐藏效果 - 扩充前端、后端与 AI 服务自动化测试,统一测试工作流并支持手动触发 ### Bug 修复 - 修复重新安装到同一目录时数据库密码未复用的问题 - 修复安装健康检查因 IPv6 或超时过短而误报启动失败的问题 - 修复上传照片后元数据请求 404、后续处理任务未派发的问题 - 修复外部图库管理员界面刷新后不显示的问题 - 修复 AI 服务异常时助手对话可能长时间卡住的问题 ## 2026-07-11 (0.7.0) ### 新增功能 - 新增**「断舍离」照片筛选**:左右滑动快速决定照片去留,轻松清理积压相册 - 新增**存储中心**:集中查看各存储用量,首页存储卡片支持点击跳转到对应照片筛选 - 照片编辑后**保留原图 EXIF 元数据**(拍摄时间、位置等),时间线与地图定位不再错乱 - AI 助手悬浮按钮支持**全屏拖动与边缘半隐藏**,不挡画面 - 点击搜索框**预热 AI 微服务**,避免首次搜索冷启动等待 - 初次使用自动跳转注册页 - 安装脚本**自动配置国内 Docker 镜像加速源**并按地域启用 ### 优化功能 - 回收站支持选择模式,批量恢复/删除更方便 - 设置、工具箱页面移动端体验优化 ### Bug 修复 - 修复照片编辑位置弹窗关闭后无法再次打开的问题 - 修复 worker 看门狗在仅剩暂停任务时循环重启的问题 ## 2026-07-07 (0.6.1) ### 新增功能 - 新增 **OpenVINO 推理后端**:统一 ONNX 后端选择逻辑,Intel CPU 环境可启用 OpenVINO 加速 AI 推理(OCR、人脸识别、图像分类、CLIP 语义搜索等) - 安装脚本自动检测 Intel CPU 并切换 openvino 模式,无需手动配置;AI 镜像标签统一为「版本号-模式」(如 `trailsnap-ai:0.6.1-openvino`) ### 优化功能 - 优化侧边栏任务管理器组件 - 更新开发指南启动命令,优化安装脚本逻辑 ## 2026-07-03 (0.6.0)[vibe coding提示词](/docs/dev/prompt/0.6.0) ### 新增功能 - 新增**「猜城市」游戏**:随机抽取相册中带位置信息的照片,让你猜拍摄城市,并根据距离与方位给出提示,用一种新方式回顾旅途照片 - 新增**任务并发度设置**,可调节后台任务并发数,灵活平衡导入速度与资源占用 - 新增**外部图库文件夹过滤**,扫描外部图库时自动跳过 NAS 索引目录(如 `@eaDir`、`#recycle`),避免照片重复统计 - 新增 `TS_DB_URL` 环境变量支持 ### 优化功能 - AI 推理性能大幅提升:GPU 推理优先、任务按类型聚合调度、推理并发化与单图容错,处理大批量照片更流畅 - 默认启用图片文件过滤设置 - 完善 e2e 测试套件(scan/light/full、P0/P1/smoke) - 更新官网品牌素材与社交链接 ### Bug 修复 - 修复任务进程持续打印错误日志的问题 - 修复相册任务未注册到任务策略导致无法执行的问题 - 修复 Windows 下 llm-server 启动失败的问题 - 修复前端镜像构建(`pnpm-workspace.yaml` 配置错误) - 修复 Docker 无效配置 ## 2026-06-27 (0.5.0) ### 新增功能 - 新增**用户昵称与头像**设置,个人资料更个性化 - 新增**朋友圈布局模式**,以时间流方式浏览照片,还原社交相册体验 - 新增**照片情绪与色彩分析**功能,自动识别照片情绪与主色调 - 新增**照片批量导出**功能,支持自定义命名模板(如 `{date}_{location}_{seq}`) - 新增**照片位置编辑**功能,支持单张调整与批量修改照片的拍摄位置 - 新增**位置统计视图**,按地点汇总照片数量与分布 - 新增**任务通知系统**,通过 SSE 实时推送任务进度,侧边栏集中管理任务 - 新增**快捷键管理**(`useHotkeys`),统一键盘交互体验 - 新增照片页直接上传入口与**反馈页面** - 新增服务**健康检查接口**,便于部署与监控 - 新增 **Windows 一键安装脚本**,简化部署流程 - 新增**文件夹过滤**功能,扫描外部图库时自动跳过 NAS 索引目录(如 `@eaDir`、`#recycle`),避免照片重复统计,并支持一键清理已索引的相关照片 ### 优化功能 - 优化导航栏与全局搜索体验 - 离线地图设置新增刷新按钮,优化 UI 与 API 返回字段 - 合并上传任务为 `PROCESS_BASIC`,简化任务流程 - 升级安装脚本至 v1.2.0,优化安全性与交互体验 ### Bug 修复 - 修复 `PhotoLightbox` 组件卸载时资源未释放和滚动锁定的问题 - 修复 Windows 一键安装脚本执行与中文乱码问题 - 移除情绪日历页面 ## 2026-06-07 (0.4.1) ### 新增功能 - 新增**图片编辑**功能,支持裁剪、旋转、涂鸦、文字、形状等编辑操作 - 新增**侧边栏导航**,重构前端布局,支持折叠模式 - 侧边栏折叠时增加鼠标悬浮文字提示 - 新增**侧边栏全局搜索**功能,快速查找照片、相册、人物等 - 新增**主题色自定义**,支持天空蓝、翡翠绿、紫罗兰、玫瑰红、琥珀橙 5 种主题色,全局一键切换 - 新增**侧边栏自定义导航项**,支持自定义侧边栏导航菜单 - 统一主题处理,提取复用组件 ### 优化功能 - 优化位置地图页面及视图组件,重构后端照片查询逻辑 - 优化多模块查询性能 - 统一图标并补充前端规范 - 优化页面 UI 布局与修复导入问题 ### Bug 修复 - 修复相册页主题色不响应与深色模式对比度问题 - 修复 primary 主题工具类映射缺失(hover/阴影不响应主题) ## 2026-05-28 (0.4.0) [vibe coding提示词](/docs/dev/prompt/0.3.10) ### 新增功能 - 照片自动整理工具箱新增"时间目录结构"选项,支持平铺结构和递归嵌套结构(如 `2026/01/01`) - 照片自动整理支持按人物自动归类 - 新增内置 AI 连接功能,开箱即用,默认使用 MiniCPM-V-4_6-Q4_K_M 多模态模型 - 新增本地 LLM 服务托管与代理能力,支持通过 llama.cpp 托管自定义模型 ### 优化功能 - 迁移所有 AI 服务至 ONNX Runtime,移除冗余依赖 - 重构 AI 服务 LLM 运行与部署逻辑,使用原生编译的 llama-server 二进制替代 pyllama-cpp-python - 实现队列满时按优先级过滤拉取任务并更新任务块大小 - 优化图片处理,支持 WebP 格式自动转换 - 优化大模型设置页面,添加内置连接标识 - 优化失败任务清除机制 - 修复整理任务进度计算异常问题 ## 2026-05-14 (0.3.9) [vibe coding提示词](/docs/dev/prompt/0.3.9) ### 新增功能 - 智能分类新增“滑雪”分类 - 智能分类支持设置封面照片 - 支持删除识别到的人物 ### 优化功能 - 缩略图采用webp格式,减少缩略图大小 - 修复任务优先级异常的问题 - 优化智能分类准确率,减少误分类 - 优化部分Ui ## 2026-04-28 (0.3.8) [vibe coding提示词](/docs/dev/prompt/0.3.8) ### 新增功能 - 新增“回收站”功能,用户可以恢复已删除的照片。 - 新增TrailSnap CLI工具,用户可以通过命令行与TrailSnap进行交互。 - 新增SKILL功能,用户可以接入OpenClaw、Claude Code等平台。 ### 优化功能 - 优化部分Ui - 优化AI聊天体验 ## 2026-04-22(0.3.6) [vibe coding提示词](/docs/dev/prompt/0.3.6) ### 优化功能 - 修复任务异常卡住的问题 - 优化任务进程管理,减少内存占用 - 加快AI大模型任务处理速度,减少等待时间 - 优化AI对话思考过程展示,用户可以查看大模型思考内容 - 优化智能分类准确率 ## 2026-04-18(0.3.3)[vibe coding提示词](/docs/dev/prompt/0.3.3) ### 新增功能 - 支持手动分类照片,用户可以自己管理分错的照片 - 支持添加多个大模型连接,用户可以选择使用的大模型 ### 优化功能 - 优化照片分类、车票识别准确率 - 优化任务处理效率,减少等待时间 - 修复部分场景下删除照片失效的问题 - 支持旧版苹果.jpg和 .mov 格式的实况图视频 - 优化部分Ui ## 2026-03-29(0.3.2)[vibe coding提示词](/docs/dev/prompt/0.3.2) ### 新增功能 - 新增“AI助手”功能,用户可以在应用中与AI大模型进行对话,智能检索相册内容,AI比你更懂相册 - 位置相册新增“足迹时间轴”功能,按时间轴展示相册中不同地点的照片,用户可以查看自己在不同时间点的足迹 - 位置相册新增“轨迹视图”功能,将一段时间内照片的地点连接起来,展示用户在不同时间点的移动轨迹 - 新增“令牌管理”功能,用户可以新建令牌,方便其他应用免登录访问相册数据 ### 优化功能 - 位置相册和车票统计页面支持自定义时间范围筛选 - 修复苹果的HEIC格式的照片元数据解析失败的问题 - 优化搜索功能,修复搜索景区失败的问题,优化搜索建议加载速度 - 优化部分Ui ## 2026-03-21(0.3.1)[vibe coding提示词](/docs/dev/prompt/0.3.1) ### 新增功能 - 新增“相似照片清理”功能 - 首页新增“拍摄日历图” - 视频播放支持倍速 ### 优化功能 - 修复删除照片后,实况图、缩略图残留问题 - 修复视频上下切换黑屏的问题 - 优化人物相册加载速度 - 修复车票智能识别权限异常的问题 - 优化部分Ui ## 2026-03-12 (0.3.0) [vibe coding提示词](/docs/dev/prompt/0.3.0) ### 新增功能 - 新增多用户支持,用户之间数据隔离 - 新增AI大模型分析照片功能,让AI分析照片内容,生成描述和评分。 - 新增“那年今日”功能,用户可以查看往年今天的照片,按图片评分排序。 - 新增“清理相册”功能,用户可以根据评分清理相册中所有AI分析完成的照片。 ### 优化功能 - 支持隐藏某个人物相册 - 支持添加照片到人物相册 - 优化人物识别精度 - 优化部分Ui ## 2026-02-25 (0.2.3) [vibe coding提示词](/docs/dev/prompt/0.2.3) ### 新增功能 - 新增图片文件过滤功能 - 位置相册新增按年份筛选功能 ### 优化功能 - 修复人物相册下一张照片显示顺序混乱的问题 - 优化页面布局和Ui ## 2026-02-05 (0.2.2) [vibe coding提示词](/docs/dev/prompt/0.2.2) ### 新增功能 - 支持显示并导出纸质车票样式(蓝票、红票) ### 优化功能 - 新增天地图瓦片缓存减少网络请求次数 - 优化位置相册地图渲染 - 修复元数据重建任务资源释放异常的问题 - 优化部分Ui显示 ## 2026-02-01 (0.2.0) [vibe coding提示词](/docs/dev/prompt/0.2.0) ### 新增功能 - 支持iPhone live photo - 支持下载多个国家的离线地图数据,或者上传自定义数据(需要重新执行“元数据提取”任务) - 地图相册新增国内358个5A级景区的位置信息(需要重新执行“元数据提取”任务) - 支持编辑自定义景区位置 - 支持搜索图片文字、地点、人物、相册、文件夹、文件名等 - 支持识别飞机票(订单截图),**需要重新执行“车票识别”任务**。 - 支持车票导入、导出功能(支持csv和json格式) ### 优化功能 - 修复照片重复显示的问题 - 修复重新执行人脸识别任务后,默认封面丢失的问题 - 优化车票识别的准确性和速度 - 修复上传大于1M的图片失败的问题 - 优化部分Ui ## 2026-01-17(0.1.0) | 功能 | 实现情况 | 描述 | | --- | --- | --- | | 上传并查看照片和视频 | √ | 支持上传本地照片和视频文件,查看和播放。 | | 添加外部文件夹 | √ | 可以添加外部文件夹作为数据源,TrailSnap 会自动扫描并索引其中的照片和视频。 | | live photo | √ | 支持vivo、oppo、小米等手机 | | **时间轴** | √ | 丝滑的时间轴滚动效果。 | | 在地图上查看照片 | √ | 可以在地图上查看所有上传的照片,点击照片可以查看详情,也可以按省、市、区单独查看(支持列表视图和地图视图)。 | | **点亮的城市** | √ | 查看所有上传的照片中出现的城市,点击城市可以查看该城市的所有照片。 | | **去过的景区** | 开发中 | 统计去过的5A级景区,点击景区可以查看该景区的所有照片,也可以自定义景区位置,自动筛选在景区范围内的照片。 | | 人脸识别 | √ | 支持识别照片中的人物,自动添加人物标签。 | | 场景智能分类 | √ | 支持根据照片中的场景自动分类,例如:夜景、宠物、美食、自拍等。 | | 智能搜索 | √ | 支持根据照片中的人物、画面内容、时间等进行搜索。 | | 标签 | √ | 支持手动添加和删除标签,也可以根据 AI 识别结果自动添加标签。 | | 条件相册 | √ | 支持根据标签、场景、人物、地点等条件筛选照片,生成自定义相册。 | | 智能相册 | √ | 支持根据照片中的内容自动生成相册,例如:“我和女朋友在海边的自拍”等。 | | **车票识别** | 开发中 | 支持识别照片中的火车票和行程单,自动提取行程信息。 | | **年度报告** | 开发中 | 自动生成2025年的出行统计报告,包括照片墙、出行城市、出行景点、行程时间轴、线路里程等。 | | **旅行日志** | 待开发 | 支持用户手动输入或 AI 识别出的行程信息,生成旅行日志。 | --- # 数据、隐私与备份 - Source: https://trailsnap.cn/docs/guide/data-safety.html - Markdown: https://trailsnap.cn/docs/guide/data-safety.md - Category: 参考信息 - Language: zh-CN # 数据、隐私与备份 TrailSnap 是自托管应用:照片、数据库和账号数据保存在你部署的服务器或 NAS 上。项目不会因为你安装了 TrailSnap 而自动接收你的照片;但服务器的实际管理员仍需要负责访问控制、备份和公网安全。 ## 数据会保存在哪里 | 数据 | 默认位置 | 你需要注意的事 | | --- | --- | --- | | 原始照片与缩略图 | 你挂载到服务的照片目录 | 不要在任务执行中直接移动或删除文件 | | 相册、账号、任务和索引 | PostgreSQL 数据库卷 | 升级和迁移前应备份 | | AI 分析结果 | 数据库及相关存储 | 删除照片后应按需要清理关联任务与结果 | | Agent Token | TrailSnap 数据库 | 仅授予必要范围,泄露后立即撤销 | ## 使用 AI 时的数据边界 - 使用本地模型或本地托管 LLM 时,推理数据保留在你的设备和服务器内。 - 配置 OpenAI、Ollama 远程实例或其他第三方模型服务时,发送哪些文字、图片或元数据取决于你启用的功能与服务商设置。请先阅读该服务的隐私条款,并避免把敏感照片用于不受信任的服务。 - 不要把 API Key、Agent Token 或含有完整 Token 的截图发布到 Issue、群聊或日志中。 ## 部署安全清单 1. 仅在家庭局域网使用时,也请为 TrailSnap 账号设置强密码。 2. 公网访问请使用域名、HTTPS 和反向代理;不要直接暴露 PostgreSQL、管理端口或 Docker Socket。 3. 仅把必要端口开放给可信网络;手机 App 通过公网访问时必须使用 HTTPS。 4. 定期更新 TrailSnap 与 Docker 镜像,并在更新前阅读[更新日志](/docs/guide/changelog)。 5. 若多人共用服务器,为每位用户创建独立账号,不要共用管理员账号或 Token。 ## 备份与恢复 至少应备份两类内容:**照片目录**与 **PostgreSQL 数据库**。只备份其中一类,恢复后都会出现照片文件与相册记录不一致的风险。 ### 建议频率 - 照片目录:增量或实时同步到另一块磁盘 / NAS。 - 数据库:每天备份;在升级、迁移、批量整理或清理前额外备份一次。 - 定期做一次恢复演练,确认备份并非只“看起来存在”。 ### 恢复原则 1. 停止相关服务,避免恢复期间继续写入。 2. 使用同一时间点的照片备份和数据库备份恢复。 3. 启动服务后检查照片数量、相册、账号和任务状态;必要时重新执行扫描或索引。 不同部署方式的卷名和目录可能不同。请先在自己的 `docker-compose.yml` 与 `.env` 中确认实际路径,再执行备份或恢复命令。 ## 数据删除 删除应用中的照片、相册或账号不等于自动抹除所有备份。若需要彻底删除,请同时检查:照片目录、数据库备份、同步盘和第三方 AI 服务的相关记录。 --- # 识别效果展示 - Source: https://trailsnap.cn/docs/guide/demo.html - Markdown: https://trailsnap.cn/docs/guide/demo.md - Category: 参考信息 - Language: zh-CN # 识别效果展示 TrailSnap 搭载了 OCR 引擎,专为火车票识别进行了深度优化。 ## 车票识别效果展示 ## 核心优势 - **高精度字段提取**:精准定位并识别车次、日期、车站、座位号、票价等关键信息。 - **复杂背景适应**:无论是平整的扫描件还是带有背景的拍摄照片,都能保持高识别率。 - **结构化数据输出**:直接输出标准化的 JSON 数据,方便开发者集成和二次处理。 > **提示**:点击图片可查看高清大图。 --- # 问题反馈 - Source: https://trailsnap.cn/docs/guide/feedback.html - Markdown: https://trailsnap.cn/docs/guide/feedback.md - Category: 参考信息 - Language: zh-CN # 问题反馈 如果你在使用过程中遇到任何问题,或有任何建议,欢迎通过以下方式联系我们。 ## 加入社区 欢迎加入 TrailSnap 官方交流群,与其他用户和开发者一起交流心得。 ### QQ交流群 QQ Group QR Code ### 微信交流群 微信交流群 QR Code ### 微信公众号 微信公众号 QR Code ## 提交需求与反馈 如果你发现了 Bug、希望提出新功能或跟进需求的审核和版本计划,请访问行影集需求平台: [进入需求平台](https://feedback.trailsnap.cn/) 提交前请先搜索已有需求,避免重复;报告问题时请尽量附上复现步骤、产品版本和运行环境。 --- # 常见问题 - Source: https://trailsnap.cn/docs/guide/questions.html - Markdown: https://trailsnap.cn/docs/guide/questions.md - Category: 参考信息 - Language: zh-CN # 常见问题 ## 安装部署问题 1. 支持哪些部署方式? 当前面向用户的部署方式是 Docker Compose。源码运行主要用于开发贡献,不作为日常部署路径;请先安装 Docker 环境。 2. 支持哪些平台? 目前支持Windows、macOS、Linux平台。支持x86架构和arm架构。 ## 外部图库问题 1. 外部图库设置失败,显示目录不存在 [查看目录设置](./settings/directories.md) ## AI相关问题 1. 怎么调用api分析照片,或者分析完之后怎么查看结果 [查看AI相关配置](./settings/aisetting.md) ## 扫描、任务与照片 1. 首次扫描很久没有完成,是否正常? 首次扫描和 AI 分析耗时取决于照片数量、硬盘速度和模型配置。先在任务页面确认任务是否仍在运行,并查看服务日志。建议用小目录验证流程后再导入完整图库。 2. 为什么扫描不到照片或提示没有权限? 确认宿主机照片目录真实存在、Docker 已挂载该目录、服务具有读取权限。若要使用整理、重命名或清理工具,还需确认写入权限。详见[部署前检查](/docs/guide/preflight)。 3. 可以直接删除或移动照片文件吗? 建议通过 TrailSnap 的功能操作,或在变更后重新扫描。对照片目录进行大规模移动、重命名或删除前,应先备份。 ## 手机与网络 1. 手机无法连接服务器怎么办? 确保手机和服务器在同一局域网,使用服务器的局域网 IP 而非 `localhost`;再检查 Docker 端口映射、系统防火墙和 Wi-Fi 是否开启了 AP 隔离。Android App 的地址填写说明见[移动 App 使用指南](/docs/guide/mobile-app)。 ## 备份与升级 1. 更新前需要做什么? 更新前备份照片目录与 PostgreSQL 数据库,并阅读[更新日志](/docs/guide/changelog)。不要只备份其中一类数据。 2. 如何安全地使用外部 AI 或 Agent Token? 仅授予必要权限,不要公开 Token;通过公网访问时使用 HTTPS。完整说明见[数据、隐私与备份](/docs/guide/data-safety)。 --- # Changelog - Source: https://trailsnap.cn/en/docs/guide/changelog.html - Markdown: https://trailsnap.cn/en/docs/guide/changelog.md - Category: Reference - Language: en # Changelog ## 2026-10-19 (0.18.1) ### Improvements - More accurate train-ticket screenshot recognition: station names without the suffix, newly opened stations, and traditional/simplified carriage-seat forms; a missing train number triggers one full-image pass, and dates ignore ads and status bars. - The desktop mobile-connection port now falls back to a new port automatically when occupied, with a prompt to re-scan; settings add automatic or custom port selection, editable directly from the startup failure page. - Legacy library upgrade verification only checks photos actually copied this time, so externally edited originals or offline disks no longer block upgrades; verification results are reused per startup. - Single photos can re-extract metadata to force-refresh EXIF cached at import. - All download artifacts now share one naming scheme (version-component-platform-arch); the download page splits NAS deployment from desktop installs and the Docker template uses a China mirror. ### Bug Fixes - Fixed bulk task rebuilds: thumbnails, metadata and ticket tasks can be re-run for the whole library from task management. - Fixed stale AI model download waits piling up; waiting tasks resume automatically once models are ready. - Fixed task worker processes lingering after exiting the desktop app and holding photo files. - Fixed train/flight ticket misclassification and ad years overriding real travel dates. ## 2026-10-19 (0.18.0) ### New - Browse 360° panorama photos with valid GPano metadata, including drag-to-look, zoom, fullscreen, quality switching and a panorama library filter. - Unified Windows installed and portable instances, with separate libraries per folder, portable ZIP packages, in-app updates and automatic migration of legacy libraries. - Added an “Automatically view originals” preference for both regular and panorama photos. ### Improvements - Windows legacy upgrades now show checking, copying, verification and startup progress, with safe pause and retry. Settings show the actual TrailSnap folder. - Improved library recovery, independent backups, relocation and failure recovery. Reinstalling the same version can repair program files. - Refined cursor-centered zoom, pan boundaries, original-image loading transitions, desktop and mobile toolbars, and menu motion. - Added navigation loading feedback and network-aware preloading; optimized memory and location queries and album grids. - Photo analysis tasks explain which AI models are pending and resume automatically when ready. - Improved Agent specifications and coding delivery in the feedback platform, including OpenAI delivery provider support. ### Bug Fixes - Fixed inconsistent paths and recovery issues during desktop upgrades, imports and photo organization; improved library preservation during installation and uninstallation. - Fixed processing failures caused by non-finite GPS values and invalid cached task metadata. - Fixed photo display while originals load, panorama browsing and mobile menu interactions. ## 2026-10-12 (0.17.4) ### New - Reworked the desktop AI extension update experience: the settings page can check for updates and show compatibility with your Server and platform, with manual download and offline import; installed extensions at or above the minimum supported version keep working without re-downloading - The shared photo picker is rebuilt: search to locate photos, reused everywhere from people covers to album covers and avatars; on mobile an alphabet scrollbar enables fast jumping - People editing now supports picking multiple library photos as cover candidates ### Improvements - Big face recognition performance gains: faster desktop face-matching queries and batch concurrency, plus an automatic CPU retry when an inference provider returns invalid results - Smarter background task scheduling: AI tasks yield to higher-priority work such as scans and thumbnails, switching once in-flight batches finish, so organizing photos is no longer blocked by AI analysis - The task queue gains scheduling indexes and photo links; deleting a photo cleans up its related tasks, and upgrading an older library backfills links and reclaims SQLite space - Metadata extraction reuses cached results and color analysis reads thumbnails instead of originals, making scans faster - Disk I/O is throttled per operation, so media processing like video metadata and motion photo extraction no longer holds the disk for long stretches ### Bug Fixes - Fixed desktop annual report photos and avatars failing to load - Fixed video metadata bloating EXIF with cover images and other binary data, with a SQLite cleanup tool - Fixed the vector type import failing on fresh PostgreSQL deployments - Fixed photo picker entry points and interactions when changing people covers, album covers, and avatars ## 2026-10-11 (0.17.3) ### New - Desktop "Data Directory" setting: move your entire photo library to another drive; migration waits for running tasks and uploads to finish, rolls back on failure, and keeps the original folder as a backup - Desktop "Connect Mobile App": shows a LAN address and QR code so your phone can back up photos to the same library; the port stays stable across restarts - Photo viewer gains "Reveal original file" in the file manager ### Improvements - Desktop cold start is dramatically faster: about 18 seconds from launch to usable down to around 4 seconds - Much faster mobile backup and uploads: original-file save confirmation is about 88% quicker; thumbnails and metadata move to background processing; chunked uploads resume after interruption and failed files no longer block the rest - More reliable background task scheduling: AI tasks run in type-based batches with fewer model switches, and disk I/O is throttled per volume for a smoother UI during scans - HEIC/HEIF photos now display as previews directly in the browser - Upload queue survives minimizing the window or switching pages ### Bug Fixes - Fixed the photo page flickering with a full refresh after background tasks finished - Fixed desktop AI chat streaming responses breaking (502) and a black console window flashing on Windows - Fixed desktop settings failing to save when AppData is encrypted - Fixed mobile photo viewer thumbnails being covered by the action bar - The Windows installer now closes a running TrailSnap automatically, so you no longer need to quit it before upgrading ## 2026-10-09 (0.17.2) ### New - Ticket wallet redesign: train and flight tickets in one place, link tickets to albums and photos, and open a ticket to see its related memories ### Improvements - Unified mobile date and time pickers covering date, time, month, and range modes - Smoother mobile albums and recycle bin with long-press multi-select; overlays now close automatically when navigating - Refined moments-style layout heights for highlighted photos - On This Day now supports swipe navigation on mobile with accidental taps suppressed - Unified dialog layering so new dialogs always stay above open panels ### Bug Fixes - Fixed timeline sorting lag and incorrect photo dimensions caused by EXIF orientation - Fixed first-install registration being blocked by railway data initialization - Transient read requests now retry automatically, and duplicate connection errors are no longer shown repeatedly ## 2026-10-04 (0.17.1) ### New - Mobile photo diaries now support single-page reading, automatic text pagination, date selection, and swipe navigation ### Improvements - Unified liquid-glass toolbars and responsive action menus across photos, albums, and memories, with bottom sheets on small screens - Refined headings, cards, and spacing on home, album, and memory pages for mobile browsing - Reduced Server Docker image size: local measurements show about 61% / 59% smaller compressed layers on AMD64 / ARM64, while retaining common video reading, thumbnails, and daily-frame film generation ### Bug Fixes - Fixed Android system-bar safe areas and keyboard layout spacing for photo covers and toolbars - Improved multi-architecture Server builds and synchronization to the China container registry ## 2026-10-03 (0.17.0) ### New - Life chapters: organize photos and memories from a period into chapters, with discovery, manual editing, diary reading, and story browsing - Memory relationship graph: explore connections between people, places, and events to rediscover related experiences - Person timeline: review one person or shared photos of two people by year, with segment hiding, restoration, and AI interpretation - Daily frame: choose a photo or video clip for each day in a calendar, fill gaps, edit captions, and preview, export, and manage silent films with one second per day - Photo diary layout: browse photos by day and expand a day to see more images - Map route lines: connect photo locations to revisit travel routes - Background color reanalysis: reanalyze photo colors in batches to refresh color search data ### Improvements - Configure local language model thread counts to suit your device - Improved person detail layouts and album titles that remain visible while scrolling - More consistent system settings and common action interfaces - Updated dependencies for more reliable installation and builds ### Bug Fixes - Fixed virtual scrolling calculations in person and album galleries - Fixed coordinates not updating after map dragging and administrative regions not refreshing after saving locations - Fixed mixed-content requests behind HTTPS reverse proxies - Fixed several styling and AI concurrency issues ### Upgrade Notes - Update Server, AI service, and clients together; Server applies database migrations on startup. Back up your database before upgrading - Daily frame film generation requires FFmpeg, FFprobe, H.264 encoding support, and a working Chinese font. Daily selections remain available when these components are missing, with an explanation shown in the interface ## 2026-09-24 (0.16.0) ### New - Memory fragments: TrailSnap now discovers candidate memories from the people, places, and ticket clues in your photos and surfaces them on the home page. Confirm them to turn scattered photos into real events with a cover, a story timeline, and linked photos, people, places, and tickets. You can also create memories manually from albums, photo selections, or the AI assistant — and AI only writes a memory after you explicitly confirm it. - Location time compare: drag a split line to compare photos of the same place across years. Enter from a location's detail page or the "This place back then" action in the photo viewer. Includes a year track, photo swapping, and one-tap then-and-now artwork generation that hides exact coordinates by default when sharing. - Group albums in the people page: photos are aggregated by co-occurring people — "me and dad" or "the three of us" each become their own album with the latest group photo as the cover. - Custom people covers: pick a person's cover from their own photos; the edit dialog is now full-screen on mobile. - The batch time-fix toolbox tool now accepts an album as the processing scope, touching only that album's photos in place. ### Improvements - Major visual refresh: desktop sidebar with rounded buttons and primary-gradient active states, a floating liquid-glass bottom bar with a directional bubble indicator on mobile, a unified design-token system, and navigation regrouped into Photos / Explore / More with collapsible, remembered groups. - Smart album overview now shows real content covers (face crops for people, representative photos for places and categories) and loads faster with new database indexes. - Mobile album actions: long-press a custom album for an edit/delete menu, and a new "more" menu on album detail pages (edit / change cover / delete). - Mobile location album filters moved to a bottom sheet, the map info drawer now snaps to three positions, and the 3D footprint globe renders at higher resolution on mobile. - AI assistant chat improvements: reworked model picker, loading animation during generation, and repeated regeneration disabled while busy. - Photo page data management hardening: state split between global and home views to stop cross-page pollution, scroll position preserved across refreshes, and timeline stats protected against request races. - Task management: SSE push on status changes, per-category status filters, and an explicit all-clear prompt; mobile backup notifications now deep-link to backup settings. - Rebuilt login and registration pages with a unified visual style. ### Bug Fixes - Fixed the photo gallery showing an "empty album" placeholder on load errors. - Fixed duplicate/similar photo cleanup pages failing to scroll in some browsers. - Restored auto-focus on the name input when opening the person edit dialog. - Fixed overlapping elements interfering with video preview interactions. ### Upgrade Notes - You can upgrade directly from 0.15.x; database migrations run automatically. Updating the Server and clients together is recommended. ## 2026-09-18 (0.15.0) ### New - Added an immersive 3D footprint map to the location album: a 3D globe showing the cities you've visited and travel routes, with 2D/3D/globe views, year filters, city search, journey replay, and year tour. Layer controls include photo heatmap, province boundaries, and 3D terrain. - Requirement platform admins can now change requirement statuses from the web UI: suggested transitions are ranked by common flow, and a reason is required and recorded in the timeline. - Added an agent-native delivery workflow to the requirement platform: approved specs become the single source of truth for agents, with delivery tasks, run records, PR links, and clarification Q&A all visible. AI triage now streams its feedback. - The requirement platform can import cc-switch backups to track token usage: real consumption and cost in a unified accounting model, with trend charts, model and device breakdowns, and request details. ### Improvements - AI requirement triage supports per-model reasoning effort settings. - Fixed footprint year boundaries so photos taken at the very end of a year are not rolled into the next one by millisecond rounding. ### Bug Fixes - Fixed Tianditu map tiles breaking on the mobile app: SDK default layers no longer bypass the server proxy, photo markers render correctly again, and stale caches are invalidated automatically after upgrading. - Fixed connecting to a new server on the mobile app: scanning a QR code or typing a new address no longer fails with "Failed to fetch", expired credentials are cleared silently, and the "scan or auto-discover" dead loop is gone. ## 2026-09-11 (0.14.2) ### New - The TrailSnap Requirements Platform is now live: submit feature requests and issues, track review outcomes and delivery plans, and explore trend and distribution charts on the dashboard. The in-app feedback page now points to the platform. - Added a developer blog to the official site, starting with an article on AI-assisted development reliability practices. ### Improvements - Tianditu maps now use server-side keys: web, desktop, and mobile all load maps through your TrailSnap Server, so the real key never appears in map resource URLs. Keys are validated by the Server before saving. - The map settings page now explains how to migrate from old browser-type keys, with documentation updated accordingly. ### Bug Fixes - Fixed maps going blank on the mobile app: the map proxy forwards the device's real User-Agent so Tianditu no longer returns 403, and failed responses are no longer cached by the WebView for 24 hours. - Fixed base map loading failures in the location trajectory view and the add-scene dialog in some environments. ### Upgrade Notes - Users with browser-type Tianditu keys from earlier versions need to create a server-side key in the Tianditu console and replace it in Settings; if you use an IP allowlist, enter your TrailSnap Server's public egress IP. ## 2026-09-08 (0.14.1) ### New - LLM settings now let you configure a display name, context window, and reasoning level for each model. Photo analysis and chat can use different models. - The Server now prunes old app installer caches and incomplete download files, and in-app updates retry automatically after weak-network interruptions. ### Improvements - Mobile backup now computes checksums in parallel and adapts media and chunk concurrency to LAN conditions, reducing small-file requests and substantially improving throughput. - The mobile album list has a refreshed layout with clearer, better-organized information. - Refined navigation visuals and photo browsing; deleting a photo now keeps your current browsing position. ### Bug Fixes - Fixed mobile backup issues involving repeated incremental scans, JPG+MP4 Live Photo pairing and upload, disk verification, type correction, and preservation of capture timestamps from the phone. - Fixed LLM connection editing and saving. Candidate models are fetched in the connection editor, while chats now show only saved models. - Fixed mobile QR-code server switching being blocked by the network policy. - Improved Live Photo loading to reduce waiting and flicker. ## 2026-09-07 (0.14.0) ### New - The Album Agent is now available: search photos with natural language, discover travel clues, create person timelines and memory-detective stories, and organize albums from real photo evidence. - Added an Agent task center for proposed, running, failed, and completed plans, with confirmation, retry, cancel, continue, and undo controls. - Added the Album Doctor repair loop for album counts, covers, descriptions, file hashes, photo times, and locations. Every repair can be previewed, confirmed, and undone. - Added safe cleanup proposals: exact duplicate photos move to the recycle bin, empty-album deletion requires typed confirmation, and all operations remain auditable and reversible. - AI travel journals can now generate personalized HTML pages for preview, export, sharing, long-image capture, and browser-based PDF printing. - Added a read-only MCP service, a Pi Agent extension, and scoped access tokens so external AI tools can query TrailSnap safely. - The location album now includes an immersive footprint map and layered GPS travel trajectories. ### Improvements - Android networking now routes through your self-hosted TrailSnap Server, with server-proxied map tiles for a more consistent experience. - Thumbnail reads no longer require a database session, and startup storage-cache prewarming improves browsing on large libraries. - Proactive memories now offer recommendation cards that open directly in an Agent conversation. - The default service port is now 3180, with installation scripts and Docker documentation updated. ### Bug Fixes - Fixed Android map-tile direct-connection failures and refined icon centering and monochrome details. - Fixed a race where a cancelled task prefetched into the worker queue could still execute; cancellation now takes effect immediately. - Fixed several Agent streaming, artifact, and background-task edge cases to improve long-running task stability. ## 2026-09-04 (0.13.1) ### New - The recycle bin now supports select-all across pages, emptying the entire bin, and restoring everything without loading every page or sending every photo ID. - Large purge operations can run in the background with live progress, avoiding long-running request timeouts. ### Improvements - Reworked bulk deletion and added database indexes. In testing, clearing 10,000 photos dropped from about 22 seconds to about 0.9 seconds while blocking other operations less. - Face clustering now runs as a separate background task instead of blocking recognition; large face libraries are streamed to substantially reduce peak memory use. - Automatic face clustering skips redundant work when little has changed recently, while manually requested clustering still runs immediately. - Unified scrollbar styling across the app and improved scrolling containers on desktop and mobile layouts. - Improved AI-facing documentation hints on the official site so assistants can find and verify TrailSnap documentation more reliably. ### Bug Fixes - Fixed the recycle-bin list failing when an item has no deletion timestamp. - Fixed incorrect cluster counts when multiple photos from the same cluster are permanently deleted together. - Fixed face similarity matching potentially scanning across users and ensured each user's configured clustering threshold is respected. ## 2026-09-03 (0.13.0) ### New - The Android App can now check for updates automatically, download the APK in-app, and launch the installer, with progress reporting, retry support, and the option to skip a version. - Added video metadata parsing for common formats such as MP4 and MOV, so capture time, location, and device information can place videos correctly on the timeline and map. - The AI assistant now supports semantic memory retrieval, prioritizing photo memories most relevant to the current question in long conversations. - Added automatic context compression for the AI assistant, preserving a concise summary plus recent messages to reduce context overflow. - The AI assistant input now supports multiline text, with Enter to send, Shift+Enter for a new line, and correct Chinese IME behavior. ### Improvements - The mobile photo viewer now uses a three-track swipe layout with adjacent-image preloading, making rapid swiping smoother and extending left/right navigation to search results, the recycle bin, folders, and more. - The mobile viewer layout now follows familiar system-gallery patterns, with clearer capture information and more focused actions. - Redesigned mobile backup and settings navigation and improved multi-select and viewing experiences. - Vectorized face clustering to speed up organizing large photo libraries. - Added AI-friendly documentation and QR-code entry points to the official site and refreshed demo images. ### Bug Fixes - Fixed mobile backup issues involving Live Photo pairing, repeated failed uploads, adaptive-gallery backup speed, and worker database connection isolation. - Fixed mobile photo viewer track offset and the Android adaptive launcher icon safe-area ratio. - Fixed local API-prefix handshake failures on desktop. ## 2026-09-01 (0.12.1) ### Bug Fixes - Fixed a Docker Server restart loop when upgrading from 0.11.0 because the database migration queried the not-yet-created `backup_key` column. - Instances where the upgrade already failed can update directly to 0.12.1 and safely retry the migration; instances that have not upgraded can also update directly without manual database changes. ## 2026-08-31 (0.12.0) ### New - Added incremental system-gallery backup to the Android App, with destination selection, progress reporting, pause/resume controls, original media preservation, and paired Live Photo support. - Added desktop management for external libraries and configurable upload destinations for importing photos into a chosen external folder. - Added a side-by-side comparison view to the similar-photo tool for easier review and cleanup. - Swipe-to-declutter now saves decisions and progress, and can synchronize offline actions after reconnecting. - The desktop installer can now switch AI runtimes to better match the device. ### Improvements - Unified connection entry points across desktop, mobile, and browser clients, with clearer mobile server setup and improved Docker LAN service discovery. - Improved desktop startup, session handling, and automatic updates to reduce repeated configuration and interrupted upgrades. - AI task concurrency now adapts to runtime pressure and retries failures; waiting tasks resume after model downloads complete. - Simplified AI performance choices and improved responsive layouts, dark mode, and keyboard accessibility throughout the Web interface. - Restructured multi-user storage for stronger file isolation and added support for longer photo paths. ### Bug Fixes - Fixed mobile backup converting original media, losing paired Live Photo files, or mishandling optional upload fields. - Fixed malformed vision-model output, tasks remaining paused after model downloads, and visual-analysis request timeouts. - Fixed cleanup failures for locked user directories on Windows, plus several mobile navigation and timeline interaction issues. ## 2026-08-22 (0.11.0) ### New - Added photo-anchored memory to the AI assistant, allowing meaningful moments from conversations about specific photos to inform more coherent future responses. - Added proactive memories: when On This Day photos are available, the assistant can prepare a personalized greeting and show an unread indicator in the sidebar. - Added folder filters to conditional albums, with multi-select support and automatic inclusion of all descendant folders. - Added multiple PP-OCRv6 tiers and the Buffalo M face model so users can choose between speed and accuracy for their hardware. ### Improvements - Unified AI model browsing, downloading, switching, and removal; switching is faster and failed removals can fall back to an available configuration. - Improved AI assistant photo search with concise samples and aggregate summaries for exploratory queries, plus automatic grid layouts for multi-photo results. - Refreshed Web, PWA, Android, and iOS icons for a more consistent product identity. ### Bug Fixes - Fixed the assistant sidebar indicator affecting accessible names and unauthenticated proactive requests disrupting login state. - Fixed model preparation and URL configuration issues in desktop builds, improving desktop AI extension installation and startup reliability. ## 2026-08-18 (0.10.2) ### New - Added **Reprocess** to the photo viewer, allowing face recognition, OCR, scene classification, visual description, and image embedding to be rerun for a single photo with live progress and results. ### Improvements - Interactive photo-processing tasks now receive priority and can continue while background classification is paused. - Improved download-button fallback so users can still reach the matching release page when the GitHub API is temporarily unavailable. - Synchronized Android and iOS version metadata for clearer upgrades and repeat installations. ### Bug Fixes - Fixed Android WebView security rules blocking photos, album covers, avatars, and On This Day images when the App connects to an HTTP self-hosted server. - Fixed database connection exhaustion during large first-time scans, which could break thumbnail generation and cascade into downstream task failures. ## 2026-08-16 (0.10.1) ### New - Completed the desktop AI extension's full service capabilities and added an AI model management page for on-demand model viewing and management; stabilized AI runtime startup and bundled face-recognition dependencies. - External links on desktop now open in the system browser; mailto and tel links are handed to system apps. ### Improvements - Switched the Windows MSI installer language to Simplified Chinese. - Optimized app icon asset sizes for a smaller installer. - Improved the official-site download and deployment docs, added a one-click Docker install guide, and fixed download-page platform-asset matching. ### Bug Fixes - Fixed Tianditu tile loading on desktop so the album location map and trajectory view render correctly. - Fixed map boundary and location data 404 after desktop packaging; map endpoints no longer fail when the working directory differs. ## 2026-08-15 (0.10.0) ### New - Added a Tauri 2 cross-platform desktop app with an embedded SQLite database for standalone use on Windows, macOS, and Linux. - Added optional desktop AI extensions with on-demand runtime installation and model downloads. - Added server switching and recent-server history to the mobile App login screen. - Added desktop and server-side folder pickers for selecting external photo-library directories. - Added pinch-to-zoom density controls for mobile photo grids while keeping the current photo anchored. - Added multi-key Tianditu management and validation, plus direct AI-service connectivity checks in Settings. ### Improvements - Improved incremental photo loading, cross-page state synchronization, album details, and the mobile timeline navigator. - Improved photo viewer, dialog, and Android back-button behavior so the active overlay closes first. - Simplified desktop and mobile navigation and regrouped travel-related entries. - AI assistant messages now use the user's custom avatar, and the mobile model selector uses a more compact layout. - The one-click installer can now back up existing data and either preserve configuration during upgrades or perform a clean reinstall. - Improved China-registry compatibility, multi-architecture frontend image builds, and release-asset naming. ### Bug Fixes - Fixed desktop SQLite date statistics, vector search, startup, and AI-extension runtime issues. - Fixed removing photos from regular albums, permanently deleting recycle-bin items, and flight-ticket update feedback. - Fixed single-photo-directory mounts and Android debug-signature conflicts during repeat installations. ## 2026-08-08 (0.9.2) ### New - Added rescan support for reviewed identities, making it easier to refresh person recognition after face-data updates. - Added download progress for offline map data. - Persisted offline reverse-geocoding data to avoid repeated downloads and lookups. - Demo mode can now prefill the login credentials automatically. ### Improvements - Added an Alibaba Cloud registry option for deployments in China. - Improved initial frontend loading and Nginx delivery. - Added pre-deployment and data-safety guidance, and improved the home page and FAQ. - Expanded automated coverage for photo, settings, media, face, and album modules. ### Bug Fixes - Fixed llama-server startup failures caused by a missing `libgomp1` runtime dependency in the AI service image. ## 2026-08-02 (0.9.1) ### New - Added Capacitor-based Android/iOS App projects. On first launch, the App lets users enter and save their self-hosted TrailSnap Server address. - Added automated Android APK builds. Pushing a `v*.*.*` tag uploads the APK and CLI artifacts to the same GitHub Release. - Added PWA support to the Web frontend, including installability and improved offline / refresh behavior. - AI Moments copy generation can now show its reasoning progress in real time. ### Improvements - Improved Android back-button and gesture behavior: close overlays first, navigate back next, then move to the background from the home screen. - Unified App and CLI publishing rules: manual builds keep Actions artifacts, while version tags create or update Releases. - Added mobile App installation, server configuration, update, and privacy guidance to the official site. ### Bug Fixes - Fixed executable permissions for the Android Gradle Wrapper on Linux GitHub runners. - Fixed PWA refresh behavior and branch image-tag handling. ## 2026-08-02 (0.9.0) ### New - Added **Moments Diary**: generate, edit, and clear AI social copy by day, with main locations and photo highlights. - Added **location album collage view** with nationwide / province browsing, automatic or manual photo selection, tile replacement, and similar-photo removal. - Added map double-click drill-down and collage selection strategies including memory value, quality, latest, and random. - Added mobile bottom-tab navigation, map/collage gestures, and an Agent drawer. ### Improvements - Reduced Server and AI image size and startup overhead; added graceful stopping and health monitoring to the AI service. - Improved social-image aspect ratios, mobile layout, and collage rendering performance. ### Bug Fixes - Fixed timezone aggregation, streaming generation, and single-image aspect ratio issues for Moments copy. - Fixed mobile collage blank screens, reverse-geocoding parsing, and several external-library and task-navigation issues. ## 2026-07-28 (0.8.1) ### New - Added an **external photo library setup wizard** for directory selection, path mapping, and scan configuration. - Added a global notification center for background tasks and system messages. - Added scheduled version-update checks. ### Improvements - Improved AI assistant context trimming and photo retrieval for long conversations and complex libraries. - Expanded automated coverage for the frontend, server, and AI service. ### Bug Fixes - Fixed reinstall, health-check, metadata dispatch, and AI-timeout issues affecting some deployments. ## 2026-07-11 (0.7.0) ### New - Added **"Letting Go" photo filter**: swipe left/right to quickly decide each photo's fate — an easy way to declutter a bloated library. - Added **Storage Center**: a unified view of storage usage across sources; the home storage card jumps straight to the corresponding photo filter. - Photo editing now **preserves original EXIF metadata** (capture time, location, etc.), so timelines and map pins stay accurate. - The AI assistant floating button now supports **free dragging and auto half-hiding at screen edges**. - Clicking the search box now **pre-warms the AI service** to avoid first-search cold-start delay. - First-time users are redirected straight to the registration page. - The install script now **auto-configures a China Docker mirror** and enables it by region. ### Improvements - The recycle bin now supports a selection mode for batch restore/delete. - Improved mobile experience for the Settings and Toolbox pages. ### Bug Fixes - Fixed the photo location-edit popup failing to reopen after being closed. - Fixed the worker watchdog restarting in a loop when only paused tasks remained. ## 2026-06-07 (0.4.1) ### New - Added **Photo editing**: crop, rotate, doodle, text, and shape tools. - Added **Sidebar navigation**: redesigned frontend layout with collapsible sidebar. - Sidebar shows hover tooltips when collapsed. - Added **Sidebar global search**: quickly find photos, albums, people, etc. - Added **Theme customization**: choose from 5 brand colors (Sky, Emerald, Violet, Rose, Amber) that apply globally with one click. - Added **Custom sidebar navigation items**: customize the sidebar navigation menu. - Unified theme handling with reusable components. ### Improvements - Optimized location map page and view component; refactored backend photo query logic. - Improved multi-module query performance. - Unified icons and refined frontend conventions. - Improved page UI layout and fixed import issues. ### Bug Fixes - Fixed album page theme color not responding and dark mode contrast issues. - Fixed missing primary theme utility class mappings (hover/shadow not following theme). ## 2026-05-28 (0.4.0) ### New - Photo organize toolbox now supports "Time directory structure" option — flat or recursive nested structure (e.g. `2026/01/01`). - Photo organize supports automatic grouping by person. - Added **Built-in AI connection**: works out of the box, using MiniCPM-V-4_6-Q4_K_M multimodal model by default. - Added **Local LLM hosting**: host custom models via llama.cpp. ### Improvements - Migrated all AI services to ONNX Runtime, removing redundant dependencies. - Refactored AI service LLM deployment logic — replaced pyllama-cpp-python with natively compiled llama-server binary. - Implemented priority-based task filtering when queue is full. - Improved image processing with WebP format auto-conversion. - Improved LLM settings page with built-in connection badge. - Improved failed task cleanup mechanism. - Fixed organize task progress calculation error. ## 2026-05-14 (0.3.9) ### New - Added "Skiing" category to smart classification. - Smart classification now supports setting cover photos. - Added ability to delete recognized people. ### Improvements - Thumbnails now use WebP format to reduce file size. - Fixed task priority anomalies. - Improved smart classification accuracy, reducing misclassification. - Improved some UI details. ## 2026-04-28 (0.3.8) ### New - Added **Recycle Bin**: restore deleted photos. - Added **TrailSnap CLI**: interact with TrailSnap via command line. - Added **Skills integration**: connect to OpenClaw, Claude Code, etc. ### Improvements - Improved some UI details. - Improved AI chat experience. ## 2026-04-22 (0.3.6) ### Improvements - Fixed tasks occasionally getting stuck. - Optimized task process management to reduce memory usage. - Speeded up LLM task processing to reduce waiting time. - Improved AI chat thinking/tool visualization so users can see intermediate steps. - Improved smart classification accuracy. ## 2026-04-18 (0.3.3) [vibe coding prompt](/docs/dev/prompt/0.3.3) ### New - Added manual photo classification so users can correct misclassified photos. - Added multiple LLM connections so users can choose which model to use. ### Improvements - Improved photo classification and ticket recognition accuracy. - Improved task processing efficiency to reduce waiting time. - Fixed photo delete failing in some scenarios. - Supported legacy Apple Live Photo formats (`.jpg` + `.mov`). - Improved some UI details. ## 2026-03-29 (0.3.2) [vibe coding prompt](/docs/dev/prompt/0.3.2) ### New - Added **AI Assistant**: chat with LLMs to search and understand your album content. - Added **Footprint Timeline** in location albums: browse photos by time across locations. - Added **Trajectory View**: connect photo locations across a time range to show travel routes. - Added **Token Management**: create tokens for third-party apps to access album data without logging in. ### Improvements - Location album and ticket stats pages support custom time ranges. - Fixed metadata parsing failures for Apple HEIC photos. - Improved search: fixed scenic spot search issues and improved suggestion loading speed. - Improved some UI details. ## 2026-03-21 (0.3.1) [vibe coding prompt](/docs/dev/prompt/0.3.1) ### New - Added **Similar Photos Cleanup**. - Added **Photo Calendar** on the home page. - Video playback supports speed control. ### Improvements - Fixed leftover Live Photo/thumbnail files after deletion. - Fixed black screen when switching videos. - Improved people album loading speed. - Fixed permission issues in ticket recognition. - Improved some UI details. ## 2026-03-12 (0.3.0) [vibe coding prompt](/docs/dev/prompt/0.3.0) ### New - Added multi-user support with data isolation. - Added LLM photo analysis: generate descriptions and scores. - Added **On This Day**: browse photos from past years, sorted by score. - Added **Album Cleanup**: clean analyzed photos based on scores. ### Improvements - Support hiding a people album. - Support adding photos to a people album. - Improved face recognition accuracy. - Improved some UI details. ## 2026-02-25 (0.2.3) [vibe coding prompt](/docs/dev/prompt/0.2.3) ### New - Added image file filtering. - Location albums support filtering by year. ### Improvements - Fixed photo ordering issues in people albums. - Improved page layout and UI. ## 2026-02-05 (0.2.2) [vibe coding prompt](/docs/dev/prompt/0.2.2) ### New - Support exporting paper-style train tickets (blue/red). ### Improvements - Added Tianditu tile caching to reduce network requests. - Improved location map rendering. - Fixed resource release issues in metadata rebuild tasks. - Improved UI display in some pages. ## 2026-02-01 (0.2.0) [vibe coding prompt](/docs/dev/prompt/0.2.0) ### New - Supported iPhone Live Photos. - Supported downloading offline maps for multiple countries, or uploading custom map data (requires rerunning **Metadata Extraction** task). - Added 358 5A scenic spots in China to the map album (requires rerunning **Metadata Extraction** task). - Supported editing custom scenic spot locations. - Supported searching by text, location, people, album, folder, filename, etc. - Supported recognizing flight tickets (order screenshots), requires rerunning **Ticket Recognition** task. - Supported ticket import/export (CSV/JSON). ### Improvements - Fixed duplicate photo display. - Fixed missing default covers after rerunning face recognition tasks. - Improved ticket recognition accuracy and speed. - Fixed upload failure for images larger than 1MB. - Improved some UI details. ## 2026-01-17 (0.1.0) | Feature | Status | Description | | --- | --- | --- | | Upload & view photos/videos | ✓ | Upload local photos and videos, view and play them. | | Add external folders | ✓ | Add external folders as data sources; TrailSnap will scan and index photos/videos automatically. | | Live Photo | ✓ | Support vivo/oppo/xiaomi and more. | | Timeline | ✓ | Smooth timeline scrolling experience. | | View photos on map | ✓ | View all uploaded photos on a map; filter by province/city/district; list & map views supported. | | Lit-up cities | ✓ | See cities appearing in photos; click a city to browse its photos. | | Visited scenic spots | In Dev | Count visited 5A scenic spots; support custom scenic spot areas; auto filter photos within the area. | | Face recognition | ✓ | Recognize people in photos and add people tags. | | Smart scene classification | ✓ | Auto classify scenes, e.g. night view, pets, food, selfie. | | Smart search | ✓ | Search by people, content, time, etc. | | Tags | ✓ | Add/remove tags manually, or auto-tag based on AI results. | | Smart albums | ✓ | Auto generate albums from content, e.g. “Selfies by the sea with my girlfriend”. | | Ticket recognition | In Dev | Recognize train tickets and itineraries, auto extract travel info. | | Annual report | In Dev | Auto generate yearly travel report: photo wall, cities, scenic spots, travel timeline, mileage, etc. | | Travel log | Planned | Generate travel logs from manual input or AI-recognized itinerary. | --- # Data, privacy, and backups - Source: https://trailsnap.cn/en/docs/guide/data-safety.html - Markdown: https://trailsnap.cn/en/docs/guide/data-safety.md - Category: Reference - Language: en # Data, privacy, and backups TrailSnap is self-hosted: your photos, database, and account data are stored on the server or NAS you operate. Installing TrailSnap does not automatically send photos to the project maintainers, but the person operating the server remains responsible for access control, backups, and public-network security. ## Where data is stored | Data | Default location | What to keep in mind | | --- | --- | --- | | Original photos and thumbnails | The photo directory mounted into the service | Do not move or delete files directly while tasks are running | | Albums, accounts, tasks, and indexes | PostgreSQL volume | Back up before upgrades or migrations | | AI analysis results | Database and related storage | Clean related tasks and results as needed after deletion | | Agent tokens | TrailSnap database | Grant the minimum scope and revoke leaked tokens immediately | ## Data boundaries when using AI - With local models or a locally hosted LLM, inference data stays on your devices and server. - When you configure OpenAI, a remote Ollama instance, or another third-party model provider, the data sent depends on the enabled feature and provider configuration. Read that provider's privacy policy first and do not send sensitive photos to untrusted services. - Never publish API keys, Agent tokens, or screenshots containing complete tokens in issues, chats, or logs. ## Deployment security checklist 1. Use strong TrailSnap account passwords, even on a home LAN. 2. For public access, use a domain, HTTPS, and a reverse proxy. Do not directly expose PostgreSQL, management ports, or the Docker socket. 3. Expose only necessary ports to trusted networks. Mobile App access over the public internet must use HTTPS. 4. Update TrailSnap and Docker images regularly; read the [changelog](/en/docs/guide/changelog) before upgrading. 5. Give each shared-server user a separate account instead of sharing admin credentials or tokens. ## Backup and recovery Back up both the **photo directory** and the **PostgreSQL database**. Restoring only one can leave photo files and album records inconsistent. - Back up photos incrementally or continuously to a separate disk / NAS. - Back up the database daily and once more before upgrades, migrations, batch organization, or cleanup. - Periodically test a restore; a backup is useful only when it can be restored. During recovery, stop relevant services, restore photos and database from the same point in time, then verify photo counts, albums, accounts, and task status. Check your own `docker-compose.yml` and `.env` for the actual volumes and paths before running any backup or restore command. ## Deleting data Deleting a photo, album, or account in the app does not automatically erase every backup. For full deletion, also check the photo directory, database backups, synced storage, and any relevant records held by third-party AI services. --- # Recognition Demo - Source: https://trailsnap.cn/en/docs/guide/demo.html - Markdown: https://trailsnap.cn/en/docs/guide/demo.md - Category: Reference - Language: en # Recognition Demo TrailSnap is powered by an OCR engine optimized specifically for train ticket recognition. ## Ticket Recognition Demo ## Core Advantages - **High-Precision Field Extraction**: Accurately locates and identifies key information such as train number, date, station, seat number, ticket price, etc. - **Complex Background Adaptation**: Maintains high recognition rates whether it's a flat scan or a photo with a background. - **Structured Data Output**: Directly outputs standardized JSON data, facilitating developer integration and secondary processing. > **Tip**: Click the image to view the high-definition large image. --- # Feedback - Source: https://trailsnap.cn/en/docs/guide/feedback.html - Markdown: https://trailsnap.cn/en/docs/guide/feedback.md - Category: Reference - Language: en # Feedback If you encounter any problems during use, or have any suggestions, please feel free to contact us through the following methods. ## Join Community Welcome to join the TrailSnap official exchange group to communicate with other users and developers. ### QQ Group QQ Group QR Code ### WeChat Group WeChat Group QR Code ### WeChat Official Account WeChat Official Account QR Code ## Submit a Requirement or Feedback If you find a bug, want to request a feature, or want to follow review and release progress, use the TrailSnap requirements platform: [Open the requirements platform](https://feedback.trailsnap.cn/) Please search for an existing requirement first. For bug reports, include reproduction steps, product version, and environment details whenever possible. --- # FAQ - Source: https://trailsnap.cn/en/docs/guide/questions.html - Markdown: https://trailsnap.cn/en/docs/guide/questions.md - Category: Reference - Language: en # FAQ ## Installation & Deployment 1. What deployment methods are supported? Docker Compose is the supported deployment path for users. Running from source is intended for contributors and is not the usual deployment route; install Docker first. 2. What platforms are supported? Windows, macOS, and Linux are supported. Both x86 and ARM architectures are supported. ## External Libraries 1. External library setup fails — "directory does not exist" [See Directory Settings](./settings/directories.md) ## AI-Related 1. How to use the API to analyze photos, or how to view results after analysis [See AI Settings](./settings/aisetting.md) ## Scanning, tasks, and photos 1. Is a long first scan normal? Yes. Scanning and AI analysis time depend on the number of photos, disk speed, and model configuration. Check the task page and service logs, and validate the workflow with a small folder before importing a full library. 2. Why cannot TrailSnap find my photos or access the folder? Confirm that the host photo directory exists, is mounted into Docker, and is readable by the service. Organize, rename, and cleanup features also need write permission. See the [pre-deployment checklist](/en/docs/guide/preflight). ## Mobile and networking 1. Why cannot my phone reach the server? Put the phone and server on the same LAN, use the server's LAN IP instead of `localhost`, then check Docker port mappings, the firewall, and Wi-Fi AP isolation. See the [Mobile App Guide](/en/docs/guide/mobile-app) for the Android address format. ## Backups and upgrades 1. What should I do before an upgrade? Back up both the photo directory and PostgreSQL database, then read the [changelog](/en/docs/guide/changelog). Backing up only one may leave data inconsistent. 2. How can I use external AI or Agent tokens safely? Grant only the required scope, never publish tokens, and use HTTPS for public access. See [Data, privacy, and backups](/en/docs/guide/data-safety). --- # Claude Code - Source: https://trailsnap.cn/docs/guide/agent/claudecode.html - Markdown: https://trailsnap.cn/docs/guide/agent/claudecode.md - Category: Agent 集成 - Language: zh-CN # Claude Code > 在 Claude Code 中使用 trailsnap-cli skill 使用 AI 管理相册。 ## 一、获取访问token 参考 [Token 设置](../settings/tokensetting.md) 获取访问token。 ## 二、安装 Claude Code 参考 [Claude Code 文档](https://code.claude.com/docs/en/setup) 进行安装。 ## 三、安装 trailsnap-cli skill :::tabs == Agent 自动安装 请将以下提示词复制给你的AI Agent(OpenClaw、Claude Code、Cursor、MaxClaw、AutoClaw、KimiClaw、TRAE、OpenCode等), 它会引导你添加token并完成安装: ```text 帮我安装 trailsnap-cli 和 skill:https://trailsnap.cn/install.md 我的 TrailSnap 地址是 http://localhost:3180 我的token 是 ts_hV5nsCZxxxxx ``` ![alt text](/images/wechat_longscreenshot_2026-04-27_224237_662.jpg) == 手动安装 根据环境选择安装方式(选择其中一种即可): - Node.js 安装:npm/npx 安装 - Python 安装:pip 安装 #### npm/npx 安装 ```shell # 安装 CLI npm install -g trailsnap-cli # 安装 CLI SKILL(必需) npx skills add lc044/trailsnap -y -g ``` #### pip 安装 ```shell # 安装 CLI pip install trailsnap-cli # 安装 CLI SKILL(必需) npx skills add lc044/trailsnap -y -g ``` #### 配置api url和 token ```shell trailsnap config set --url --token ``` #### 验证 ```shell trailsnap photos list --limit 1 ``` ::: ## 使用skill 直接通过自然语言让 Claude 查询相册: > "帮我使用 trailsnap-cli skill,查一下最近在西安拍的照片有哪些?" > "我去年国庆节去了哪些地方,帮我写一个HTML格式的旅游日记。" --- # Agent Skills - Source: https://trailsnap.cn/docs/guide/agent/ - Markdown: https://trailsnap.cn/docs/guide/agent/index.md - Category: Agent 集成 - Language: zh-CN # Agent Skills TrailSnap CLI 可以作为 Agent 工具(Skill)被无缝集成到各种 AI 编码助手或 Agent 平台中,例如 Claude Code、OpenClaw / Roo Code 等。通过让 Agent 调用 CLI,AI 能够直接获取、分析和查询您的相册数据,实现基于个人图库的智能问答。 支持 MCP 的客户端可以直接连接 TrailSnap 内置的 Streamable HTTP 服务,无需包装 CLI。请参考 [配置 TrailSnap MCP](./mcp.md)。 1. Claude Code [使用说明](./claudecode.md) 2. OpenClaw / Roo Code 等 IDE Agent [使用说明](./openclaw.md) 3. 其它 Agent 平台集成 如果您正在使用 Dify、Coze、FastGPT 或自研 Agent 框架,您可以将 CLI 包装为系统级工具(Tool): 请将以下提示词复制给你的AI Agent(OpenClaw、Claude Code、Cursor、MaxClaw、AutoClaw、KimiClaw、TRAE、OpenCode等), 它会引导你添加token并完成安装: ```text 帮我安装 trailsnap-cli 和 skill:https://trailsnap.cn/install.md 我的 TrailSnap 地址是 http://localhost:3180 我的token 是 ts_hV5nsCZxxxxx ``` ## 使用skill 直接通过自然语言让 Agent 查询相册: > "帮我使用 trailsnap-cli skill,查一下最近在西安拍的照片有哪些?" > "我去年国庆节去了哪些地方,帮我写一个HTML格式的旅游日记。" 👉 [查看 AI 生成的旅行日记示例](/examples/travel-diary-2025-golden-week.html) --- # 配置 TrailSnap MCP - Source: https://trailsnap.cn/docs/guide/agent/mcp.html - Markdown: https://trailsnap.cn/docs/guide/agent/mcp.md - Category: Agent 集成 - Language: zh-CN # 配置 TrailSnap MCP TrailSnap 内置 MCP(Model Context Protocol)服务。支持 MCP 的 AI 客户端可以在不接触数据库和照片原始路径的情况下,查询当前用户的照片、相册、人物与回忆线索,还可以创建必须由用户在 TrailSnap 中确认的相册整理方案。 MCP 使用独立的 Agent Token,不需要把账号 JWT 或登录密码交给外部 Agent。 ## 1. 确认连接地址 MCP 使用 **Streamable HTTP** 传输。根据 TrailSnap 的访问方式选择地址: | 使用方式 | MCP 地址 | | --- | --- | | Docker、NAS、桌面版或反向代理的统一入口 | `https://你的域名/api/mcp/` | | 局域网统一入口 | `http://主机IP:3180/api/mcp/` | | 开发环境直接访问后端 | `http://127.0.0.1:8000/mcp/` | 统一入口只需要开放 TrailSnap 的前端端口,不需要额外暴露后端、AI 服务或数据库端口。建议保留地址末尾的 `/`。 ## 2. 创建 Agent Token 1. 登录 TrailSnap。 2. 打开“设置 → 令牌管理”。 3. 选择“新增令牌”,填写名称和过期时间。 4. 只勾选 Agent 实际需要的权限。 5. 输入当前账号密码完成验证,并立即安全保存生成的 `ts_` Token。 | 权限 | 用途 | | --- | --- | | `photos:read` | 搜索照片、分析回忆线索 | | `albums:read` | 查询相册列表 | | `people:read` | 查询人物、人物时间线 | | `albums:propose` | 创建待用户确认的相册方案;不能直接执行 | ::: tip 最小权限 只做照片问答时通常只需要 `photos:read`。只有当用户确实希望 Agent 整理照片时,才增加 `albums:propose`。 ::: 生成 Token 后请立即安全保存。不要把真实 Token 提交到 Git、写入公开文档、发布到 Issue,或交给不受信任的 Agent。 ## 3. 配置 MCP 客户端 不同客户端的配置文件位置可能不同,但核心配置相同:Streamable HTTP 地址和 Bearer Token。 ```json { "mcpServers": { "trailsnap": { "type": "http", "url": "https://photos.example.com/api/mcp/", "headers": { "Authorization": "Bearer ts_your_agent_token" } } } } ``` 部分客户端将 `type` 写作 `streamable-http`,或者把请求头放在单独的认证设置中;以该客户端的 MCP 文档为准。请勿把示例中的域名和 Token 原样使用。 保存配置并重启客户端后,应能看到以下工具: - `search_photos`:按日期、地点、OCR、媒体类型、人物和评分搜索照片。 - `list_albums`:查询相册、封面和照片数量。 - `list_people`:查询可见人物与人物 ID。 - `investigate_memory`:根据模糊时间、地点、人物和文字线索寻找候选回忆。 - `get_person_timeline`:生成人物事件时间线。 - `propose_album_organization`:生成 7 天内有效的待确认相册方案。 可以用下面的问题验证连接: > 查找我最近在上海拍摄的 10 张照片,并说明筛选依据。 ## 4. 配置 Pi Agent Pi 本身不直接加载通用 MCP 配置。TrailSnap 仓库提供了 Pi Bridge 和配套 Skill,会把 MCP 工具注册为 Pi 原生工具。 ```shell npm install -g trailsnap-cli trailsnap config set --url "https://photos.example.com" --token "ts_your_agent_token" pi install git:github.com/LC044/TrailSnap ``` 进入 Pi 后运行: ```text /trailsnap-status ``` Bridge 会优先读取以下环境变量: ```text TRAILSNAP_MCP_URL=https://photos.example.com/api/mcp/ TRAILSNAP_API_TOKEN=ts_your_agent_token ``` 没有设置环境变量时,它会复用 `trailsnap config set` 保存的地址和 Token。Pi 中的工具名称带有 `trailsnap_` 前缀,例如 `trailsnap_search_photos`。 ## 5. 公网和反向代理部署 通过域名或局域网地址访问时,在 TrailSnap Server 的环境变量中配置对外可访问的站点根地址: ```text TRAILSNAP_PUBLIC_URL=https://photos.example.com ``` Docker Compose 示例: ```yaml services: server: environment: TRAILSNAP_PUBLIC_URL: https://photos.example.com ``` 配置后,MCP 公开地址为 `https://photos.example.com/api/mcp/`,相册提案返回的审批链接也能被外部 Agent 直接交给用户打开。 只有在 MCP 使用独立域名时才需要额外配置: ```text TRAILSNAP_MCP_URL=https://mcp.example.com/mcp/ TRAILSNAP_MCP_ALLOWED_HOSTS=mcp.example.com ``` `TRAILSNAP_MCP_ALLOWED_HOSTS` 可以填写多个以逗号分隔的主机。只添加真实提供 TrailSnap MCP 的主机,不要关闭 Host 校验。 ## 6. 相册提案如何确认 具有 `albums:propose` 权限的 Agent 只能创建 `proposed` 状态的方案。此时相册尚未创建,照片和标签也没有变化。 Agent 应把返回的 `approval_url` 交给用户。用户使用正常 TrailSnap 账号打开页面,检查名称、照片、封面与标签,然后明确选择“确认执行”或“拒绝方案”。Agent Token 不能确认、拒绝或撤销方案。 ## 常见问题 ### 返回 401 Unauthorized 检查请求头是否为 `Authorization: Bearer ts_...`,Token 是否过期或已被撤销。Agent Token 不能替换成大模型服务商的 API Key。 ### 工具提示缺少权限 重新创建包含对应 scope 的 Token。例如人物时间线需要 `people:read`,相册提案需要 `albums:propose`。不建议为方便一次性授权全部权限。 ### 公网访问提示 Invalid Host header 确认已经设置正确的 `TRAILSNAP_PUBLIC_URL`。使用独立 MCP 域名时,将该主机加入 `TRAILSNAP_MCP_ALLOWED_HOSTS`。 ### 提案链接是相对路径 为 Server 设置 `TRAILSNAP_PUBLIC_URL` 后会返回绝对审批链接。TrailSnap Pi Bridge 也会根据 MCP 地址自动补全相对链接。 ### Agent 能否删除或移动照片 不能。当前 MCP 不开放删除照片、移动文件、重命名文件、直接修改相册或执行 HTML。需要管理和运维能力时,请使用 [TrailSnap CLI](./trailsnap-cli.md),并谨慎保管具有写权限的登录凭证。 --- # OpenClaw / Roo Code - Source: https://trailsnap.cn/docs/guide/agent/openclaw.html - Markdown: https://trailsnap.cn/docs/guide/agent/openclaw.md - Category: Agent 集成 - Language: zh-CN # OpenClaw / Roo Code OpenClaw / Roo Code 等 IDE Agent 可以调用 TrailSnap CLI 作为 Skill,让 AI 通过 TrailSnap API 查询你的个人相册数据。 ## 一、获取访问 token 参考 [Token 设置](../settings/tokensetting.md) 获取访问 token。 ## 二、安装 trailsnap-cli 和 Skill :::tabs == Agent 自动安装 请将以下提示词复制给你的AI Agent(OpenClaw、Claude Code、Cursor、TRAE 等), 它会引导你添加 token 并完成安装: ```text 帮我安装 trailsnap-cli 和 skill:https://trailsnap.cn/install.md 我的 TrailSnap 地址是 http://localhost:3180 我的token 是 ts_hV5nsCZxxxxx ``` == 手动安装 ```shell npm install -g trailsnap-cli npx skills add lc044/trailsnap -y -g trailsnap config set --url --token ``` ::: ## 三、在对话中使用 示例: > "帮我使用 trailsnap-cli skill,查一下最近在上海拍的20张照片有哪些?" > "帮我找出包含登机口文字的照片,整理一下我的航班记录。" --- # TrailSnap CLI 工具 - Source: https://trailsnap.cn/docs/guide/agent/trailsnap-cli.html - Markdown: https://trailsnap.cn/docs/guide/agent/trailsnap-cli.md - Category: Agent 集成 - Language: zh-CN # TrailSnap CLI 工具 ::: tip TrailSnap CLI 工具是一个基于TrailSnap API的命令行工具,可以通过命令行管理TrailSnap的相册数据。 ::: ## 一、安装使用 ### 安装 trailsnap-cli工具 你可以通过以下三种方式下载安装trailsnap-cli工具: 1. pip 安装 ```bash pip install trailsnap-cli # 验证安装是否成功 trailsnap -v ``` 2. npm 安装 ```bash npm install -g trailsnap-cli # 验证安装是否成功 trailsnap -v ``` 3. 从GitHub获取二进制文件 从GitHub获取二进制文件,然后添加到环境变量中。 下载地址:[https://github.com/LC044/TrailSnap/releases](https://github.com/LC044/TrailSnap/releases) ### 使用 trailsnap-cli工具 首次使用需要配置TrailSnap的API URL和Token(替换 `` 和 `` 为实际的URL和Token,如何获取请参考[Token 设置](/docs/guide/settings/tokensetting))。 ```bash trailsnap config set --url --token ``` 配置完成之后使用简单查询命令验证是否成功。 ```bash trailsnap photos list --limit 5 ``` ## 二、命令列表 ::: tip 核心说明:所有命令需在终端执行,格式统一为 `trailsnap [options]`。涉及 API 交互的命令(如 photos、locations 等)需先通过 `config set` 配置 API 地址和 Token,否则会直接报错并退出。 ::: ### 2.1、基础命令 #### 2.1.1 help - 显示帮助信息 「功能」:显示所有可用命令、命令结构及各命令的核心参数,快速查阅命令用法。 「格式」:`--help` 「示例」: ```bash trailsnap --help ``` ### 2.2、配置命令 #### 2.2.1 config set - 配置API URL和Token 「功能」:配置 CLI 使用的 TrailSnap 统一访问地址和 Bearer Token,是所有 API 交互类命令的前置操作。 「格式」:`config set --url API地址 --token API凭证` 「参数说明」: - `--url`(必填):TrailSnap 统一访问地址,例如:`http://localhost:3180`。CLI 会自动使用 `/api`。 - `--token`(必填):API访问凭证(Bearer Token),用于身份验证,需从后端获取。 「示例」: ```bash trailsnap config set --url http://localhost:3180 --token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` 「输出说明」:配置成功后会输出配置文件保存路径(写入同目录 `.env`),例如:`配置已保存到 .../.env`。 ### 2.3、照片管理命令 #### 2.3.1 photos - 照片管理主命令 「功能」:包含照片列表查询、单张照片详情获取、照片删除三个核心子命令,所有子命令需先完成API配置。 ##### 2.3.1.1 photos list - 查询照片列表 「功能」:查询照片列表,支持分页与按相册/地点/设备信息过滤。返回结果为简化字段集合。 「格式」:`photos list [--skip N] [--limit N] [--album-id 相册ID] [--city 城市] [--province 省份] [--make 品牌] [--model 型号]` 「参数说明」(支持组合筛选): - `--skip`:跳过 N 张照片(默认 0) - `--limit`:限制返回 N 张照片(默认 10) - `--order_by`:排序字段,默认按值得回忆评分排序,可选值:quality_score(画面质量评分),memory_score(值得回忆评分),photo_time(拍摄时间) - `--image-type`:按图片类型过滤照片,多个类型用逗号分隔,可选值:Camera(手机或相机拍摄)、Screenshot(截图)、Other(未知的其他类型) - `--start-time`:按开始时间过滤照片,格式为 YYYY-MM-DD HH:MM:SS - `--end-time`:按结束时间过滤照片,格式为 YYYY-MM-DD HH:MM:SS - `--album-id`:按相册 ID 过滤,多个 ID 用逗号分隔 - `--people-id`:按人物 ID 过滤,多个 ID 用逗号分隔 - `--tag-id`:按标签 ID 过滤,多个 ID 用逗号分隔 - `--city`:按城市过滤,多个城市用逗号分隔(全称) - `--province`:按省份过滤,多个省份用逗号分隔(全称) - `--scene`:按景区过滤,多个景区用逗号分隔 - `--make`:按相机品牌过滤,多个品牌用逗号分隔 - `--model`:按相机型号过滤,多个型号用逗号分隔 「返回值」:JSON 数组,每项包含 `id`、`filename`、`file_type`、`photo_time` 「示例」: ```bash trailsnap photos list --limit 20 --city 西安市,上海市 ``` ##### 2.3.1.2 photos info - 获取单张照片信息 「功能」:获取指定 ID 照片的元数据信息与内容描述信息。 「格式」:`photos info --photo-id 照片ID` 「参数说明」: - `--photo-id`(必填):照片唯一ID,可通过photos list命令获取。 「返回值」:JSON 对象,包含: - `address`:照片详细拍摄地址(精确到街道) - `albums`:所属相册信息 - `tags`:标签信息 - `faces_identities`:人物(面部识别身份)信息 - `description`:照片内容描述信息 - `description`:照片画面描述(若无则为空字符串) - `memory_score`:照片值得回忆分数(0-100,100为值得回忆) - `quality_score`:照片质量分数(0-100,100为最高质量) - `narrative`:照片一句话文案(若无则为空字符串) 「示例」: ```bash trailsnap photos info --photo-id 10001 ``` ##### 2.3.1.3 photos delete - 删除单张照片 「功能」:删除指定ID的照片,删除后不可恢复(需谨慎操作)。 「格式」:`photos delete --photo-id 照片ID` 「参数说明」: - `--photo-id`(必填):需删除的照片唯一ID。 「示例」: ```bash trailsnap photos delete --photo-id 10001 ``` 「输出说明」:删除成功提示 `照片 删除成功`,失败提示 `照片删除失败或不存在`。 ### 2.4、分类标签命令 #### 2.4.1 tags list - 查询分类标签 「功能」:查询分类标签列表,支持分页。 「格式」:`tags list [--skip N] [--limit N]` 「参数说明」: - `--skip`:跳过 N 个记录(默认 0) - `--limit`:限制返回 N 个记录(默认 100) 「示例」: ```bash trailsnap tags list ``` 「输出说明」:输出 JSON 数组,每项包含 `id`、`name`(tag_name)、`count`。 ### 2.5、相册管理命令 #### 2.5.1 albums list - 查询相册列表 「功能」:查询相册列表,支持分页。 「格式」:`albums list [--skip N] [--limit N]` 「参数说明」: - `--skip`:跳过 N 个相册(默认 0) - `--limit`:限制返回 N 个相册(默认 100) 「输出说明」:输出 JSON 数组,每项包含 `id`、`name`、`count`(num_photos)、`description`、`condition`、`type`。 「示例」: ```bash trailsnap albums list ``` ### 2.6、位置相关命令 #### 2.6.1 locations - 位置查询主命令 「功能」:包含位置分布查询、足迹时间轴查询两个子命令,基于照片的GPS信息统计。 ##### 2.6.1.1 locations list - 查询位置分布 「功能」:查询位置分布,不含时间信息(地点名、照片数量)。支持按层级分组与日期范围过滤。 「格式」:`locations list [--level city|province|district|scene] [--skip N] [--limit N] [--start-date YYYY-MM-DD] [--end-date YYYY-MM-DD]` 「参数说明」: - `--level`:分组级别(默认 city,可选:city、province、district、scene) - `--skip`:跳过 N 个位置(默认 0) - `--limit`:限制返回 N 个位置(默认 100) - `--start-date`:可选,开始日期(YYYY-MM-DD) - `--end-date`:可选,结束日期(YYYY-MM-DD) 「返回值」:JSON 数组,每项包含 `name`、`count` 「示例」: ```bash trailsnap locations list ``` ##### 2.6.1.2 locations timeline - 查询足迹时间轴 「功能」:查询足迹时间轴列表,按时间段和地点分组(开始日期、结束日期、地点名、照片数量)。支持按层级分组与日期范围过滤。 「格式」:`locations timeline [--level city|province|district|scene] [--skip N] [--limit N] [--start-date YYYY-MM-DD] [--end-date YYYY-MM-DD]` 「参数说明」: - `--level`:分组级别(默认 city,可选:city、province、district、scene) - `--skip`:跳过 N 个位置(默认 0) - `--limit`:限制返回 N 个位置(默认 100) - `--start-date`:可选,开始日期(YYYY-MM-DD) - `--end-date`:可选,结束日期(YYYY-MM-DD) 「返回值」:JSON 数组,每项包含 `startDate`、`endDate`、`locationName`、`count` 「示例」: ```bash trailsnap locations timeline --level city --start-date 2025-01-01 --end-date 2025-06-30 ``` ### 2.7、人物识别命令 #### 2.7.1 people list - 查询已识别的人物/面孔 「功能」:查询人物(面部识别身份)列表,支持按类型过滤。 「格式」:`people list [--limit N] [--types named,unnamed,hidden]` 「参数说明」: - `--limit`:返回的记录数(默认 100) - `--types`:查询类型,逗号分隔,默认 `named`;可选值:`named`、`unnamed`、`hidden` 「输出说明」:输出 JSON 数组,每项包含 `id`、`name`(identity_name)、`tags`、`description`、`face_count`。 「示例」: ```bash trailsnap people list ``` ### 2.8、存储文件夹命令 #### 2.8.1 folders list - 查询挂载的存储文件夹列表 「功能」:查询系统中已挂载的存储目录信息。 「格式」:`folders list` 「输出说明」:直接输出后端接口返回的 JSON(字段结构以服务端为准)。 「示例」: ```bash trailsnap folders list ``` ### 2.9、媒体文件命令 #### 2.9.1 medias get - 获取照片的媒体文件或URL 「功能」:获取指定照片的媒体内容/访问地址,支持输出 URL、base64、或保存到本地文件。 「格式」:`medias get [--photo-id 照片ID] [--size small|medium|large] [--format url|base64|file] [--output 文件路径]` 「参数说明」: - `--photo-id`:照片 ID(默认 100) - `--size`:照片质量/尺寸(默认 medium,可选:small、medium、large) - `--format`:输出格式(默认 url(可以把链接插入到HTML页面或者markdown文件),可选:url、base64、file) - `--output`:输出文件路径(仅当 `--format file` 时必填) 「示例」: ```bash # 输出 URL(large 输出原图URL,small/medium 输出缩略图URL) trailsnap medias get --photo-id 10001 --format url --size large # base64 输出(缩略图base64编码) trailsnap medias get --photo-id 10001 --format base64 --size medium # 保存到本地文件 trailsnap medias get --photo-id 10001 --format file --output .\photo_10001.jpg ``` ### 2.10、注意事项 - 所有涉及 API 交互的命令(photos、locations、people 等),必须先执行 `config set` 配置 API URL 和 Token,否则会提示 `错误: API URL 和 Token 未配置,请先运行 'config' 命令。` 并退出。 - 所有命令可通过 `--help` 查询详细用法,若参数错误,会提示具体错误信息及正确格式。 --- # TrailSnap CLI 安装指南 - Source: https://trailsnap.cn/install.html - Markdown: https://trailsnap.cn/install.md - Category: Agent 集成 - Language: zh-CN # TrailSnap CLI 安装指南 以下步骤面向 AI Agent,部分步骤需要用户在浏览器中配合完成。 ## 环境要求 开始安装之前,请确保环境中已安装: - Node.js(npm/npx 安装需要) - Python 3(pip 安装需要) ## 第 1 步 安装 根据环境选择安装方式(选择其中一种即可): - Node.js 安装:npm/npx 安装 - Python 安装:pip 安装 ### npm/npx 安装 ```shell # 安装 CLI npm install -g trailsnap-cli # 安装 CLI SKILL(必需) npx skills add lc044/trailsnap -y -g ``` ### pip 安装 ```shell # 安装 CLI pip install trailsnap-cli # 安装 CLI SKILL(必需) npx skills add lc044/trailsnap -y -g ``` ## 第 2 步 配置api url和 token Agent 需要询问用户 TrailSnap 的 API URL 和 Token(如何获取请参考[TrailSnap API 文档](https://trailsnap.cn/docs/guide/settings/tokensetting.html)),收到用户输入后,执行以下命令配置: ```shell trailsnap config set --url --token ``` ## 第 3 步 验证 ```shell trailsnap photos list --limit 1 ``` --- # Claude Code - Source: https://trailsnap.cn/en/docs/guide/agent/claudecode.html - Markdown: https://trailsnap.cn/en/docs/guide/agent/claudecode.md - Category: Agent integration - Language: en # Claude Code > Use the trailsnap-cli skill in Claude Code to manage your album with AI. ## 1. Get an access token See [Token Settings](../settings/tokensetting.md). ## 2. Install Claude Code See the official docs: [Claude Code setup](https://code.claude.com/docs/en/setup). ## 3. Install trailsnap-cli skill :::tabs == Agent guided install Copy the prompt below to your Agent (OpenClaw, Claude Code, Cursor, TRAE, etc.). It will guide you to add the token and finish installation: ```text Help me install trailsnap-cli and the skill: https://trailsnap.cn/install.md My TrailSnap address is http://localhost:3180 My token is ts_hV5nsCZxxxxx ``` ![alt text](/images/wechat_longscreenshot_2026-04-27_224237_662.jpg) == Manual install Choose one install method: - Node.js: npm/npx - Python: pip #### npm/npx ```shell npm install -g trailsnap-cli npx skills add lc044/trailsnap -y -g ``` #### pip ```shell pip install trailsnap-cli npx skills add lc044/trailsnap -y -g ``` #### Configure API URL and token ```shell trailsnap config set --url --token ``` #### Verify ```shell trailsnap photos list --limit 1 ``` ::: ## Use the Skill Ask Claude in natural language: > "Use the trailsnap-cli skill and list my recent photos taken in Xi'an." > "Where did I travel last National Day? Generate an HTML travel diary for me." --- # Agent Skills - Source: https://trailsnap.cn/en/docs/guide/agent/ - Markdown: https://trailsnap.cn/en/docs/guide/agent/index.md - Category: Agent integration - Language: en # Agent Skills TrailSnap CLI can be used as an Agent tool (Skill) in different AI coding assistants or Agent platforms, such as Claude Code and OpenClaw / Roo Code. By letting the Agent call the CLI, AI can query and analyze your album data and answer questions based on your personal library. MCP-compatible clients can connect directly to TrailSnap's built-in Streamable HTTP server without wrapping the CLI. See [Configure TrailSnap MCP](./mcp.md). 1. Claude Code [How to use](./claudecode.md) 2. OpenClaw / Roo Code and other IDE Agents [How to use](./openclaw.md) 3. Other Agent platforms If you use Dify, Coze, FastGPT, or your own Agent framework, you can wrap the CLI as a system tool. Copy the prompt below to your Agent (OpenClaw, Claude Code, Cursor, TRAE, etc.). It will guide you to add the token and finish installation: ```text Help me install trailsnap-cli and the skill: https://trailsnap.cn/install.md My TrailSnap address is http://localhost:3180 My token is ts_hV5nsCZxxxxx ``` ## Use the Skill Ask your Agent in natural language: > "Use the trailsnap-cli skill and list my recent photos taken in Xi'an." > "Where did I travel last National Day? Generate an HTML travel diary for me." 👉 [View an AI-generated travel diary example](/examples/travel-diary-2025-golden-week.html) --- # Configure TrailSnap MCP - Source: https://trailsnap.cn/en/docs/guide/agent/mcp.html - Markdown: https://trailsnap.cn/en/docs/guide/agent/mcp.md - Category: Agent integration - Language: en # Configure TrailSnap MCP TrailSnap includes a Model Context Protocol (MCP) server. MCP-compatible AI clients can query the current user's photos, albums, people, and memory clues without accessing the database or original file paths. They can also create album organization proposals that require explicit confirmation inside TrailSnap. MCP uses a dedicated Agent Token, so an external agent never needs your account JWT or login password. ## 1. Choose the endpoint TrailSnap MCP uses **Streamable HTTP**: | Deployment | MCP endpoint | | --- | --- | | Docker, NAS, desktop, or reverse-proxy public entry | `https://your-domain.example/api/mcp/` | | LAN public entry | `http://host-ip:3180/api/mcp/` | | Direct backend access during development | `http://127.0.0.1:8000/mcp/` | The unified public entry only requires the TrailSnap frontend port. Do not expose the backend, AI service, or database ports separately. Keep the trailing `/` in the endpoint. ## 2. Create an Agent Token 1. Sign in to TrailSnap. 2. Open **Settings → Token Management**. 3. Select **New Token**, then set a name and expiration time. 4. Grant only the scopes required by the agent. 5. Verify your account password and immediately store the generated `ts_` token securely. | Scope | Purpose | | --- | --- | | `photos:read` | Search photos and investigate memory clues | | `albums:read` | List albums | | `people:read` | List people and build person timelines | | `albums:propose` | Create a proposal for user confirmation; cannot execute it | ::: tip Least privilege Photo Q&A usually needs only `photos:read`. Add `albums:propose` only when the user wants the agent to organize selected photos. ::: Store the token securely as soon as it is generated. Never commit it to Git, publish it in an issue or screenshot, or share it with an untrusted agent. ## 3. Configure an MCP client Configuration locations vary by client, but every client needs the Streamable HTTP endpoint and Bearer token: ```json { "mcpServers": { "trailsnap": { "type": "http", "url": "https://photos.example.com/api/mcp/", "headers": { "Authorization": "Bearer ts_your_agent_token" } } } } ``` Some clients call the type `streamable-http` or store headers in a separate authentication section. Follow your client's MCP documentation and replace all example values. After saving the configuration and restarting the client, these tools should be available: - `search_photos`: search by date, place, OCR, media type, people, and scores. - `list_albums`: list albums, covers, and photo counts. - `list_people`: list visible people and identity IDs. - `investigate_memory`: find candidate memories from fuzzy time, place, person, and text clues. - `get_person_timeline`: build an event timeline for a person. - `propose_album_organization`: create an album proposal that expires after seven days. Try this prompt to verify the connection: > Find my 10 most recent photos taken in Shanghai and explain why they matched. ## 4. Configure Pi Agent Pi does not load a generic MCP configuration directly. The TrailSnap repository provides a Pi Bridge and Skill that register the MCP tools as native Pi tools. ```shell npm install -g trailsnap-cli trailsnap config set --url "https://photos.example.com" --token "ts_your_agent_token" pi install git:github.com/LC044/TrailSnap ``` Run this command inside Pi to verify the connection: ```text /trailsnap-status ``` The Bridge prefers these environment variables: ```text TRAILSNAP_MCP_URL=https://photos.example.com/api/mcp/ TRAILSNAP_API_TOKEN=ts_your_agent_token ``` If they are absent, it reuses the URL and token saved by `trailsnap config set`. Pi tool names use the `trailsnap_` prefix, for example `trailsnap_search_photos`. ## 5. Public and reverse-proxy deployment When TrailSnap is accessed through a domain or LAN address, set the externally reachable site root on the Server service: ```text TRAILSNAP_PUBLIC_URL=https://photos.example.com ``` Docker Compose example: ```yaml services: server: environment: TRAILSNAP_PUBLIC_URL: https://photos.example.com ``` The public MCP endpoint becomes `https://photos.example.com/api/mcp/`. Album proposals also contain approval links that an external agent can give directly to the user. Only configure a dedicated MCP address when MCP uses a separate hostname: ```text TRAILSNAP_MCP_URL=https://mcp.example.com/mcp/ TRAILSNAP_MCP_ALLOWED_HOSTS=mcp.example.com ``` `TRAILSNAP_MCP_ALLOWED_HOSTS` accepts comma-separated hosts. Add only hosts that actually serve TrailSnap MCP; do not disable Host validation. ## 6. Confirm an album proposal An agent with `albums:propose` can only create a plan in the `proposed` state. No album, photo relationship, or tag changes occur at this point. The agent must give the returned `approval_url` to the user. The user signs in with a normal TrailSnap account, reviews the name, photos, cover, and tags, then explicitly confirms or rejects the proposal. An Agent Token cannot confirm, reject, or undo a plan. ## Troubleshooting ### 401 Unauthorized Check that the header is `Authorization: Bearer ts_...` and that the token has not expired or been revoked. A model-provider API key is not a TrailSnap Agent Token. ### A tool reports a missing scope Create a new token with the required scope. Person timelines need `people:read`; album proposals need `albums:propose`. Avoid granting every scope by default. ### Invalid Host header over a public address Set `TRAILSNAP_PUBLIC_URL` to the correct public site root. For a dedicated MCP hostname, add it to `TRAILSNAP_MCP_ALLOWED_HOSTS`. ### The approval URL is relative Set `TRAILSNAP_PUBLIC_URL` on the Server to return an absolute approval URL. The TrailSnap Pi Bridge also resolves relative URLs against the MCP origin. ### Can an agent delete or move photos? No. MCP does not expose photo deletion, file moves, renames, direct album mutation, or HTML execution. Use the [TrailSnap CLI](./trailsnap-cli.md) for administrative workflows and protect credentials that allow writes. --- # OpenClaw / Roo Code - Source: https://trailsnap.cn/en/docs/guide/agent/openclaw.html - Markdown: https://trailsnap.cn/en/docs/guide/agent/openclaw.md - Category: Agent integration - Language: en # OpenClaw / Roo Code OpenClaw / Roo Code can call TrailSnap CLI as a Skill, so the Agent can query your personal album data through TrailSnap APIs. ## 1. Get an access token See [Token Settings](../settings/tokensetting.md). ## 2. Install trailsnap-cli and the Skill You can let the Agent guide you: ```text Help me install trailsnap-cli and the skill: https://trailsnap.cn/install.md My TrailSnap address is http://localhost:3180 My token is ts_hV5nsCZxxxxx ``` Or install manually: ```shell npm install -g trailsnap-cli npx skills add lc044/trailsnap -y -g trailsnap config set --url --token ``` ## 3. Use it in chat Examples: > "Use trailsnap-cli to list the last 20 photos I took in Shanghai." > "Find photos containing 'boarding gate' text and summarize my flight history." --- # TrailSnap CLI - Source: https://trailsnap.cn/en/docs/guide/agent/trailsnap-cli.html - Markdown: https://trailsnap.cn/en/docs/guide/agent/trailsnap-cli.md - Category: Agent integration - Language: en # TrailSnap CLI ::: tip TrailSnap CLI is a command-line tool built on TrailSnap APIs. It can be used directly in your terminal, or as a Skill for Agents. ::: ## 1. Installation ### Install trailsnap-cli You can install trailsnap-cli in one of three ways: 1. pip ```bash pip install trailsnap-cli # Verify installation trailsnap -v ``` 2. npm ```bash npm install -g trailsnap-cli # Verify installation trailsnap -v ``` 3. Binary release from GitHub Download the binary from GitHub Releases and add it to your PATH: https://github.com/LC044/TrailSnap/releases ### Using trailsnap-cli On first use, configure your API URL and Token (replace `` and `` with actual values — see [Token Settings](/en/docs/guide/settings/tokensetting)): ```bash trailsnap config set --url --token ``` After configuration, verify with a simple query: ```bash trailsnap photos list --limit 5 ``` ## 2. Command Reference ::: tip All commands are run in the terminal using the format `trailsnap [options]`. Commands that interact with the API (photos, locations, etc.) require prior configuration via `config set`, otherwise an error will be shown. ::: ### 2.1 Basic Commands #### 2.1.1 help — Show help Displays all available commands, their structure, and core parameters for quick reference. ```bash trailsnap --help ``` ### 2.2 Configuration Commands #### 2.2.1 config set — Configure API URL and Token Configures the CLI with the unified TrailSnap address and Bearer token. This is a prerequisite for all API commands. Format: `config set --url API_URL --token API_TOKEN` Parameters: - `--url` (required): unified TrailSnap address, e.g. `http://localhost:3180`. The CLI automatically uses `/api`. - `--token` (required): API access token (Bearer Token) for authentication, obtained from the backend. Example: ```bash trailsnap config set --url http://localhost:3180 --token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` On success, the config file path is displayed (written to `.env` in the same directory). ### 2.3 Photo Management Commands #### 2.3.1 photos — Photo management Contains three sub-commands: list photos, get photo info, and delete a photo. All sub-commands require prior API configuration. ##### 2.3.1.1 photos list — List photos Query photos with pagination and filtering by album, location, or device info. Returns a simplified field set. Format: `photos list [--skip N] [--limit N] [--album-id ID] [--city CITY] [--province PROVINCE] [--make BRAND] [--model MODEL]` Parameters (can be combined): - `--skip`: Skip N photos (default 0) - `--limit`: Return N photos (default 10) - `--order_by`: Sort field; defaults to memory score. Options: `quality_score`, `memory_score`, `photo_time` - `--image-type`: Filter by image type, comma-separated. Options: `Camera` (phone/camera), `Screenshot`, `Other` - `--start-time`: Filter by start time, format: `YYYY-MM-DD HH:MM:SS` - `--end-time`: Filter by end time, format: `YYYY-MM-DD HH:MM:SS` - `--album-id`: Filter by album ID, comma-separated - `--people-id`: Filter by person ID, comma-separated - `--tag-id`: Filter by tag ID, comma-separated - `--city`: Filter by city, comma-separated (full name) - `--province`: Filter by province, comma-separated (full name) - `--scene`: Filter by scenic spot, comma-separated - `--make`: Filter by camera brand, comma-separated - `--model`: Filter by camera model, comma-separated Returns: JSON array with `id`, `filename`, `file_type`, `photo_time` Example: ```bash trailsnap photos list --limit 20 --city "Xi'an,Shanghai" ``` ##### 2.3.1.2 photos info — Get photo details Get metadata and content description for a specific photo. Format: `photos info --photo-id PHOTO_ID` Parameters: - `--photo-id` (required): Unique photo ID, obtainable via `photos list`. Returns: JSON object containing: - `address`: Detailed shooting address (down to street level) - `albums`: Album information - `tags`: Tag information - `faces_identities`: Person (face identity) information - `description`: Photo content description - `description`: Photo scene description (empty string if none) - `memory_score`: Memory worthiness score (0–100, 100 = most memorable) - `quality_score`: Photo quality score (0–100, 100 = highest quality) - `narrative`: One-line caption (empty string if none) Example: ```bash trailsnap photos info --photo-id 10001 ``` ##### 2.3.1.3 photos delete — Delete a photo Delete a specific photo by ID. This action is irreversible — use with caution. Format: `photos delete --photo-id PHOTO_ID` Parameters: - `--photo-id` (required): Unique ID of the photo to delete. Example: ```bash trailsnap photos delete --photo-id 10001 ``` On success: `Photo deleted successfully`. On failure: `Photo deletion failed or not found`. ### 2.4 Tag Commands #### 2.4.1 tags list — List classification tags Query classification tags with pagination. Format: `tags list [--skip N] [--limit N]` Parameters: - `--skip`: Skip N records (default 0) - `--limit`: Return N records (default 100) Example: ```bash trailsnap tags list ``` Returns: JSON array with `id`, `name` (tag_name), `count`. ### 2.5 Album Commands #### 2.5.1 albums list — List albums Query albums with pagination. Format: `albums list [--skip N] [--limit N]` Parameters: - `--skip`: Skip N albums (default 0) - `--limit`: Return N albums (default 100) Returns: JSON array with `id`, `name`, `count` (num_photos), `description`, `condition`, `type`. Example: ```bash trailsnap albums list ``` ### 2.6 Location Commands #### 2.6.1 locations — Location queries Contains two sub-commands: location distribution and footprint timeline, based on photo GPS data. ##### 2.6.1.1 locations list — Query location distribution Query location distribution without time info (place name, photo count). Supports grouping by level and date range filtering. Format: `locations list [--level city|province|district|scene] [--skip N] [--limit N] [--start-date YYYY-MM-DD] [--end-date YYYY-MM-DD]` Parameters: - `--level`: Grouping level (default `city`; options: `city`, `province`, `district`, `scene`) - `--skip`: Skip N locations (default 0) - `--limit`: Return N locations (default 100) - `--start-date`: Optional start date (YYYY-MM-DD) - `--end-date`: Optional end date (YYYY-MM-DD) Returns: JSON array with `name`, `count` Example: ```bash trailsnap locations list ``` ##### 2.6.1.2 locations timeline — Footprint timeline Query footprint timeline grouped by time period and location (start date, end date, location name, photo count). Supports grouping by level and date range filtering. Format: `locations timeline [--level city|province|district|scene] [--skip N] [--limit N] [--start-date YYYY-MM-DD] [--end-date YYYY-MM-DD]` Parameters: - `--level`: Grouping level (default `city`; options: `city`, `province`, `district`, `scene`) - `--skip`: Skip N locations (default 0) - `--limit`: Return N locations (default 100) - `--start-date`: Optional start date (YYYY-MM-DD) - `--end-date`: Optional end date (YYYY-MM-DD) Returns: JSON array with `startDate`, `endDate`, `locationName`, `count` Example: ```bash trailsnap locations timeline --level city --start-date 2025-01-01 --end-date 2025-06-30 ``` ### 2.7 People Commands #### 2.7.1 people list — List recognized people/faces Query people (face identities) with type filtering. Format: `people list [--limit N] [--types named,unnamed,hidden]` Parameters: - `--limit`: Number of records to return (default 100) - `--types`: Query types, comma-separated; default `named`. Options: `named`, `unnamed`, `hidden` Returns: JSON array with `id`, `name` (identity_name), `tags`, `description`, `face_count`. Example: ```bash trailsnap people list ``` ### 2.8 Folder Commands #### 2.8.1 folders list — List mounted storage folders Query information about mounted storage directories. Format: `folders list` Returns: JSON output from the backend API (field structure per server response). Example: ```bash trailsnap folders list ``` ### 2.9 Media Commands #### 2.9.1 medias get — Get photo media file or URL Get media content/access URL for a specific photo, supporting URL, base64, or local file output. Format: `medias get [--photo-id ID] [--size small|medium|large] [--format url|base64|file] [--output FILE_PATH]` Parameters: - `--photo-id`: Photo ID (default 100) - `--size`: Photo quality/size (default `medium`; options: `small`, `medium`, `large`) - `--format`: Output format (default `url` — can be embedded in HTML/Markdown; options: `url`, `base64`, `file`) - `--output`: Output file path (required only when `--format file`) Example: ```bash # Output URL (large = original image URL; small/medium = thumbnail URL) trailsnap medias get --photo-id 10001 --format url --size large # Base64 output (thumbnail base64 encoding) trailsnap medias get --photo-id 10001 --format base64 --size medium # Save to local file trailsnap medias get --photo-id 10001 --format file --output ./photo_10001.jpg ``` ### 2.10 Notes - All API-interacting commands (photos, locations, people, etc.) require prior `config set` with API URL and Token. Otherwise, the error message `Error: API URL and Token not configured. Please run 'config' first.` will be shown. - All commands support `--help` for detailed usage. Invalid parameters will show specific error messages and the correct format. --- # AI微服务设计 - Source: https://trailsnap.cn/docs/dev/ai_service.html - Markdown: https://trailsnap.cn/docs/dev/ai_service.md - Category: 开发者文档 - Language: zh-CN # AI微服务设计 AI 微服务用于承载 TrailSnap 的 AI 能力(如 OCR、人脸识别、场景分类、图片内容分析等),由后端任务系统按需调用。 ## 运行方式 - Docker Compose 部署时,会包含 `trailsnap-ai` 服务。 - 默认通过内网地址被后端访问:`AI_API_URL=http://ai:8001` ## LLM 托管 AI 服务支持本地 LLM 服务托管与代理能力: - 支持通过 llama.cpp 原生编译的 llama-server 二进制运行 LLM 服务 - 支持自定义模型路径、服务端口和空闲超时时间 - 自动处理模型下载、服务启停与空闲资源回收 - 提供 OpenAI 格式的 LLM 代理路由,透明转发请求到本地 llama.cpp 服务 多模态模型使用 MiniCPM-V-4_6-Q4_K_M,支持图片内容理解、标签生成等视觉任务。 ## llama.cpp 安装 使用内置 AI 连接需要安装 llama.cpp。 ### Windows ```bash # 使用 winget 安装 winget install llama.cpp # 或手动下载:https://github.com/ggerganov/llama.cpp/releases ``` ### Linux ```bash git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp mkdir build && cd build cmake .. -DLLAMA_CURL=ON cmake --build . --config Release sudo cp llama-server /usr/local/bin/ ``` ### macOS ```bash brew install llama.cpp ``` ## 常见接口 - 源码开发时 Swagger 文档:`http://localhost:8001/docs`。生产 Compose 中 AI 服务仅限内部访问,不映射用户端口。 ## 常见问题 - AI 服务无法访问:检查 `AI_API_URL` 配置与容器网络是否一致 - 识别任务无进度:在应用内"任务管理"查看任务状态与错误信息 - LLM 任务失败:确认 llama.cpp 已安装且 `llama-server` 命令可用 --- # 架构设计文档 - Source: https://trailsnap.cn/docs/dev/architecture.html - Markdown: https://trailsnap.cn/docs/dev/architecture.md - Category: 开发者文档 - Language: zh-CN # 架构设计文档 ::: code-group ```python [Python] console.log('js 代码') ``` ```sh [pnpm] console.log('ts 代码') ``` ```vue ``` ::: ## 1. 整体架构图 TrailSnap 采用典型的前后端分离架构,由前端展示层、后端服务层、AI 微服务层和数据存储层组成。 ![](https://blog.siyuan.ink/static/img/acdb9b89e748395e47df046c90fd005c.aaa.webp) 1. **前端展示层**:通过 Nginx 反向代理统一入口,支持 HTTP/HTTPS 访问,为用户提供前端交互界面。 2. **后端服务层**:以 FastAPI 为核心,通过安全认证模块实现 JWT 身份鉴权与多用户权限隔离,保障家庭多用户使用安全;拆分业务逻辑服务与任务管理器,实现同步业务与异步 AI 任务的解耦;通过 SQLAlchemy ORM 对接 PostgreSQL 存储元数据,通过文件服务对接 NAS 本地文件系统存储图片,完全适配 NAS 存储架构。 3. **AI 微服务层**:采用统一入口调度,内置模型管理器,实现模型按需懒加载、空闲自动卸载、按需自动下载的智能生命周期管理,大幅降低 NAS 内存与算力占用;集成 PaddleOCR、InsightFace、YOLO+OCR、CLIP 等 AI 能力,覆盖 OCR 识别、人脸识别、票据识别、向量检索等核心相册功能,同时支持对接 Qwen、GPT 等外部大模型,具备良好扩展性。 4. **数据存储层**:元数据与文件分离存储,数据完全本地化,保障家庭数据隐私安全。 ## 2. 技术选型及版本 ### 2.1 前端技术栈 ### 2.2 后端技术栈 - **编程语言**: Python 3.12+ - **Web 框架**: FastAPI 0.122.0 - **ASGI 服务器**: Uvicorn 0.38.0 - **ORM**: SQLAlchemy 2.0.44 - **数据库迁移**: Alembic 1.17.2 - **数据库驱动**: psycopg2 (PostgreSQL) - **任务/异步**: APScheduler、`aiohttp` - **AI/CV (AI 微服务)**: - PaddleOCR ==3.3.2 - PaddlePaddle-GPU `==3.2.0`(可选 GPU) - OpenCV `opencv-python-headless >=4.9.0` - Torch `>=2.0.0`、TorchVision `>=0.15.0`(部分模型可用) - InsightFace(人脸) - **日志**: 自定义 JSON 队列日志 + 按日容量滚动(server 与 ai 均内置) ### 2.3 数据库 - **PostgreSQL(PgVector)**: 关系型数据库,存储用户、相册、照片元数据、系统设置等。 ## 3. 目录结构与模块说明 ### 3.1 根目录 - `package/server`: 后端服务代码 - `package/website`: 前端应用代码 - `doc`: 项目文档 ### 3.2 后端结构 (`package/server`) - **app/**: 核心应用代码 - `api/`: API 路由定义 (EndPoints),按功能模块划分 (user, album, photo, etc.) - `core/`: 核心配置与工具 (Logger, Config) - `crud/`: 数据库 CRUD 操作封装 - `db/`: 数据库模型 (Models) 与会话管理 (Session) - `schemas/`: Pydantic 数据模型 (Request/Response schemas) - `service/`: 复杂业务逻辑与后台服务 (TaskManager, Indexer, Storage) - `utils/`: 通用工具函数 (Exif解析, 文件名处理) - **railway/**: 铁路相关功能模块 (独立的数据处理与同步逻辑) - **yolo_ocr/**: OCR 与票据识别相关模型与脚本 - **main.py**: 应用入口,路由挂载、CORS、中间件与端口配置(默认 `:8000`) ### 3.3 前端结构 (`package/website`) - **src/**: 源代码 - `api/`: 后端接口封装 - `assets/`: 静态资源 (图片, CSS) - `components/`: 通用 Vue 组件 (PhotoGallery, TrainTicket, etc.) - `composables/`: 组合式函数 (Hooks) - `layouts/`: 页面布局组件 - `router/`: 路由配置 - `stores/`: Pinia 状态管理仓库 - `types/`: TypeScript 类型定义 - `views/`: 页面视图 (Pages) - `package.json`: 依赖与版本管理,内含脚本 `dev/build/preview` ### 3.4 AI 微服务结构 (`package/ai`) - **app/main.py**: AI 服务入口(默认 `:8001`),挂载 `ocr/face/object-detection/tickets` 路由 - **app/services/**: 模型服务(`ocr_service.py`、`face_service.py`、`model_manager.py` 懒加载与资源释放) - **app/core/logger.py**: JSON 队列日志,按日容量滚动 - **requirements.txt**: 依赖与版本约束(PaddleOCR、PaddlePaddle-GPU、Torch、OpenCV 等) ## 4. 关键交互与调用链 ```mermaid sequenceDiagram participant FE as 前端 (Vue) participant S as 后端服务 :8000 participant AI as AI 微服务 :8001 participant DB as PostgreSQL participant FS as 文件系统 FE->>S: GET /api/ocr?photo_id=... S->>DB: 查询 ocr_results DB-->>S: 归一化多边形/文本 S-->>FE: JSON 响应 S->>AI: POST /ocr/predict (异步任务) AI->>AI: PaddleOCR 推理 AI-->>S: rec_texts/rec_scores/rec_polys S->>DB: 写入 ocr_results(坐标归一化 0~1) FE->>S: 媒体操作/相册管理 S->>FS: 读取/写入媒体文件 S->>DB: 写入/查询元数据 ``` --- # 后端框架分析文档 - Source: https://trailsnap.cn/docs/dev/backend.html - Markdown: https://trailsnap.cn/docs/dev/backend.md - Category: 开发者文档 - Language: zh-CN # 后端框架分析文档 ## 1. 技术栈详细说明 ### 1.1 核心框架 - **FastAPI**(Server): 高性能异步 Web 框架,提供自动化 OpenAPI 文档 (`/docs`)。 - **Uvicorn**: ASGI 服务器,运行 FastAPI 应用。 - **Pydantic**: 请求/响应模型与数据校验。 ### 1.2 数据持久化 - **PostgreSQL**: 主数据库。 - **SQLAlchemy (Async)**: ORM 框架,使用异步模式 (`AsyncSession`) 与数据库交互,提高并发处理能力。 - **Alembic**: 数据库版本控制工具,用于处理 Schema 变更迁移。 ### 1.3 异步任务与服务 - **APScheduler**: 用于定时任务调度(虽然代码中主要使用了自定义的 TaskManager,但依赖列表中包含此库,可能用于周期性任务)。 - **TaskManager**: 自定义任务管理器 (`app/service/task_manager.py`),用于处理耗时操作,如: - 照片扫描与索引 - 缩略图生成 - 元数据提取 - OCR 识别任务 ### 1.4 AI 与 图像处理 - **PaddleOCR**(AI 微服务): 文本检测与识别,支持 `rec_texts/rec_scores/rec_polys` 输出。 - **InsightFace**(AI 微服务): 人脸检测/关键点/特征提取。 - **YOLO (Ultralytics)**: 服务端独立脚本用于票据区域检测与裁剪。 - **OpenCV**: 图像解码与基础处理。 ## 2. 服务模块划分与调用关系 ```mermaid graph TD Request[Client Request] --> Middleware[Middleware Logging/CORS] Middleware --> Router[API Routers] subgraph Modules [module layer] Router --> UserMod[User Module] Router --> AlbumMod[Album Module] Router --> PhotoMod[Photo Module] Router --> TaskMod[Task Module] Router --> RailwayMod[Railway Module] end subgraph Services [service layer] PhotoMod --> StorageSvc[Storage Service] PhotoMod --> IndexerSvc[Indexer Service] TaskMod --> TaskMgr[Task Manager] TaskMgr --> Workers[Worker Threads/Processes] end subgraph External [external dependencies] Workers --> AI_Svc[AI Service :8001] Workers --> FileSys[File System] StorageSvc --> FileSys end subgraph Data [data layer] UserMod --> CRUD[CRUD Operations] AlbumMod --> CRUD PhotoMod --> CRUD CRUD --> DB[(PostgreSQL)] end ``` ### 2.2 AI 微服务调用链 ```mermaid sequenceDiagram participant S as Server :8000 participant AI as AI Service :8001 participant DB as PostgreSQL S->>AI: POST /ocr/predict (multipart form: file) AI->>AI: PaddleOCR.ocr(img) AI-->>S: prunedResult(rec_texts, rec_scores, rec_polys) S->>DB: 写入 ocr_results(坐标归一化为 0~1) ``` ### 2.1 关键模块解析 - **API Routers (`app/api`)**: 控制层,处理 HTTP 请求,参数校验,调用 Service 或 CRUD 层。 - **CRUD Layer (`app/crud`)**: 数据访问层,封装所有数据库交互逻辑,保持业务逻辑纯净。 - **Service Layer (`app/service`)**: 业务逻辑层,处理复杂业务,如文件系统操作、调用 AI 模型、后台任务管理。 ## 3. API 设计规范与现状 ### 3.1 规范 - **RESTful 风格**: 接口设计遵循资源导向,如 `GET /albums` 获取列表,`POST /albums` 创建相册。 - **响应格式**: 使用 Pydantic 模型定义 Response Schema,确保返回数据结构一致。 - **状态码**: 遵循 HTTP 标准状态码(200 成功, 201 创建, 400 请求错误, 401 未授权, 404 未找到, 500 服务器错误)。 ### 3.2 接口文档现状 - **Swagger UI**: FastAPI 自动生成交互式文档,地址通常为 `/docs`。 - **ReDoc**: 另一种风格的文档,地址通常为 `/redoc`。 - **主要资源**: - `/users`: 用户相关。 - `/albums`: 相册的增删改查。 - `/photos`: 照片上传、流式获取、元数据管理。 - `/tasks`: 任务状态查询、任务触发。 - `/settings`: 系统配置管理。 - `/faces`: 人脸实体与照片管理。 - `/ocr`: OCR 识别记录查询(`GET /ocr?photo_id=...`)。 - `/train-ticket`: 火车票 CRUD 与导出。 - `/railway`: 铁路站点与运行计划接口。 ### 3.3 日志与异常 - **日志**: JSON 队列日志 + 按日容量滚动;每条记录包含 `timestamp/level/message/operation/params/result`。 - **异常**: 统一捕获并写入日志;AI 调用失败或图像解码错误将返回相应错误码并记录。 ### 3.4 数据模型说明(示例) - **OCR 结果**(表 `ocr_results`): - `text: str`、`text_score: float`、`polygon: List[List[float]]`(坐标归一化至 0~1) - 查询接口:`GET /ocr?photo_id=` 返回列表记录 --- # 功能设计文档 - Source: https://trailsnap.cn/docs/dev/feature-proposals.html - Markdown: https://trailsnap.cn/docs/dev/feature-proposals.md - Category: 开发者文档 - Language: zh-CN # 功能设计文档 本文档收录 TrailSnap 待开发功能的设计草案,供社区讨论和贡献参考。 --- ## 1. 图片编辑功能 ### 1.1 背景与目标 用户当前只能查看照片,缺少基本的编辑能力。图片编辑是相册应用的高频需求,可为后续"自动生成朋友圈九宫格"等功能打下基础。 ### 1.2 功能范围 **基础编辑** - 裁剪(自由裁剪、比例裁剪如 1:1、16:9) - 旋转(90°、水平翻转、垂直翻转) - 缩放与拖拽 **标签与标注** - 添加文字标签(支持字体、颜色、大小) - 添加箭头、框选等简单图形 - 添加时间、地点水印 **滤镜与调整** - 基础调整:亮度、对比度、饱和度 - 预设滤镜:复古、黑白、柔和等 ### 1.3 技术方案 - 前端使用 Canvas API 或 WebGL 实现无损编辑 - 编辑结果支持导出为原图质量的 JPEG/PNG - 编辑历史记录(Undo/Redo) ### 1.4 优先级 **中优先级** - 作为工具箱模块的一部分开发 --- ## 2. 照片自动整理 ### 2.1 背景与目标 用户照片随时间积累杂乱,手动整理耗时。通过 AI 自动按时间、地点、内容等维度归类,减少用户操作成本。 ### 2.2 整理规则 | 规则 | 说明 | 示例 | | --- | --- | --- | | 按年份月份 | 创建 `2024/2024-03` 或 `2024-03` 文件夹 | 2024/2024-03 或 2024-03 | | 按日期 | 创建 `2024/2024-03-15` 或 `2024-03-15` 文件夹 | 2024/2024-03-15 或 2024-03-15 | | 按人物 | 创建 `人物-张三/` 文件夹 | 张三的人脸照片 | | 按场景 | 创建 `美食/`、`宠物/` 文件夹 | 分类后的照片 | ### 2.3 技术方案 - 使用现有元数据(EXIF、地理位置、人脸标签、场景分类) - 复制或移动照片(用户选择) - 支持预览整理结果后再执行 - 记录整理日志,支持撤销 - **新增:支持平铺结构和递归嵌套结构两种时间目录格式** ### 2.4 状态 **已实现** - 工具箱 → 照片自动整理 ### 2.5 优先级 ~~**中优先级**~~ → 已上线 --- ## 3. 自动旅行日志 ### 3.1 背景与目标 用户在旅行后常需手动整理照片、编写游记,过程繁琐。AI 可自动从照片、票据、地点等数据生成结构化旅行记录。 ### 3.2 输入数据 - 旅行期间的照片(含元数据) - 识别出的火车票、飞机票、门票 - 地理位置轨迹 - 可能的 AI 描述与评分 ### 3.3 输出内容 **结构化日志** - 标题:旅行名称(如"2024年3月厦门之旅") - 时间:出发日期、返回日期、总天数 - 行程:每日行程时间线 - 地点:去过的城市/景点 - 人物:同行者 - 费用:交通、门票等分类统计 **图文混排** - 支持导出为 Markdown/HTML - 可直接发布到博客平台 - 支持生成 PDF ### 3.4 技术方案 - 使用 LangChain/LangGraph 编排多步骤生成流程 - 分阶段生成:行程概览 → 每日详情 → 费用统计 → 最终润色 - 支持流式输出,展示生成进度 - 提供模板引擎,支持自定义输出格式 ### 3.5 优先级 **高优先级** - 核心差异化功能 --- ## 4. 朋友圈九宫格生成 ### 4.1 背景与目标 用户分享旅行照片到朋友圈时,需手动拼图、选图、配文。提供一键生成九宫格及配套文案,降低分享成本。 ### 4.2 功能模块 **智能选图** - 从旅行照片中 AI 选出 9 张最具代表性的照片 - 考虑因素:质量评分、内容多样性、时间分布 **拼图样式** - 3×3 标准九宫格 - 自由排版(支持 1+2+6 等异形布局) - 样式模板:简约、文艺、复古 **文案生成** - 根据照片内容、景点生成文案 - 支持多种风格:诗意、幽默、简短 - 可选择添加话题标签 ### 4.3 技术方案 - 使用 Canvas API 实现拼图 - 调用大模型生成文案(few-shot prompts) - 支持预览和微调 ### 4.4 优先级 **高优先级** - 强社交传播属性 --- ## 5. 视频高光剪辑 ### 5.1 背景与目标 静态照片难以传达旅行氛围。从 Live Photo、视频素材中自动剪辑 15-30 秒的高光短片,适合分享到短视频平台。 ### 5.2 功能模块 **素材收集** - 支持 Live Photo 视频片段 - 支持用户上传的视频文件 - 支持按相册/时间筛选素材 **智能剪辑** - 自动识别高光时刻(如笑容、动作、风景转换) - 自动匹配合适的背景音乐 - 生成多种时长版本(15s/30s/60s) **后期处理** - 转场效果(淡入淡出、滑动) - 基础调色 - 添加文字标题/字幕 ### 5.3 技术方案 - 使用 OpenCV 进行视频分析(场景检测、光学流) - 使用 FFmpeg 进行视频处理与导出 - 或接入云服务(如剪映 API) ### 5.4 优先级 **低优先级** - 技术复杂度高,可后期考虑 --- ## 6. 网络文件夹扫描 ### 6.1 背景与目标 用户的照片可能分散存储在各种网盘和网络存储中,如百度网盘、阿里云盘、OneDrive、SMB 共享目录、WebDAV 服务器等。打通这些数据源,让 TrailSnap 能够统一管理和分析跨平台的照片资产。 ### 6.2 支持的存储类型 **云盘服务** | 服务 | API 类型 | 说明 | | --- | --- | --- | | 百度网盘 | 开放 API | 需要申请应用获取 API Key | | 阿里云盘 | 开放 API | OAuth2.0 授权 | | OneDrive | Microsoft Graph API | OAuth2.0 授权 | | Google Drive | Google Drive API | OAuth2.0 授权 | | Dropbox | Dropbox API | OAuth2.0 授权 | **网络文件协议** | 协议 | 说明 | 适用场景 | | --- | --- | --- | | SMB/CIFS | Windows 网络共享、NAS 常用协议 | 家庭 NAS、局域网共享 | | WebDAV | HTTP-based 文件访问协议 | 许多 NAS 和云服务支持 | | FTP/SFTP | 传统文件传输协议 | legacy 系统连接 | ### 6.3 功能模块 **连接管理** - 支持添加多个存储账号 - OAuth2.0 授权流程(云盘) - 账号凭据安全存储(加密) - 连接状态检测与自动重连 **文件扫描** - 递归扫描指定文件夹 - 仅扫描图片文件(jpg、png、heic、raw 等) - 增量扫描(仅扫描新增文件) - 扫描进度展示与中断支持 **元数据提取** - 文件名、路径、大小、创建/修改时间 - EXIF 元数据(相机、GPS、时间) - 与现有照片库去重(基于文件哈希) **预览与导入** - 缩略图预览 - 选择性导入(按文件夹、按日期范围) - 导入模式:仅索引(原文件保留在原处)或复制到本地 ### 6.4 技术方案 **云盘 SDK** - 百度网盘:[baidupcs-go](https://github.com/qingxinrun/baidupcs-go) 或官方 Python SDK - 阿里云盘:自研 OAuth2 + API 调用 - OneDrive:[Microsoft Graph SDK for Python](https://github.com/microsoftgraph/msgraph-sdk-python) - Google Drive:[google-api-python-client](https://github.com/google/google-api-python-client) - Dropbox:[dropbox-sdk-python](https://github.com/dropbox/dropbox-sdk-python) **网络协议** - SMB:[pysmb](https://github.com/miketeo/pysmb) 或 [python-smb](https://github.com/miketeo/python-smb) - WebDAV:[webdavclient3](https://github.com/barneygale/webdavclient3) - FTP/SFTP:[ftplib](https://docs.python.org/3/library/ftplib.html) / [pysftp](https://github.com/paramiko/pysftp) **架构设计** ``` ┌─────────────────────────────────────────┐ │ Storage Adapter Layer │ │ ┌─────────┐ ┌─────────┐ ┌───────────┐ │ │ │ BaiduPCS│ │ Aliyun │ │ OneDrive │ │ │ └─────────┘ └─────────┘ └───────────┘ │ │ ┌─────────┐ ┌─────────┐ ┌───────────┐ │ │ │ SMB │ │ WebDAV │ │ SFTP │ │ │ └─────────┘ └─────────┘ └───────────┘ │ └─────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ Unified File Indexer │ │ - 文件列表抽象层 │ │ - 去重检测(MD5/SHA256) │ │ - 元数据标准化 │ └─────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ TrailSnap Photo Store │ │ - 导入照片到本地索引 │ │ - 或仅保持元数据引用 │ └─────────────────────────────────────────┘ ``` **安全性** - 云盘 OAuth Token 安全存储(加密后存库) - 网络协议凭据加密存储 - 定期刷新 Token - 最小权限原则(只申请读权限) ### 6.5 优先级 **高优先级** - 大幅扩展数据源,提升应用价值 --- ## 7. 家庭共享与协作 ### 7.1 背景与目标 家庭成员可能共用一个 TrailSnap 实例,或希望共享特定相册给家人。支持多用户协作场景。 ### 7.2 功能模块 **权限管理** - 管理员、普通用户角色 - 相册级权限控制(查看、编辑、分享) - 访客模式(仅查看指定相册) **相册分享** - 生成分享链接(可选密码保护) - 有效期控制(24小时/7天/永久) - 禁止下载开关 **评论与点赞** - 家庭成员可对照片评论 - 简单点赞反应 ### 7.3 技术方案 - 复用现有用户系统,增加角色字段 - 分享链接使用 JWT 或临时 Token - 评论存储在独立表 ### 7.4 优先级 **低优先级** - 涉及多用户场景可后续考虑 --- ## 8. 智能相册推荐 ### 8.1 背景与目标 用户可能不会主动创建相册。系统可主动推荐"值得整理"的相册,如"周末小聚"、"十一长假"等。 ### 8.2 推荐场景 | 场景 | 触发条件 | | --- | --- | | 周末小聚 | 周六/日有 5+ 张照片,集中在一地 | | 十一长假 | 国庆假期有 20+ 张照片 | | 美食集锦 | 近期"美食"分类有 10+ 张照片 | | 家人时刻 | 近期含"父母""子女"标签照片居多 | | 景点打卡 | 某 5A 景区有 3+ 张照片 | ### 8.3 技术方案 - 定时任务扫描,分析近期照片分布 - 基于规则+AI 识别生成推荐 - 展示给用户确认后创建相册 ### 8.4 优先级 **中优先级** - 提升用户活跃度 --- ## 优先级汇总 | 优先级 | 功能 | | --- | --- | | **高** | 自动旅行日志、朋友圈九宫格、网络文件夹扫描 | | **中** | 图片编辑、智能相册推荐 | | **低** | 视频高光剪辑、家庭共享与协作 | | **已上线** | 照片自动整理 | --- *本文档为设计草案,具体实现细节可在正式开发前进一步细化。欢迎通过 Issue 或 PR 贡献想法。* --- # 前端框架分析文档 - Source: https://trailsnap.cn/docs/dev/frontend.html - Markdown: https://trailsnap.cn/docs/dev/frontend.md - Category: 开发者文档 - Language: zh-CN # 前端框架分析文档 ## 1. 技术栈拆解 ### 1.1 核心框架 项目使用 **Vue 3** 作为核心框架,采用 Composition API 提供灵活的逻辑复用能力;配合 **TypeScript** 提供静态类型检查,增强代码健壮性;构建工具为 **Vite**。 ### 1.2 UI 组件库与样式 - **Element Plus**: 作为主要的基础组件库,提供按钮、表单、对话框等通用组件。 - **TailwindCSS**: 用于原子化 CSS 样式开发,提供灵活的布局和响应式设计能力,减少编写自定义 CSS 的需求。 - **图标**: 使用 `lucide-vue-next` 和 `mingcute_icon` 提供现代化的矢量图标。 ### 1.3 状态与路由管理 - **Pinia**: 取代 Vuex 成为新一代状态管理工具,提供更简洁的 API 和更好的 TypeScript 支持。主要 Store 包括: - `albumStore`: 管理相册列表和详情。 - `photoStore`: 管理照片数据和浏览状态。 - `ticketStore`: 管理车票和行程数据。 - **Vue Router**: 处理单页应用 (SPA) 的路由跳转,支持嵌套路由和导航守卫。 ### 1.4 数据交互 - **Axios**: 封装 HTTP 请求,配合 `src/utils/request.ts` 进行拦截器配置(统一处理 Token、错误响应)。 - **API 层**: `src/api` 目录将接口调用按模块封装,与业务逻辑解耦。 ## 2. 前端组件层级关系 ```mermaid graph TD App[App.vue] --> Layout{Layout Strategy} Layout --> |Default| MainLayout[MainLayout.vue] Layout --> |Blank| BlankLayout[BlankLayout.vue] MainLayout --> NavBar[NavBar.vue] MainLayout --> RouterView[RouteOutlet.vue / RouterView] MainLayout --> Footer[Footer.vue] RouterView --> HomePage[HomePage.vue] RouterView --> AlbumPage[AlbumPage.vue] RouterView --> TicketPage[TicketPage.vue] RouterView --> Settings[Settings.vue] AlbumPage --> AlbumList[AlbumList.vue] AlbumPage --> AlbumDetail[AlbumDetail.vue] AlbumDetail --> PhotoGallery[PhotoGallery.vue] PhotoGallery --> PhotoLightbox[PhotoLightbox.vue] TicketPage --> TicketTimeline[TicketTimeline.vue] TicketTimeline --> TicketCard[TicketCard.vue] TicketCard --> TrainTicket[TrainTicket.vue] Settings --> BasicSettings[BasicSettings.vue] Settings --> UserMgmt[UserManagement.vue] Settings --> TaskMgmt[TaskManagement.vue] ``` ## 3. 性能指标与优化分析 ### 3.1 现有性能特性 - **按需引入**: Element Plus 和图标库通常支持按需引入,减少包体积。 - **虚拟列表**: `composables/useVirtualLayout.ts` 表明项目中已实现或计划实现虚拟滚动,这对于展示大量照片(瀑布流)或长列表至关重要,能显著减少 DOM 节点数量,提升渲染性能。 - **响应式布局**: 利用 TailwindCSS 实现多端适配,避免了针对不同设备加载不同代码的冗余。 ### 3.2 优化空间 1. **图片加载优化**: - 瀑布流布局应配合后端提供的缩略图接口,避免直接加载原图。 - 实现图片懒加载 (Lazy Loading),仅当图片进入视口时才加载。 2. **代码分割 (Code Splitting)**: - 路由懒加载:确保 `router/index.ts` 中使用 dynamic import (`() => import(...)`) 加载组件,减小首屏包体积。 3. **构建优化**: - 利用 Vite 的构建特性,配置合理的 `splitVendorChunkPlugin` 或自定义 `rollupOptions` 将第三方库分包缓存。 4. **状态管理优化**: - 避免 Store 过于庞大,合理拆分 Store 模块。 - 确保 Store 中的数据仅在需要时更新,减少不必要的组件重渲染。 5. **交互与绘制优化**: - OCR 多边形绘制建议使用 `requestAnimationFrame` 批量刷新,减少频繁重排。 - 对于大图预览,采用 `object-fit` 与 CSS 硬件加速 (`will-change: transform`) 提升滚动与缩放体验。 ## 4. 前端与后端交互示意 ```mermaid sequenceDiagram participant FE as Vue Frontend participant API as Server API :8000 participant AI as AI Service :8001 FE->>API: GET /api/ocr?photo_id=... API-->>FE: OCR records (归一化多边形/文本) FE->>API: 媒体/相册相关接口 API-->>FE: 列表/详情/流式媒体 API->>AI: POST /ocr/predict (由任务触发) AI-->>API: prunedResult (rec_texts/rec_scores/rec_polys) ``` --- # TrailSnap 开发者文档 - Source: https://trailsnap.cn/docs/dev/guide.html - Markdown: https://trailsnap.cn/docs/dev/guide.md - Category: 开发者文档 - Language: zh-CN # TrailSnap 开发者文档 本文档旨在为开发者提供 TrailSnap 项目的开发指南,涵盖环境搭建、项目结构、开发流程等内容。 ## 目录 1. [项目简介与技术栈](#1-项目简介与技术栈) 2. [开发环境准备](#2-开发环境准备) 3. [项目结构详解](#3-项目结构详解) 4. [后端开发指南](#4-后端开发指南) 5. [前端开发指南](#5-前端开发指南) 6. [AI 服务开发指南](#6-ai-服务开发指南) 7. [数据库迁移](#7-数据库迁移) --- ## 1. 项目简介与技术栈 TrailSnap 是一个前后端分离的项目,集成了 AI 能力。 - **前端**: Vue 3, TypeScript, Vite, Element Plus, TailwindCSS - **后端**: Python (FastAPI), SQLAlchemy, Alembic - **数据库**: PostgreSQL (需开启 pgvector 插件以支持向量搜索) - **AI 服务**: 独立微服务,基于 FastAPI,集成 PaddleOCR, InsightFace, YOLO 等模型。 ## 2. 开发环境准备 在开始开发之前,请确保您的机器上安装了以下工具: - **Git**: 版本控制 - **Python**: 3.10+ (推荐 3.12) - **Node.js**: v18+ (推荐 v20 或 v22) - **pnpm**: 前端包管理器 (`npm install -g pnpm`) - **Docker & Docker Compose**: 用于快速启动数据库 ## 3. 项目结构详解 ``` TrailSnap/ ├── doc/ # 项目文档 ├── package/ │ ├── ai/ # AI 微服务 │ │ ├── app/ # AI 核心逻辑 │ │ └── ... │ ├── server/ # 后端主服务 │ │ ├── app/ # FastAPI 应用 │ │ │ ├── api/ # 接口路由 │ │ │ ├── core/ # 配置与日志 │ │ │ ├── crud/ # 数据库操作 │ │ │ ├── db/ # 模型定义 │ │ │ ├── schemas/ # Pydantic 模型 │ │ │ └── service/ # 业务逻辑 │ │ └── ... │ └── website/ # 前端应用 │ ├── src/ # 源代码 │ └── ... └── ... ``` ## 4. 后端开发指南 后端位于 `package/server`。 ### 4.1 启动数据库 项目依赖 PostgreSQL 和 pgvector 插件。推荐使用 Docker 启动:由于文档部署限制,请直接查看项目源码中 `package/server/README.md` 文件。 ### 4.2 安装依赖 推荐使用 `uv` 进行包管理。 ```bash cd package/server # 安装 uv pip install uv # 使用 uv uv sync ``` ### 4.3 配置文件 在 `package/server/data` 目录下创建 `.env` 文件(参考 README 或直接配置): ```env DB_URL=postgresql://user:password@localhost:5432/trailsnap RAILWAY_DB_URL=postgresql://user:password@localhost:5432/railway AI_URL=http://localhost:8001 ``` ### 4.4 运行服务 ```bash # 第一次运行、或数据库结构发生变化时需要初始化数据库 uv run python start.py # 数据库结构初始化完成后,启动服务 uv run uvicorn main:app --reload --port 8000 ``` API 文档地址:`http://localhost:8000/docs` ## 5. 前端开发指南 前端位于 `package/website`。 ### 5.1 安装依赖 ```bash cd package/website pnpm install ``` ### 5.2 运行开发服务器 ```bash pnpm dev ``` 访问地址:`http://localhost:5176` ### 5.3 构建 ```bash pnpm build ``` ## 6. AI 服务开发指南 AI 服务位于 `package/ai`,为后端提供 OCR 和人脸识别能力。 ### 6.1 安装依赖 ```bash cd package/ai pip install uv # 安装依赖(CPU版本) uv sync --extra cpu # 安装依赖(GPU版本) uv sync --extra gpu ``` ### 6.2 运行服务 ```bash uv run uvicorn app.main:app --reload --port 8001 ``` ## 7. 数据库迁移 后端使用 Alembic 管理数据库迁移。 **注意**:修改 `db/models` 下的模型后,必须执行迁移才能生效。 1. **生成迁移脚本** ```bash cd package/server alembic revision --autogenerate -m "描述修改内容" ``` 2. **执行迁移** ```bash alembic upgrade head ``` 3. **常用命令** - `alembic current`: 查看当前版本 - `alembic history`: 查看历史版本 - `alembic downgrade -1`: 回滚上一个版本 ## 8. 打包docker镜像 ```bash cd TrailSnap # 一键打包docker镜像 docker-compose up -d --build ``` ```bash # 打包前端镜像 docker build -t crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-frontend:master -f package/website/Dockerfile . # 打包后端镜像 docker build -t crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-backend:master -f package/server/Dockerfile . # 打包AI镜像 docker build -t crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-ai:master -f package/ai/Dockerfile . ``` --- # 任务管理模块设计文档 - Source: https://trailsnap.cn/docs/dev/task_manager.html - Markdown: https://trailsnap.cn/docs/dev/task_manager.md - Category: 开发者文档 - Language: zh-CN # 任务管理模块设计文档 > TrailSnap 是部署在NAS上的AI相册,该架构设计充分考虑到了NAS设备的特点(通常CPU性能较低、无GPU加速、照片数量较多且一般存储在机械硬盘上、docker等软件一般安装在高速的固态硬盘上)。 ## 1. 整体架构 任务管理模块采用**多级缓冲 + 生产者-消费者(Multi-Level Buffer + Producer-Consumer)**模型,以**数据库(PostgreSQL)作为持久化后端,以内存优先级队列作为调度中枢**,实现了任务生产与消费的彻底解耦。该架构主要包含以下四个核心组件: - **生产者 (TaskManager)**: 运行在 API 服务进程中,负责接收用户请求或系统触发的事件,生成任务并写入数据库。 - **持久化任务队列 (Database Table)**: `Task` 表充当可靠的任务持久化存储,存储任务的类型、状态、优先级、负载参数等信息,确保在服务重启时任务不丢失。 - **调度中枢 (TaskQueueManager)**: 位于 `task_worker.py` 中的内存调度模块,维护三个独立优先队列(CPU / IO / AI),负责从数据库批量拉取任务并进行优先级排序。 - **消费者 (TaskWorker)**: 三个独立的工作协程(CPU Consumer、IO Consumer、AI Consumer),分别监听对应分类队列,以**自适应速率**消费任务并通过执行池完成处理。 ### 架构图示 ![](https://blog.siyuan.ink/static/img/f9dff9426ecdcd388450744aa3830f6a.TaskManager.webp) ```mermaid graph TD Client[客户端/API] -->|请求任务| TM[TaskManager Producer] TM -->|写入 PENDING| DB[(PostgreSQL Task Table)] subgraph TaskWorker [TaskWorker 调度中枢] TW_P[Producer Loop] -->|拉取任务分组| DB TW_P -->|入队| QM[TaskQueueManager] QM -->|Semaphore 限流| C_CPU[CPU Consumer Loop] QM -->|Semaphore 限流| C_IO[IO Consumer Loop] QM -->|Semaphore 限流| C_AI[AI Consumer Loop] end C_CPU -->|ThreadPool Executor| CPU_Exec[CPU 执行池
批量处理缩略图/元数据] C_IO -->|直接执行| IO_Exec[IO 执行池
批量 AI 请求/人脸识别] C_AI -->|并发控制| AI_Exec[AI 执行池
大模型批量描述生成] CPU_Exec -->|结果| RQ[Result Queue] IO_Exec -->|结果| RQ AI_Exec -->|结果| RQ RQ -->|批量刷新| DB RQ -->|触发后续任务| TM ``` ## 2. 核心设计思想 ### 2.1 策略模式与工厂模式(Strategy + Factory Pattern) 任务执行层彻底采用了**策略模式**进行解耦: - **BaseTaskStrategy**(抽象基类):定义了所有任务处理器必须实现的接口,包括 `process()`(单任务处理)和 `process_batch()`(批量处理),以及 `handle_completion()`(完成回调)。 - **TaskStrategyFactory**(策略工厂):通过类方法注册机制(`@TaskStrategyFactory.register(TaskType.XXX)`),维护了一个从 `TaskType` 到具体策略类的映射表。调度层完全不依赖具体任务类型,仅通过工厂动态获取策略实例,实现了**开闭原则(OCP)**——新增任务类型无需修改调度核心代码。 ### 2.2 反馈驱动的自适应生产速度 传统轮询模型的通病是**无意义的数据库 I/O**:无论队列是否积压,都按固定频率拉取数据。 本系统实现了**队列深度反馈驱动**的生产逻辑: - `TaskQueueManager` 实时暴露三个队列的 `qsize()`。 - 生产者每次循环时,先检查各队列长度是否低于阈值(`QUEUE_THRESHOLD = 50`)。 - **仅当队列空闲且低于阈值时,才从数据库拉取任务**。消费快则补充快,消费慢甚至停止生产,真正实现了"以消费拉动生产"的节能高效模式。 ### 2.3 多级缓冲与批量处理(Multi-Level Batching) 为最大化处理效率并减少数据库 I/O 操作频率,系统实现了**三级缓冲架构**: 1. **数据库**:作为任务的持久化存储,每次查询最多从数据库提取 150 条 PENDING 任务。 2. **内存任务队列**:将这 150 条任务按 `TaskType` 分组,同类型任务再按batch大小(8)分组,每组为一个"原始批次",放入对应的任务队列中。 3. **执行池**:执行池拿到原始批次后,会根据任务类型从策略工厂获取对应的策略实例,调用 `process_batch()` 方法批量处理任务,以降低CPU调度切换开销。 这种设计既保证了数据库 I/O 的低频性(一次取一大把),又确保了内存中每个任务对象的轻量性,以及 AI 微服务批量接口的最大利用率(每批 8 张图是 AI 服务的最佳性价比点)。 ### 2.4 优先级优先队列(Priority Queue Scheduling) `TaskQueueManager` 内部使用 `asyncio.PriorityQueue` 作为各分类队列的实现: ```python # 入队元素结构:(负优先级, 计数器, Batch列表) await queue.put((-priority, count, batch)) ``` - **优先级取反**:因为 Python 的小根堆默认数值越小越先出,故取反使得**高数值优先级反而先被消费**。 - **计数器打破僵局**:当两个 Batch 优先级相同时,用自增计数器区分,避免直接比较字典导致的 `TypeError`。 ## 3. 生产者与消费者协同机制 TaskManager 作为任务的入口,其包含五个协程: 1. task Worker(生产者协程): 监控任务队列的状态,根据阈值从数据库拉取任务,推入对应的任务队列。 2. CPU Consumer(消费者协程): 从 CPU 队列中取出 Batch,批量处理缩略图/元数据。 3. IO Consumer(消费者协程): 从 IO 队列中取出 Batch,批量处理 AI 请求/人脸识别。 4. AI Consumer(消费者协程): 从 AI 队列中取出 Batch,批量处理大模型描述生成。 5. Result Handler(结果处理协程): 从 `result_queue` 中获取处理结果,批量更新数据库状态。 ### 生产者 & 调度中枢 - **职责**: 从数据库批量拉取 PENDING 任务,按 TaskType 分组并切分为标准 Batch(每批 ≤ 8),以任务中第一个元素的优先级作为整批的优先级,推入对应的内存分类队列。 ### 消费者并发控制 每个消费者协程内部维护一个 `asyncio.Semaphore` 来实现**细粒度并发控制**: | 队列类型 | 最大并发数 | 适用场景 | |---------|-----------|---------| | CPU | `os.cpu_count() 或 4` | 缩略图生成、元数据提取 | | IO | `10` | 人脸识别、OCR、图像分类、向量嵌入 | | AI | `2` | 视觉描述生成(依赖大模型,资源稀缺) | 消费者必须先获取信号量许可,才能从队列取出 Batch——这保证了即使数据库一次性拉取了大量任务,内存中也不会因为无限制并发导致资源耗尽。 ### 执行结果异步处理 每个任务处理完成后,不会立即更新数据库状态,而是将结果写入 `result_queue`,由 `Result Handler` 协程批量处理并更新数据库状态。 ## 4. 任务策略体系 所有具体任务处理器均继承自 `BaseTaskStrategy`,通过 `@TaskStrategyFactory.register(TaskType.XXX)` 注册。 ### 4.1 策略基类接口 ```python class BaseTaskStrategy(ABC): @property @abstractmethod def task_category(self) -> str: # 返回 'CPU' | 'IO' | 'AI' pass @abstractmethod async def process(self, worker, task: Task, db: Session) -> Any: pass # 单任务处理(兼容旧接口) async def process_batch(self, worker, tasks: List[Task], db: Session) -> List[Dict]: # 默认实现:循环调用 process(),子类可覆盖以实现真正的批量处理 results = [] for task in tasks: res = await self.process(worker, task, db) results.append({...}) return results async def handle_completion(self, worker, items: List[Dict], db: Session) -> None: # 任务完成后的回调,用于触发后续任务链(如 PROCESS_BASIC 完成后触发元数据提取) pass ``` ### 4.2 典型策略实现 #### BasicTaskStrategy(CPU 批量处理) CPU 任务(如缩略图生成)存在大量同步阻塞 I/O(文件读写)和 CPU 计算(OpenCV)。 **优化措施**:实现 `process_basic_cpu_batch_job`,在**单次线程池调用**中顺序处理 8 个子任务: ```python def process_basic_cpu_batch_job(tasks_data: List[Dict]) -> List[Dict]: results = [] for data in tasks_data: res = process_basic_cpu_job(data['file_path'], data['file_id'], ...) results.append(res) return results ``` 这样,8 张图片的缩略图生成**共享同一次线程池上下文切换开销**,极大提升了 CPU 密集型任务的吞吐量。 #### AI/IO 策略(网络批量请求) 对于依赖外部 AI 微服务的任务(如 `face.py`、`ocr.py`),`process_batch` 会将 8 张图片的 Base64 编码合并为**单次 HTTP 请求**: ```python async def process_batch(self, worker, tasks, db): b64_images = [read_image_base64(p) for p in valid_photos] async with aiohttp.ClientSession() as session: async with session.post(api_url, json={"images": b64_images}) as resp: results = (await resp.json())['results'] # 批量解析返回结果,批量更新数据库 ``` 这种方式将 8 次网络往返缩减为 1 次,显著降低了网络延迟对整体吞吐的影响。 ## 5. 任务优先级实现 任务优先级通过 `Task` 表中的 `priority` 字段(整数)实现,数值越大优先级越高。 - **默认优先级**: 系统定义了 `DEFAULT_PRIORITIES` 字典,自动为不同类型的任务分配优先级。 - `SCAN_FOLDER` (100)、`PROCESS_BASIC` (99)、`GENERATE_THUMBNAIL` (98)、`EXTRACT_METADATA` (97): 扫描与基础媒体处理。 - AI 任务:`CLASSIFY_IMAGE` (10)、`RECOGNIZE_FACE` (9)、`IMAGE_EMBEDDING` (8)、`OCR` (7)、`RECOGNIZE_TICKET` (4)、`VISUAL_DESCRIPTION` (1)。 - 用户主动触发的交互任务使用优先级 10000,即使该类型的自动任务已暂停也可执行。 - **调度逻辑**: 消费者从内存队列取任务时,PriorityQueue 自动保证高优先级 Batch 优先被消费。 - **AI 阶段切换**: 同类型连续处理以减少模型切换。新增可执行的更高优先级类型时,停止补充当前类型并撤回尚未执行的预取批次,等待在途批次和结果提交完成后切换。剩余任务保留为 PENDING,之后自动恢复;同级或低级任务不打断阶段。暂停、扩展维护或未到重试时间的任务不触发切换。 ## 6. 任务状态管理 任务在其生命周期中会在以下状态间流转(定义在 `TaskStatus` 枚举中): 1. **PENDING**: 初始状态,任务已创建但未被执行。 2. **PROCESSING**: 正在执行中。Worker 从数据库取出任务后立即设置此状态。 3. **COMPLETED**: 执行成功。通常在完成后会从数据库中删除记录,以保持表轻量。 4. **FAILED**: 执行出错。记录保留在数据库中,并附带错误信息供排查。 **启动恢复机制**: 服务启动时,`TaskWorker` 会执行 `_recover_unfinished_tasks`,将所有处于 `PROCESSING` 状态的任务重置为 `PENDING`,确保服务意外崩溃后任务不丢失。 ## 7. 异常处理与超时控制 ### 超时机制 每个 Batch 执行都包裹在 `asyncio.wait_for` 中: - AI 任务(依赖大模型响应):**120 秒**超时上限。 - CPU / IO 任务:**300 秒**超时上限。 超时后,Batch 内所有子任务会被批量标记为 `FAILED`,并附带超时错误信息,防止单个慢任务永久占用并发配额导致系统瘫痪。 ### 异常处理 1. **Batch 级捕获**:在 `execute_batch_task_wrapper` 中统一拦截,写入 `result_queue`。 2. **策略级容错**:每个策略的 `process_batch` 内部自行处理业务异常(如文件不存在、分辨率过滤),返回结构化的失败结果。 3. **进程级容错**:Worker 主循环包含宽泛的 `try-except` 块,配合 `asyncio.CancelledError` 优雅退出,确保单个任务或策略的严重错误不会导致整个 Worker 崩溃。 4. **系统级容错**:即使系统整体崩溃(断电、重启等),未完成的任务都持久化存储在数据库中,确保任务不丢失。系统重启后,会自动从数据库中恢复未完成的任务,继续执行。有些任务可能已经完成但是数据库中没有更新状态,此时再重做一遍也不会有问题,因为所有的任务操作都是**幂等的**,多次执行也不会改变最终结果。 ## 8. 资源管理与生命周期 ### 执行池动态管理 - **进程池(ProcessPoolExecutor)**:用于 CPU 密集型任务,冷启动成本高,空闲 **300 秒**后才关闭。 - **线程池(ThreadPoolExecutor)**:用于 IO 密集型任务和 CPU 任务的批量包装执行,空闲 **300 秒**后关闭。 - **AI 消费者并发限制**:通过 `asyncio.Semaphore(2)` 严格控制同时进行的大模型请求数量,防止压垮外部 AI 服务。 ### 空闲退避策略(Exponential Backoff) 当队列完全空闲时,Producer 循环采用**指数退避**策略休眠: ```python backoff_delay = min(1.0 * (1.5 ** retries), 10.0) # 1s → 1.5s → 2.25s → ... → 10s 上限 ``` 空闲超过 **5 分钟**时,Worker 自动退出以释放所有资源,待下次有任务时由外部监控重启。 ## 9. 性能优化策略总结 | 优化手段 | 描述 | 效果 | |---------|------|------| | **多级缓冲架构** | 数据库 → 内存队列 → 执行池 | 读写分离,数据库 I/O 降低 90%+ | | **自适应生产速度** | 队列深度反馈驱动拉取 | 消除空轮询,CPU 占用接近零 | | **PriorityQueue 调度** | 高优先级任务优先消费 | 关键任务零延迟响应 | | **批量打包(8/Batch)** | AI 微服务批量接口 | 网络往返次数降至 1/8 | | **CPU 批量线程处理** | 单线程顺序处理 8 张图片 | 线程切换开销降低 87.5% | | **asyncio.Semaphore 限流** | 消费者协程级并发控制 | 内存中无无限并发风险 | | **asyncio.wait_for 超时** | Batch 执行超时兜底 | 单慢任务无法瘫痪整个系统 | | **指数退避 + 自动退出** | 空闲时节能降耗 | 5 分钟无任务即释放所有资源 | | **完成即删除** | 成功任务从数据库清除 | Task 表保持轻量,查询不退化 | ## 10. 扩展指南 ### 新增任务类型 1. 在 `app/db/models/task.py` 的 `TaskType` 枚举中添加新类型。 2. 创建新的策略类,继承 `BaseTaskStrategy`,实现 `process()` 或 `process_batch()` 方法。 3. 使用 `@TaskStrategyFactory.register(TaskType.NEW_TYPE)` 注册。 4. 在 `task_manager.py` 的 `DEFAULT_PRIORITIES` 中添加默认优先级。 **无需修改 TaskWorker 核心代码**,即可完成新任务类型的接入。 --- # AI Service Design - Source: https://trailsnap.cn/en/docs/dev/ai_service.html - Markdown: https://trailsnap.cn/en/docs/dev/ai_service.md - Category: Developer documentation - Language: en # AI Service Design The AI service hosts TrailSnap AI capabilities (e.g. OCR, face recognition, scene classification, image analysis). The backend task system calls it when needed. ## How it runs - In Docker Compose deployment, it is provided as the `trailsnap-ai` service. - Backend calls it via the internal network by default: `AI_API_URL=http://ai:8001` ## LLM Hosting The AI service supports local LLM hosting and proxy capabilities: - Supports running LLM services via natively compiled llama-server binary from llama.cpp - Supports custom model paths, service ports, and idle timeouts - Automatically handles model download, service start/stop, and idle resource recovery - Provides OpenAI-format LLM proxy routes, transparently forwarding requests to the local llama.cpp service The multimodal model uses MiniCPM-V-4_6-Q4_K_M, supporting image content understanding, tag generation, and other visual tasks. ## llama.cpp Installation Using the built-in AI connection requires llama.cpp to be installed. ### Windows ```bash # Install via winget winget install llama.cpp # Or download manually: https://github.com/ggerganov/llama.cpp/releases ``` ### Linux ```bash git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp mkdir build && cd build cmake .. -DLLAMA_CURL=ON cmake --build . --config Release sudo cp llama-server /usr/local/bin/ ``` ### macOS ```bash brew install llama.cpp ``` ## Common endpoints - Source-development Swagger docs: `http://localhost:8001/docs`. In production Compose, AI stays private and has no user-facing port. ## Troubleshooting - AI service not reachable: check `AI_API_URL` and Docker networking. - Tasks not progressing: check task status/errors in **Settings → Task Management**. - LLM task failed: confirm llama.cpp is installed and the `llama-server` command is available. --- # Architecture Design Document - Source: https://trailsnap.cn/en/docs/dev/architecture.html - Markdown: https://trailsnap.cn/en/docs/dev/architecture.md - Category: Developer documentation - Language: en # Architecture Design Document ## 1. Overall Architecture Diagram TrailSnap adopts a typical separated frontend and backend architecture, consisting of a frontend presentation layer, a backend service layer, an AI microservice layer, and a data storage layer. 1. **Frontend Presentation Layer**: Provides a unified entry point through Nginx reverse proxy, supports HTTP/HTTPS access, and delivers the interactive frontend interface to users. 2. **Backend Service Layer**: Built on FastAPI as the core, with a security authentication module for JWT identity verification and multi-user permission isolation, ensuring safe family multi-user usage; separates business logic services from the task manager, achieving decoupling of synchronous business and async AI tasks; connects to PostgreSQL via SQLAlchemy ORM for metadata storage, and interfaces with the NAS local file system via file services for image storage — fully adapted to NAS storage architecture. 3. **AI Microservice Layer**: Uses a unified entry dispatch with a built-in model manager implementing intelligent lifecycle management — lazy loading on demand, automatic unloading when idle, and automatic download when needed — significantly reducing NAS memory and compute usage; integrates PaddleOCR, InsightFace, YOLO+OCR, CLIP, and other AI capabilities, covering OCR recognition, face recognition, ticket recognition, vector search, and other core album functions; also supports connecting to external LLMs like Qwen and GPT for good extensibility. 4. **Data Storage Layer**: Metadata and files are stored separately, with all data stored locally to ensure family data privacy and security. ```mermaid flowchart TD User[👨‍💻 User Browser] -->|⚡ HTTP/HTTPS| FE[Frontend App
Vue 3 + Vite] subgraph Frontend_Layer[🖥️ Frontend Presentation Layer] FE -->|📡 Axios / REST| API8000 FE -->|💾 Pinia| Store[Global State Management] FE -->|🎨 ElementPlus| UI[UI Component Library] end subgraph Backend_Layer[⚙️ Backend Service Layer] API8001[Backend Service
FastAPI :8000] --> Routers[API Route Dispatch] Routers --> Services[Business Logic Services] Services -->|🗄️ ORM Mapping| DBConn[SQLAlchemy] Services -->|📂 File IO| FS[File System] Services -->|⏳ Async Scheduling| TM[Task Manager] TM -->|🔗 HTTP Call| AI8001 end subgraph AI_Service[🤖 AI Microservice Layer] AI8001[AI Microservice
FastAPI :8001] --> OCR[PaddleOCR Text Recognition] AI8001 --> Face[InsightFace Face Recognition] AI8001 --> OD[Object Detection] AI8001 --> Ticket[Ticket Recognition
YOLO + OCR] end subgraph Data_Layer[💽 Data Persistence Layer] DBConn --> DB[(PostgreSQL Database)] FS --> Storage[Local/Mounted Storage] end ``` ```mermaid flowchart TD User[👨‍💻 User Browser] -->|⚡ HTTP/HTTPS| FE[Frontend App
Vue 3 + Vite] ``` ## 2. Technology Stack & Versions ### 2.1 Frontend Stack ### 2.2 Backend Stack - **Programming Language**: Python 3.12+ - **Web Framework**: FastAPI 0.122.0 - **ASGI Server**: Uvicorn 0.38.0 - **ORM**: SQLAlchemy 2.0.44 - **Database Migration**: Alembic 1.17.2 - **Database Driver**: psycopg2 (PostgreSQL) - **Task/Async**: APScheduler, `aiohttp` - **AI/CV (AI Microservice)**: - PaddleOCR ==3.3.2 - PaddlePaddle-GPU `==3.2.0` (Optional GPU) - OpenCV `opencv-python-headless >=4.9.0` - Torch `>=2.0.0`, TorchVision `>=0.15.0` (Some models available) - InsightFace (Face) - **Logger**: Custom JSON queue logger + daily capacity rolling (built-in for both server and ai) ### 2.3 Database - **PostgreSQL (PgVector)**: Relational database, stores users, albums, photo metadata, system settings, etc. ## 3. Directory Structure & Module Description ### 3.1 Root Directory - `package/server`: Backend service code - `package/website`: Frontend application code - `doc`: Project documentation ### 3.2 Backend Structure (`package/server`) - **app/**: Core application code - `api/`: API route definitions (EndPoints), divided by functional modules (user, album, photo, etc.) - `core/`: Core configuration and tools (Logger, Config) - `crud/`: Database CRUD operation encapsulation - `db/`: Database models (Models) and session management (Session) - `schemas/`: Pydantic data models (Request/Response schemas) - `service/`: Complex business logic and background services (TaskManager, Indexer, Storage) - `utils/`: Common utility functions (Exif parsing, filename processing) - **railway/**: Railway related functional modules (independent data processing and synchronization logic) - **yolo_ocr/**: OCR and ticket recognition related models and scripts - **main.py**: Application entry, route mounting, CORS, middleware, and port configuration (default `:8000`) ### 3.3 Frontend Structure (`package/website`) - **src/**: Source code - `api/`: Backend interface encapsulation - `assets/`: Static resources (images, CSS) - `components/`: Common Vue components (PhotoGallery, TrainTicket, etc.) - `composables/`: Composable functions (Hooks) - `layouts/`: Page layout components - `router/`: Route configuration - `stores/`: Pinia state management store - `types/`: TypeScript type definitions - `views/`: Page views (Pages) - `package.json`: Dependency and version management, including scripts `dev/build/preview` ### 3.4 AI Microservice Structure (`package/ai`) - **app/main.py**: AI service entry (default `:8001`), mounting `ocr/face/object-detection/tickets` routes - **app/services/**: Model services (`ocr_service.py`, `face_service.py`, `model_manager.py` lazy loading and resource release) - **app/core/logger.py**: JSON queue logger, daily capacity rolling - **requirements.txt**: Dependencies and version constraints (PaddleOCR, PaddlePaddle-GPU, Torch, OpenCV, etc.) ## 4. Key Interactions & Call Chain ```mermaid sequenceDiagram participant FE as Frontend (Vue) participant S as Backend Service :8000 participant AI as AI Microservice :8001 participant DB as PostgreSQL participant FS as File System FE->>S: GET /api/ocr?photo_id=... S->>DB: Query ocr_results DB-->>S: Normalized polygon/text S-->>FE: JSON Response S->>AI: POST /ocr/predict (Async Task) AI->>AI: PaddleOCR Inference AI-->>S: rec_texts/rec_scores/rec_polys S->>DB: Write ocr_results (Coordinates normalized 0~1) FE->>S: Media Operations/Album Management S->>FS: Read/Write Media Files S->>DB: Write/Query Metadata ``` --- # Backend Framework Analysis Document - Source: https://trailsnap.cn/en/docs/dev/backend.html - Markdown: https://trailsnap.cn/en/docs/dev/backend.md - Category: Developer documentation - Language: en # Backend Framework Analysis Document ## 1. Tech Stack Detailed Description ### 1.1 Core Framework - **FastAPI** (Server): High-performance asynchronous Web framework, providing automated OpenAPI documentation (`/docs`). - **Uvicorn**: ASGI server, running FastAPI applications. - **Pydantic**: Request/Response models and data validation. ### 1.2 Data Persistence - **PostgreSQL**: Main database. - **SQLAlchemy (Async)**: ORM framework, interacting with the database using asynchronous mode (`AsyncSession`) to improve concurrency processing capabilities. - **Alembic**: Database version control tool, used for handling Schema change migrations. ### 1.3 Asynchronous Tasks & Services - **APScheduler**: Used for scheduled task scheduling (although the code mainly uses custom TaskManager, the library is included in the dependency list and may be used for periodic tasks). - **TaskManager**: Custom task manager (`app/service/task_manager.py`), used for handling time-consuming operations, such as: - Photo scanning and indexing - Thumbnail generation - Metadata extraction - OCR recognition tasks ### 1.4 AI & Image Processing - **PaddleOCR** (AI Microservice): Text detection and recognition, supporting `rec_texts/rec_scores/rec_polys` output. - **InsightFace** (AI Microservice): Face detection/key points/feature extraction. - **YOLO (Ultralytics)**: Independent server-side script for ticket area detection and cropping. - **OpenCV**: Image decoding and basic processing. ## 2. Service Module Division & Call Relationship ```mermaid graph TD Request[Client Request] --> Middleware[Middleware (Logging/CORS)] Middleware --> Router[API Routers] subgraph Modules [Functional Modules] Router --> UserMod[User Module] Router --> AlbumMod[Album Module] Router --> PhotoMod[Photo Module] Router --> TaskMod[Task Module] Router --> RailwayMod[Railway Module] end subgraph Services [Business Service Layer] PhotoMod --> StorageSvc[Storage Service] PhotoMod --> IndexerSvc[Indexer Service] TaskMod --> TaskMgr[Task Manager] TaskMgr --> Workers[Worker Threads/Processes] end subgraph External [External Dependencies] Workers --> AI_Svc[AI Service :8001] Workers --> FileSys[File System] StorageSvc --> FileSys end subgraph Data [Data Layer] UserMod --> CRUD[CRUD Operations] AlbumMod --> CRUD PhotoMod --> CRUD CRUD --> DB[(PostgreSQL)] end ``` ### 2.2 AI Microservice Call Chain ```mermaid sequenceDiagram participant S as Server :8000 participant AI as AI Service :8001 participant DB as PostgreSQL S->>AI: POST /ocr/predict (multipart form: file) AI->>AI: PaddleOCR.ocr(img) AI-->>S: prunedResult(rec_texts, rec_scores, rec_polys) S->>DB: Write ocr_results (Coordinates normalized to 0~1) ``` ### 2.1 Key Module Analysis - **API Routers (`app/api`)**: Controller layer, handles HTTP requests, parameter validation, calls Service or CRUD layer. - **CRUD Layer (`app/crud`)**: Data access layer, encapsulates all database interaction logic, keeping business logic pure. - **Service Layer (`app/service`)**: Business logic layer, handles complex business, such as file system operations, calling AI models, background task management. ## 3. API Design Specifications & Status ### 3.1 Specifications - **RESTful Style**: Interface design follows resource orientation, such as `GET /albums` to get list, `POST /albums` to create album. - **Response Format**: Use Pydantic models to define Response Schema, ensuring consistent return data structure. - **Status Codes**: Follow HTTP standard status codes (200 Success, 201 Created, 400 Request Error, 401 Unauthorized, 404 Not Found, 500 Server Error). ### 3.2 Interface Document Status - **Swagger UI**: FastAPI automatically generates interactive documentation, address is usually `/docs`. - **ReDoc**: Another style of documentation, address is usually `/redoc`. - **Main Resources**: - `/users`: User related. - `/albums`: Album CRUD. - `/photos`: Photo upload, streaming acquisition, metadata management. - `/tasks`: Task status query, task triggering. - `/settings`: System configuration management. - `/faces`: Face entity and photo management. - `/ocr`: OCR recognition record query (`GET /ocr?photo_id=...`). - `/train-ticket`: Train ticket CRUD and export. - `/railway`: Railway station and operation plan interfaces. ### 3.3 Logs & Exceptions - **Logs**: JSON queue log + daily capacity rolling; each record contains `timestamp/level/message/operation/params/result`. - **Exceptions**: Unified capture and write to log; AI call failure or image decoding error will return corresponding error code and record. ### 3.4 Data Model Description (Example) - **OCR Result** (Table `ocr_results`): - `text: str`, `text_score: float`, `polygon: List[List[float]]` (Coordinates normalized to 0~1) - Query Interface: `GET /ocr?photo_id=` returns list of records --- # Feature Design Document - Source: https://trailsnap.cn/en/docs/dev/feature-proposals.html - Markdown: https://trailsnap.cn/en/docs/dev/feature-proposals.md - Category: Developer documentation - Language: en # Feature Design Document This document collects design drafts for upcoming TrailSnap features, serving as a reference for community discussion and contributions. --- ## 1. Image Editing ### 1.1 Background & Goals Users can currently only view photos, lacking basic editing capabilities. Image editing is a high-frequency need for album applications and lays the groundwork for features like "Social Media 9-Grid Generator" down the line. ### 1.2 Feature Scope **Basic Editing** - Crop (free crop, aspect ratio crop such as 1:1, 16:9) - Rotate (90°, horizontal flip, vertical flip) - Zoom & drag **Tags & Annotations** - Add text labels (with font, color, size options) - Add simple shapes such as arrows and selection boxes - Add time and location watermarks **Filters & Adjustments** - Basic adjustments: brightness, contrast, saturation - Preset filters: vintage, black & white, soft, etc. ### 1.3 Technical Approach - Use Canvas API or WebGL on the frontend for lossless editing - Editing results support export to original-quality JPEG/PNG - Edit history (Undo/Redo) ### 1.4 Priority **Medium** — to be developed as part of the Toolbox module --- ## 2. Photo Auto-Organize ### 2.1 Background & Goals Photos accumulate haphazardly over time, and manual organization is tedious. AI can automatically categorize photos by time, location, content, and other dimensions, reducing the user's effort. ### 2.2 Organization Rules | Rule | Description | Example | | --- | --- | --- | | By year & month | Create `2024/2024-03` or `2024-03` folder | 2024/2024-03 or 2024-03 | | By date | Create `2024/2024-03-15` or `2024-03-15` folder | 2024/2024-03-15 or 2024-03-15 | | By person | Create `Person-Zhang San/` folder | Face photos of Zhang San | | By scene | Create `Food/`, `Pets/` folders | Classified photos | ### 2.3 Technical Approach - Use existing metadata (EXIF, geolocation, face tags, scene classification) - Copy or move photos (user's choice) - Support previewing results before executing - Log organization operations, support undo - **New: support both flat and recursive nested time directory formats** ### 2.4 Status **Implemented** — Toolbox → Photo Auto-Organize ### 2.5 Priority ~~**Medium**~~ → Launched --- ## 3. Auto Travel Journal ### 3.1 Background & Goals After a trip, users often need to manually sort photos and write travelogues — a tedious process. AI can automatically generate structured travel records from photos, tickets, locations, and other data. ### 3.2 Input Data - Photos from the trip (with metadata) - Recognized train tickets, flight tickets, admission tickets - Geographic location tracks - Possible AI descriptions and ratings ### 3.3 Output Content **Structured Journal** - Title: trip name (e.g., "March 2024 Xiamen Trip") - Time: departure date, return date, total days - Itinerary: daily timeline - Places: cities/attractions visited - People: travel companions - Expenses: categorized totals for transportation, tickets, etc. **Mixed Text & Images** - Support export to Markdown/HTML - Ready for publishing to blog platforms - Support PDF generation ### 3.4 Technical Approach - Use LangChain/LangGraph to orchestrate the multi-step generation pipeline - Staged generation: itinerary overview → daily details → expense summary → final polish - Support streaming output to show generation progress - Provide a template engine for customizing output formats ### 3.5 Priority **High** — core differentiating feature --- ## 4. Social Media 9-Grid Generator ### 4.1 Background & Goals When sharing travel photos on social media, users need to manually collage, select, and caption images. Providing one-click 9-grid generation with accompanying captions lowers the sharing barrier. ### 4.2 Feature Modules **Smart Photo Selection** - AI picks 9 most representative photos from the trip - Considerations: quality score, content diversity, temporal distribution **Collage Layouts** - 3x3 standard 9-grid - Free-form layouts (support irregular layouts such as 1+2+6) - Style templates: minimal, artistic, vintage **Caption Generation** - Generate captions based on photo content and landmarks - Support multiple styles: poetic, humorous, brief - Option to add hashtag labels ### 4.3 Technical Approach - Use Canvas API for collage rendering - Call large language model for caption generation (few-shot prompts) - Support preview and fine-tuning ### 4.4 Priority **High** — strong social sharing appeal --- ## 5. Video Highlight Reel ### 5.1 Background & Goals Static photos alone cannot fully convey the atmosphere of a trip. Automatically clipping 15-30 second highlight reels from Live Photos and video footage is ideal for sharing on short-video platforms. ### 5.2 Feature Modules **Footage Collection** - Support Live Photo video segments - Support user-uploaded video files - Support filtering by album/time range **Smart Editing** - Automatically identify highlight moments (e.g., smiles, actions, scene transitions) - Auto-match suitable background music - Generate multiple duration versions (15s/30s/60s) **Post-Processing** - Transition effects (fade in/out, slide) - Basic color grading - Add text titles/subtitles ### 5.3 Technical Approach - Use OpenCV for video analysis (scene detection, optical flow) - Use FFmpeg for video processing and export - Or integrate cloud services (e.g., JianYing API) ### 5.4 Priority **Low** — high technical complexity; can be considered later --- ## 6. Network Folder Scanning ### 6.1 Background & Goals Users' photos may be scattered across various cloud drives and network storage, such as Baidu Netdisk, Aliyun Drive, OneDrive, SMB shared directories, WebDAV servers, etc. Connecting these data sources enables TrailSnap to uniformly manage and analyze cross-platform photo assets. ### 6.2 Supported Storage Types **Cloud Drive Services** | Service | API Type | Notes | | --- | --- | --- | | Baidu Netdisk | Open API | Requires applying for an API Key | | Aliyun Drive | Open API | OAuth2.0 authorization | | OneDrive | Microsoft Graph API | OAuth2.0 authorization | | Google Drive | Google Drive API | OAuth2.0 authorization | | Dropbox | Dropbox API | OAuth2.0 authorization | **Network File Protocols** | Protocol | Description | Use Cases | | --- | --- | --- | | SMB/CIFS | Common protocol for Windows network shares and NAS | Home NAS, LAN sharing | | WebDAV | HTTP-based file access protocol | Supported by many NAS and cloud services | | FTP/SFTP | Traditional file transfer protocols | Legacy system connections | ### 6.3 Feature Modules **Connection Management** - Support adding multiple storage accounts - OAuth2.0 authorization flow (cloud drives) - Secure storage of account credentials (encrypted) - Connection status monitoring and auto-reconnection **File Scanning** - Recursively scan specified folders - Scan only image files (jpg, png, heic, raw, etc.) - Incremental scanning (only new files) - Scan progress display and interrupt support **Metadata Extraction** - File name, path, size, creation/modification time - EXIF metadata (camera, GPS, timestamp) - Deduplication against existing photo library (based on file hash) **Preview & Import** - Thumbnail preview - Selective import (by folder, by date range) - Import mode: index-only (original files stay in place) or copy to local storage ### 6.4 Technical Approach **Cloud Drive SDKs** - Baidu Netdisk: [baidupcs-go](https://github.com/qingxinrun/baidupcs-go) or official Python SDK - Aliyun Drive: custom OAuth2 + API calls - OneDrive: [Microsoft Graph SDK for Python](https://github.com/microsoftgraph/msgraph-sdk-python) - Google Drive: [google-api-python-client](https://github.com/google/google-api-python-client) - Dropbox: [dropbox-sdk-python](https://github.com/dropbox/dropbox-sdk-python) **Network Protocols** - SMB: [pysmb](https://github.com/miketeo/pysmb) or [python-smb](https://github.com/miketeo/python-smb) - WebDAV: [webdavclient3](https://github.com/barneygale/webdavclient3) - FTP/SFTP: [ftplib](https://docs.python.org/3/library/ftplib.html) / [pysftp](https://github.com/paramiko/pysftp) **Architecture Design** ``` ┌─────────────────────────────────────────┐ │ Storage Adapter Layer │ │ ┌─────────┐ ┌─────────┐ ┌───────────┐ │ │ │ BaiduPCS│ │ Aliyun │ │ OneDrive │ │ │ └─────────┘ └─────────┘ └───────────┘ │ │ ┌─────────┐ ┌─────────┐ ┌───────────┐ │ │ │ SMB │ │ WebDAV │ │ SFTP │ │ │ └─────────┘ └─────────┘ └───────────┘ │ └─────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ Unified File Indexer │ │ - File listing abstraction layer │ │ - Deduplication (MD5/SHA256) │ │ - Metadata normalization │ └─────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ TrailSnap Photo Store │ │ - Import photos to local index │ │ - Or keep metadata reference only │ └─────────────────────────────────────────┘ ``` **Security** - Cloud drive OAuth tokens stored securely (encrypted before saving to database) - Network protocol credentials encrypted at rest - Periodic token refresh - Least-privilege principle (request read-only access) ### 6.5 Priority **High** — significantly expands data sources and increases application value --- ## 7. Family Sharing & Collaboration ### 7.1 Background & Goals Family members may share a single TrailSnap instance or want to share specific albums with each other. Supporting multi-user collaboration scenarios. ### 7.2 Feature Modules **Permission Management** - Admin and regular user roles - Album-level permission control (view, edit, share) - Guest mode (view-only for designated albums) **Album Sharing** - Generate sharing links (optional password protection) - Expiration control (24 hours / 7 days / permanent) - Disable download toggle **Comments & Likes** - Family members can comment on photos - Simple like reactions ### 7.3 Technical Approach - Reuse existing user system, add role fields - Sharing links use JWT or temporary tokens - Comments stored in a separate table ### 7.4 Priority **Low** — multi-user scenarios can be considered later --- ## 8. Smart Album Recommendations ### 8.1 Background & Goals Users may not proactively create albums. The system can suggest "worth organizing" albums, such as "Weekend Gathering", "National Day Holiday", etc. ### 8.2 Recommendation Scenarios | Scenario | Trigger Condition | | --- | --- | | Weekend Gathering | 5+ photos on Saturday/Sunday, concentrated in one location | | National Day Holiday | 20+ photos during the National Day holiday | | Food Collection | 10+ photos in the "Food" category recently | | Family Moments | Recent photos predominantly tagged "Parents" or "Children" | | Landmark Check-in | 3+ photos at a 5A scenic spot | ### 8.3 Technical Approach - Scheduled task scanning, analyzing recent photo distribution - Generate recommendations based on rules + AI recognition - Present to user for confirmation before creating albums ### 8.4 Priority **Medium** — improves user engagement --- ## Priority Summary | Priority | Features | | --- | --- | | **High** | Auto Travel Journal, Social Media 9-Grid, Network Folder Scanning | | **Medium** | Image Editing, Smart Album Recommendations | | **Low** | Video Highlight Reel, Family Sharing & Collaboration | | **Launched** | Photo Auto-Organize | --- *This document is a design draft. Implementation details may be further refined before formal development. Welcome contributions via Issue or PR.* --- # Frontend Framework Analysis Document - Source: https://trailsnap.cn/en/docs/dev/frontend.html - Markdown: https://trailsnap.cn/en/docs/dev/frontend.md - Category: Developer documentation - Language: en # Frontend Framework Analysis Document ## 1. Tech Stack Breakdown ### 1.1 Core Framework The project uses **Vue 3** (`^3.5.13`) as the core framework, adopting Composition API to provide flexible logic reuse capabilities; coupled with **TypeScript** (`^5.9.3`) to provide static type checking and enhance code robustness; the build tool is **Vite** (`^6.2.0`). ### 1.2 UI Component Library & Styling - **Element Plus**: As the main basic component library, providing general components such as buttons, forms, and dialogs. - **TailwindCSS**: Used for atomic CSS style development, providing flexible layout and responsive design capabilities, reducing the need to write custom CSS. - **Icons**: Uses `lucide-vue-next` and `mingcute_icon` to provide modern vector icons. ### 1.3 State & Route Management - **Pinia**: Replaces Vuex as the new generation state management tool, providing a more concise API and better TypeScript support. Main Stores include: - `albumStore`: Manages album lists and details. - `photoStore`: Manages photo data and browsing status. - `ticketStore`: Manages tickets and itinerary data. - **Vue Router**: Handles Single Page Application (SPA) route transitions, supporting nested routes and navigation guards. ### 1.4 Data Interaction - **Axios**: Encapsulates HTTP requests, configured with interceptors in `src/utils/request.ts` (unified processing of Token, error responses). - **API Layer**: The `src/api` directory encapsulates interface calls by module, decoupling them from business logic. ### 1.5 Versions & Dependency Sources Frontend dependency versions are based on `package/website/package.json`: - `vue ^3.5.13`, `vite ^6.2.0`, `typescript ^5.9.3` - `element-plus ^2.11.9`, `tailwindcss 3.4.17` - `pinia ^3.0.3`, `vue-router ^4.5.0` - `axios ^1.12.2`, `echarts ^6.0.0` - Others: `@vueuse/core ^14.0.0`, `video.js ^8.23.4`, etc. ## 2. Frontend Component Hierarchy ```mermaid graph TD App[App.vue] --> Layout{Layout Strategy} Layout --> |Default| MainLayout[MainLayout.vue] Layout --> |Blank| BlankLayout[BlankLayout.vue] MainLayout --> NavBar[NavBar.vue] MainLayout --> RouterView[RouteOutlet.vue / RouterView] MainLayout --> Footer[Footer.vue] RouterView --> HomePage[HomePage.vue] RouterView --> AlbumPage[AlbumPage.vue] RouterView --> TicketPage[TicketPage.vue] RouterView --> Settings[Settings.vue] AlbumPage --> AlbumList[AlbumList.vue] AlbumPage --> AlbumDetail[AlbumDetail.vue] AlbumDetail --> PhotoGallery[PhotoGallery.vue] PhotoGallery --> PhotoLightbox[PhotoLightbox.vue] TicketPage --> TicketTimeline[TicketTimeline.vue] TicketTimeline --> TicketCard[TicketCard.vue] TicketCard --> TrainTicket[TrainTicket.vue] Settings --> BasicSettings[BasicSettings.vue] Settings --> UserMgmt[UserManagement.vue] Settings --> TaskMgmt[TaskManagement.vue] ``` ## 3. Performance Metrics & Optimization Analysis ### 3.1 Existing Performance Features - **On-demand Import**: Element Plus and icon libraries usually support on-demand import, reducing bundle size. - **Virtual List**: `composables/useVirtualLayout.ts` indicates that virtual scrolling has been implemented or planned in the project, which is crucial for displaying large numbers of photos (waterfall flow) or long lists, significantly reducing the number of DOM nodes and improving rendering performance. - **Responsive Layout**: Utilizing TailwindCSS to achieve multi-terminal adaptation, avoiding redundancy of loading different codes for different devices. ### 3.2 Optimization Space 1. **Image Loading Optimization**: - Waterfall flow layout should coordinate with the thumbnail interface provided by the backend to avoid loading original images directly. - Implement Image Lazy Loading, loading only when the image enters the viewport. 2. **Code Splitting**: - Route Lazy Loading: Ensure that dynamic import (`() => import(...)`) is used in `router/index.ts` to load components, reducing the first screen bundle size. 3. **Build Optimization**: - Utilize Vite's build features, configure reasonable `splitVendorChunkPlugin` or custom `rollupOptions` to cache third-party libraries separately. 4. **State Management Optimization**: - Avoid overly large Stores, split Store modules reasonably. - Ensure that data in the Store is updated only when necessary, reducing unnecessary component re-rendering. 5. **Interaction & Drawing Optimization**: - OCR polygon drawing is recommended to use `requestAnimationFrame` for batch refreshing, reducing frequent reflows. - For large image preview, use `object-fit` and CSS hardware acceleration (`will-change: transform`) to improve scrolling and zooming experience. ## 4. Frontend & Backend Interaction Diagram ```mermaid sequenceDiagram participant FE as Vue Frontend participant API as Server API :8000 participant AI as AI Service :8001 FE->>API: GET /api/ocr?photo_id=... API-->>FE: OCR records (Normalized polygon/text) FE->>API: Media/Album Related Interfaces API-->>FE: List/Detail/Streaming Media API->>AI: POST /ocr/predict (Triggered by Task) AI-->>API: prunedResult (rec_texts/rec_scores/rec_polys) ``` --- # TrailSnap Developer Documentation - Source: https://trailsnap.cn/en/docs/dev/guide.html - Markdown: https://trailsnap.cn/en/docs/dev/guide.md - Category: Developer documentation - Language: en # TrailSnap Developer Documentation This document aims to provide developers with a guide to the TrailSnap project, covering environment setup, project structure, development process, etc. ## Table of Contents - [TrailSnap Developer Documentation](#trailsnap-developer-documentation) - [Table of Contents](#table-of-contents) - [1. Project Introduction \& Tech Stack](#1-project-introduction--tech-stack) - [2. Development Environment Preparation](#2-development-environment-preparation) - [3. Project Structure Detail](#3-project-structure-detail) - [4. Backend Development Guide](#4-backend-development-guide) - [4.1 Start Database](#41-start-database) - [4.2 Install Dependencies](#42-install-dependencies) - [4.3 Configuration File](#43-configuration-file) - [4.4 Run Service](#44-run-service) - [5. Frontend Development Guide](#5-frontend-development-guide) - [5.1 Install Dependencies](#51-install-dependencies) - [5.2 Run Development Server](#52-run-development-server) - [5.3 Build](#53-build) - [6. AI Service Development Guide](#6-ai-service-development-guide) - [6.1 Install Dependencies](#61-install-dependencies) - [6.2 Run Service](#62-run-service) - [7. Database Migration](#7-database-migration) - [8. Build Docker Image](#8-build-docker-image) --- ## 1. Project Introduction & Tech Stack TrailSnap is a project with separated frontend and backend, integrating AI capabilities. - **Frontend**: Vue 3, TypeScript, Vite, Element Plus, TailwindCSS - **Backend**: Python (FastAPI), SQLAlchemy, Alembic - **Database**: PostgreSQL (requires enabling pgvector extension to support vector search) - **AI Service**: Independent microservice, based on FastAPI, integrating models like PaddleOCR, InsightFace, YOLO. ## 2. Development Environment Preparation Before starting development, please ensure that the following tools are installed on your machine: - **Git**: Version control - **Python**: 3.10+ (Recommended 3.12) - **Node.js**: v18+ (Recommended v20 or v22) - **pnpm**: Frontend package manager (`npm install -g pnpm`) - **Docker & Docker Compose**: Used to quickly start the database ## 3. Project Structure Detail ``` TrailSnap/ ├── doc/ # Project documentation ├── package/ │ ├── ai/ # AI Microservice │ │ ├── app/ # AI Core Logic │ │ └── ... │ ├── server/ # Backend Main Service │ │ ├── app/ # FastAPI Application │ │ │ ├── api/ # API Routes │ │ │ ├── core/ # Config & Logger │ │ │ ├── crud/ # Database Operations │ │ │ ├── db/ # Model Definitions │ │ │ ├── schemas/ # Pydantic Models │ │ │ └── service/ # Business Logic │ │ └── ... │ └── website/ # Frontend Application │ ├── src/ # Source Code │ └── ... └── ... ``` ## 4. Backend Development Guide The backend is located in `package/server`. ### 4.1 Start Database The project depends on PostgreSQL and the pgvector extension. It is recommended to use Docker to start it: due to documentation deployment restrictions, please refer directly to the `package/server/README.md` file in the project source code. ### 4.2 Install Dependencies It is recommended to use `uv` for package management. ```bash cd package/server # Install uv pip install uv # Use uv uv sync ``` ### 4.3 Configuration File Create a `.env` file in the `package/server/data` directory (refer to README or configure directly): ```env DB_URL=postgresql://user:password@localhost:5432/trailsnap RAILWAY_DB_URL=postgresql://user:password@localhost:5432/railway AI_URL=http://localhost:8001 ``` ### 4.4 Run Service ```bash # First run requires initializing the database python start.py # Start in development mode uvicorn main:app --reload --port 8000 ``` API Documentation Address: `http://localhost:8000/docs` ## 5. Frontend Development Guide The frontend is located in `package/website`. ### 5.1 Install Dependencies ```bash cd package/website pnpm install ``` ### 5.2 Run Development Server ```bash pnpm dev ``` Access Address: `http://localhost:5176` ### 5.3 Build ```bash pnpm build ``` ## 6. AI Service Development Guide The AI service is located in `package/ai`, providing OCR and face recognition capabilities for the backend. ### 6.1 Install Dependencies ```bash cd package/ai pip install uv # Install dependencies (CPU version) uv sync --extra cpu # Install dependencies (GPU version) uv sync --extra gpu ``` ### 6.2 Run Service ```bash uvicorn app.main:app --reload --port 8001 ``` ## 7. Database Migration The backend uses Alembic to manage database migrations. **Note**: After modifying models under `db/models`, you must execute migration for it to take effect. 1. **Generate Migration Script** ```bash cd package/server alembic revision --autogenerate -m "Description of changes" ``` 2. **Execute Migration** ```bash alembic upgrade head ``` 3. **Common Commands** - `alembic current`: View current version - `alembic history`: View version history - `alembic downgrade -1`: Rollback to previous version ## 8. Build Docker Image ```bash cd TrailSnap # One-click build docker image docker-compose up -d --build ``` ```bash # Build frontend image docker build -t crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-frontend:master -f package/website/Dockerfile . # Build backend image docker build -t crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-backend:master -f package/server/Dockerfile . # Build AI image docker build -t crpi-d7wuvvdylhqugyu2.cn-hangzhou.personal.cr.aliyuncs.com/siyuan044/trailsnap-ai:master -f package/ai/Dockerfile . ``` --- # Task Management Module Design - Source: https://trailsnap.cn/en/docs/dev/task_manager.html - Markdown: https://trailsnap.cn/en/docs/dev/task_manager.md - Category: Developer documentation - Language: en # Task Management Module Design > TrailSnap is an AI photo album deployed on NAS devices. This architecture is designed with NAS characteristics in mind (typically low CPU performance, no GPU acceleration, large photo collections stored on HDDs, while Docker and other software are installed on SSDs). ## 1. Overall Architecture The task management module adopts a **Multi-Level Buffer + Producer-Consumer** model, using **PostgreSQL as the persistent backend and in-memory priority queues as the scheduling hub**, achieving complete decoupling between task production and consumption. The architecture consists of four core components: - **Producer (TaskManager)**: Runs in the API service process, responsible for receiving user requests or system-triggered events, generating tasks and writing them to the database. - **Persistent Task Queue (Database Table)**: The `Task` table serves as reliable persistent storage, storing task type, status, priority, payload parameters, etc., ensuring tasks survive service restarts. - **Scheduling Hub (TaskQueueManager)**: An in-memory scheduling module in `task_worker.py` that maintains three independent priority queues (CPU / IO / AI), responsible for batch-fetching tasks from the database and priority-sorting them. - **Consumers (TaskWorker)**: Three independent worker coroutines (CPU Consumer, IO Consumer, AI Consumer), each listening to its categorized queue, consuming tasks at **adaptive rates** and processing them through execution pools. ### Architecture Diagram ![](https://blog.siyuan.ink/static/img/f9dff9426ecdcd388450744aa3830f6a.TaskManager.webp) ```mermaid graph TD Client[Client/API] -->|Request Task| TM[TaskManager Producer] TM -->|Write PENDING| DB[(PostgreSQL Task Table)] subgraph TaskWorker [TaskWorker Scheduling Hub] TW_P[Producer Loop] -->|Fetch & Group| DB TW_P -->|Enqueue| QM[TaskQueueManager] QM -->|Semaphore Throttle| C_CPU[CPU Consumer Loop] QM -->|Semaphore Throttle| C_IO[IO Consumer Loop] QM -->|Semaphore Throttle| C_AI[AI Consumer Loop] end C_CPU -->|ThreadPool Executor| CPU_Exec[CPU Pool
Batch thumbnail/metadata] C_IO -->|Direct Execute| IO_Exec[IO Pool
Batch AI requests/face recognition] C_AI -->|Concurrency Control| AI_Exec[AI Pool
Batch LLM description generation] CPU_Exec -->|Result| RQ[Result Queue] IO_Exec -->|Result| RQ AI_Exec -->|Result| RQ RQ -->|Batch Flush| DB RQ -->|Trigger Follow-up| TM ``` ## 2. Core Design Principles ### 2.1 Strategy + Factory Pattern The task execution layer uses the **Strategy Pattern** for complete decoupling: - **BaseTaskStrategy** (abstract base class): Defines the interface all task handlers must implement, including `process()` (single task), `process_batch()` (batch processing), and `handle_completion()` (completion callback). - **TaskStrategyFactory** (strategy factory): Uses class method registration (`@TaskStrategyFactory.register(TaskType.XXX)`) to maintain a mapping from `TaskType` to concrete strategy classes. The scheduling layer has no dependency on specific task types — it only obtains strategy instances dynamically through the factory, achieving the **Open-Closed Principle (OCP)**: adding new task types requires no changes to the scheduling core. ### 2.2 Feedback-Driven Adaptive Production A common problem with traditional polling models is **wasteful database I/O**: data is fetched at a fixed frequency regardless of queue backlog. This system implements **queue-depth feedback-driven** production logic: - `TaskQueueManager` exposes the `qsize()` of all three queues in real time. - The producer checks whether each queue length is below a threshold (`QUEUE_THRESHOLD = 50`) before every loop. - **Tasks are only fetched from the database when a queue is idle and below the threshold**. Fast consumption triggers fast replenishment; slow consumption halts production — a truly "consumption-driven production" energy-efficient model. ### 2.3 Multi-Level Batching To maximize processing efficiency and reduce database I/O frequency, the system implements a **three-level buffer architecture**: 1. **Database**: As persistent storage, each query fetches up to 150 PENDING tasks. 2. **In-memory task queues**: These 150 tasks are grouped by `TaskType`, then sub-grouped into batches of 8. Each group is an "raw batch" placed into the corresponding categorized queue. 3. **Execution pools**: When an execution pool receives a raw batch, it obtains the corresponding strategy instance from the factory and calls `process_batch()` for batch processing, reducing CPU scheduling overhead. This design ensures low-frequency database I/O (fetching a large batch at once), lightweight in-memory task objects, and maximum utilization of the AI microservice batch API (8 images per batch is the optimal throughput point). ### 2.4 Priority Queue Scheduling `TaskQueueManager` uses `asyncio.PriorityQueue` for each categorized queue: ```python # Enqueue element structure: (negative priority, counter, batch list) await queue.put((-priority, count, batch)) ``` - **Priority negation**: Python's min-heap pops the smallest value first, so negation makes **higher priority values get consumed first**. - **Counter tiebreaker**: When two batches have the same priority, a monotonically increasing counter differentiates them, avoiding `TypeError` from comparing dictionaries. ## 3. Producer & Consumer Coordination TaskManager serves as the task entry point, containing five coroutines: 1. **task Worker** (producer coroutine): Monitors task queue status, fetches tasks from the database based on thresholds, and pushes them into the corresponding queues. 2. **CPU Consumer** (consumer coroutine): Takes batches from the CPU queue, processes thumbnails/metadata in bulk. 3. **IO Consumer** (consumer coroutine): Takes batches from the IO queue, processes AI requests/face recognition in bulk. 4. **AI Consumer** (consumer coroutine): Takes batches from the AI queue, processes LLM description generation in bulk. 5. **Result Handler** (result coroutine): Gets processing results from `result_queue`, batch-updates database status. ### Producer & Scheduling Hub - **Responsibilities**: Batch-fetch PENDING tasks from the database, group by TaskType, split into standard batches (≤ 8 per batch), assign the priority of the first element as the batch priority, and push into the corresponding in-memory categorized queue. ### Consumer Concurrency Control Each consumer coroutine maintains an `asyncio.Semaphore` for **fine-grained concurrency control**: | Queue Type | Max Concurrency | Use Case | |---------|-----------|---------| | CPU | `os.cpu_count() or 4` | Thumbnail generation, metadata extraction | | IO | `10` | Face recognition, OCR, image classification, vector embedding | | AI | `2` | Visual description generation (depends on LLM, scarce resource) | A consumer must acquire a semaphore permit before taking a batch from the queue — this ensures that even if the database fetches a large number of tasks at once, memory won't be exhausted by unlimited concurrency. ### Async Result Processing After each task completes, the database status is not updated immediately. Instead, results are written to `result_queue` and batch-processed by the `Result Handler` coroutine. ## 4. Task Strategy System All concrete task handlers inherit from `BaseTaskStrategy` and register via `@TaskStrategyFactory.register(TaskType.XXX)`. ### 4.1 Strategy Base Class Interface ```python class BaseTaskStrategy(ABC): @property @abstractmethod def task_category(self) -> str: # Returns 'CPU' | 'IO' | 'AI' pass @abstractmethod async def process(self, worker, task: Task, db: Session) -> Any: pass # Single task processing (legacy interface) async def process_batch(self, worker, tasks: List[Task], db: Session) -> List[Dict]: # Default: calls process() in a loop; subclasses can override for true batch processing results = [] for task in tasks: res = await self.process(worker, task, db) results.append({...}) return results async def handle_completion(self, worker, items: List[Dict], db: Session) -> None: # Post-completion callback for triggering follow-up task chains # (e.g. PROCESS_BASIC completion triggers metadata extraction) pass ``` ### 4.2 Typical Strategy Implementations #### BasicTaskStrategy (CPU Batch Processing) CPU tasks (e.g. thumbnail generation) involve heavy synchronous blocking I/O (file reads/writes) and CPU computation (OpenCV). **Optimization**: Implements `process_basic_cpu_batch_job`, which processes 8 sub-tasks sequentially within a **single thread pool call**: ```python def process_basic_cpu_batch_job(tasks_data: List[Dict]) -> List[Dict]: results = [] for data in tasks_data: res = process_basic_cpu_job(data['file_path'], data['file_id'], ...) results.append(res) return results ``` This way, thumbnail generation for 8 images **shares a single thread pool context switch overhead**, significantly improving CPU-intensive task throughput. #### AI/IO Strategy (Network Batch Requests) For tasks that depend on the external AI microservice (e.g. `face.py`, `ocr.py`), `process_batch` combines Base64 encodings of 8 images into a **single HTTP request**: ```python async def process_batch(self, worker, tasks, db): b64_images = [read_image_base64(p) for p in valid_photos] async with aiohttp.ClientSession() as session: async with session.post(api_url, json={"images": b64_images}) as resp: results = (await resp.json())['results'] # Batch-parse results, batch-update database ``` This reduces 8 network round-trips to 1, significantly mitigating the impact of network latency on overall throughput. ## 5. Task Priority Task priority is implemented via the `priority` field (integer) in the `Task` table, where larger values indicate higher priority. - **Default priorities**: The system defines a `DEFAULT_PRIORITIES` dictionary to automatically assign priorities to different task types. - `SCAN_FOLDER` (100), `PROCESS_BASIC` (99), `GENERATE_THUMBNAIL` (98), `EXTRACT_METADATA` (97): Scanning and basic media processing. - AI tasks: `CLASSIFY_IMAGE` (10), `RECOGNIZE_FACE` (9), `IMAGE_EMBEDDING` (8), `OCR` (7), `RECOGNIZE_TICKET` (4), `VISUAL_DESCRIPTION` (1). - User-initiated interactive tasks use priority 10000 and can run while automatic work of that type is paused. - **Scheduling logic**: When consumers take tasks from in-memory queues, `PriorityQueue` automatically ensures higher-priority batches are consumed first. - **AI phase switching**: Tasks of the same type run consecutively to reduce model switching. When a runnable higher-priority type arrives, the producer stops replenishing the current type and withdraws queued batches. It switches after in-flight batches and result persistence finish. Remaining tasks stay PENDING and resume later; equal or lower priorities do not interrupt a phase. Paused tasks, extension maintenance and future retry deadlines do not trigger a switch. ## 6. Task Status Management Tasks transition between the following states during their lifecycle (defined in the `TaskStatus` enum): 1. **PENDING**: Initial state — task created but not yet executed. 2. **PROCESSING**: Executing — Worker sets this status immediately after fetching the task. 3. **COMPLETED**: Execution successful — usually the record is deleted from the database to keep the table lightweight. 4. **FAILED**: Execution failed — record retained in the database with error info for troubleshooting. **Startup Recovery Mechanism**: On service startup, `TaskWorker` runs `_recover_unfinished_tasks`, resetting all tasks in `PROCESSING` status to `PENDING`, ensuring tasks are not lost after an unexpected crash. ## 7. Exception Handling & Timeout Control ### Timeout Mechanism Each batch execution is wrapped in `asyncio.wait_for`: - AI tasks (dependent on LLM response): **120 seconds** timeout. - CPU / IO tasks: **300 seconds** timeout. On timeout, all sub-tasks in the batch are marked as `FAILED` with a timeout error message, preventing a single slow task from permanently consuming a concurrency slot and paralyzing the system. ### Exception Handling 1. **Batch-level capture**: Unified interception in `execute_batch_task_wrapper`, written to `result_queue`. 2. **Strategy-level fault tolerance**: Each strategy's `process_batch` handles business exceptions internally (e.g. file not found, resolution filtering), returning structured failure results. 3. **Process-level fault tolerance**: The Worker main loop contains broad `try-except` blocks with graceful `asyncio.CancelledError` handling, ensuring severe errors from a single task or strategy do not crash the entire Worker. 4. **System-level fault tolerance**: Even if the system crashes entirely (power loss, restart, etc.), uncompleted tasks are persisted in the database. On restart, tasks are automatically recovered and re-executed. Some tasks may have already completed but their database status was not updated — re-executing them is safe because all task operations are **idempotent**. ## 8. Resource Management & Lifecycle ### Dynamic Execution Pool Management - **ProcessPoolExecutor**: For CPU-intensive tasks — high cold-start cost, shuts down after **300 seconds** of idle time. - **ThreadPoolExecutor**: For IO-intensive tasks and CPU task batch wrappers — shuts down after **300 seconds** of idle time. - **AI consumer concurrency limit**: Strictly controlled via `asyncio.Semaphore(2)` to prevent overwhelming the external AI service. ### Exponential Backoff on Idle When all queues are completely idle, the Producer loop uses **exponential backoff** sleep: ```python backoff_delay = min(1.0 * (1.5 ** retries), 10.0) # 1s → 1.5s → 2.25s → ... → 10s cap ``` After **5 minutes** of continuous idle, the Worker exits automatically to release all resources. It will be restarted by the external monitor when new tasks arrive. ## 9. Performance Optimization Summary | Technique | Description | Effect | |---------|------|------| | **Multi-level buffer architecture** | Database → memory queue → execution pool | Read-write separation; 90%+ reduction in DB I/O | | **Adaptive production rate** | Queue-depth feedback-driven fetching | Eliminates empty polling; CPU usage near zero when idle | | **PriorityQueue scheduling** | Higher-priority tasks consumed first | Zero-delay response for critical tasks | | **Batch packaging (8/batch)** | AI microservice batch API | Network round-trips reduced to 1/8 | | **CPU batch thread processing** | Sequential processing of 8 images in one thread | Thread switch overhead reduced by 87.5% | | **asyncio.Semaphore throttling** | Coroutine-level concurrency control per consumer | No risk of unlimited in-memory concurrency | | **asyncio.wait_for timeout** | Batch execution timeout safeguard | Single slow task cannot paralyze the system | | **Exponential backoff + auto-exit** | Energy-saving during idle | All resources released after 5 min of inactivity | | **Delete on completion** | Successful tasks removed from database | Task table stays lightweight; queries never degrade | ## 10. Extension Guide ### Adding a New Task Type 1. Add the new type to the `TaskType` enum in `app/db/models/task.py`. 2. Create a new strategy class inheriting `BaseTaskStrategy`, implementing `process()` or `process_batch()`. 3. Register using `@TaskStrategyFactory.register(TaskType.NEW_TYPE)`. 4. Add a default priority in `task_manager.py`'s `DEFAULT_PRIORITIES`. **No changes to the TaskWorker core code are needed** to integrate a new task type.