
### 💾🎉 copyparty
使用[*任何*](#browser-support)网页浏览器提供可断点续传的上传/下载,将几乎任何设备变成文件服务器
* 服务器仅需 Python(2 或 3),所有依赖项均为可选
* 🔌 协议:[http(s)](#the-browser) // [webdav](#webdav-server) // [sftp](#sftp-server) // [ftp(s)](#ftp-server) // [tftp](#tftp-server) // [smb/cifs](#smb-server)
* 📱 [Android 应用](#android-app) // [iPhone 快捷指令](#ios-shortcuts)
👉 **[立即开始](#quickstart)!** 或访问运行在我地下室 Intel NUC 上的 **[只读演示服务器](https://a.ocv.me/pub/demo/)** 👀
📷 **屏幕截图:** [浏览器](#the-browser) // [上传](#uploading) // [撤销上传](#unpost) // [缩略图](#thumbnails) // [搜索](#searching) // [文件搜索](#file-search) // [zip 下载](#zip-downloads) // [Markdown 查看器](#markdown-viewer)
🎬 **视频:** [上传](https://a.ocv.me/pub/demo/pics-vids/up2k.webm) // [命令行上传](https://a.ocv.me/pub/demo/pics-vids/u2cli.webm) // [边传边下](https://a.ocv.me/pub/g/nerd-stuff/cpp/2024-0418-race-the-beam.webm) // 👉 **[功能展示](https://a.ocv.me/pub/demo/showcase-hq.webm)** ([youtube](https://www.youtube.com/watch?v=15_-hgsX2V0))
在挪威 🇳🇴 开发,并包含来自[非挪威地区](https://github.com/9001/copyparty/graphs/contributors)的贡献
## 自述文件目录
* 顶部
* [快速开始](#quickstart) - 只需运行 **[copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py)** —— 就是这样! 🎉
* [镜像站](#mirrors) - 其他可以下载 copyparty 的地方
* [在家庭网络](#at-home) - 使其可通过互联网访问
* [在服务器上](#on-servers) - 在服务器上你可能还需要这些
* [功能特性](#features) - 另请参阅[与类似软件的对比](./docs/versus.md)
* [用户评价](#testimonials) - 小部分用户反馈集合
* [开发动机](#motivations) - 项目目标 / 理念
* [注意事项](#notes) - 一般说明
* [已知问题](#bugs) - 大致按遇到的可能性排序
* [非本软件的 Bug](#not-my-bugs) - 同样按此顺序排列
* [破坏性更新](#breaking-changes) - 升级说明
* [常见问题解答](#FAQ) - “经常”被问到的问题
* [账户与卷](#accounts-and-volumes) - 按文件夹、按用户分配权限
* [文件夹覆盖](#shadowing) - 隐藏特定子文件夹
* [点文件](#dotfiles) - Unix 风格的隐藏文件/文件夹
* [浏览器](#the-browser) - 使用网络浏览器访问 copyparty 服务器
* [选项卡](#tabs) - UI 中的主要选项卡
* [快捷键](#hotkeys) - 浏览器具有以下快捷键
* [导航窗格](#navpane) - 在面包屑导航和导航窗格之间切换
* [缩略图](#thumbnails) - 按 `g` 或 `田` 切换网格视图以代替文件列表
* [ZIP 下载](#zip-downloads) - 将文件夹(或选定的文件)下载为 `zip` 或 `tar` 文件
* [正在上传](#uploading) - 将文件/文件夹拖入网页浏览器进行上传
* [文件搜索](#file-search) - 将文件拖入浏览器还可以查看它们是否已存在于服务器上
* [撤销上传](#unpost) - 撤销/删除意外上传的文件
* [定时删除](#self-destruct) - 可以为上传设置生命周期
* [边传边下](#race-the-beam) - 在文件仍在传输时即可开始下载([演示视频](http://a.ocv.me/pub/g/nerd-stuff/cpp/2024-0418-race-the-beam.webm))
* [传入的文件](#incoming-files) - 控制面板显示所有传入文件的预计到达时间
* [文件管理器](#file-manager) - 剪切/粘贴、重命名和删除文件/文件夹(如果你有权限)
* [分享](#shares) - 通过创建临时链接来分享文件或文件夹
* [批量重命名](#batch-rename) - 选择一些文件并按 `F2` 调出重命名 UI
* [RSS 订阅](#rss-feeds) - 使用你的 RSS 阅读器监控文件夹
* [OPDS 订阅](#opds-feeds) - 从你的电子书阅读器浏览和下载文件
* [最近上传](#recent-uploads) - 列出所有最近的上传
* [媒体播放器](#media-player) - 几乎可以播放所有现存的音频格式
* [播放列表](#playlists) - 创建并播放 [m3u8](https://en.wikipedia.org/wiki/M3U) 播放列表
* [创建播放列表](#creating-a-playlist) - 使用独立的媒体播放器或 copyparty
* [音频均衡器](#audio-equalizer) - 以及[动态范围压缩器](https://en.wikipedia.org/wiki/Dynamic_range_compression)
* [修复 Android 上的不可靠播放](#fix-unreliable-playback-on-android) - 由于手机/应用设置引起
* [文本文件查看器](#textfile-viewer) - 支持日志文件等的实时流式传输([演示](https://a.ocv.me/pub/demo/logtail/))
* [Markdown 查看器](#markdown-viewer) - 并且有*两个*编辑器
* [Markdown 变量](#markdown-vars) - 使用服务器端变量展开的动态文档
* [其他技巧](#other-tricks)
* [搜索功能](#searching) - 按大小、日期、路径/名称、mp3 标签等进行搜索...
* [服务器配置](#server-config) - 使用参数或配置文件,或混合使用两者
* [版本检查器](#version-checker) - 晚上睡得更香
* [日志记录](#logging) - 服务器日志默认发送到 stdout
* [Zeroconf](#zeroconf) - 在局域网中宣告启用的服务([图片](https://user-images.githubusercontent.com/241032/215344737-0eae8d98-9496-4256-9aa8-cd2f6971810d.png))
* [mDNS](#mdns) - 局域网域名和功能宣告器
* [SSDP](#ssdp) - Windows 资源管理器宣告器
* [二维码](#qr-code) - 打印二维码 [(屏幕截图)](https://user-images.githubusercontent.com/241032/194728533-6f00849b-c6ac-43c6-9359-83e454d11e00.png) 以便快速访问
* [FTP 服务器](#ftp-server) - 可以使用 `--ftp 3921` 启动 FTP 服务器
* [SFTP 服务器](#sftp-server) - 大约可达 700 MiB/s(比 WebDAV 和 FTP 慢)
* [WebDAV 服务器](#webdav-server) - 支持读写
* [从 Windows 连接到 WebDAV](#connecting-to-webdav-from-windows) - 使用 GUI
* [TFTP 服务器](#tftp-server) - 可以使用 `--tftp 3969` 启动 TFTP 服务器(读/写)
* [SMB 服务器](#smb-server) - 不安全、速度慢,不推荐用于广域网
* [浏览器用户体验](#browser-ux) - 微调 UI
* [Open Graph](#opengraph) - Discord 和社交媒体嵌入
* [文件去重](#file-deduplication) - 启用基于符号链接的上传去重
* [文件索引](#file-indexing) - 启用音乐搜索、上传撤销和更好的去重功能
* [排除模式](#exclude-patterns) - 节省一些时间
* [文件系统保护](#filesystem-guards) - 避免遍历到其他文件系统中
* [定期重新扫描](#periodic-rescan) - 文件系统监控
* [上传规则](#upload-rules) - 使用 volflags 设置上传规则
* [压缩上传](#compress-uploads) - 文件可以在上传时自动压缩
* [Chmod 和 Chown](#chmod-and-chown) - 按卷分配的文件系统权限和所有权
* [其他标志](#other-flags)
* [descript.ion](#description) - 为文件夹中的每个文件添加描述
* [点隐藏](#dothidden) - 在文件夹中按外观隐藏特定文件
* [缩略图预生成](#thumbnail-pregen) - 如果你想在启动时预先生成所有内容
* [数据库位置](#database-location) - 卷内(`.hist/up2k.db`,默认)或其他位置
* [从音频文件提取元数据](#metadata-from-audio-files) - 设置 `-e2t` 在上传时索引标签
* [从 xattrs 提取元数据](#metadata-from-xattrs) - Unix 扩展文件属性
* [文件解析器插件](#file-parser-plugins) - 提供自定义解析器以索引额外的标签
* [事件钩子](#event-hooks) - 在上传、重命名等操作时触发程序([示例](./bin/hooks/))
* [ZeroMQ](#zeromq) - 事件钩子可以发送 zeromq 消息
* [上传事件](#upload-events) - 更古老、更强大的方法([示例](./bin/mtag/))
* [处理器](#handlers) - 使用插件重新定义行为([示例](./bin/handlers/))
* [IP 认证](#ip-auth) - 基于 IP 范围 (CIDR) 自动登录
* [IP 限制](#restrict-to-ip) - 将用户限制在特定的 IP 范围 (CIDR) 内
* [身份提供商](#identity-providers) - 用 OAuth 等方式替换 copyparty 密码
* [通用 Header 认证](#generic-header-auth) - 通过请求头进行认证的其他方式
* [用户可更改的密码](#user-changeable-passwords) - 如果允许,用户可以更改自己的密码
* [使用云作为存储](#using-the-cloud-as-storage) - 连接到 AWS S3 存储桶或类似服务
* [对 Google 隐藏](#hiding-from-google) - 告诉搜索引擎你不想被索引
* [主题](#themes)
* [完整示例](#complete-examples)
* [监听 80 和 443 端口](#listen-on-port-80-and-443) - 成为一个*真正的*网络服务器
* [反向代理](#reverse-proxy) - 在其他网站旁运行 copyparty
* [Real-IP](#real-ip) - 教导 copyparty 如何获取客户端 IP
* [反向代理性能](#reverse-proxy-performance)
* [永久 Cloudflare 隧道](#permanent-cloudflare-tunnel) - 如果你有域名并想迅速将你的 copyparty 上线
* [Prometheus](#prometheus) - 可以启用指标/统计数据
* [其他极其特定的功能](#other-extremely-specific-features) - 你永远找不到这些的用武之地
* [自定义 MIME 类型](#custom-mimetypes) - 更改文件扩展名的关联
* [GDPR 合规性](#GDPR-compliance) - 想象一下以专业方式使用 copyparty...
* [功能特性开关](#feature-chickenbits) - 功能有 bug?把它拆掉
* [功能实验开关](#feature-beefybits) - 强制启用在你的操作系统/环境中存在已知问题的功能
* [软件包](#packages) - 这个派对可能比你想象的更近
* [Arch 软件包](#arch-package) - `pacman -S copyparty`(在 [Arch Linux extra](https://archlinux.org/packages/extra/any/copyparty/) 中)
* [Fedora 软件包](#fedora-package) - 尚不存在
* [Gentoo ::guru 软件包](#gentoo-guru-package) - `emerge www-servers/copyparty::guru`(在 [::guru](https://wiki.gentoo.org/wiki/Project:GURU) 中)
* [Homebrew Formulae](#homebrew-formulae) - `brew install copyparty ffmpeg`
* [Nix 软件包](#nix-package) - `nix profile install github:9001/copyparty`
* [NixOS 模](#nixos-module)
* [浏览器支持](#browser-support) - 太长不看:支持
* [服务器名人堂](#server-hall-of-fame) - 运行 copyparty 的意想不到的事物
* [客户端示例](#client-examples) - 使用非浏览器客户端与 copyparty 交互
* [文件夹同步](#folder-sync) - 将文件夹同步到 copyparty 或从 copyparty 同步
* [挂载为驱动器](#mount-as-drive) - 将远程 copyparty 服务器作为本地文件系统
* [Android 应用](#android-app) - 一键上传到 copyparty
* [iOS 快捷指令](#iOS-shortcuts) - 没有 iPhone 应用,但是
* [性能表现](#performance) - 默认设置通常没问题 - 预期 `8 GiB/s` 下载,`1 GiB/s` 上传
* [客户端性能](#client-side) - 上传文件时
* [安全性](#security) - 有一个提供公告的 [Discord 服务器](https://discord.gg/25J8CdTT6G)
* [注意事项](#gotchas) - 可能出乎意料的行为
* [CORS](#cors) - 跨域请求配置
* [文件密钥](#filekeys) - 防止文件名被暴力猜测
* [目录密钥](#dirkeys) - 共享卷中的特定文件夹
* [密码哈希](#password-hashing) - 你可以哈希密码
* [HTTPS](#https) - HTTP 和 HTTPS 均受支持
* [从崩溃中恢复](#recovering-from-crashes)
* [客户端崩溃](#client-crashes)
* [Firefox 白屏死机](#firefox-wsod) - Firefox 87 在上传期间可能会崩溃
* [HTTP API](#HTTP-API) - 参见 [开发说明](./docs/devnotes.md#http-api)
* [依赖项](#dependencies) - 强制依赖
* [可选依赖项](#optional-dependencies) - 启用附加功能
* [依赖项特性开关](#dependency-chickenbits) - 阻止加载可选依赖项
* [依赖项取消 Vendoring](#dependency-unvendoring) - 强制使用系统模块
* [可选的 GPL 内容](#optional-gpl-stuff)
* [SFX](#sfx) - 独立的“二进制文件”(推荐!)
* [copyparty.exe](#copypartyexe) - 下载 [copyparty.exe](https://github.com/9001/copyparty/releases/latest/download/copyparty.exe) (Win8+) 或 [copyparty32.exe](https://github.com/9001/copyparty/releases/latest/download/copyparty32.exe) (Win7+)
* [Zipapp](#zipapp) - 另一种紧急替代方案,[copyparty.pyz](https://github.com/9001/copyparty/releases/latest/download/copyparty.pyz)
* [在 Android 上安装](#install-on-android)
* [在 iOS 上安装](#install-on-iOS)
* [报告 Bug](#reporting-bugs) - 关于上下文的建议以及提交位置
* [开发说明](#devnotes) - 构建说明等,参见 [./docs/devnotes.md](./docs/devnotes.md)
## 快速开始
只需运行 **[copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py)** —— 就是这样! 🎉
* 或者通过 [pypi](https://pypi.org/project/copyparty/) 安装:`python3 -m pip install --user -U copyparty`
* 或者如果你无法安装 Python,可以改用 [copyparty.exe](#copypartyexe)
* 或者安装在 [Arch](#arch-package) / [Homebrew](#homebrew-formulae) ╱ [NixOS](#nixos-module) ╱ [通过 Nix](#nix-package)
* 或者如果你在 Android 上,请在 Termux 中 [安装 copyparty](#install-on-android)
* 或者也许是 iPhone 或 iPad?[在 iOS 的 a-Shell 中安装](#install-on-iOS)
* 或者也许你有一台 [群晖 NAS / DSM](./docs/synology-dsm.md)
* 或者如果你安装了 [uv](https://docs.astral.sh/uv/),运行 `uv tool run copyparty`
* 或者如果你的电脑一团糟且其他方法都无效,[尝试 pyz](#zipapp)
* 或者如果你的操作系统已经挂了,试试 [可引导的闪存盘 / CD-ROM](https://a.ocv.me/pub/stuff/edcd001/enterprise-edition/)
* 或者如果你还不信任 copyparty 并想稍微隔离它一下,那么...
* ...也许用 [prisonparty](./bin/prisonparty.sh) 创建一个微型 [chroot](https://wiki.archlinux.org/title/Chroot)(非常便携),
* ...或者用 [bubbleparty](./bin/bubbleparty.sh) 将其包裹在 [bubblewrap](https://github.com/containers/bubblewrap) 中(更好)
* 或者如果你更喜欢 [使用 Docker](./scripts/docker/) 🐋 你也可以那样做
* Docker 已经内置了所有依赖,因此跳过此步骤:
安装一些推荐的依赖以启用缩略图(图像/音频/视频)、媒体索引和音频转码功能:
* **Alpine:** `apk add py3-pillow ffmpeg`
* **Debian:** `apt install --no-install-recommends python3-pil ffmpeg`
* **Fedora:** rpmfusion + `dnf install python3-pillow ffmpeg --allowerasing`
* **FreeBSD:** `pkg install py311-sqlite3 py311-pillow ffmpeg`
* **MacOS:** `port install py-Pillow ffmpeg`
* **MacOS**(替代方案): `brew install pillow ffmpeg`
* **Windows:** `python -m pip install --user -U Pillow`
* 手动安装 [Python](https://www.python.org/downloads/windows/) 和 [FFmpeg](#optional-dependencies);不要使用 `winget` 或 `Microsoft Store`(这会破坏 $PATH)
* copyparty.exe 自带 `Pillow`,只需要 [ffmpeg](#optional-dependencies) 用于媒体标签/视频缩略图
* 参见 [可选依赖项](#optional-dependencies) 以启用更多功能
不带参数运行 copyparty(例如在 Windows 上双击它)将允许所有人读写当前文件夹;你可能需要 [账户和卷](#accounts-and-volumes)
或者查看 [一些使用示例](#complete-examples) 获取灵感,或者 [完整的 Windows 示例](./docs/examples/windows.md)
一些推荐的选项:
* `-e2dsa` 启用通用[文件索引](#file-indexing)
* `-e2ts` 启用音频元数据索引(需要 FFprobe 或 Mutagen)
* `-v /mnt/music:/music:r:rw,foo -a foo:bar` 将 `/mnt/music` 共享为 `/music`,任何人可`r`(只读),而用户 `foo`(密码 `bar`)拥有读写权限
* 将 `:r:rw,foo` 替换为 `:r,foo` 可使该文件夹仅对 `foo` 可读,其他任何人不可见
* 有关语法和其他权限,请参阅 [账户和卷](#accounts-and-volumes)(或 [`--help-accounts`](https://copyparty.eu/cli/#accounts-help-page))
### 镜像站
其他可以下载 copyparty 的地方(非 GitHub 链接):
* https://copyparty.eu/ (hetzner, 芬兰, 官方镜像):
* https://copyparty.eu/py = https://copyparty.eu/copyparty-sfx.py = sfx 版
* https://copyparty.eu/en = https://copyparty.eu/copyparty-en.py = 仅英文 sfx 版
* https://copyparty.eu/pyz = https://copyparty.eu/copyparty.pyz = zipapp 版
* https://copyparty.eu/enz = https://copyparty.eu/copyparty-en.pyz = 企业 pyz 版
* https://copyparty.eu/cli = 在线命令行帮助文本
### 在家庭网络中
通过启动一个 [Cloudflare 快速隧道](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/) 使其可以通过互联网访问,就像这样:
首先下载 [cloudflared](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/),然后使用 `cloudflared tunnel --url http://127.0.0.1:3923` 启动隧道
当隧道启动时,它会显示一个 URL,你可以分享这个 URL 让任何人浏览你的存储库或向你上传文件
但是如果你有一个域名,那么你可能想跳过随机自动生成的 URL,而是创建一个[永久 Cloudflare 隧道](#permanent-cloudflare-tunnel)
由于人们将通过 Cloudflare 连接,请使用 `--xff-hdr cf-connecting-ip` 运行 copyparty 以正确检测客户端 IP
### 在服务器上
在服务器上你可能还需要这些,尤其是生产环境:
* [contrib/systemd/copyparty.service](contrib/systemd/copyparty.service) 将 copyparty 作为 systemd 服务运行(详见内部指南)
* [contrib/systemd/prisonparty.service](contrib/systemd/prisonparty.service) 在 chroot 中运行(以获得额外的安全性)
* [contrib/podman-systemd/](contrib/podman-systemd/) 在 Podman 容器中将 copyparty 作为 systemd 服务运行(详见内部指南)
* [contrib/openrc/copyparty](contrib/openrc/copyparty) 在 Alpine / Gentoo 上运行 copyparty
* [contrib/rc/copyparty](contrib/rc/copyparty) 在 FreeBSD 上运行 copyparty
* [NixOS 模块](#nixos-module) 在 NixOS 主机上运行 copyparty
* [contrib/nginx/copyparty.conf](contrib/nginx/copyparty.conf) 在 Nginx 后面进行[反向代理](#reverse-proxy)(以获得更好的 HTTPS)
并记得打开你需要的端口;这是一个包含 copyparty 提供的所有功能的完整示例:
```
firewall-cmd --permanent --add-port={80,443,3921,3922,3923,3945,3990}/tcp # --zone=libvirt
firewall-cmd --permanent --add-port=12000-12099/tcp # --zone=libvirt
firewall-cmd --permanent --add-port={69,1900,3969,5353}/udp # --zone=libvirt
firewall-cmd --reload
```
(69:tftp, 1900:ssdp, 3921:ftp, 3922:sftp, 3923:http/https, 3945:smb, 3969:tftp, 3990:ftps, 5353:mdns, 12000:passive-ftp)
## 功能特性
另请参阅[与类似软件的对比](./docs/versus.md)
* 后端相关
* ☑ IPv6 + Unix 域套接字
* ☑ [多处理](#performance)(真正的多线程)
* ☑ 卷(挂载点)
* ☑ [账户系统](#accounts-and-volumes)
* ☑ [FTP 服务器](#ftp-server)
* ☑ [TFTP 服务器](#tftp-server)
* ☑ [WebDAV 服务器](#webdav-server)
* ☑ [SMB/CIFS 服务器](#smb-server)
* ☑ 用于快速访问的 [二维码](#qr-code)
* ☑ [UPnP / Zeroconf / mDNS / SSDP](#zeroconf)
* ☑ [事件钩子](#event-hooks) / 脚本运行器
* ☑ [反向代理支持](https://github.com/9001/copyparty#reverse-proxy)
* ☑ 跨平台 (Windows, Linux, MacOS, Android, iOS, FreeBSD, arm32/arm64, ppc64le, s390x, RISC-V/riscv64, SGI IRIX)
* 上传
* ☑ 基础功能:普通 multipart,支持 IE6
* ☑ [up2k](#uploading):基于 JS,可断点续传,多线程
* **无文件大小限制!** 即使在 Cloudflare 之后也是如此
* ☑ 暂存区:简单的 PUT 文件投放器
* ☑ 文件名随机化器
* ☑ 只写文件夹
* ☑ [撤销上传](#unpost):撤销/删除意外上传
* ☑ [定时销毁](#self-destruct)(在服务器端或客户端指定)
* ☑ [边传边下](#race-the-beam)(几乎类似于点对点)
* ☑ 符号链接/丢弃重复项(基于内容匹配)
* 下载
* ☑ 在浏览器中下载单个文件
* ☑ [以 zip / tar 文件形式下载文件夹](#zip-downloads)
* ☑ [FUSE 客户端](https://github.com/9001/copyparty/tree/hovudstraum/bin#partyfusepy)(只读)
* 浏览器
* ☑ [导航窗格](#navpane)(目录树侧边栏)
* ☑ 文件管理器(剪切/粘贴、删除、[批量重命名](#batch-rename))
* ☑ 音频播放器(带有 [OS 媒体控制](https://user-images.githubusercontent.com/241032/215347492-b4250797-6c90-4e09-9a4c-721edf2fb15c.png)和 opus/mp3 转码功能)
* ☑ 将视频文件作为音频播放(在服务器上转换)
* ☑ 创建并播放 [m3u8 播放列表](#playlists)
* ☑ 带有 webm 播放器的图片库
* ☑ 以及 cbz 漫画阅读器
* ☑ 带有语法高亮的文本文件浏览器](#textfile-viewer)
* ☑ 不断增长的文件的实时流式传输(例如日志文件)
* ☑ [缩略图](#thumbnails)
* ☑ ...使用 Pillow、pyvips 或 FFmpeg 生成的图像
* ☑ ...使用 rawpy 生成的 RAW 图像
* ☑ ...使用 FFmpeg 生成的视频
* ☑ ...使用 FFmpeg 生成的音频(频谱图)
* ☑ 缓存淘汰(最大保留时间;可能最终支持最大容量)
* ☑ 多语言 UI(英语、挪威语、中文,[欢迎添加你的语言](./docs/rice/#translations))
* ☑ 单页应用 (SPA)(在上传时浏览)
* 服务器索引
* ☑ [按内容定位文件](#file-search)
* ☑ 按名称/路径/日期/大小搜索
* ☑ [按 ID3 标签等搜索](#searching)
* 客户端支持
* ☑ [文件夹同步](#folder-sync)(仅单向;永远不会支持完全同步)
* ☑ [curl 友好](https://user-images.githubusercontent.com/241032/215322619-ea5fd606-3654-40ad-94ee-2bc058647bb2.png)
* ☑ [Open Graph](#opengraph)(Discord 嵌入)
* Markdown
* ☑ [查看器](#markdown-viewer)
* ☑ 编辑器(有何不可呢)
* ☑ [变量](#markdown-vars)
附注:缺少什么吗?把你想到的任何疯狂点子作为[功能需求](https://github.com/9001/copyparty/issues/new?assignees=9001&labels=enhancement&template=feature_request.md)或[讨论](https://github.com/9001/copyparty/discussions/new?category=ideas)发出来 🤙
## 用户评价
小部分用户反馈集合
`足够好`、`出乎意料地准确`、`认证的优秀软件`、`就是好用`、`为什么`、`哇这比 Nextcloud 好多了`
* UI 简直就是场灾难。如果要详细描述的话,我恐怕无法保持文明的用语
# 开发动机
项目目标 / 理念
* 逆向的 Unix 哲学 —— 做所有的事情,并且做得*还过得去*
* 快速插入的服务,在紧要关头提供大量功能
* [一些替代方案](./docs/versus.md)可能更适合你
* 随处运行,支持所有环境
* 支持尽可能多的网络浏览器和 Python 版本
* 每个浏览器至少应该能够浏览、下载、上传文件
* 成为在老旧机器之间传输资料的优秀应急解决方案
* 最小化的依赖
* 但通过可选依赖添加附加功能也是可以的
* 所有内容均为纯文本,便于排查恶意代码
* 无需准备 / 设置,只需运行 sfx(这也是纯文本的)
* 适应性强、可塑、可扩展
* 没有构建步骤;修改 js/python 不需要 node.js 或类似工具
发家致富明确*不是*动机,但如果你想捐款,请查看我的 [GitHub 个人主页](https://github.com/9001),了解关于我一般开源软件捐款的信息(另外,感谢!)
## 注意事项
一般说明:
* 纸张打印受深色/浅色模式影响!浅色模式用于彩色,深色模式用于灰度
* 因为目前没有浏览器正确实现用于执行此操作的媒体查询 orz
浏览器特定说明:
* iPhone/iPad:使用 Firefox 下载文件
* Android Chrome:增加“parallel uploads”以提高速度(Android 的 bug)
* Android Firefox:选择文件需要一些时间(他们对 ☝️ 的修复)
* 桌面版 Firefox:~~如果你的文件很大,可能会消耗数 GB 的内存~~ *现在似乎没问题了*
* 桌面版 Firefox:[可能会阻止你拔出 USB 闪存盘](https://bugzilla.mozilla.org/show_bug.cgi?id=1792598),直到你访问 `about:memory` 并点击 `Minimize memory usage`
服务器操作系统特定说明:
* RHEL8 / Rocky8:你可以使用 `/usr/libexec/platform-python` 运行 copyparty
服务器备注:
* 支持 PyPy,但如果你启用了数据库,普通的 CPython 会更快
# 已知问题
大致按遇到的可能性排序
* 一般问题:
* `--th-ff-jpg` 可能可以修复某些 FFmpeg 版本(macOS、某些 Linux)上的视频缩略图问题
* `--th-ff-swr` 可能可以修复某些 FFmpeg 版本上的音频缩略图问题
* 如果 `up2k.db`(文件系统索引)位于 Samba 共享或网络磁盘上,当共享短暂断开时,你将会遇到不可预知的行为
* 请使用 `--hist` 或 `hist` volflag(`-v [...]:c,hist=/tmp/foo`)将数据库和缩略图放在本地磁盘上
* 或者,如果你只想移动数据库(而不是缩略图),请使用 `--dbpath` 或 `dbpath` volflag
* 启动时所有卷必须存在/可用;否则 up2k(尤其是 MTP)会变得一团糟
* 可能还有更多,请告诉我
* Python 3.4 及更老版本(包括 2.7):
* 由于 [Python 当时还未处理 EINTR](https://peps.python.org/pep-0475/),会出现许多罕见且令人兴奋的边缘情况
* 从 copyparty 下载可能会突然失败,但上传*应该*没问题
* Windows 上的 Python 2.7:
* 无法使用 `-e2d` 索引非 ASCII 文件名
* 无法处理带有乱码的文件名
如果你有新的令人兴奋的 Bug 要分享,请参阅 [报告 Bug](#reporting-bugs)
## 非本软件的 Bug
同样按此顺序排列
* [Chrome issue 1317069](https://bugs.chromium.org/p/chromium/issues/detail?id=1317069) -- 如果你尝试通过将包含符号链接的文件夹拖入浏览器来上传它,被链接的文件将不会被上传
* [Chrome issue 1352210](https://bugs.chromium.org/p/chromium/issues/detail?id=1352210) -- 明文 HTTP 的文件哈希速度可能比 HTTPS 快(但也会极其消耗 CPU)
* [Chrome issue 383568268](https://issues.chromium.org/issues/383568268) -- Web Worker 中的文件读取器可能会导致 OOM / 崩溃浏览器标签页
* copyparty 有一个似乎运行得很好的变通方案
* [Firefox issue 1790500](https://bugzilla.mozilla.org/show_bug.cgi?id=1790500) -- 上传大约 4000 个小文件后整个浏览器可能会崩溃
* Windows:由于 [最大路径长度](https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry) 限制,从网络浏览器上传可能会失败并提示 "directory iterator got stuck";请尝试在上传前将文件移动到路径更短的地方
* Android:由于[电池使用设置](#fix-unreliable-playback-on-android),音乐播放会随机停止
* iPhone:音量控制不起作用,因为 [Apple 不希望它起作用](https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html#//apple_ref/doc/uid/TP40009523-CH5-SW11)
* `AudioContext` 可能永远不是一个可行的变通方案,因为 Apple 引入新问题的速度比修复现有问题的速度快
* iPhone:音乐音量在歌曲切换时会忽高忽低
* 我对此无能为力,因为 `AudioContext` 在 Safari 中仍然是坏的
* iPhone:预加载功能(在媒体播放器选项选项卡中)可能会在每首歌曲结束前 20 秒引起微小的音频故障,但禁用它可能会导致出现更严重的 iOS Bug
* 只是一种直觉,禁用预加载可能会导致播放完全停止,或者可能干扰蓝牙扬声器
* 试图添加有关此问题的工具提示,但看起来 Apple 弄坏了我的工具提示
* iPhone:预加载的 awo 文件会让 Safari 在播放开始时记录 MEDIA_ERR_NETWORK 错误,但歌曲播放得很好,所以爱咋咋地
* awo,即 opus-weba,是 Apple 对 opus 支持的新尝试,取代了技术上仅限于 CBR opus 的 opus-caf
* iPhone:预加载另一个 awo 文件可能会导致播放停止
* 可以通过 `mp.onpreload` 中的 `mp.au.play()` 在某种程度上缓解,但这可能会在 Safari 中触发竞态条件,导致同一个音频对象开始并行播放两次...
* Windows:如果文件夹名称以 `.` 结尾,则无法访问该文件夹
* 这是 Python 或 Windows 的 Bug
* Windows:msys2-python 3.8.6 在离开 up2k 中的带作用域的互斥锁时偶尔会抛出 `RuntimeError: release unlocked lock`
* 这是 msys2 的 Bug,普通的 Windows 版 Python 没有问题
* VirtualBox:在虚拟机中运行且 up2k 数据库位于 vboxsf 中时,SQLite 会抛出 `Disk I/O Error`
* 请使用 `--hist` 或 `hist` volflag(`-v [...]:c,hist=/tmp/foo`)将数据库和缩略图放置在虚拟机内部
* 或者,如果你只想移动数据库(而不是缩略图),请使用 `--dbpath` 或 `dbpath` volflag
* 在 mergerfs 上也会发生这种情况,因此请将数据库放在其他地方
* Ubuntu:无法将某些文件夹中的文件拖入 Firefox 或 Chrome
* 由于 snap 安全策略——请参阅 `snap connections firefox` 以获取允许列表,`removable-media` 显然允许所有的 `/mnt` 和 `/media`
# 破坏性更新
升级说明
* `1.9.16` (2023-11-04):
* `--stats`/Prometheus:`cpp_bans` 重命名为 `cpp_active_bans`,它和 `cpp_uptime` 一起变为了 gauges 类型
* `1.6.0` (2023-01-29):
* HTTP API:delete/move 现在是 `POST` 而不是 `GET`
* 除了 `GET` 和 `HEAD` 之外的所有操作都必须通过 [CORS 验证](#cors)
* `1.5.0` (2022-12-03):大于 128 GiB 的文件采用[新的块大小公式](https://github.com/9001/copyparty/commit/54e1c8d261df)
* **用户:** 如果你使用的是命令行上传器,请升级到最新的 [CLI 上传器](https://github.com/9001/copyparty/blob/hovudstraum/bin/u2c.py)
* **开发者:** 更新第三方的 up2k 客户端(如果存在的话)
# 常见问题解答
“经常”被问到的问题
* CopyParty?
* 不!名称是 copyparty(全小写)或 Copyparty —— 毕竟它是[一个单词](https://en.wiktionary.org/wiki/copyparty) :>
* 什么是 volflag?
* 按卷配置;许多(并非所有)全局选项可以设置为 volflags,并且大多数(并非所有)volflags 也可以设置为全局选项;[完整的 volflags 列表](https://copyparty.eu/cli/#flags-help-page)
* 什么是卷?
* 一个从 URL(`/music/`)到服务器本地文件系统上文件夹(`C:\Users\ed\Music`)的映射,随后可以通过 copyparty 访问它,具体取决于你在其上设置的权限和选项 —— 参见[账户和卷](#accounts-and-volumes)
* 我可以更改 🌲 旋转松树的加载动画吗?
* [可以的...](https://github.com/9001/copyparty/tree/hovudstraum/docs/rice#boring-loader-spinner) :-(
* 是否可以阻止对文件夹的读取访问,除非你知道其中某个特定文件的确切 URL?
* 是的,使用 [`g` 权限](#accounts-and-volumes),请参阅那里的示例
* 你也可以使用 Linux 文件系统权限来做到这一点;`chmod 111 music` 将使访问 `music` 文件夹内的文件和文件夹成为可能,但不能列出直接内容 —— 也适用于其他软件,不仅是 copyparty
* 我可以通过将密码包含在 URL 中来将他人链接到受密码保护的卷/文件吗?
* 是的,通过在末尾添加 `?pw=hunter2`;如果 URL 中已经包含参数(即末尾包含 `?`),则将 `?` 替换为 `&`
* 如果你启用了 `--usernames`,则请使用 `?pw=username:password`
* `?pw` 可以通过 `--pw-urlp=A` 禁用,但这会破坏对许多客户端的支持
* 如何阻止 `.hist` 文件夹在我的硬盘上到处出现?
* 默认情况下,会在每个卷内创建一个 `.hist` 文件夹,用于存放文件系统索引、缩略图、音频转码和 Markdown 文档历史记录。请使用 `--hist` 全局选项或 `hist` volflag 将其移动到其他位置;参见[数据库位置](#database-location)
* 如果我给 copyparty 一个 URL,它可以把文件下载到我的服务器上吗?
* 可以,使用[钩子](https://github.com/9001/copyparty/blob/hovudstraum/bin/hooks/wget.py)
* Firefox 拒绝通过 HTTPS 连接,提示 "Secure Connection Failed" 或 "SEC_ERROR_BAD_SIGNATURE",并且没有显示通常的 "Accept the Risk and Continue" 按钮
* Firefox 损坏了其证书存储;通过退出 Firefox,然后在你的 Firefox 配置文件文件夹中找到并删除名为 `cert9.db` 的文件来修复此问题
* 当我尝试访问网站时,服务器总是显示 `thank you for playing`
* 你因恶意流量而被封禁了!如果这属于误封,并且你运行了反向代理和/或类似 Cloudflare 的服务,请参阅 [Real-IP](#real-ip) 了解如何解决此问题
* 即使 是 HTTPS,copyparty 似乎也认为我正在使用 HTTP
* 你的反向代理没有发送 `X-Forwarded-Proto: https` 头;这可能是因为你的反向代理本身也感到困惑。确保没有任何中间件(例如 Cloudflare)在流量到达你的入口点之前终止了 HTTPS
* 缩略图坏了(你看到一个彩色的方块,上面写着文件类型)
* 你需要安装 `FFmpeg` 或 `Pillow`;参见[缩略图](#thumbnails)
* 缩略图坏了,特别是 iPhone 拍摄的照片和视频
* 由于[法律原因](docs/bad-codecs.md),[Docker 镜像](https://github.com/9001/copyparty/blob/hovudstraum/scripts/docker)和[可引导闪存盘](https://a.ocv.me/pub/stuff/edcd001/enterprise-edition/)无法读取 HEIF/HEIC 图像和 H265/HEVC 视频
* 缩略图坏了(出现了一些图像,但其他文件只显示一个空白框,和/或显示损坏的图像占位符)
* 可能是由于反向代理干扰了请求 URL 并剥离了查询参数(`?th=w`),因此请检查你的 URL 重写规则
* 也可能是由于反向代理和/或 CDN 中的缓存设置不正确,因此请确保未设置任何忽略查询字符串的配置
* 也可能是由于与隐私相关的浏览器扩展行为异常,因此请尝试禁用它们
* 我想学习 Python 和/或编程,并正在考虑在此之际看看 copyparty 的源代码
* _| _ __ _ _|_
(_| (_) | | (_) |_
# 账户和卷
按文件夹、按用户分配权限 - 如果你的设置变得越来越复杂,请考虑使用[配置文件](./docs/example.conf)而不是命令行参数
* 这样更容易管理,并且你可以在运行时使用 `systemctl reload copyparty` 修改配置,或者更方便地使用控制面板中的 `[reload cfg]` 按钮(如果用户在任何卷中拥有 `a`/admin 权限)
* 对 `[global]` 配置部分的更改需要重新启动才能生效
可以通过 [`--help-accounts`](https://copyparty.eu/cli/#accounts-help-page) 查看快速摘要
使用参数配置账户/卷:
* `-a usr:pwd` 添加用户名为 `usr`、密码为 `pwd` 的账户
* `-v .::r` 将当前文件夹 `.` 添加为 Web 根目录,任何人可`r`(只读)
* 语法是 `-v src:dst:perm:perm:...` 即本地路径、URL 路径以及一个或多个要设置的权限
* 将相同的权限授予多个账户:
`-v .::r,usr1,usr2:rw,usr3,usr4` = usr1/2 只读,usr3/4 读写
权限:
* `r` (读取):浏览文件夹内容、下载文件、作为 zip/tar 下载、查看文件密钥/目录密钥
* `w` (写入):上传文件、将文件移动/复制*到此*文件夹中
* `m` (移动):*从此*文件夹移动文件/文件夹
* `d` (删除):删除文件/文件夹
* `.` (点文件):用户可以请求在目录列表中显示点文件
* `g` (获取):只能下载文件,无法查看文件夹内容或 zip/tar
* `G` (上传获取):与 `g` 相同,但上传者可以看到自己的[文件密钥](#filekeys)(参见下面示例中的 `fk`)
* `h` (html):与 `g` 相同,但文件夹会返回其 index.html,并且 index.html 不需要文件密钥
* `a` (管理员):可以查看上传时间、上传者 IP、重新加载配置
* `A` ("全部"):等同于 `rwmda.`(读/写/移动/删除/管理员/点文件)
示例:
* 添加名为 u1、u2、u3 且密码为 p1、p2、p3 的账户: `-a u1:p1 -a u2:p2 -a u3:p3`
* 将文件夹 `/srv` 设为文件系统的根目录,任何人均可只读: `-v /srv::r`
* 将文件夹 `/mnt/music` 在 `/music` 路径下可用,u1 和 u2 只读,u3 读写: `-v /mnt/music:music:r,u1,u2:rw,u3`
* 未授权用户访问 Web 根目录时可以看到 `music` 文件夹存在,但无法打开它
* 将文件夹 `/mnt/incoming` 在 `/inc` 路径下可用,u1 仅可写,u2 可读可移动: `-v /mnt/incoming:inc:w,u1:rm,u2`
* 未授权用户访问 Web 根目录时可以看到 `inc` 文件夹存在,但无法打开它
* `u1` 可以打开 `inc` 文件夹,但无法查看内容,只能向其中上传新文件
* `u2` 可以浏览它并将文件从 `/inc` *移动到* `u2` 拥有写入权限的任何文件夹
* 将文件夹 `/mnt/ss` 在 `/i` 路径下可用,u1 读写,其他人仅可获取,并启用文件密钥: `-v /mnt/ss:i:rw,u1:g:c,fk=4`
* `c,fk=4` 将 `fk` ([文件密钥](#filekeys)) volflag 设置为 4,意味着每个文件获得一个 4 字符的访问密钥
* `u1` 可以上传文件、浏览文件夹并查看生成的文件密钥
* 其他用户无法浏览该文件夹,但如果他们拥有带有文件密钥的完整文件 URL,则可以访问文件
* 将 `g` 权限替换为 `wg` 将允许匿名用户上传文件,但看不到访问它所需的文件密钥
* 将 `g` 权限替换为 `wG` 将允许匿名用户上传文件,并作为回报收到可用的直接链接
如果你想向所有已登录的用户授予访问权限,`acct` 组将始终包含所有已知用户,例如 `-v /mnt/music:music:r,@acct`
* 执行相反操作,即向所有未登录的人授予访问权限。`*,-@acct` 可以做到这一点,例如 `-v /srv/welcome:welcome:r,*,-@acct`
* 也可以从组中减去单个用户: `@admins,-james`
任何尝试暴力破解密码的人都将根据 `--ban-pw` 规则被封禁;默认值为在 1 小时内失败 9 次则封禁 24 小时
如果你想使用配置文件而不是命令行参数(这很好!),这里有与上述示例相同的配置文件;将其保存为 `foobar.conf` 并像这样使用: `python copyparty-sfx.py -c foobar.conf`
* 你也可以使用 `PRTY_CONFIG=foobar.conf python copyparty-sfx.py`(在 Docker 等环境中很方便)
```
[accounts]
u1: p1 # create account "u1" with password "p1"
u2: p2 # (note that comments must have
u3: p3 # two spaces before the # sign)
[groups]
g1: u1, u2 # create a group
[/] # this URL will be mapped to...
/srv # ...this folder on the server filesystem
accs:
r: * # read-only for everyone, no account necessary
[/music] # create another volume at this URL,
/mnt/music # which is mapped to this folder
accs:
r: u1, u2 # only these accounts can read,
r: @g1 # (exactly the same, just with a group instead)
r: @acct # (alternatively, ALL users who are logged in)
rw: u3 # and only u3 can read-write
[/inc]
/mnt/incoming
accs:
w: u1 # u1 can upload but not see/download any files,
rm: u2 # u2 can browse + move files out of this volume
[/i]
/mnt/ss
accs:
rw: u1 # u1 can read-write,
g: * # everyone can access files if they know the URL
flags:
fk: 4 # each file URL will have a 4-character password
```
## 文件夹覆盖
通过在特定子文件夹上挂载另一个卷来隐藏它们
例如 `-v /mnt::r -v /var/empty:web/certs:`(注意:没有权限)将服务器文件夹 `/mnt` 挂载为 Web 根目录,但在 `/web/certs` 处挂载了另一个卷 —— 因此访问者只能看到 `/mnt` 和 `/mnt/web` 的内容(位于 URL `/` 和 `/web`),而看不到 `/mnt/web/certs`,因为 URL `/web/certs` 被映射到了 `/var/empty`
紧接着本节上面的示例配置文件可能会更好地解释这一点;第一个卷 `/` 被映射到 `/srv`,这意味着 http://127.0.0.1:3923/music 将尝试读取服务器文件系统上的 `/srv/music`,但由于 `/music` 处还有另一个映射到 `/mnt/music` 的卷,因此它会转到 `/mnt/music`
因此,要覆盖(隐藏)文件/文件夹,只需定义一个卷但省略 `accs:` 权限部分
## 点文件
Unix 风格的隐藏文件/文件夹,名称以点开头
如果知道名称,任何人都可以访问它们,但它们通常不会出现在目录列表中
如果指定了全局选项 `-ed`,或者卷具有 volflag `dots`,或者用户具有 `.` 权限,则客户端可以请求在目录列表中查看点文件
除非满足上述条件之一**并且**设置了全局选项 / volflag `dotsrch`,否则点文件不会出现在搜索结果中
配置文件示例,其中以两种不同的方式授予了相同的查看点文件权限,仅供参考:
```
[/foo]
/srv/foo
accs:
r.: ed # user "ed" has read-access + dot-access in this volume;
# dotfiles are visible in listings, but not in searches
flags:
dotsrch # dotfiles will now appear in search results too
dots # another way to let everyone see dotfiles in this vol
```
# 浏览器
使用网络浏览器访问 copyparty 服务器

## 选项卡
UI 中的主要选项卡
* `[🔎]` [搜索](#searching) 按大小、日期、路径/名称、mp3 标签...
* `[🧯]` [撤销上传](#unpost):撤销/删除意外上传
* `[🚀]` 和 `[🎈]` 是[上传工具](#uploading)
* `[📂]` mkdir:创建目录
* `[📝]` 新建文件:创建一个新的文本文件
* `[📟]` 发送消息:发送到服务器日志,或者如果设置了 `--urlform save` 则写入文本文件
* `[🎺]` 音频播放器配置选项
* `[⚙️]` 常规客户端配置选项
## 快捷键
浏览器具有以下快捷键(始终基于 QWERTY 键盘)
* `?` 显示快捷键帮助
* `B` 切换面包屑导航 / [导航窗格](#navpane)
* `I/K` 上一个/下一个文件夹
* `M` 父文件夹(或折叠当前文件夹)
* `V` 在导航窗格中切换文件夹 / 文本文件
* `G` 切换列表 / [网格视图](#thumbnails) —— 与右下角的 `田` 相同
* `T` 切换缩略图 / 图标
* `ESC` 关闭各种内容
* `ctrl-K` 删除选定的文件/文件夹
* `ctrl-X` 剪切选定的文件/文件夹
* `ctrl-C` 将选定的文件/文件夹复制到剪贴板
* `ctrl-V` 粘贴(移动/复制)
* `Y` 下载选定的文件
* `F2` [重命名](#batch-rename)选定的文件/文件夹
* 当文件/文件夹被选中时(在非网格视图中):
* `Up/Down` 移动光标
* shift+`Up/Down` 选择并移动光标
* ctrl+`Up/Down` 移动光标并滚动视口
* `Space` 切换文件选择
* `Ctrl-A` 切换全选
* 当文本文件打开时:
* `I/K` 上一个/下一个文本文件
* `S` 切换打开文件的选择状态
* `M` 关闭文本文件
* 播放音频时:
* `J/L` 上一首/下一首歌
* `U/O` 快退/快进 10 秒
* `0..9` 跳转到 0%..90%
* `P` 播放/暂停(也会开始播放当前文件夹)
* `Y` 下载文件
* 查看图像 / 播放视频时:
* `J/L, Left/Right` 上一个/下一个文件
* `Home/End` 第一个/最后一个文件
* `F` 切换全屏
* `S` 切换选择
* `R` 顺时针旋转(shift=逆时针)
* `Y` 下载文件
* `Esc` 关闭查看器
* 视频:
* `U/O` 快退/快进 10 秒
* `0..9` 跳转到 0%..90%
* `P/K/Space` 播放/暂停
* `M` 静音
* `C` 继续播放下一个视频
* `V` 循环整个文件
* `[` 循环范围(起点)
* `]` 循环范围(终点)
* 当导航窗格打开时:
* `A/D` 调整树宽度
* 在[网格视图](#thumbnails)中:
* `S` 切换多选
* shift+`A/D` 缩放
* 在 Markdown 编辑器中:
* `^s` 保存
* `^h` 标题
* `^k` 自动格式化表格
* `^u` 跳转到下一个 Unicode 字符
* `^e` 切换编辑器 / 预览
* `^up, ^down` 跳转段落
## 导航窗格
在面包屑导航和导航窗格之间切换
点击 `🌲` 或按 `B` 快捷键可在屑路径(默认)和导航窗格(树状浏览器侧边栏)之间切换
* `[+]` 和 `[-]`(或快捷键 `A`/`D`)调整大小
* `[🎯]` 跳转到当前打开的文件夹
* `[📃]` 切换显示文件夹和文本文件
* `[📌]` 在停靠面板中显示所有父文件夹的名称
* `[a]` 切换随着进入深层级自动加宽
* `[↵]` 切换自动换行
* `[👀]` 鼠标悬停时显示完整名称(如果自动换行已关闭)
## 缩略图
按 `g` 或 `田` 切换网格视图以代替文件列表,然后按 `t` 切换图标 / 缩略图
* 可以通过 `--grid` 全局设为默认,或者通过 volflag `grid` 按卷设置
* 通过在链接中添加 `?imgs` 启用,或使用 `?imgs=0` 禁用

它使用 Pillow / pyvips / FFmpeg 处理静态图像,并使用 FFmpeg 处理视频文件,因此你可能希望使用 `--no-thumb` 或者也许只用 `--no-vthumb`,具体取决于你的用户有多“危险”
* pyvips 比 Pillow 快 3 倍,Pillow 比 FFmpeg 快 3 倍
* 使用 volflag `dthumb` 禁用特定卷的所有缩略图,或使用 `dvthumb` / `dathumb` / `dithumb` 仅禁用视频/音频/图像
* 有关在 Windows 上安装 FFmpeg,请参见[可选依赖项](#optional-dependencies)
除非你使用了 `--no-athumb`,否则音频文件将使用 FFmpeg 转换为频谱图(某些 FFmpeg 构建版本可能需要 `--th-ff-swr`)
具有以下名称的图像(参见 `--th-covers`)将成为其所在文件夹的缩略图: `folder.png`、`folder.jpg`、`cover.png`、`cover.jpg`
* 顺序很重要,因此如果文件夹中同时存在 `cover.png` 和 `folder.jpg`,它将选择第一个匹配的 `--th-covers` 条目(`folder.jpg`)
* 并且,如果你启用了[文件索引](#file-indexing),它也会尝试将这些名称作为点文件(`.folder.jpg` 等)查找,然后回退到文件夹中的第一张图片(如果它包含任何图片)
启用 `multiselect` 后,你可以点击文件进行选择,然后按住 shift 键点击另一个文件进行范围选择
* `multiselect` 主要适用于手机/平板电脑,但 `[⚙️] settings` 选项卡中的 `sel` 选项更适合桌面使用,允许通过 CTRL 键点击进行选择,以及通过 SHIFT 键点击进行范围选择,这一切都不会影响常规点击
* 可以通过 `--gsel` 全局将 `sel` 选项设为默认,或通过 volflag `gsel` 按卷设置
要显示 `/icons/exe.png` 和 `/icons/elf.gif` 作为所有 `.exe` 和 `.elf` 文件的缩略图,请执行以下操作: `--ext-th=exe=/icons/exe.png --ext-th=elf=/icons/elf.gif`
* 也可以选择将每个映射作为单独的 volflags;参见下面的配置文件示例
* 支持的图像格式为 [jpg, png, gif, webp, ico](https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Formats/Image_types)
* 小心使用 svg;如果你在同一页面上显示过多不同的 svg 文件,Chrome 将会崩溃(限制约为 250 个)—— 然而,将少数几个相同的 svg 文件显示数千次是没问题的
注意:
* heif/heifs/heic/heics 图像通常需要 `libvips` [可选依赖](#optional-dependencies),但由于[法律原因](docs/bad-codecs.md),这在 Docker 镜像中无法实现
* 如果你不想动态生成缩略图,而是希望在服务器启动时生成所有缩略图,请参阅[缩略图预生成](#thumbnail-pregen)
配置文件示例:
```
[global]
no-thumb # disable ALL thumbnails and audio transcoding
no-vthumb # only disable video thumbnails
[/music]
/mnt/nas/music
accs:
r: * # everyone can read
flags:
dthumb # disable ALL thumbnails and audio transcoding
dvthumb # only disable video thumbnails
ext-th: exe=/ico/exe.png # /ico/exe.png is the thumbnail of *.exe
ext-th: elf=/ico/elf.gif # ...and /ico/elf.gif is used for *.elf
th-covers: folder.png,folder.jpg,cover.png,cover.jpg # the default
```
## ZIP 下载
将文件夹(或选定的文件)下载为 `zip` 或 `tar` 文件
在 `[⚙️] config` 选项卡中选择你想要的存档类型:
| 名称 | URL 后缀 | 描述 |
|--|--|--|
| `tar` | `?tar` | 普通 gnutar,配合 `curl \| tar -xv` 使用效果极佳 |
| `pax` | `?tar=pax` | pax 格式的 tar,面向未来,速度不够快 |
| `tgz` | `?tar=gz` | gzip 压缩的 gnu-tar(慢),用于 `curl \| tar -xvz` |
| `txz` | `?tar=xz` | 带有 xz / lzma 压缩的 gnu-tar(非常慢) |
| `zip` | `?zip` | 到处都能用,Win7 及更旧版本上的文件名会有乱码 |
| `zip_dos` | `?zip=dos` | 传统的 cp437(无 Unicode)修复文件名乱码 |
| `zip_crc` | `?zip=crc` | 提前计算 crc32 的 cp437,适用于真正古老的软件 |
* gzip 默认级别为 `3`(0=最快,9=最好),使用 `?tar=gz:9` 更改
* xz 默认级别为 `1`(0=最快,9=最好),使用 `?tar=xz:9` 更改
* bz2 默认级别为 `2`(1=最快,9=最好),使用 `?tar=bz2:9` 更改
* 隐藏文件([点文件](#dotfiles))会被排除,除非账户有权限列出它们
* `up2k.db` 和 `dir.txt` 始终被排除
* bsdtar 支持流式解压: `curl foo?zip | bsdtar -xv`
* 很好,因为 copyparty 的 zip 在处理小文件时比 tar 更快
* 但是 `?tar` 更适合大文件,特别是总大小超过 4 GiB 的情况
* `zip_crc` 下载会花费更长的时间,因为服务器必须读取每个文件两次
* 这仅为了支持 MS-DOS PKZIP v2.04g(1993 年 10 月)及更旧的版本
* 你实际上是怎么访问 copyparty 的
你也可以通过在浏览器中点击文件来将选定的文件或文件夹打包成 zip,这会在右下角弹出一个选择编辑器和 zip 按钮

很酷的技巧:通过在 URL 后追加参数 `?tar&opus` 或 `?tar&mp3` 下载文件夹,可在将所有音频文件(除 aac|m4a|mp3|ogg|opus|wma 外)添加到存档之前将其转码为 opus/mp3
* 非常有用,如果你距离起飞还有 5 分钟,才意识到手机上没有任何音乐,但你的服务器只有 flac 文件,下载这些文件会耗尽你所有的数据流量 + 而且根本没有足够的时间
* URL 参数 `&nodot` 会跳过点文件/点文件夹;如果你的账户有权限查看它们,默认情况下它们是包含在内的
* URL 参数 `&j` / `&w` 会生成 jpeg/webm 缩略图/频谱图,而不是原始的音频/视频/图像(`&p` 用于音频波形)
* 也可用于预生成缩略图;结合 `--th-maxage=9999999` 或 `--th-clean=0` 使用
* 不过现在也有真正的[缩略图预生成](#thumbnail-pregen)了,所以直接用那个就好
## 正在上传
将文件/文件夹拖入网页浏览器进行上传
拖放是推荐的方式,但你也可以:
* 在你的文件资源管理器中选择一些文件(不是文件夹),然后在浏览器窗口中按 CTRL-V
* 使用[命令行上传工具](https://github.com/9001/copyparty/tree/hovudstraum/bin#u2cpy)
* 使用 [curl、sharex、ishare...](#client-examples) 上传
通过拖放或 CTRL-V 上传文件时,会启动使用 `up2k` 的上传;浏览器中有两种可用的上传工具:
* `[🎈] bup`,基础版上传工具,支持自 Netscape 4.0 以来的几乎所有浏览器
* `[🚀] up2k`,那个优秀的 / 功能丰富的版本
注意:你可以使用 `[🧯]` [撤销上传](#unpost)来撤销/删除你自己的上传(这也是你中止未完成上传的地方,但你必须先刷新页面)
up2k 有几个优点:
* 你可以将文件夹拖入浏览器(文件会被递归添加)
* 文件按块处理,每个块都会进行校验和检查
* 如果上传被网络问题中断,会自动恢复
* 如果你重启了浏览器或电脑,只需再次上传相同的文件即可恢复上传
* 服务器检测到任何损坏;客户端重新上传受影响的块
* 客户端不会上传服务器上已存在的任何内容
* 没有文件大小限制,即使代理限制了请求大小(例如 Cloudflare)
* 在某些互联网连接(主要是美国的)上,由于并行连接,速度比 ftp/scp/tarpipe 快得多
* 文件的最后修改时间戳会被保留
有关其工作原理的详细信息,请参阅 [up2k](./docs/devnotes.md#up2k),或观看[演示视频](https://a.ocv.me/pub/demo/pics-vids/#gf-0f6f5c0d)

**温馨提示:** 你可以使用 [contrib/plugins/minimal-up2k.js](contrib/plugins/minimal-up2k.js) 避免吓跑用户,它会让界面看起来[简单得多](https://user-images.githubusercontent.com/241032/118311195-dd6ca380-b4ef-11eb-86f3-75a3ff2e1332.png)
**温馨提示:** 如果你在 `[⚙️] settings` 选项卡中启用了 `favicon`(通过在文本框中输入内容),浏览器选项卡中的图标将指示上传进度 —— 此外,`[🔔]` 和/或 `[🔊]` 开关可启用上传完成时的可见和/或声音通知
up2k 的 UI 是精致直观体验的缩影:
* “parallel uploads”指定同时上传多少个块
* `[🏃]` 在一个文件正在上传时继续分析其他文件
* `[🥔]` 显示更简单的 UI,便于从慢速设备进行更快的上传
* `[🛡️]` 决定何时覆盖服务器上的现有文件
* `🛡️` = 从不(改为生成一个新文件名)
* `🕒` = 如果服务器文件较旧则覆盖
* `♻️` = 如果文件不同则始终覆盖
* `[🎲]` 在上传期间生成随机文件名
* `[🔎]` 在上传和[文件搜索](#file-search)模式之间切换
* 如果你是通过将文件拖入浏览器来添加的,请忽略 `[🔎]`
然后是它下方的选项卡,
* `[ok]` 是成功完成的文件
* `[ng]` 是失败/被拒绝的文件(已存在,...)
* `[done]` 显示 `[ok]` 和 `[ng]` 的组合列表,按时间顺序排列
* `[busy]` 当前正在哈希处理、等待上传或正在上传的文件
* 加上来自 `[done]` 和 `[que]` 的各最多 3 个条目作为上下文
* `[que]` 是所有仍在排队等待的文件
请注意,由于 up2k 必须读取每个文件两次,因此在某些极端情况下(文件大于你的 RAM,加上互联网连接速度比你硬盘的读取速度快,或者如果你使用的是早期的双核处理器),`[🎈] bup` 在*理论上*最多可以快 2 倍
如果你正在恢复大规模上传并希望跳过已完成文件的哈希处理,你可以在 `[⚙️] config` 选项卡中启用 `turbo`,但请阅读该按钮上的工具提示
如果服务器位于强制限制请求大小的代理后面,你可以使用服务器选项 `--u2sz` 配置 up2k 以悄悄低于该限制(默认为 96 MiB,以支持 Cloudflare)
如果你想默认用新上传替换服务器上的现有文件,请使用 `--u2ow 2` 运行(仅在用户拥有删除权限时有效,并且仍然可以在 UI 中使用 `🛡️` 禁用)
### 文件搜索
将文件拖入浏览器还可以让你查看它们是否已存在于服务器上

当你将文件拖入/放到浏览器中时,你会看到两个放置区: `Upload` 和 `Search`
文件将在客户端进行哈希处理,每个哈希值被发送到服务器,由服务器检查该文件是否存在于某处
文件如果存在则进入 `[ok]`(并且你会得到一个指向其位置的链接),否则它们会落入 `[ng]`
* 将文件搜索与上传器结合的主要原因是代码太像意大利面条了,无法将其分离到其他地方,虽然现在已不再是这种情况,但我现在对这个想法已经热忱到无法自拔了
如果你有一个“wark”(文件标识符/校验和),你也可以在 [🔎] 选项卡的 `raw` 字段中输入 `w = kFpDiztbZc8Z1Lzi` 进行搜索
### 撤销上传
使用 UI 中的 `[🧯]` 选项卡撤销/删除意外上传

即使你没有常规的移动/删除权限,也可以撤销上传,但仅限于在过去 `--unpost` 秒内(默认为 12 小时)上传的文件,并且服务器必须运行有 `-e2d` 参数
配置文件示例:
```
[global]
e2d # enable up2k database (remember uploads)
unpost: 43200 # 12 hours (default)
```
### 定时删除
可以为上传设置生命周期,到期后它们将过期 / 定时销毁
该功能必须通过 `lifetime` [上传规则](#upload-rules)在每个卷上启用,它设置了文件在服务器上保留的最长时间上限
客户端可以使用 [up2k UI](#uploading) 指定更短的过期时间 —— 相关选项在导航到启用了 `lifetimes` 的文件夹时会变得可见 —— 或者通过使用 `life` [上传修饰符](./docs/devnotes.md#write)
在客户端指定自定义过期时间会影响允许撤销上传的时间跨度,因此请留意 up2k UI 中的估算值
### 边传边下
在文件仍在传输时即可开始下载([演示视频](http://a.ocv.me/pub/g/nerd-stuff/cpp/2024-0418-race-the-beam.webm)) —— 这几乎就像是点对点
要求文件使用 up2k 上传(这是默认的拖放上传器),或者命令行程序
### 传入的文件
控制面板显示所有传入文件的预计到达时间,但仅针对上传到你有读取权限的卷中的文件

## 文件管理器
剪切/粘贴、重命名和删除文件/文件夹(如果你有权限)
文件选择:点击该行上的某处(不是链接本身),然后:
* `空格键` 切换选择
* `上/下键` 移动
* `shift+上/下键` 移动并选择
* `ctrl-shift+上/下键` 同时滚动屏幕
* 按住 shift 键点击另一行进行范围选择
* 剪切:选择一些文件并按 `ctrl-x`
* 复制:选择一些文件并按 `ctrl-c`
* 粘贴:在另一个文件夹中按 `ctrl-v`
* 重命名:按 `F2`
你可以跨浏览器选项卡复制/移动文件(在一个选项卡中剪切/复制,在另一个选项卡中粘贴)
## 分享
通过创建临时链接来分享文件或文件夹
当在服务器设置中启用此功能(`--shr`)后,点击右下角的 `share` 按钮即可分享你当前所在的文件夹,或者:
* 先选择一个文件夹以分享该文件夹
* 选择一个或多个文件以仅分享这些文件
此功能的设计考虑了[身份提供商](#identity-providers) —— 配置你的反向代理以跳过 IdP 对给定 URL 前缀的访问控制,并使用它来安全地共享特定文件/文件夹,而无需常规的身份验证检查
创建分享时,创建者可以选择以下任意选项:
* 密码保护
* 在一定时间后过期; `0` 或留空表示无限期
* 允许访问者上传(如果创建分享的用户具有写入权限)
半有意为之的限制:
* 清理过期分享仅在设置了全局选项 `e2d` 和/或服务器上至少有一个卷具有 volflag `e2d` 时才起作用
* 仅共享来自同一卷的文件夹;如果你正在共享一个包含其他卷的文件夹,那么这些卷的内容将不可用
* 如果你在创建受密码保护的分享后更改了[密码哈希](#password-hashing)设置,那么该分享将停止工作
* 与[关闭时忘记 IdP 卷](https://github.com/9001/copyparty/blob/hovudstraum/docs/idp.md#idp-volumes-are-forgotten-on-shutdown)相关,任何指向用户 IdP 卷的分享在该用户于重启后发出第一次请求之前都将不可用
* 没有“首次访问后删除”选项,因为这很棘手
* 当将某些内容链接到 Discord(例如)时,它会被他们的抓取器访问,这会被算作一次命中
* 浏览器将无法恢复中断的下载,除非请求者的 IP 被加入允许名单 X 分钟(参考:棘手)
指定 `--shr /foobar` 以启用此功能;随后会创建一个名为 `foobar` 的顶级虚拟文件夹,所有的分享都将从那里提供
* 你可以随意命名,`foobar` 只是一个例子
* 如果你使用配置文件,请将 `shr: /foobar` 放入 `[global]` 部分
用户可以在控制面板中删除他们自己的分享,并且一组特权用户(`--shr-adm`)被允许查看和/或删除服务器上的任何分享
volflag `--shr-who` 允许你控制谁可以从该卷创建分享,可以是 `no`(没有人)、`a`(拥有管理员权限的人)或 `auth`(已登录的人)
分享过期后,它会在控制面板中保留 `--shr-rt` 分钟(默认为 1 天),所有者可以通过在那里延长过期时间来恢复它
**安全说明:** 使用此功能并不意味着你可以跳过[账户和卷](#accounts-and-volumes)章节 —— 你仍然需要限制对你不打算与未经验证的用户共享的卷的访问!仅在反向代理中使用规则限制对 `/share` 文件夹的访问是不够的。
## 批量重命名
选择一些文件并按 `F2` 调出重命名 UI
到启用尾部跟踪的文件
## markdown 查看器
并且有 *两个* 编辑器

内置了一个用于内联可点击缩略图的扩展;
* 在文档某处添加 `` 即可启用它
* 使用 `!th[l](your.jpg)` 添加缩略图,其中 `l` 表示左对齐(`r` = 右对齐)
* 单独一行带有 `---` 将清除浮动 / 内联
* 如果 README.md 显示在文件列表下方,缩略图将在画廊查看器中打开
其他注意事项,
* 文档预览具有最大宽度,与打印时的 A4 纸张宽度相同
### markdown 变量
具有服务器端变量扩展的动态文档,可将 `{{self.ip}}` 等内容替换为客户端的 IP,或将 `{{srv.htime}}` 替换为服务器上的当前时间
有关用法和示例,请参见 [./srv/expand/](./srv/expand/)
## 其他技巧
* 你可以通过在 URL 后面添加 `&20` / `&20s` / `&1m20` / `&t=1:20`(例如在 `.../#af-c8960dab` 之后)来链接到音频文件中的特定时间戳
* 启用音频均衡器有助于在某些浏览器中使无缝专辑实现真正的无缝播放,因此可以考虑将所有值保持为零并开启它
* 通过在 URL 中添加 `?ls=t` 来获取纯文本文件列表,或通过 `?ls=v` 获取紧凑的彩色列表(适用于 Unix 终端)
* 如果你正在使用媒体热键切换歌曲,并且已经厌倦了看到 Windows 不允许你禁用的 OSD 弹窗,可以考虑使用 [./contrib/media-osd-bgone.ps1](contrib/#media-osd-bgoneps1)
* 点击左下角的 `π` 可打开用于调试的 javascript 提示符
* 名为 `.prologue.html` / `.epilogue.html` 的文件将在目录列表之前/之后渲染,除非指定了 `--no-logues`
* 名为 `descript.ion` / `DESCRIPT.ION` 的文件将被解析并显示在文件列表中,如果不符合标准则作为尾声显示
* 名为 `README.md` / `readme.md` 的文件将在目录列表之后渲染,除非指定了 `--no-readme`(但 `.epilogue.html` 优先)
* 而 `PREADME.md` / `preadme.md` 将显示在目录列表上方,除非指定了 `--no-readme` 或存在 `.prologue.html`
* `README.md` 和 `*logue.html` 可以包含在嵌入到目录列表之前由服务器端替换的占位符值;请参见 [`--help-exp`](https://copyparty.eu/cli/#exp-help-page)
## 搜索
按大小、日期、路径/名称、mp3 标签等进行搜索……

当使用 `-e2dsa` 启动时,copyparty 将扫描/索引你的所有文件。这可以避免在上传时出现重复,同时也使得这些卷可以通过 Web UI 进行搜索:
* 通过 `size`/`date`/`directory-path`/`filename` 进行搜索查询,或者……
* 拖放一个本地文件以查看服务器上的某个位置是否存在相同的内容,请参见 [文件搜索](#file-search)
路径/名称查询以空格分隔,通过 AND 逻辑组合,使用 `-` 前缀来否定词语,例如:
* 路径:`shibayan -bossa` 会找到所有包含 `shibayan` 文件夹的文件,但会过滤掉路径中任何存在 `bossa` 的结果
* 名称:`demetori styx` 会为你提供 [好东西](https://www.youtube.com/watch?v=zGh0g14ZJ8I&list=PL3A147BD151EE5218&index=9)
`raw` 字段允许更复杂的操作,例如 `( tags like *nhato* or tags like *taishi* ) and ( not tags like *nhato* or not tags like *taishi* )`,它会找到所有由 nhato 或 taishi 制作的歌曲,排除合作作品(糟糕的例子,你为什么要这么做)
为了使上述示例生效,请添加命令行参数 `-e2ts` 以同时扫描/索引音乐文件中的标签,这就引出了下一个话题:
# 服务器配置
使用参数或配置文件,或者两者混合使用:
* 配置文件(`-c some.conf`)可以设置额外的命令行参数;请参见 [./docs/example.conf](docs/example.conf) 和 [./docs/example2.conf](docs/example2.conf)
* `kill -s USR1`(等同于 `systemctl reload copyparty`)可从配置文件重新加载账户和卷,而无需重启
* 或者,如果用户在任何卷中拥有 `a`/管理员 权限,可以点击控制面板中的 `[reload cfg]` 按钮
* 对 `[global]` 配置部分的更改需要重启才能生效
**注意:** 尽管这个 README 如此庞大,但仍有许多未记录的功能。运行 copyparty 并加上 [`--help`](https://copyparty.eu/cli/)(或点击该链接)以查看所有可用的全局选项;所有这些选项都可以在配置文件的 `[global]` 部分使用,而在 [`--help-flags`](https://copyparty.eu/cli/#flags-help-page) 中列出的所有内容都可以作为卷中的 volflags(每卷配置)使用。
* 如果在 docker/podman 中运行,请尝试:`docker run --rm -it copyparty/ac --help`
* 或者,如果你更喜欢纯文本,请访问 https://copyparty.eu/helptext.txt
## 版本检查器
通过让 copyparty 定期检查你的版本是否存在[已知漏洞](https://github.com/9001/copyparty/security/advisories),晚上可以睡得更安心
可以通过将全局选项 `--vc-url` 设置为以下 URL 之一来启用此功能;所有这些 URL 都提供相同的信息,因此选择哪一个都可以
* `https://api.copyparty.eu/advisories`
* `https://api.github.com/repos/9001/copyparty/security-advisories?per_page=9`
还可以考虑以下选项:
* 全局选项 `--vc-age` 是检查该 URL 的频率(以小时为单位);默认为 3
* 可以启用全局选项 `--vc-exit` 以便在检测到漏洞时立即恐慌并退出
* 如果未启用 `--vc-exit`,它只会在控制面板上为所有拥有权限 `a` 或 `A` 的用户显示警告
配置文件示例:
```
[global]
vc-url: https://api.copyparty.eu/advisories
vc-age: 3 # how many hours to wait between each check
vc-exit # emergency-exit if current version is vulnerable
```
## 日志记录
服务器日志默认发送到标准输出(但也可以记录到文件)
"stdout" 通常意味着终端,或者是 journalctl,或者是任何从你的 docker 容器收集日志的组件,因此这取决于你的设置
* [-q](https://copyparty.eu/cli/#g-q) 禁用记录到 stdout,并可能稍微提高性能
* 将其与 `-lo logfolder/cpp-%Y-%m-%d.txt` 结合使用以改为记录到文件
* `%Y-%m-%d` 会使它每天创建一个新的日志文件,并以日期作为文件名
* 全局选项 [--rlo](https://copyparty.eu/cli/#rlo-help-page) 决定了如果文件名已被占用会发生什么
* `-lo whatever.txt` 可以在不使用 `-q` 的情况下使用,以便同时记录到两者
* 默认情况下,如果终端支持(通常是这种情况),日志文件将带有颜色
* 使用 [文本文件查看器](https://github.com/user-attachments/assets/8a828947-2fae-4df9-bd2a-3de46f42d478) 或终端中的 `less -R` 来正确查看颜色
* 如果你不想要[颜色](https://youtu.be/biW5UVGkPMA?t=148):
* `--flo 2` 仅禁用日志文件的颜色
* `--no-ansi` 同时禁用终端和日志文件的颜色
配置文件示例:
```
[global]
log-date: %Y-%m-%d # show dates on stdout too
lo: /var/log/cpp/%Y-%m-%d.txt # logfile path
flo: 2 # just text (no colors) in logfile
q # disable stdout; use logfile only
```
## zeroconf
在局域网上 announce 已启用的服务([图片](https://user-images.githubusercontent.com/241032/215344737-0eae8d98-9496-4256-9aa8-cd2f6971810d.png)) —— `-z` 同时启用 [mdns](#mdns) 和 [ssdp](#ssdp)
* `--z-on` / `--z-off` 将此功能限制在某些网络中
配置文件示例:
```
[global]
z # enable all zeroconf features (mdns, ssdp)
zm # only enables mdns (does nothing since we already have z)
z-on: 192.168.0.0/16, 10.1.2.0/24 # restrict to certain subnets
```
### mdns
局域网域名和功能 announcer
使用 [multicast dns](https://en.wikipedia.org/wiki/Multicast_DNS) 为 copyparty 提供一个域名,局域网上的任何机器都可以使用该域名访问它
所有已启用的服务([webdav](#webdav-server)、[ftp](#ftp-server)、[smb](#smb-server))都将出现在支持 mDNS 的文件管理器中(KDE、gnome、macOS 等)
如果机器的主机名是 `partybox`,那么域名将是 `partybox.local`,除非 `--name` 指定了其他内容
并且 Web UI 将在 http://partybox.local:3923/ 上可用
* 如果你想去掉 `:3923` 以便可以使用 http://partybox.local/ 代替,请参见[监听 80 和 443 端口](#listen-on-port-80-and-443)
### ssdp
Windows 资源管理器 announcer
使用 [ssdp](https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol) 使 copyparty 出现在局域网上所有机器的 Windows 文件资源管理器中
双击该图标会打开“连接”页面,其中解释了如何将 copyparty 挂载为本地文件系统
如果 copyparty 没有出现在 Windows 资源管理器中,请使用 `--zsv` 查看原因:
* 可能是发现多播发送自一个与服务器子网不相交的 IP
## qr 码
打印一个 qr 码[(截图)](https://user-images.githubusercontent.com/241032/194728533-6f00849b-c6ac-43c6-9359-83e454d11e00.png)以便快速访问,非常适合在不断更改子网的 Android 热点上的手机之间使用
* `--qr` 启用它
* `--qrs` 使用 https 而不是 http
* `--qrl lootbox/?pw=hunter2` 附加到 URL,链接到带有密码 `hunter2` 的 `lootbox` 文件夹
* `--qrz 1` 强制使用 1 倍缩放,而不是自动缩放以适应终端大小
* 1 倍缩放可能会在某些终端/字体上渲染不正确,但 2 倍缩放应该总是可以正常工作
* `--qr-pin 1` 使 qr 码固定在控制台底部(永远不会滚动消失)
* `--qr-file qr.txt:1:2` 将一个小 qr 码写入 `qr.txt`
* `--qr-file qr.txt:2:2` 将一个大 qr 码写入 `qr.txt`
* `--qr-file qr.svg:1:2` 将一个矢量图形 qr 码写入 `qr.svg`
* `--qr-file qr.png:8:4:333333:ffcc55` 写入一个放大 8 倍的黄底灰字 `qr.png`
* `--qr-file qr.png:8:4::ffffff` 写入一个放大 8 倍的透明底白字 `qr.png`
如果启用了 [mdns](#mdns),它会使用服务器主机名,否则将使用你的外部 IP(默认路由),除非 `--qri` 指定了特定的 IP 前缀或域
## ftp 服务器
可以使用 `--ftp 3921` 启动 FTP 服务器,和/或使用 `--ftps` 进行显式 TLS (ftpes)
* 基于 [pyftpdlib](https://github.com/giampaolo/pyftpdlib)
* 需要专用端口(不能与 HTTP/HTTPS API 共享)
* 上传不可恢复 —— 如有必要请删除并重新开始
* 默认以主动模式运行,你可能需要 `--ftp-pr 12000-13000`
* 如果同时启用了 `ftp` 和 `ftps`,端口范围将被对半划分
* 某些较旧的软件(Debian 稳定版上的 FileZilla)无法在 TLS 下使用被动模式
* 使用任何用户名 + 你的密码登录,或将密码放在用户名字段中
* 除非你启用了 `--usernames`
一些推荐的 FTP / FTPS 客户端;`wark` = 示例密码:
* https://winscp.net/eng/download.php
* https://filezilla-project.org/ 在主动模式下使用 ftps 有点吃力,但其他方面没问题
* https://rclone.org/ 使用 `tls=false explicit_tls=true` 进行 FTPS
* `lftp -u k,wark -p 3921 127.0.0.1 -e ls`
* `lftp -u k,wark -p 399 127.0.0.1 -e 'set ssl:verify-certificate no; ls'`
* `curl ftp://127.0.0.1:3921/`(明文 ftp)
* `curl --ssl-reqd ftp://127.0.0.1:3990/`(加密 ftps)
配置文件示例,将 FTP 限制为仅使用端口 3921 和 12000-12099,因此必须在防火墙中打开所有这些端口:
```
[global]
ftp: 3921
ftp-pr: 12000-12099
```
## sftp 服务器
传输速度大约为 700 MiB/s(比 webdav 和 ftp 慢)
sftp 服务器需要可选依赖项 [paramiko](https://pypi.org/project/paramiko/);
* 如果你**没有**使用 docker,请以某种方式安装 paramiko
* 如果你**正在**使用 docker,请使用以下镜像变体之一:`ac` / `im` / `iv` / `dj`
使用 `--sftp 3922` 启用 sftpd 以监听端口 3922;
* 使用全局选项 `sftp-key` 将 ssh 密钥与用户关联;
* 命令行:`--sftp-key 'david ssh-ed25519 AAAAC3NzaC...'`
* 配置文件:`sftp-key: david ssh-ed25519 AAAAC3NzaC...`
* `--sftp-pw` 允许使用密码登录(默认仅限 ssh 密钥)
* `--sftp-anon foo` 允许使用用户名 `foo` 且无需密码登录;提供与未登录时网站相同的访问权限/权限
有关其他选项,请参见 [--help 中的 sftp 部分](https://copyparty.eu/cli/#g-sftp)
## webdav 服务器
支持读写,支持 winXP 及更高版本、macOS、nautilus/gvfs ……这是[直接从操作系统的文件资源管理器访问 copyparty](#mount-as-drive) 的绝佳方式
点击控制面板中的[连接](http://127.0.0.1:3923/?hc)按钮,查看 Windows、Linux、macOS 的连接说明
一般用法:
* 使用任何用户名 + 你的密码登录,或将密码放在用户名字段中(密码字段可以为空/任意填写)
* 除非你启用了 `--usernames`
在 macOS 上,从 Finder 连接:
* [前往] -> [连接到服务器...] -> http://192.168.123.1:3923/
为了能够编辑现有文件,客户端必须具有删除权限,并且某些 webdav 客户端还需要 [daw](https://copyparty.eu/cli/#g-daw) 卷标志或全局选项(如果客户端发送 `x-oc-mtime` 标头则不需要)。没有 `daw`,这些客户端将无法修改现有文件,而是创建名称类似于 `notes.txt-1771978661.726032-3i9GPghL.txt` 的新副本。**注意:** 启用 `daw` 还将使用户在具有删除访问权限的情况下覆盖现有文件的所有 PUT 上传,因此请谨慎使用。另一种替代方案是 [dav-port](https://copyparty.eu/cli/#g-dav-port) 选项
### 从 Windows 连接到 webdav
使用图形界面(WinXP 或更高版本):
* 右键点击 [我的电脑] -> [映射网络驱动器] -> 文件夹:`http://192.168.123.1:3923/`
* 仅在 winXP 上,请改为点击 `Sign up for online storage` 超链接并将 URL 放在那里
* 建议将你的密码作为用户名提供;密码字段可以是任意内容或为空
* 除非你启用了 `--usernames`
Windows 内置的 webdav 客户端存在以下错误列表;你可以通过使用 rclone 连接来避免所有这些问题:
* win7+ 在重启后重新认证时实际上并不会将密码发送到服务器,除非你首先尝试使用错误的密码登录,然后再切换到正确的密码
* 或者直接将你的密码输入到用户名字段中以完全绕过它
* 连接到允许匿名读取的文件夹将使写入变得不可能,因为 Windows 决定不需要登录
* 解决方法:连接两次;首先连接到一个需要认证的文件夹,然后连接到你实际想要的文件夹,并保持这两个都已挂载
* 或者设置服务器选项 `--dav-auth` 以强制所有 webdav 客户端进行密码认证
* win7+ 可能会为每个文件打开一个新的 TCP 连接,有时会忘记关闭它们,最终需要重启
* 可能与 NIC 相关 (??),在 win10-ltsc 上使用 e1000e 会出现此问题,但使用 virtio 则不会
* Windows 无法访问包含无效 unicode 或禁止字符(`<>:"/\|?*`)的文件名,或以 `.` 结尾的文件名的文件夹
* winXP 无法显示超出*某些范围*的 unicode 字符
* Latin-1 正常,平假名则不行(即使在日文 XP 上作为 shift-jis 也不行)
## tftp 服务器
可以使用 `--tftp 3969` 启动 TFTP 服务器(读/写)(除非你*真的*在与 90 年代的硬件通信,否则你可能更想使用 [ftp](#ftp-server)(如果是这样的话,我们绝对应该一起玩玩))
* 基于 [partftpy](https://github.com/9001/partftpy)
* 无账户;从全局可读文件夹读取,写入全局可写文件夹,覆盖全局可删除文件夹
* 需要专用端口(不能与 HTTP/HTTPS API 共享)
* 以 root 身份运行(或见下文)以使用规范推荐的端口 `69`(不错)
* 可以从预定义的端口范围回复(有利于防火墙)
* 仅支持 binary/octet/image 传输模式(不支持 netascii)
* **不**支持 [RFC 7440](https://datatracker.ietf.org/doc/html/rfc7440),因此在广域网上会极其缓慢
* 假设默认 blksize (512),在 100BASE-T 上预计 1100 KiB/s,在 wifi 上 400-500 KiB/s,在差的 wifi 上 200
大多数客户端期望在端口 69 上找到 TFTP,但在 Linux 和 macOS 上你需要以 root 身份监听该端口。或者,监听 3969 并在服务器上使用 NAT 将 69 转发到该端口;
* 在 Linux 上:`iptables -t nat -A PREROUTING -i eth0 -p udp --dport 69 -j REDIRECT --to-port 3969`
一些推荐的 TFTP 客户端:
* curl(跨平台,读/写)
* get:`curl --tftp-blksize 1428 tftp://127.0.0.1:3969/firmware.bin`
* put:`curl --tftp-blksize 1428 -T firmware.bin tftp://127.0.0.1:3969/`
* Windows:`tftp.exe`(你可能已经有了)
* `tftp -i 127.0.0.1 put firmware.bin`
* Linux:`tftp-hpa`、`atftp`
* `atftp --option "blksize 1428" 127.0.0.1 3969 -p -l firmware.bin -r firmware.bin`
* `tftp -v -m binary 127.0.0.1 3969 -c put firmware.bin`
## smb 服务器
不安全,速度慢,不推荐用于广域网,使用 `--smb` 启用只读或使用 `--smbw` 启用读写
点击控制面板中的[连接](http://127.0.0.1:3923/?hc)按钮,查看 Windows、Linux、macOS 的连接说明
依赖项:`python3 -m pip install --user -U impacket==0.13.0`
* 更新版本的 impacket 希望能正常工作,但由于使用了 monkeypatching,也许不行
一些针对 SMB/CIFS 的**重大警告**,按重要性递减排序:
* 不能完全确信只读就是只读
* smb 后端未完全与 vfs 集成,这意味着可能存在安全问题(路径遍历)。请使用 `--smb-port`(见下文)和 [prisonparty](./bin/prisonparty.sh) 或 [bubbleparty](./bin/bubbleparty.sh)
* 账户密码按预期在每个卷上工作,账户权限(读/写/移动/删除)也是如此,但必须提供 `--smbw` 才能允许从 smb 写入
* [shadowing](#shadowing) 可能按预期工作,但不做保证
* 与 pw-hashing 或 `--usernames` 不兼容
以及一些小问题,
* 客户端只能看到大文件夹中的前约 400 个文件;
* 这最初是由于 [impacket#1433](https://github.com/SecureAuthCorp/impacket/issues/1433) 引起的,该问题已在 impacket-0.12 中修复,因此你可以使用 `--smb-nwa-1` 禁用此变通方法,但这样你会得到无法接受的糟糕性能
* 服务器配置的热重载(`/?reload=cfg`)不包括 `[global]` 部分(命令行参数)
* 仅监听第一个 IPv4 `-i` 接口(默认 = :: = 0.0.0.0 = 全部)
* 登录在 winXP 上不起作用,但匿名访问是可以的 —— 删除 copyparty 配置中的所有账户即可实现此目的
* win10 及更高版本不允许匿名/无账户连接
* 仅支持 python3
* 速度慢(Windows 内置的 webdav 支持快 5 倍,而 rclone-webdav 快 30 倍)
* 这些数字专门针对 copyparty 的 smb-server(因为它很糟糕);其他 smb-servers 应该与 webdav 类似
已知客户端错误:
* 仅在 win7 上,`--smb1` 比 smb2(默认)快得多,因为它会在 smb2 上不断重新扫描文件夹
* 然而 smb1 存在错误,并且在 win10 及更高版本上默认未启用
* Windows 无法访问包含无效 unicode 或禁止字符(`<>:"/\|?*`)的文件名,或以 `.` 结尾的文件名的文件夹
smb 协议监听 TCP 端口 445,这是 Linux 和 macOS 上的特权端口,这将需要以 root 身份运行 copyparty。然而,可以通过使用 `--smb-port 3945` 在另一个端口上监听,然后在服务器上使用 NAT 将流量从 445 转发到那里来避免这种情况;
* 在 Linux 上:`iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 445 -j REDIRECT --to-port 3945`
使用以下之一进行认证:
* 用户名 `$username`,密码 `$password`
* 用户名 `$password`,密码 `k`
## 浏览器用户体验
调整用户界面
* 使用 `--sort` 全局设置默认排序顺序,或使用 `sort` 卷标志按卷设置;指定一个或多个以逗号分隔的列进行排序,并在列名前加上 `-` 以进行反向排序
* 你可以使用的列名在将鼠标悬停在目录列表中的列标题上时会作为工具提示显示,例如 `href ext sz ts tags/.up_at tags/Circle tags/.tn tags/Artist tags/Title`
* 要按音乐顺序(专辑、曲目、艺术家、标题)排序并以文件名作为后备,你可以使用 `--sort tags/Circle,tags/.tn,tags/Artist,tags/Title,href`
* 要按上传日期排序,首先使用 `-e2d -mte +.up_at` 在列表中启用显示上传日期,然后使用 `--sort tags/.up_at`
有关更多信息,请参见 [./docs/rice](./docs/rice),包括:
* 如何[隐藏 UI 元素](./docs/rice/README.md#hide-ui-elements)
* [自定义字体](./docs/rice/README.md#custom-fonts)
* [自定义加载动画](./docs/rice/README.md#boring-loader-spinner)
* 将内容(css/`
`/...)[添加到 html `` 标签](./docs/rice/README.md#head)
* [添加你自己的翻译](./docs/rice/README.md#translations)
## opengraph
Discord 和社交媒体嵌入
可以使用 `--og` 全局启用,或使用卷标志 `og` 按卷启用
请注意,这会禁用盗链,因为 opengraph 规范要求如此;要绕过此 intentional 限制,你可以按用户代理选择性地启用 opengraph,例如 `--og-ua '(Discord|Twitter|Slack)bot'`(或卷标志 `og_ua`)
你也可以通过在 URL 后附加 `?raw` 来盗链文件
如果你想用自己的 jinja2 模板完全替换 copyparty 的响应,请将模板文件路径提供给 `--og-tpl` 或卷标志 `og_tpl`(可以通过 `this` 对象获取 `HttpCli` 的所有成员)
## 文件去重
使用 `--dedup` 全局启用基于符号链接的上传去重,或使用卷标志 `dedup` 按卷启用
默认情况下,当有人尝试上传服务器上已存在的文件时,上传将被礼貌地,并且服务器会将现有文件复制到上传应该去的位置
如果你使用 `--dedup` 启用去重,它将创建一个符号链接而不是完整的副本,从而减少磁盘空间的使用
* 相反,如果你的服务器连接到了 s3-glacier 或类似的读取成本很高的存储,并且你不能使用 `--safe-dedup=1` 因为有其他软件在篡改你的文件,所以你想完全禁用重复数据检测,那么你可以全局指定 `--no-clone` 或将 `noclone` 作为卷标志
**警告:** 启用去重时,你还应该:
* 使用 `-e2dsa` 或卷标志 `e2dsa` 启用索引(见下文的[文件索引](#file-indexing)部分);强烈推荐
* ……和/或 `--hardlink-only` 以使用基于硬链接的去重而不是符号链接;见下文解释
* ……和/或 `--reflink` 以使用 CoW/reflink 去重(比硬链接安全得多,但取决于操作系统/文件系统)
如果你只启用去重而不启用上述任何一项,重命名/删除文件将是不安全的;如果你启用了索引,那么就没有*必要*同时进行硬链接(但你可能仍然想要这样做)
默认情况下,去重是基于符号链接(软链接)完成的;这些是指向文件最近完整副本的小文件
你可以选择使用硬链接而不是软链接,全局使用 `--hardlink-only` 或卷标志 `hardlinkonly`,并且你可以选择使用 `--reflink` 或卷标志 `reflink` 来使用 reflinks
使用 reflinks (CoW, 写入时复制) 的优点:
* 完全安全(当你的文件系统正确支持时);任何一个文件都可以被编辑或删除,而不影响其他副本
* 仅限 Linux 5.3 或更高版本,仅限 Python 3.14 或更高版本,仅限某些文件系统(btrfs 可能没问题,xfs 也许也可以,但 zfs 有错误)
使用硬链接的优点:
* 硬链接与其他软件的兼容性更好;它们的行为完全像常规文件
* 你可以使用其他文件管理器安全地移动和重命名文件
* 符号链接需要由 copyparty 管理,以确保目标保持正确
使用符号链接(默认)的优点:
* 每个符号链接都可以有自己的最后修改时间戳,但单个时间戳由所有硬链接共享
* 符号链接使其他软件更明显地看出该文件不是常规文件,因此这可能不太危险
* 硬链接看起来像常规文件,因此其他软件可能会认为可以安全编辑它们而不影响其他副本
**警告:** 如果你编辑了去重文件的内容,那么你也将编辑该文件的所有其他副本!使用硬链接时这尤其令人惊讶,因为它们看起来像常规文件,但同一个文件存在于多个位置
全局选项 `--xlink` / 卷标志 `xlink` 额外启用了跨卷去重,但这可能存在错误,不推荐使用
配置文件示例:
```
[global]
e2dsa # scan and index filesystem on startup
dedup # symlink-based deduplication for all volumes
[/media]
/mnt/nas/media
flags:
hardlinkonly # this vol does hardlinks instead of symlinks
```
## 文件索引
启用音乐搜索、撤销上传和更好的去重
文件索引依赖于两个数据库表:up2k 文件树(`-e2d`)和元数据标签(`-e2t`),存储在 `.hist/up2k.db` 中。可以通过参数、卷标志或两者混合进行配置。
通过参数:
* `-e2d` 在上传时启用文件索引
* `-e2ds` 也会在启动时扫描可写文件夹以查找新文件
* `-e2dsa` 也会扫描所有挂载的卷(包括只读卷)
* `-e2t` 在上传时启用元数据索引
* `-e2ts` 也会扫描所有尚无标签的文件中的标签
* `-e2tsr` 也会删除所有现有标签,进行完整的重新索引
* `-e2v` 在启动时通过比较数据库中的哈希值来验证文件完整性
* `-e2vu` 使用文件系统中的新哈希值修补数据库
* `-e2vp` 恐慌并杀死 copyparty 作为替代
相同的参数也可以设置为卷标志,此外还有 `d2d`、`d2ds`、`d2t`、`d2ts`、`d2v` 用于禁用:
* `-v ~/music::r:c,e2ds,e2tsr` 会在启动时对所有内容进行完整的重新索引
* `-v ~/music::r:c,d2d` 禁用**所有**索引,即使启用了任何 `-e2*`
* `-v ~/music::r:c,d2t` 禁用所有 `-e2t*`(标签),不影响 `-e2d*`
* `-v ~/music::r:c,d2ds` 禁用启动时扫描;仅索引新上传
* `-v ~/music::r:c,d2ts` 相同,仅影响标签
注意:
* 上传时间可以通过启用 `.up_at` 元数据键在文件列表中显示,全局使用 `-e2d -mte +.up_at` 或按卷使用卷标志 `e2d,mte=+.up_at`(对目录列表性能有约 17% 的影响)
* 并且可以使用全局选项 `-e2d -mte +w` 或卷标志 `e2d,mte=+w` 显示文件校验和(对于拥有 `a` 权限的用户始终激活)
* `e2tsr` 可能总是过于小题大做,因为 `e2ds`/`e2dsa` 会捕获任何文件修改,而 `e2ts` 随后会重新索引这些文件,除非是有新版本的 copyparty 带来了新的解析器,并且发布说明另有指示
配置文件示例(顺便说一下,推荐这些选项):
```
[global]
e2dsa # scan and index all files in all volumes on startup
e2ts # check newly-discovered or uploaded files for media tags
```
### 排除模式
为了节省时间,你可以提供一个正则表达式模式用于文件路径,以便仅按文件名/路径/大小/最后修改时间进行索引(而不是文件内容的哈希值),方法是设置 `--no-hash '\.iso$'` 或卷标志 `:c,nohash=\.iso$`,这会带来以下后果:
* 初始索引速度快得多,尤其是当卷位于网络磁盘上时
* 使得无法进行[文件搜索](#file-search)
* 如果有人上传相同的文件内容,上传将不会被检测为重复,因此它不会被符号链接或拒绝
类似地,你可以使用 `--no-idx [...]` 和 `:c,noidx=\.iso$` 完全忽略文件/文件夹
注意:`no-idx` 和/或 `no-hash` 会阻止这些文件的重复数据删除
* 在 macOS 上运行时,所有常见的 Apple 元数据文件默认被排除
如果你全局设置了 `--no-hash [...]`,你可以使用标志 `:c,nohash=` 为特定卷启用哈希
要从搜索结果中排除某些文件路径,请使用 `--srch-excl` 或卷标志 `srch_excl` 而不是 `--no-idx`,例如 `--srch-excl 'password|logs/[0-9]'`
配置文件示例:
```
[/games]
/mnt/nas/games
flags:
noidx: \.iso$ # skip indexing iso-files
srch_excl: password|logs/[0-9] # filter search results
```
### 文件系统防护
使用 `--xdev` / 卷标志 `:c,xdev` 避免遍历到其他文件系统,例如跳过任何指向另一个硬盘的符号链接或绑定挂载
和/或你可以使用 `--xvol` / `:c,xvol` 忽略所有离开卷顶级目录的符号链接,但仍允许指向其他位置的绑定挂载
* 如果符号链接指向用户具有相同访问权限级别的另一个卷,则允许使用 `xvol` 的符号链接
这些选项会降低性能;最坏情况下的估计是目录列表减少 14%,以 tar 格式下载减少 35%
从 copyparty v1.7.0 开始,这些选项还会阻止在运行时访问文件——在以前的版本中,它只是索引器的提示
### 定期重新扫描
文件系统监控;如果 copyparty 不是唯一在你的文件系统上执行操作的软件,你可能需要启用定期重新扫描以保持索引最新
参数 `--re-maxage 60` 将每 60 秒重新扫描所有卷,与按卷指定的卷标志 `:c,scan=60` 相同
在进行重新扫描时上传会被禁用,因此当有写入活动(上传、重命名等)发生时,重新扫描将延迟 `--db-act`(默认 10 秒)
注意:文件夹缩略图是在文件系统索引期间选择的,因此随着图像的上传/删除,可以使用定期重新扫描来保持它们的准确性(或者使用控制面板中的 `reload` 按钮手动进行重新扫描)
配置文件示例:
```
[global]
re-maxage: 3600
[/pics]
/mnt/nas/pics
flags:
scan: 900
```
## 上传规则
使用卷标志设置上传规则,以下是一些示例:
* `:c,sz=1k-3m` 设置允许的文件大小在 1 KiB 到 3 MiB 之间(包括边界)(后缀:`b`、`k`、`m`、`g`)
* `:c,df=4g` 如果剩余磁盘空间不足 4 GiB,则阻止上传
* `:c,vmaxb=1g` 如果卷总大小将超过 1 GiB,则阻止上传
* `:c,vmaxn=4k` 如果卷将包含超过 4096 个文件,则阻止上传
* `:c,nosub` 禁止上传到子目录;与 `rotn` 和 `rotf` 配合良好:
* `:c,rotn=1000,2` 将上传移动到子文件夹中,每个文件夹最多容纳 1000 个文件,然后创建一个新文件夹,深度为两层(必须至少为 1)
* `:c,rotf=%Y/%m/%d/%H` 强制文件按照该日期格式上传到子文件夹结构中
* `:c,rotf_tz=Europe/Oslo` 设置时区(默认为 UTC,除非更改了全局选项 `rotf-tz`)
* 如果有人上传到 `/foo/bar`,路径将被重写为 `/foo/bar/2021/08/06/23`,例如
* 但实际值并未验证,只验证结构,因此上传者可以选择任何符合格式字符串的值
* 只是为了避免增加 up2k 的复杂性,它已经够乱了
* `:c,lifetime=300` 当上传的文件满 5 分钟后将其删除
你还可以设置适用于每个 IP 和每个卷的事务限制,但这些限制假设使用 `-j 1`(默认),否则限制将会被打乱,例如 `-j 4` 将允许在你设置的限制的 1 倍到 4 倍之间,具体取决于客户端被路由到哪个处理节点
* `:c,maxn=250,3600` 允许每个 IP 在 1 小时内上传 250 个文件(按卷跟踪)
* `:c,maxb=1g,300` 允许每个 IP 在 5 分钟内总共上传 1 GiB(按卷跟踪)
注意:
* `vmaxb` 和 `vmaxn` 需要 `e2ds` 卷标志或 `-e2dsa` 全局选项
配置文件示例:
```
[/inc]
/mnt/nas/uploads
accs:
w: * # anyone can upload here
rw: ed # only user "ed" can read-write
flags:
e2ds # filesystem indexing is required for many of these:
sz: 1k-3m # accept upload only if filesize in this range
df: 4g # free disk space cannot go lower than this
vmaxb: 1g # volume can never exceed 1 GiB
vmaxn: 4k # ...or 4000 files, whichever comes first
nosub # must upload to toplevel folder
lifetime: 300 # uploads are deleted after 5min
maxn: 250,3600 # each IP can upload 250 files in 1 hour
maxb: 1g,300 # each IP can upload 1 GiB over 5 minutes
```
## 压缩上传
文件可以在上传时自动压缩,可以根据用户请求(如果配置允许)或由服务器配置强制执行
* 卷标志 `gz` 允许 gz 压缩
* 卷标志 `xz` 允许 lzma 压缩
* 卷标志 `pk` **强制**压缩所有文件
* URL 参数 `pk` 使用服务器默认算法请求压缩
* URL 参数 `gz` 或 `xz` 使用特定算法请求压缩
* URL 参数 `xz` 请求 xz 压缩
注意事项,
* `gz` 和 `xz` 参数接受一个可选参数,即压缩级别(范围 0 到 9)
* `pk` 卷标志接受可选参数 `ALGORITHM,LEVEL`,然后它将强制应用于所有上传,例如 `gz,9` 或 `xz,0`
* 默认压缩为 gzip 级别 9
* 支持除 up2k 之外的所有上传方法
* 文件将在压缩后建立索引,因此重复数据检测和文件搜索将无法按预期工作
一些示例,
* `-v inc:inc:w:c,pk=xz,0`
名为 inc 的文件夹,共享为 inc,对所有人只写,强制使用级别 0 的 xz 压缩
* `-v inc:inc:w:c,pk`
相同的只写 inc,但强制使用 gz 压缩(默认)而不是 xz
* `-v inc:inc:w:c,gz`
如果客户端上传到 `/inc?pk` 或 `/inc?gz` 或 `/inc?gz=4`,则允许(但不强制)gz 压缩
## chmod 和 chown
按卷设置文件系统权限和所有权
默认情况下:
* 所有文件夹的 chmod 为 755
* 文件通常为 chmod 644(由 umask 定义)
* 用户/组为运行 copyparty 的身份
可以按卷进行配置:
* 卷标志 `chmod_f` 设置文件权限;默认=`644`(通常)
* 卷标志 `chmod_d` 设置目录权限;默认=`755`
* 卷标志 `uid` 设置所有者用户 ID
* 卷标志 `gid` 设置所有者组 ID注意:
* `gid` 只能设置为 copyparty 进程所属的组之一
* `uid` 只能在 copyparty 以 root 身份运行时设置(感谢你的信任)
## 其他标志
* `:c,magic` 启用对无名称上传的文件类型检测,等同于 `--magic`
* 需要 https://pypi.org/project/python-magic/ `python3 -m pip install --user -U python-magic`
* 在 Windows 上请改为获取此文件 `python3 -m pip install --user -U python-magic-bin`
* `cachectl` 更改 Web 浏览器缓存响应的方式(`Cache-Control` 响应头);默认为 `no-cache`,这将防止重复下载相同的文件,除非必要(浏览器会询问 copyparty 文件是否已更改)
* 在链接中添加 `?cache` 将用“完全缓存此内容 69 秒”覆盖此设置;`?cache=321` 是 321 秒,`?cache=i` 是 7 天
## descript.ion
通过将描述添加到名为 `descript.ion` 的文本文件中,为文件夹中的每个文件添加描述
有关示例,请参见 https://copyparty.eu/beta/ —— 这是一个基本的 `descript.ion` 文件:
```
bookmark.mp3 Taishi feat. Rita - Bookmark Memories
slowstep.mp3 Taishi feat. 向日葵 - Slow Step -F.L.C.A-
prsnlzr.mp3 Taishi feat. みとせのりこ - Personalizer
cosmos.mp3 Taishi feat. Rita - Into the cosmos
```
## dothidden
通过将特定文件添加到名为 `.hidden` 的文本文件中,在文件夹中从视觉上隐藏它们
此选项默认禁用;启用卷标志和/或全局选项 `dothidden`
这**仅是出于美观目的!** 文件仍然可以通过多种方式轻松访问,例如通过以 zip/tar 格式下载,因此**不要**依赖此功能来保证安全性。
## 缩略图预生成
如果你想在启动时预生成所有内容(通常是个糟糕的主意);
默认情况下,缩略图是在客户端需要时即时创建的,然后在服务器上缓存 [--th-maxage](https://copyparty.eu/cli/#g-th-maxage) 秒(默认为一周),因此大多数缩略图只需创建一次,然后最终从缓存中删除以保留磁盘空间
但是如果你需要在查看文件夹时立即可用每个缩略图,那么首先将缩略图过期时间增加到非常大的值,然后将全局选项 `th-pregen` 和卷标志 `th_pregen` 设置为以逗号分隔的缩略图格式列表,以便在服务器启动时自动生成;
所有可能格式的完整列表是:`j,jf,jf3,j3,w,wf,wf3,w3,x,xf,xf3,x3,opus,mp3,flac,wav`,我很快就会解释这些含义
* `j` = jpeg 裁剪,`jf` = jpeg 未裁剪,`jf3` = jpeg 未裁剪三倍大小,`j3` jpeg 裁剪三倍大小
* `w` = webm 裁剪,`wf` = webm 未裁剪,...,`x` = jxl 裁剪,`xf` = jxl 未裁剪,...
* 是的,根据 copyparty 的说法,音频转码在技术上也是缩略图——别想太多 ( ゚ ヮ゚)
* 与缩略图不同,音频转码的过期时间由 [--ac-maxage](https://copyparty.eu/cli/#g-ac-maxage) 配置
无论如何,显然你**不**希望预生成 flac/wav,因为它们非常庞大,而其他所有内容也会变得相当大,因为所有这些都会累加起来;
* 每个常规缩略图(j, jf, w, wf, x, xf)大约占用 16 KiB 磁盘空间
* 每个三倍大小的缩略图(j3, jf3, w3, wf3, x3, xf3)大约占用 96 KiB
* 每个 opus / mp3 音频转码大约占用...不知道,6 MiB?取决于歌曲长度
因此,一千张图片转换为所有可能的常规大小图像格式(`j,jf,w,wf,x,xf`)会占用 **96 MiB**,而所有可能的 3 倍大小(`jf3,j3,wf3,w3,xf3,x3`)会占用 **562 MiB**,或者所有格式总计 **658 MiB**,这就是为什么默认设置是*不*在启动时预生成,而是使用缓存按需生成的原因
## 数据库位置
卷内(`.hist/up2k.db`,默认)或其他位置
copyparty 会在每个卷内创建一个名为 `.hist` 的子文件夹,用于存储数据库、缩略图和其他一些内容
或者,可以使用 `--hist` 参数或 `hist=` 卷标志将它们保存在一个单一的位置,或者两者混合使用:
* `--hist ~/.cache/copyparty -v ~/music::r:c,hist=-` 将 `~/.cache/copyparty` 设置为放置卷信息的默认位置,但 `~/music` 会获得常规的 `.hist` 子文件夹(`-` 恢复默认行为)
默认情况下,用于 `-e2d` 和 `-e2t` 的每卷 `up2k.db` sqlite3 数据库存储在缩略图旁边,遵循 `--hist` 选项,但可以使用全局选项 `--dbpath` 和/或卷标志 `dbpath` 将数据库放在其他位置
如果你的存储后端不可靠(NFS 或坏的 HDD),你可以指定一个或多个“界标”以便在进行任何与数据库相关的操作之前查找。界标是一个始终预期存在于卷内的文件。这可以避免在发生停机时进行不必要的文件系统重新扫描。每行一个界标(参见下面的示例)
注意:
* 强烈建议将 hist 文件夹放在 SSD 上以提高性能
* Markdown 编辑始终存储在本地 `.hist` 子目录中
* 在 Windows 上,卷标志路径是类 cygwin 的,因此 `/c/temp` 表示 `C:\temp`,但对于 `--hist` 请使用常规路径
* 你也可以将 cygpaths 用于卷,`-v C:\Users::r` 和 `-v /c/users::r` 都可以工作
配置文件示例:
```
[global]
hist: ~/.cache/copyparty # put db/thumbs/etc. here by default
[/pics]
/mnt/nas/pics
flags:
hist: - # restore the default (/mnt/nas/pics/.hist/)
hist: /mnt/nas/cache/pics/ # can be absolute path
landmark: me.jpg # /mnt/nas/pics/me.jpg must be readable to enable db
landmark: info/a.txt^=ok # and this textfile must start with "ok"
```
## 音频文件中的元数据
设置 `-e2t` 以在上传时索引标签
`-mte` 决定要索引并在浏览器中显示哪些标签(以及显示顺序),这可以按卷更改:
* `-v ~/music::r:c,mte=title,artist` 索引并显示 *title*,后跟 *artist*
如果你在 `mte` 中添加/删除了某个标签,你需要运行一次 `-e2tsr` 来重建数据库,否则只有新文件会受到影响
但是,不使用 `-mte`,`-mth` 是一种在浏览器中隐藏标签的更好方法:这些标签默认不会显示,但它们仍然会被索引并变得可搜索,用户可以在 `[⚙️] config` 面板中选择取消隐藏它们
`-mtm` 可用于添加或重新定义元数据映射,假设你的媒体文件包含 `foo` 和 `bar` 标签,并且你希望它们在浏览器中显示为 `qux`(如果两者都存在则优先使用 `foo`),那么执行 `-mtm qux=foo,bar`,现在你可以使用 `-mte artist,title,qux`
以 `.` 开头的标签,例如 `.bpm` 和 `.dur`(ation),表示数值
有关默认映射,请参见 [mtag.py](https://github.com/9001/copyparty/blob/hovudstraum/copyparty/mtag.py) 中那混乱而美丽的字典(应该涵盖 mp3、opus、flac、m4a、wav、aif)
`--no-mutagen` 禁用 Mutagen 并改用 FFprobe,这...
* 比 Mutagen 慢大约 20 倍
* 捕获 Mutagen 未捕获的少数标签
* 旋律调性、视频分辨率、帧率、pixfmt
* 避免将任何 GPL 代码引入 copyparty
* 更重要的是,它对传入的文件运行 FFprobe,如果你的 FFmpeg 存在 CVE,这会很糟糕
`--mtag-to` 设置标签扫描超时;默认值非常高(60 秒),以照顾 zfs 和其他随机冻结的文件系统。较低的值(如 10)通常是安全的,从而可以更快地处理棘手的文件
### 来自 xattrs 的元数据
Unix 扩展文件属性(仅限 Linux)可以索引到数据库中并使其可搜索;
* `--db-xattr user.foo,user.bar` 将索引 xattr `user.foo` 和 `user.bar`,
* `--db-xattr user.foo=foo,user.bar=bar` 将以名称 `foo` 和 `bar` 索引它们,
* `--db-xattr ~~user.foo,user.bar` 将索引 *除* `user.foo` 和 `user.bar` 之外的所有内容,
* `--db-xattr ~~` 将索引所有内容
但请注意,还必须使用 `-mte` 启用标签,因此这里有一些完整的示例:
* `-e2ts --db-xattr user.foo,user.bar -mte +user.foo,user.bar`
* `-e2ts --db-xattr user.foo=foo,user.bar=bar -mte +foo,bar`
至于首先实际将 xattr `user.foo` 添加到文件中,
* `setfattr -n user.foo -v 'utsikt fra fløytoppen' photo.jpg`
## 文件解析器插件
提供自定义解析器以索引额外的标签,另请参见 [./bin/mtag/README.md](./bin/mtag/README.md)
copyparty 可以使用 `mtp`(作为参数或卷标志)调用外部程序来收集文件的额外元数据,默认超时为 60 秒,并且默认情况下只分析包含音频的文件(参见下文的 ay/an/ad)
* `-mtp .bpm=~/bin/audio-bpm.py` 将以音频文件作为参数 1 执行 `~/bin/audio-bpm.py` 以提供 `.bpm` 标签(如果音频元数据中不存在该标签)
* `-mtp key=f,t5,~/bin/audio-key.py` 使用 `~/bin/audio-key.py` 获取 `key` 标签,替换任何现有的元数据标签(`f,`),如果耗时超过 5 秒则中止(`t5,`)
* `-v ~/music::r:c,mtp=.bpm=~/bin/audio-bpm.py:c,mtp=key=f,t5,~/bin/audio-key.py` 两者均作为按卷配置,哇,这变得越来越难看了
*但是等等,还有更多!* `-mtp` 也可以使用 `a` 标志用于非音频文件:`ay` 仅处理音频文件(默认),`an` 仅处理非音频文件,或 `ad` 处理所有文件(d 代表 dontcare)
* 顺便说一下,“音频文件”也意味着视频,只要有音频流即可
* `-mtp ext=an,~/bin/file-ext.py` 运行 `~/bin/file-ext.py` 以获取 `ext` 标签,仅当文件不是音频时(`an`)
* `-mtp arch,built,ver,orig=an,eexe,edll,~/bin/exe.py` 运行 `~/bin/exe.py` 以获取有关 Windows 二进制文件的属性,仅当文件不是音频(`an`)且文件扩展名为 exe 或 dll 时
* 如果你想将解析器链式连接,请使用 `p` 标志设置处理顺序
* `-mtp foo=p1,~/a.py` 在 `-mtp foo=p2,~/b.py` 之前运行,并将目前检测到的所有标签作为 json 转发到 b.py 的标准输入
* 选项 `c0` 禁用捕获 stdout/stderr,因此 copyparty 根本不会从进程中接收任何标签——相反,被调用的程序可以自由地将任何内容打印到控制台,只需将 copyparty 用作启动器
* `c1` 仅捕获 stdout,`c2` 仅捕获 stderr,而 `c3`(默认)捕获两者
* 你可以使用选项 `kt` 控制解析器超时时的杀死方式,`kt` 杀死整个进程树(默认),`km` 仅杀死主进程,或 `kn` 让它继续运行直到 copyparty 终止
如果某些功能不起作用,请尝试使用 `--mtag-v` 获取详细的错误消息
配置文件示例;请注意,`mtp` 是一个附加选项,因此所有 mtp 选项都将生效:
```
[/music]
/mnt/nas/music
flags:
mtp: .bpm=~/bin/audio-bpm.py # assign ".bpm" (numeric) with script
mtp: key=f,t5,~/bin/audio-key.py # force/overwrite, 5sec timeout
mtp: ext=an,~/bin/file-ext.py # will only run on non-audio files
mtp: arch,built,ver,orig=an,eexe,edll,~/bin/exe.py # only exe/dll
```
## 事件钩子
在上传、重命名等操作时触发程序([示例](./bin/hooks/))
你可以在事件发生之前和/或之后设置钩子,目前你可以钩住上传、移动/重命名和删除
有一大堆标志和东西,请参见 [`--help-hooks`](https://copyparty.eu/cli/#hooks-help-page)
如果你想编写自己的钩子,请参见 [开发说明](./docs/devnotes.md#event-hooks)
### zeromq
事件钩子可以发送 zeromq 消息,而不是运行程序
要在每次文件上传时发送一条 0mq 消息,
* `--xau zmq:pub:tcp://*:5556` 向任何/所有连接的 SUB 客户端发送 PUB
* `--xau t3,zmqpush:tcp://*:5557` 向恰好一个连接的 PULL 客户端发送 PUSH
* `--xau t3,j,zmq:req:tcp://localhost:5555` 向连接的 REP 客户端发送 REQ
PUSH 和 REQ 示例带有 `t3`(3 秒后超时),因为如果没有客户端可以通信,它们会阻塞
* REQ 示例使用 `t3,j` 将扩展的上传信息作为 json 发送,而不是仅发送文件系统路径
如果你需要某些东西来接收消息,请参见 [zmq-recv.py](https://github.com/9001/copyparty/blob/hovudstraum/bin/zmq-recv.py)
配置文件示例;请注意,钩子是附加选项,因此所有 xau 选项都将生效:
```
[global]
xau: zmq:pub:tcp://*:5556` # send a PUB to any/all connected SUB clients
xau: t3,zmq:push:tcp://*:5557` # send PUSH to exactly one connected PULL cli
xau: t3,j,zmq:req:tcp://localhost:5555` # send REQ to the connected REP cli
```
### 上传事件
更古老、更强大的方法([示例](./bin/mtag/)):
```
-v /mnt/inc:inc:w:c,e2d,e2t,mte=+x1:c,mtp=x1=ad,kn,/usr/bin/notify-send
```
那是命令行示例;这是配置文件示例:
```
[/inc]
/mnt/inc
accs:
w: *
flags:
e2d, e2t # enable indexing of uploaded files and their tags
mte: +x1
mtp: x1=ad,kn,/usr/bin/notify-send
```
因此,文件系统位置 `/mnt/inc` 共享在 `/inc`,对所有人只写,将 `x1` 附加到要索引的标签列表(`mte`),并使用 `/usr/bin/notify-send` 为任何文件类型(`ad`)“提供”标签 `x1`,并在超时时禁用杀死(`kn`)
这将会运行命令 `notify-send`,并将上传文件的路径作为第一个也是唯一的参数(因此在 Linux 上它将在屏幕上显示一个通知)
请注意,这比新的[事件钩子](#event-hooks)复杂得多,但这种方法具有以下优点:
* 非阻塞且多线程;不会阻碍其他上传
* 你可以访问来自 FFmpeg 和其他 mtp 解析器的标签
* 仅在遇到新的唯一文件时触发,而不是重复文件
请注意,它将占用解析线程,因此请派生任何昂贵的操作(或设置 `kn` 让 copyparty 为你派生)——反之,如果你有意进行排队/单线程处理,你可以将其与 `--mtag-mt 1` 结合使用
作为参考,如果你要使用事件钩子执行此操作,它会是这样的:`-e2d --xau notify-send,hello,--`
## 处理程序
使用插件重新定义行为([示例](./bin/handlers/))
用完全不同的内容替换 404 和 403 错误(目前就这些)
至于客户端内容,有[用于修改 UI/UX 的插件](./contrib/plugins/)
## IP 认证
基于 IP 范围 (CIDR) 自动登录,使用全局选项 `--ipu`
例如,如果每个 IP 以 `192.168.123` 开头的人都应该以用户 `spartacus` 身份自动登录,那么你可以指定 `--ipu=192.168.123.0/24=spartacus` 作为命令行选项,或者将其放在配置文件中:
```
[global]
ipu: 192.168.123.0/24=spartacus
```
重复该选项以映射其他子网
**小心使用此功能!** 如果你使用了反向代理,那么你肯定需要确保已正确配置 [real-ip](#real-ip),并且将反向代理的 IP 置空可能是个好主意,以防万一;因此,如果你的反向代理从 `172.24.27.9` 发送请求,那么应该是 `--ipu=172.24.27.9/32=`
### 限制为特定 IP
使用全局选项 `--ipr` 将用户限制在某些 IP 范围 (CIDR) 内
例如,如果用户 `spartacus` 不是从以 `192.168.123` 或 `172.16` 开头的 IP 连接,则应该被拒绝,那么你可以指定 `--ipr=192.168.123.0/24,172.16.0.0/16=spartacus` 作为命令行选项,或者将其放在配置文件中:
```
[global]
ipr: 192.168.123.0/24,172.16.0.0/16=spartacus
```
重复该选项以映射其他用户
## 身份提供者
用 oauth 等替换 copyparty 密码
你可以禁用内置的基于密码的登录系统,并用一个单独的软件(身份提供者)替换它,该软件随后将处理用户的认证/授权;这使得可以使用 passkeys / fido2 / webauthn / yubikey / ldap / active directory / oauth / 许多其他单点登录装置登录
* 常规配置定义的用户将作为不包含有效(受信任的)IdP 用户名标头的请求的备用方案
* `--auth-ord` 配置认证优先级,例如允许使用 copyparty 密码覆盖 IdP
* 可以使用 `--idp-login` 和 `--idp-logout` 将登录/注销链接/按钮替换为指向你 IdP 的链接,例如 `--idp-login /idp/login/?redir={dst}` 会将 `{dst}` 展开为用户点击登录时所在的页面
* 如果你的 IdP 服务器速度慢,可以考虑使用 `--idp-cookie`,让带有 cookie `cppws` 的请求绕过 IdP;为某次派对添加的基于会话的实验性功能
一些流行的身份提供者是 [Authelia](https://www.authelia.com/)(基于配置文件)和 [authentik](https://goauthentik.io/)(基于 GUI,更复杂)
有一个 [docker-compose 示例](./docs/examples/docker/idp-authelia-traefik),希望能作为一个很好的起点(如果你是 DIY 类型,或者参见 [./docs/idp.md](./docs/idp.md))
copyparty 配置选项的一个更完整的示例[看起来像这样](./docs/examples/docker/idp/copyparty.conf)
但如果你只是想让用户更改自己的密码,那么你可能需要的是[用户可更改密码](#user-changeable-passwords)
### 通用请求头认证
通过标头进行认证的其他方式
如果你有一个中间件可以添加带有用户标识符的标头,例如 Tailscale 的 `Tailscale-User-Login: alice.m@forest.net`,那么你可以通过使用 `--idp-hm-usr '^Tailscale-User-Login^alice.m@forest.net^alice'` 定义该映射来自动认证为 `alice`,或者使用以下配置文件:
```
[global]
idp-hm-usr: ^Tailscale-User-Login^alice.m@forest.net^alice
```
重复整个 `idp-hm-usr` 选项以添加更多映射
## 用户可更改密码
如果允许,用户可以在控制面板中更改自己的密码
* 与[身份提供者](#identity-providers)不兼容
* 必须使用 `--chpw` 启用,因为账户共享是一个流行的用例
* 如果你想启用此功能但拒绝特定账户列表更改密码,你可以使用 `--chpw-no name1,name2,name3,...`
* 要执行密码重置,请编辑服务器配置并在那里为用户提供另一个密码,然后执行[配置重载](#server-config)或服务器重启
* 自定义密码保存在文件系统路径 `--chpw-db` 的文本文件中,默认为 copyparty 配置文件夹中的 `chpw.json`
* 如果你使用不同的用户运行多个 copyparty 实例,你*几乎肯定*希望为每个实例指定单独的数据库
* 如果启用了[密码哈希](#password-hashing),数据库中的密码也会被哈希
* ……这意味着如果你更改了密码哈希设置,所有用户定义的密码将被遗忘
## 使用云作为存储
连接到 AWS S3 存储桶及类似服务
没有对此的内置支持,但你可以使用 FUSE 软件,例如 [rclone](https://rclone.org/) / [geesefs](https://github.com/yandex-cloud/geesefs) / [JuiceFS](https://juicefs.com/en/),首先将你的云存储挂载为本地磁盘,然后让 copyparty 使用该磁盘上的(某个文件夹)作为卷
如果 copyparty 无法访问 rclone/geesefs/JuiceFS 提供的本地文件夹(例如它看起来不可见),那么你可能需要在运行 rclone 时带上 `--allow-other` 和/或在 `/etc/fuse.conf` 中启用 `user_allow_other`
使用默认配置,你可能会获得不错的速度,但最有可能被限制为每个文件使用一个 TCP 连接,因此上传客户端将无法并行发送多个块
还有人测试了 geesefs 结合 [gocryptfs](https://nuetzlich.net/gocryptfs/) 的效果出奇地好,在千兆网络上获得了 60 MiB/s 的上传速度,但 JuiceFS 以 80 MiB/s 胜出,使用了其内置加密
你可以通过为 `--iobuf` / `--s-rd-sz` / `--s-wr-sz` 指定更大的值来提高性能
## 隐藏以躲避 Google
告诉搜索引擎你不想被索引,可以使用老式的 [robots.txt](https://www.robotstxt.org/robotstxt.html) 或通过 copyparty 设置:
* `--no-robots` 全局添加带有 `noindex, nofollow` 的 HTTP (`X-Robots-Tag`) 和 HTML (`
`) 标头
* 卷标志 `[...]:c,norobots` 对单个卷执行相同的操作
* 卷标志 `[...]:c,robots` 允许搜索引擎抓取该卷,即使全局设置了 `--no-robots`
此外,`--force-js` 禁用纯 HTML 文件夹列表,使得*某些*搜索引擎更难解析——请注意,能够理解 javascript 的爬虫(例如 Google)不会受到影响
## 主题
你可以使用 `--theme 2` 更改默认主题,并通过修改 `browser.css` 或提供你自己的 CSS 给 `--css-browser` 来添加你自己的主题,然后通过增加 `--themes` 来告诉 copyparty 它们的存在
0. classic dark |
2. flat pm-monokai |
4. vice |
1. classic light |
3. flat light
|
5. hotdog stand |
HTML 标签的类名是根据所选主题设置的,用于将颜色设置为 css 变量 ++
* 每个主题*通常*有一个深色主题(偶数)和一个浅色主题(奇数),成对显示
* 第一个主题(主题 0 和 1)是 `html.a`,第二个主题(2 和 3)是 `html.b`
* 如果选择了浅色主题,则设置 `html.y`,否则设置 `html.z`
* 因此,如果选择了第二个主题的深色版本,你可以使用 `html.b`、`html.z`、`html.bz` 中的任何一个来指定规则
请参见 [./copyparty/web/browser.css](./copyparty/web/browser.css) 的顶部,那里设置了颜色变量,底部有特定于布局的内容
如果你想更改字体,请参见 [./docs/rice/](./docs/rice/)
## 完整示例
* 有关精美的 Windows 设置,请参见[在 Windows 上运行](./docs/examples/windows.md)
* 或者使用以下任何示例,如果你使用的是 exe 版本,只需将 `python copyparty-sfx.py` 替换为 `copyparty.exe`
* 允许任何人下载或上传文件到当前文件夹:
`python copyparty-sfx.py`
* 使用 `-e2dsa -e2ts` 启用搜索和音乐索引
* 使用 `--ftp 3921` 在端口 3921 上启动 FTP 服务器
* 使用 `-z` 在你的局域网上 announce 它,使其出现在 Windows/Linux 文件管理器中
* 任何人都可以上传,但没有人能看到任何文件(甚至上传者也不能):
`python copyparty-sfx.py -e2dsa -v .::w`
* 如果空闲磁盘空间不足 4 GiB,则使用 `--df 4` 阻止上传
* 使用 `--xau bin/hooks/notify.py` 在新上传时显示弹窗
* 任何人都可以上传,并为他们执行的每次上传接收“秘密”链接:
`python copyparty-sfx.py -e2dsa -v .::wG:c,fk=8`
* 任何人都可以浏览(`r`),只有 `kevin`(密码 `okgo`)可以上传/移动/删除(`A`)文件:
`python copyparty-sfx.py -e2dsa -a kevin:okgo -v .::r:A,kevin`
* 只读音乐服务器:
`python copyparty-sfx.py -v /mnt/nas/music:/music:r -e2dsa -e2ts --no-robots --force-js --theme 2`
* ……带有 bpm 和调性扫描
`-mtp .bpm=f,audio-bpm.py -mtp key=f,audio-key.py`
* ……带有 `kevin` 的读写文件夹,其密码为 `okgo`
`-a kevin:okgo -v /mnt/nas/inc:/inc:rw,kevin`
* ……带有磁盘日志记录
`-lo log/cpp-%Y-%m%d-%H%M%S.txt.xz`
## 监听 80 和 443 端口
成为一个*真正的*网络服务器,人们只需访问你的 IP 或域名即可访问,无需指定端口
**如果你使用的是 Windows,** 那么你只需添加命令行参数 `-p 80,443` 即可完成!很好
**如果你使用的是 macOS,** 抱歉,我不知道
**如果你使用的是 Linux,** 你有以下 4 个选项:
* **选项 1:** 设置一个[反向代理](#reverse-proxy) —— 如果你运行的是合适的无头服务器,这非常有意义,因为这样你还能获得真正的 HTTPS
* **选项 2:** NAT 到 3923 —— 这很麻烦,因为你需要在每次重启时都执行此操作,并且确切的命令可能取决于你的 Linux 发行版:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3923
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 3923
* **选项 3:** 禁用阻止使用 80 和 443 的[安全策略](https://www.w3.org/Daemon/User/Installation/PrivilegedPorts.html);这*可能*没问题:
setcap CAP_NET_BIND_SERVICE=+eip $(realpath $(which python))
python copyparty-sfx.py -p 80,443
* **选项 4:** 以 root 身份运行 copyparty(请不要这样做)
## 反向代理
在托管的现有网络服务器(例如 nginx、caddy 或 apache)旁边运行 copyparty
你可以:
* 给 copyparty 自己的域或子域(推荐)
* 或进行基于位置的代理,使用 `--rp-loc=/stuff` 告诉 copyparty 它挂载在哪里——这会带来轻微的性能成本和更高的出错概率
* 如果 copyparty 提示 `incorrect --rp-loc or webserver config; expected vpath starting with [...]`,这可能是因为网络服务器从请求 URL 中剥离了代理位置——请参见下面 Apache 示例中的 `ProxyPass`
在反向代理后面运行时(这包括 Cloudflare 等服务),正确配置 real-ip 非常重要,因为许多功能依赖于知道客户端的 IP。最好/最安全的方法是配置你的反向代理,使其为 copyparty 提供一个仅包含客户端真实/实际 IP 地址的标头,然后设置 `--xff-hdr theHeaderName --rproxy 1`,或者,如果你希望/需要让 copyparty 处理此问题,请注意解释如何执行此操作的红色和黄色日志消息。基本上,日志会这样说:
请注意,除非你正确配置了上述内容,否则 `--rp-loc` 将完全无法工作
某些反向代理(例如 [Caddy](https://caddyserver.com/))可以自动为你获取有效的 https/tls 证书,有些支持 HTTP/2 和 QUIC,这*可能*是一个不错的速度提升,具体取决于许多因素
* **警告:** nginx-QUIC (HTTP/3) 仍处于实验阶段,可能会使上传变慢很多,因此目前推荐使用 HTTP/1.1
* 取决于服务器/客户端,HTTP/1.1 也可能比 HTTP/2 快 5 倍
为了提高安全性(以及 10% 的性能提升),可以考虑使用 `-i unix:770:www:/dev/shm/party.sock` 监听 unix 套接字(权限 `770` 意味着只有 `www` 组的成员可以访问它)
示例网络服务器 / 反向代理配置:
* [Apache 配置](contrib/apache/copyparty.conf)
* Caddy UDS:`caddy reverse-proxy --from :8080 --to unix///dev/shm/party.sock`
* Caddy TCP:`caddy reverse-proxy --from :8081 --to http://127.0.0.1:3923`
* [HAProxy 配置](contrib/haproxy/copyparty.conf)
* [Lighttpd 子域](contrib/lighttpd/subdomain.conf) —— 整个域/子域
* [Lighttpd 子路径](contrib/lighttpd/subpath.conf) —— 基于位置(不是最优,但以备不时之需)
* [Nginx 配置](contrib/nginx/copyparty.conf) —— 推荐
* [Traefik 配置](contrib/traefik/copyparty.yaml) —— 仅使用 v3.6.7 或更新版本 [由于 CVE-2025-66490](https://github.com/9001/copyparty/issues/1205)
### real-ip
教导 copyparty 在反向代理或 WAF,或其他保护服务(如 Cloudflare)后面运行时如何查看客户端 IP
如果你(可能还有其他人)不断收到一条写着 `thank you for playing` 的消息,那么你因恶意流量而被封禁了。此封禁适用于 copyparty *认为*标识了可疑客户端的 IP 地址——因此,根据你的设置,你可能需要告诉 copyparty 在哪里找到正确的 IP
对于最常见的设置,服务器日志中应该会有一条有用的消息解释该怎么做,但如果你想了解更多信息,请参见 [docs/xff.md](docs/xff.md),包括一个让它**直接工作**的快速技巧(**不**推荐,但是嘛……)
### 反向代理性能
大多数反向代理支持使用 uds/unix 套接字(`/dev/shm/party.sock`,更快/推荐)或使用 tcp(`127.0.0.1`)连接到 copyparty
当 copyparty 监听 uds / unix 套接字 / unix 域套接字,并且反向代理连接到它时:
| index.html | upload | download | software |
| ------------ | ----------- | ----------- | -------- |
| 28'900 req/s | 6'900 MiB/s | 7'400 MiB/s | 无代理 |
| 18'750 req/s | 3'500 MiB/s | 2'370 MiB/s | haproxy |
| 9'900 req/s | 3'750 MiB/s | 2'200 MiB/s | caddy |
| 18'700 req/s | 2'200 MiB/s | 1'570 MiB/s | nginx |
| 9'700 req/s | 1'750 MiB/s | 1'830 MiB/s | apache |
| 9'900 req/s | 1'300 MiB/s | 1'470 MiB/s | lighttpd |
当反向代理改为连接到 `127.0.0.1` 时(基础和/或老式的方式),速度会稍差一些:
| index.html | upload | download | software |
| ------------ | ----------- | ----------- | -------- |
| 21'200 req/s | 5'700 MiB/s | 6'700 MiB/s | 无代理 |
| 14'500 req/s | 1'700 MiB/s | 2'170 MiB/s | haproxy |
| 11'100 req/s | 2'750 MiB/s | 2'000 MiB/s | traefik |
| 8'400 req/s | 2'300 MiB/s | 1'950 MiB/s | caddy |
| 13'400 req/s | 1'100 MiB/s | 1'480 MiB/s | nginx |
| 8'400 req/s | 1'000 MiB/s | 1'000 MiB/s | apache |
| 6'500 req/s | 1'270 MiB/s | 1'500 MiB/s | lighttpd |
总而言之,`haproxy > caddy > traefik > nginx > apache > lighttpd`,并在可能的情况下使用 uds(traefik 尚不支持)
* 如果这些结果是我胡说八道,因为我的配置示例很糟糕,请提交纠正!
## 永久 Cloudflare 隧道
如果你有一个域名,并且想让你的 copyparty 快速上线,无论是从 CGNAT 后面的家用 PC,还是从没有现有[反向代理](#reverse-proxy)设置的服务器,一种方法是创建一个 [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/)(以前称为“Argo Tunnel”)
我建议制作一个 `Locally-managed tunnel` 以获得更多控制权,但如果你更喜欢制作 `Remotely-managed tunnel`,目前的方法如下:
* `cloudflare dashboard` » `zero trust` » `networks` » `tunnels` » `create a tunnel` » `cloudflared` » 选择一个很酷的 `subdomain` 并将 `path` 留空,然后使用 `
安装后,启动系统服务或用户服务,并访问 http://127.0.0.1:3923 获取更多说明(除非您已经编辑了配置文件,这种情况下您可能已经准备就绪了)
## fedora 软件包
尚不存在;有传言称正在打包中!请关注此页面...
## gentoo ::guru 软件包
`emerge www-servers/copyparty::guru`(在 [::guru](https://wiki.gentoo.org/wiki/Project:GURU) 中)
但首先需要启用 `::guru` 仓库;
```
emerge -an app-eselect/eselect-repository
eselect repository enable guru
emerge --sync guru
```
以用户身份启动服务:
* OpenRC:`rc-service -U copyparty start && rc-update -U add copyparty default`
* systemd:[待办]
## homebrew formulae
`brew install copyparty ffmpeg` -- https://formulae.brew.sh/formula/copyparty
应该适用于所有 Mac(Intel 和 Apple Silicon)以及所有相关的 macOS 版本
homebrew 软件包由 homebrew 团队维护(感谢!)
## nix 软件包
`nix profile install github:9001/copyparty`
需要启用 [flake](https://nixos.wiki/wiki/Flakes) 的 nix 安装环境
一些推荐的依赖项默认已启用;如果您想添加/删除某些功能/依赖项,请[覆盖该软件包](https://github.com/9001/copyparty/blob/hovudstraum/contrib/package/nix/copyparty/default.nix#L3-L22)
选择 `ffmpeg-full` 而不是 `ffmpeg-headless` 主要是因为我们需要 `withWebp`(而且 `withOpenmpt` 也不错),并且当时能够使用缓存的构建似乎比优化大小更重要——如果您不同意,欢迎提交 PR 👍
## NixOS 模块
适用于启用 [flake](https://nixos.wiki/wiki/Flakes) 的 NixOS 安装:
```
{
# add copyparty flake to your inputs
inputs.copyparty.url = "github:9001/copyparty";
# ensure that copyparty is an allowed argument to the outputs function
outputs = { self, nixpkgs, copyparty }: {
nixosConfigurations.yourHostName = nixpkgs.lib.nixosSystem {
modules = [
# load the copyparty NixOS module
copyparty.nixosModules.default
({ pkgs, ... }: {
# add the copyparty overlay to expose the package to the module
nixpkgs.overlays = [ copyparty.overlays.default ];
# (optional) install the package globally
environment.systemPackages = [ pkgs.copyparty ];
# configure the copyparty module
services.copyparty.enable = true;
})
];
};
};
}
```
如果您在配置中不使用 flake,可以使用其他依赖管理工具,如 [npins](https://github.com/andir/npins)、[niv](https://github.com/nmattia/niv),甚至是普通的 [`fetchTarball`](https://nix.dev/manual/nix/stable/language/builtins#builtins-fetchTarball),如下所示:
```
{ pkgs, ... }:
let
# npins example, adjust for your setup. copyparty should be a path to the downloaded repo
# for niv, just replace the npins folder import with the sources.nix file
copyparty = (import ./npins).copyparty;
# or with fetchTarball:
copyparty = fetchTarball "https://github.com/9001/copyparty/archive/hovudstraum.tar.gz";
in
{
# load the copyparty NixOS module
imports = [ "${copyparty}/contrib/nixos/modules/copyparty.nix" ];
# add the copyparty overlay to expose the package to the module
nixpkgs.overlays = [ (import "${copyparty}/contrib/package/nix/overlay.nix") ];
# (optional) install the package globally
environment.systemPackages = [ pkgs.copyparty ];
# configure the copyparty module
services.copyparty.enable = true;
}
```
NixOS 上的 copyparty 通过 `services.copyparty` 选项进行配置,例如:
```
services.copyparty = {
enable = true;
# the user to run the service as
user = "copyparty";
# the group to run the service as
group = "copyparty";
# directly maps to values in the [global] section of the copyparty config.
# see `copyparty --help` for available options
settings = {
i = "0.0.0.0";
# use lists to set multiple values
p = [ 3210 3211 ];
# use booleans to set binary flags
no-reload = true;
# using 'false' will do nothing and omit the value when generating a config
ignored-flag = false;
};
# create users
accounts = {
# specify the account name as the key
ed = {
# provide the path to a file containing the password, keeping it out of /nix/store
# must be readable by the copyparty service user
passwordFile = "/run/keys/copyparty/ed_password";
};
# or do both in one go
k.passwordFile = "/run/keys/copyparty/k_password";
};
# create a group
groups = {
# users "ed" and "k" are part of the group g1
g1 = [ "ed" "k" ];
};
# create a volume
volumes = {
# create a volume at "/" (the webroot), which will
"/" = {
# share the contents of "/srv/copyparty"
path = "/srv/copyparty";
# see `copyparty --help-accounts` for available options
access = {
# everyone gets read-access, but
r = "*";
# users "ed" and "k" get read-write
rw = [ "ed" "k" ];
};
# see `copyparty --help-flags` for available options
flags = {
# "fk" enables filekeys (necessary for upget permission) (4 chars long)
fk = 4;
# scan for new files every 60sec
scan = 60;
# volflag "e2d" enables the uploads database
e2d = true;
# "d2t" disables multimedia parsers (in case the uploads are malicious)
d2t = true;
# skips hashing file contents if path matches *.iso
nohash = "\.iso$";
};
};
};
# you may increase the open file limit for the process
openFilesLimit = 8192;
# override the package used by the module to add dependencies, e.g. for hooks
package = pkgs.copyparty.override {
# provides exiftool for bin/hooks/image-noexif.py
extraPackages = [ pkgs.exiftool ];
};
};
```
/run/keys/copyparty/ 中的 passwordFile 可以例如由 [agenix](https://github.com/ryantm/agenix) 生成,或者如果可以接受的话,您也可以直接将其转储到 nix store 中
# 浏览器支持
太长不看:没问题

`ie` = internet-explorer,`ff` = firefox,`c` = chrome,`iOS` = iPhone/iPad,`Andr` = Android
| 功能 | ie6 | ie9 | ie10 | ie11 | ff 52 | c 49 | iOS | Andr |
| --------------- | --- | ---- | ---- | ---- | ----- | ---- | --- | ---- |
| 浏览文件 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| 缩略图视图 | - | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| 基础上传 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| up2k | - | - | `*1` | `*1` | 是 | 是 | 是 | 是 |
| 创建目录 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| 发送消息 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| 设置排序方式 | - | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| zip 打包选择 | - | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| 文件搜索 | - | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| 文件重命名 | - | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| 文件剪切/粘贴 | - | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| 撤销上传 | - | - | 是 | 是 | 是 | 是 | 是 | 是 |
| 导航窗格 | - | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| 图片查看器 | - | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| 视频播放器 | - | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| markdown 编辑器 | - | - | `*2` | `*2` | 是 | 是 | 是 | 是 |
| markdown 查看器 | - | `*2` | `*2` | `*2` | 是 | 是 | 是 | 是 |
| 播放 mp3/m4a | - | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| 播放 ogg/opus | - | - | - | - | 是 | 是 | `*3` | 是 |
| **= 功能 =** | ie6 | ie9 | ie10 | ie11 | ff 52 | c 49 | iOS | Andr |
* internet explorer 6 到 8 表现相同
* firefox 52 和 chrome 49 是最终的 winxp 版本
* `*1` 可以,但非常慢(ie10:`1 MiB/s`,ie11:`270 KiB/s`)
* `*2` 只能处理纯文本文档(不进行 markdown 渲染)
* `*3` iOS 11 及更高版本,仅限 opus,并且服务器需要 FFmpeg
尝试查看目录索引的更奇特浏览器的简要概述:
| 浏览器 | 能否正常工作 |
| ------- | ------------- |
| **links** (2.21/macports) | 可以浏览、登录、上传/创建目录/发消息 |
| **lynx** (2.8.9/macports) | 可以浏览、登录、上传/创建目录/发消息 |
| **w3m** (0.5.3/macports) | 可以浏览、登录、以 100kB/s 速度上传、创建目录/发消息 |
| **netsurf** (3.10/arch) | 基本上是 ie6,但具有更好的 CSS(javascript 几乎不起作用) |
| **opera** (11.60/winxp) | 正常:缩略图、图片查看器、zip 选择、重命名/剪切/粘贴。异常:up2k、导航窗格、markdown、音频 |
| **ie4** 和 **netscape** 4.0 | 可以浏览、使用 `?b=u` 上传、使用 `&pw=wark` 认证 |
| **ncsa mosaic** 2.7 | 无法通过,[图1](https://user-images.githubusercontent.com/241032/174189227-ae816026-cf6f-4be5-a26e-1b3b072c1b2f.png) - [图2](https://user-images.githubusercontent.com/241032/174189225-5651c059-5152-46e9-ac26-7e98e497901b.png) |
| **SerenityOS** (7e98457) | 出现页面错误,使用 `?b=u` 可以工作,文件上传未实现 |
| **sony psp** 5.50 | 可以浏览、上传/创建目录/发消息 (感谢 dwarf) [截图](https://github.com/user-attachments/assets/9d21f020-1110-4652-abeb-6fc09c533d4f) |
| **nintendo 3ds** | 可以浏览、上传、查看缩略图 (感谢 bnjmn) |
| **Nintendo Wii (Opera 9.0 "Internet Channel")** | 可以浏览,无法上传或下载(无本地存储),可以查看图片 - 使用 `?b=u` 效果最佳,默认视图已损坏 |

# 服务器名人堂
运行 copyparty 的意外事物:
* 一台旧的 [allwinner](https://a.ocv.me/pub/g/nerd-stuff/cpp/servers/aallwinner.jpg) android 电视盒子(用拉链带绑在 HDD 上),运行的固件会在启动早期将 CPU 翻转为 Big-Endian 模式
* copyparty 已[认证为 BE 就绪](https://a.ocv.me/pub/g/nerd-stuff/cpp/servers/be-ready.png) -- 感谢,[Øl Telecom](http://ol-tele.com/)!
* 一台[SGI O2 (照片)](https://a.ocv.me/pub/g/nerd-stuff/cpp/servers/sgi-o2.jpg?cache),总共有 64 MiB RAM,运行 SGI IRIX;[截图](https://a.ocv.me/pub/g/nerd-stuff/cpp/servers/sgi-o2.png?cache)
* 再次感谢 [Øl Telecom](http://ol-tele.com/) 的出色人员
* 一块[智能手表](https://a.ocv.me/pub/g/nerd-stuff/cpp/servers/clockyparty.jpg)
# 客户端示例
使用非浏览器客户端与 copyparty 交互
* javascript:将一些状态转储到文件中(两个单独的示例)
* `await fetch('//127.0.0.1:3923/', {method:"PUT", body: JSON.stringify(foo)});`
* `var xhr = new XMLHttpRequest(); xhr.open('POST', '//127.0.0.1:3923/msgs?raw'); xhr.send('foo');`
* curl/wget:上传一些文件(post=文件,chunk=标准输入)
* `post(){ curl -F f=@"$1" http://127.0.0.1:3923/?pw=wark;}`
`post movie.mkv` (返回 HTML)
* `post(){ curl -F f=@"$1" 'http://127.0.0.1:3923/?want=url&pw=wark';}`
`post movie.mkv` (返回热链接)
* `post(){ curl -H pw:wark -H rand:8 -T "$1" http://127.0.0.1:3923/;}`
`post movie.mkv` (随机文件名)
* `post(){ wget --header='pw: wark' --post-file="$1" -O- http://127.0.0.1:3923/?raw;}`
`post movie.mkv`
* `chunk(){ curl -H pw:wark -T- http://127.0.0.1:3923/;}`
`chunk
/dev/tcp/127.0.0.1/3923`
* python:[u2c.py](https://github.com/9001/copyparty/blob/hovudstraum/bin/u2c.py) 是一个命令行 up2k 客户端 [(webm)](https://ocv.me/stuff/u2cli.webm)
* 文件上传、文件搜索、[文件夹同步](#folder-sync)、自动恢复中止/中断的上传
* 可从 copyparty 下载:控制面板 -> 连接 -> [u2c.py](http://127.0.0.1:3923/.cpr/a/u2c.py)
* 请参阅 [./bin/README.md#u2cpy](bin/README.md#u2cpy)
* FUSE:将 copyparty 服务器挂载为本地文件系统
* [./bin/](bin/) 中提供了跨平台的 python 客户端
* 能够挂载 nginx 和 iis 的目录列表,而不仅仅是 copyparty
* 可从 copyparty 下载:控制面板 -> 连接 -> [partyfuse.py](http://127.0.0.1:3923/.cpr/a/partyfuse.py)
* [rclone](https://rclone.org/) 作为客户端可以提供约 5 倍的性能,请参阅 [./docs/rclone.md](docs/rclone.md)
* sharex(截图工具):请参阅 [./contrib/sharex.sxcu](./contrib/#sharexsxcu)
* 对于 macos 上的截图,请参阅 [./contrib/ishare.iscu](./contrib/#ishareiscu)
* 对于 linux 上的截图,请参阅 [./contrib/flameshot.sh](./contrib/flameshot.sh)
* [Custom Uploader](https://f-droid.org/en/packages/com.nyx.custom_uploader/)(一款 Android 应用)作为 copyparty 自有应用 [PartyUP!](#android-app) 的替代品
* 如果您将 UploadURL 设置为 `://your.com/foo/?want=url&pw=hunter2` 且 FormDataName 为 `f` 即可工作
* contextlet(Web 浏览器集成);请参阅 [contrib contextlet](contrib/#send-to-cppcontextletjson)
* [igloo irc](https://iglooirc.com/):方法:`post` 主机:`https://you.com/up/?want=url&pw=hunter2` Multipart:`yes` 文件参数:`f`
copyparty 返回您的 PUT/POST 的截断 sha512sum 的 base64 编码;您可以在本地生成相同的校验和以验证上传:
```
b512(){ printf "$((sha512sum||shasum -a512)|sed -E 's/ .*//;s/(..)/\\x\1/g')"|base64|tr '+/' '-_'|head -c44;}
b512
''
''
该应用**不是**完整的 copyparty 服务器!只是一个基础的上传客户端,目前还没有什么花哨的功能
如果您想在安卓设备上运行 copyparty 服务器,请参阅[在 Android 上安装](#install-on-android)
# iOS 快捷指令
没有 iPhone 应用,但以下快捷指令也几乎同样好用:
* [上传到 copyparty](https://www.icloud.com/shortcuts/41e98dd985cb4d3bb433222bc1e9e770) ([离线版](https://github.com/9001/copyparty/raw/hovudstraum/contrib/ios/upload-to-copyparty.shortcut)) ([png](https://user-images.githubusercontent.com/241032/226118053-78623554-b0ed-482e-98e4-6d57ada58ea4.png)) 基于 [Daedren](https://github.com/Daedren) 的[原版](https://www.icloud.com/shortcuts/ab415d5b4de3467b9ce6f151b439a5d7)(感谢!)
* 可以剥离 EXIF、上传文件、图片、视频、链接、剪贴板内容
* 可以下载链接并将目标文件重新托管在 copyparty 上(请参阅快捷指令内的第一条评论)
* 如果您从图库分享到快捷指令,图片会变成低分辨率,因此最好启动快捷指令并从那里挑选内容
如果您想在 iPhone 或 iPad 上运行 copyparty 服务器,请参阅[在 iOS 上安装](#install-on-iOS)
# 性能
默认设置通常就很好——预期 `8 GiB/s` 下载,`1 GiB/s` 上传
以下是一些大致按实用性排序的调整:
* 禁用 HTTP/2 和 HTTP/3 可以使上传速度提高 5 倍,具体取决于服务器/客户端软件
* `-q` 禁用日志记录并能带来很大帮助,即使与 `-lo` 结合将日志重定向到文件时也是如此
* 将 `--hist` 指向快速位置(SSD)可以在设置 `-e2d` 或 `-e2t` 时使目录列表和搜索更快
* 并且无论是否启用 e2d/e2t,都会使缩略图加载更快
* `--dedup` 启用去重功能,从而在有人上传重复文件时避免写入 HDD
* `--safe-dedup 1` 通过跳过对文件内容的验证,使上传过程中的去重速度大大提高;如果卷中没有其他软件正在编辑/移动文件,则这是安全的
* `--no-dirsz` 显示文件夹 inode 的大小而不是内容的总大小,使文件夹列表速度提高约 30%
* 如果您不关心实际的文件哈希,而只想让名称/标签可搜索,请在索引网络磁盘时使用 `--no-hash .`
* 如果您的卷位于网络磁盘(例如 NFS / SMB / s3)上,为 `--iobuf` 和/或 `--s-rd-sz` 和/或 `--s-wr-sz` 指定更大的值可能会有所帮助;尝试将它们全部设置为 `524288` 或 `1048576` 或 `4194304`
* `--no-htp --hash-mt=0 --mtag-mt=1 --th-mt=1` 最大限度地减少线程数量;可以在某些奇特环境(如 vscode 调试器)中提供帮助
* 在 AlpineLinux 或其他基于 musl 的发行版上运行时,请尝试使用 mimalloc 以获得更高的性能(以及两倍的 RAM 使用量);`apk add mimalloc2` 并使用环境变量 `LD_PRELOAD=/usr/lib/libmimalloc-secure.so.2` 运行 copyparty
* 请注意,mimalloc 在与 prisonparty 和/或 bubbleparty/bubblewrap 结合使用时需要特别小心;您必须授予它对 `/proc` 和 `/sys` 的访问权限,否则您会遇到 FFmpeg 问题(音频转码、缩略图)
* `-j0`(通常*不*推荐)启用多处理(真正的多线程),可以将延迟降低到 `20+80/numCores` 百分比,并通常提高 CPU 密集型工作负载的性能,例如:
* 大量连接(多用户或重型客户端)
* 同时进行的下载和上传使 20gbps 连接饱和
* 如果启用了 `-e2d`,`-j2` 可使目录列表性能提高 4 倍;`-j4` 可提高 16 倍
...然而,在大多数情况下,它可能会*降低*性能,因为它也会在上传期间增加服务器/文件系统/HDD 的负载,并增加内部通信的开销,因此保持默认值通常是最佳选择
* 使用 [pypy](https://www.pypy.org/) 而不是 [cpython](https://www.python.org/) 在某些工作负载下*可以*快 70%,但在许多其他情况下会更慢
* 并且 pypy 有时在启动时使用 `-j0` 会崩溃(待办事项:创建 issue)
* 如果您在 **Windows 或 macOS 上**运行 copyparty 服务器:
* `--casechk=n` 使其快得多,但也会引发您对不区分大小写的文件系统所期望的[通常意外](https://github.com/9001/copyparty/issues/781)
* 这与配置文件中的 `casechk: n` 相同
## 客户端
上传文件时,
* 在使用 chrome/firefox 从极快的存储设备(NVMe SSD)上传时,请在 `[⚙️] 设置` 选项卡中启用 `[wasm]`,以更有效地利用所有 CPU 核心进行哈希处理
* 在 Safari 上不要这样做(不启用运行得更快)
* 在旧版浏览器上不要这样做;可能会引发浏览器错误(浏览器耗尽所有 RAM 并崩溃)
* 可以通过服务器端使用 `--nosubtle 137`(chrome v137+)或 `--nosubtle 2`(chrome+firefox)默认启用
* 推荐使用 chrome(很遗憾),至少与 firefox 相比:
* 哈希处理速度提高 90%,尤其是在 SSD 上
* 通过极快的互联网上传时速度提高 40%
* 但 [u2c.py](https://github.com/9001/copyparty/blob/hovudstraum/bin/u2c.py) 可以再次比 chrome 快 40%
* 如果您遇到了 CPU 瓶颈,或者浏览器占满了一个 CPU 核心:
* 如果您通过切换离开 `[🚀]` up2k ui 选项卡(或关闭它)来隐藏上传状态列表,上传速度最多可提高 30%
* 或者,您可以通过点击 `[🥔]` 切换到轻量级的 potato 界面
* 切换到另一个浏览器选项卡也可以,在这种情况下,网站图标将每 10 秒更新一次
* 这不太可能成为问题,但在上传许多小文件、或者您的互联网速度太快、或者电脑太慢时可能会发生
# 安全
有一个用于发布公告的 [discord 服务器](https://discord.gg/25J8CdTT6G);对所有重要更新使用 `@everyone`(由于没有更好的主意)
一些关于强化的说明
* 当且仅当您的 copyparty 直接面向互联网(不通过反向代理)时,设置 `--rproxy 0`
* 否则 CORS 无法正常工作
* 如果您允许匿名上传或出于其他原因不信任卷中的内容,可以使用 volflag `nohtml` 来防止 XSS
* 这会将 HTML 文档和 SVG 图像作为纯文本返回,并且还会禁用 markdown 渲染
* `nohtml` volflag 还启用了 `noscript`,它本身可以阻止*大多数* javascript 运行;仅启用 `noscript` 而不启用 `nohtml` 使得查看 html 和 svg 文件可能是安全的(见下文),但必须使用 `nohtml` 来阻止 markdown 文档中的 javascript
* “可能安全”是因为它依赖于 `Content-Security-Policy`,因此它取决于反向代理是否转发它,以及浏览器是否理解它,但 `nohtml`(终极方案)始终有效
* 在反向代理后运行时,请侦听 unix 套接字以实现更严格的访问控制(和更高的性能);请参阅 [reverse-proxy](#reverse-proxy) 或 [`--help-bind`](` 标签
* `-lo cpp-%Y-%m%d-%H%M%S.txt.xz` 启用磁盘日志记录
* `-ls **,*,ln,p,r` 在启动时扫描任何危险的符号链接
其他杂项说明:
* 您可以通过授予 `g` 权限而不是 `r` 权限来禁用目录列表,仅接受文件的直接 URL
* 您可能需要[文件密钥](#filekeys)来防止文件名暴力破解
* 权限 `h` 而不是 `r` 使 copyparty 表现得像具有禁用目录列表/索引功能的传统 Web 服务器,转而返回 index.html
* 与文件密钥的兼容性:index.html 本身无需正确的文件密钥即可检索,但所有其他文件都受保护
## 注意事项
可能出乎意料的行为
* 对文件夹没有读取访问权限的用户仍然可以看到 `.prologue.html` / `.epilogue.html` / `PREADME.md` / `README.md` 的内容,例如为了展示如何使用上传器的描述
* 用户可以通过几种方式提交为其他访问者自动运行(在沙盒中)的 `