mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2026-11-10 12:43:54 +08:00
main
28
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b8ab76091a |
fix(seed): make 189 CAS rapid upload carry the right file, hashes and slice size (#3341)
* fix(seed): keep CAS hash matrix for 189 rapid upload CAS seeds only carry MD5 + slice MD5s, but the quick-save path rebuilt the rapid-upload request through a torrent container, which requires SHA-1 piece hashes. Every 189 秒传 therefore failed before any request was sent and reported 'target driver cannot reuse the available hashes'. - build the rapid-upload request directly from the seed file, keeping the whole MD5, slice MD5s, the drive's slice size and the legacy slice digest - let 189pc run initMultiUpload/checkTransSecond/commitMultiUploadFile when slice hashes are available, falling back to the legacy whole-MD5 upload - surface the real rapid-upload error instead of the generic message * fix(189pc): surface daily flow limit instead of generic rapid-upload error The CAS path now reaches 189's upload API, and the first real rejection is UserDayFlowOverLimited (account daily upload flow exhausted). Treat it as a terminal account state instead of retrying: - add errs.DailyFlowLimitExceeded and map UserDayFlowOverLimited / 'flow is out' onto it (189 returns it as a business code inside HTTP 200) - skip the legacy whole-MD5 fallback once the account is limited - report 'rapid upload failed: ...' with the real reason and mark the rest of the batch unavailable instead of one request per file * fix(seed): refuse to generate a seed from a seed container Generating a .cas seed from a .cas file produced an artifact with exactly the same name in the same folder, so PutDirectly overwrote the original seed with a seed-of-seed: the payload then described the few-hundred-byte metadata file instead of the video. Rapid upload of that seed 'succeeds' and only creates another .cas, which looks like CAS 秒传 doing nothing. - skip .oss/.torrent/.cas/.cas.torrent when expanding a directory - reject an explicit selection of a seed container with an actionable message - refuse to write an artifact over one of its own source files * refactor(cas): derive slice size from file size and store the final digest CAS 判重只比较最终分片摘要(逐片 MD5 汇总后再取 MD5),而切法由文件大小固定:10MiB / 20MiB / 更大文件按 1999 片上限向上取 10MiB 的整数倍。之前把 sliceMd5 当成「可变分片的哈希」、总是从逐片列表现算,切法一变就对不上云端。 - add torrent.CASSliceSize / CASPartCount / CASUniformSliceSize as the single source of truth; 189pc.partSize delegates to it - .cas writes the final digest in sliceMd5 and the per-slice list in partsMd5; slice_md5s stays readable for old files - rapid upload prefers the explicit sliceMd5 and only derives it from parts when absent - generation, recalculate and inline conversion hash CAS files at CASSliceSize per file and drop parts that do not match that slicing - piece_size no longer influences CAS hashing * fix(seed): refuse to rapid-upload a seed that describes itself A .cas generated from another .cas documents the metadata file itself (name ends with .cas, a few hundred bytes). Rapid-uploading it just creates another same-named .cas in the target folder, which looks like CAS 秒传 doing nothing. Reject that case with an actionable message instead. * test(seed): lock the rapid-upload name and the seed-of-seed guard - extract seedRapidUploadBlocker so the guard is testable - add an end-to-end test proving a legacy 5-field .cas resolves to the video name, size, slice size and final slice MD5 - add a test that seed containers are refused for rapid upload * refactor(seed): output seed and torrent messages in English Turn the error strings, task statuses and progress labels of the transfer-seed / torrent feature into English, including the 189 CAS rapid-upload path and the front-end facing guards. Comments and unrelated log lines are untouched. * refactor(cas): make the CAS slice rule a verbatim port of the 189 upload rule CAS slice size must be exactly what 189 uses when uploading, otherwise the sliceMd5 submitted for rapid upload can never match the digest the drive stored. - CASSliceSize now copies 189pc partSize expression by expression (same DEFAULT constant, same float expression, same 5x lower bound) - expectedCASPartCount mirrors fastUpload's count: one slice when size <= sliceSize, otherwise ceil(size/sliceSize) - add cross-package tests comparing CASSliceSize/CASPartCount against a verbatim copy of the 189 rule, and partSize against CASSliceSize * fix(seed): address CAS sidecar and digest review findings P1 FsStream hashed uploads with seedPieceSize() while the sidecar declared the CAS slice size; unknown-size CAS uploads now fail before writing the file instead of after. P1 buildCASFileEntry only compared piece counts, so 8MiB slices could be reused as 10MiB CAS slices; it now requires the slicing to match. P2 multi-slice payloads without sliceMd5 are rejected instead of falling back to the whole-file MD5, and oversized CAS slice sizes are clamped for the seed container only. --------- Co-authored-by: pikachuren <pikachuren@example.com> |
||
|
|
ef5d8c8d41 |
feat(media): scan every folder level, save incrementally, TV tags, seed task progress (#3263)
* feat(media): scan every folder level, save incrementally, TV tags, seed task progress Media library - Merge mode now walks every folder level instead of only the first one. A folder that directly contains media files is one collection and is not split further; a folder without media is descended into. Loose files in the scan root stay individual items. Depth is capped at 16. - Scanning no longer buffers the whole tree before writing: items are flushed to the database every 20 items or 3 seconds, for all four media types, so results appear while the scan is still running. Skipped and failed items still advance the progress counter. - The scan path type tag now decides movie vs. series. Tags such as TV series / anime / variety / documentary mark every video under the path as "tv" (shown as series in Emby, also for single files); movie tags force "movie" even when merge mode is on. Unrecognised tags keep the old rule (folder items are series). Emby virtual folders use the same rule. - Fix: a music folder containing a non-audio file was dropped entirely. Playback URL - When no site_url is configured and the request host is a loopback address (127.0.0.1 / localhost / ::1), stream_url now returns relative /d and /p paths instead of absolute loopback URLs. An explicit site_url or a forwarded host still produces absolute URLs. Seed tasks - Seed generation reports progress by bytes hashed plus a stage message and is exposed at /task/seed_generate. - Seed save, rapid upload and transit transfer register a display-only task at /task/seed_save (the operation stays synchronous) so progress is visible in the task list. Tests cover tag classification, index-length checks, level-by-level merge scanning (stop at collection, list errors, depth limit) and loopback detection. Co-Authored-By: Claude <noreply@anthropic.com> * fix(server): keep site_url path prefix in playback base url site_url 允许配置成 /openlist 这样的路径前缀;原先只有以 http 开头才走绝对地址,前缀模式下播放地址会丢掉前缀导致 404。改为配置了 site_url 就统一用 GetApiUrlFromRequest 生成。 * feat(media): season-aware episodes, album admin api, cover upload, zip export - 扫描:季目录(第N季/Season N/S01)解析季号写入 EpisodeInfo.season,Emby 与播放器可按季分组;显式电影标签不再被季目录反推成剧集;merge_depth 语义固定为「第 N 层=一条记录」,与模型注释、UI 一致 - 刮削:音乐条目的文件自带封面(data:/thumb:/站内地址)不再被在线封面覆盖 - 后台新增:封面 URL/上传(/admin/media/items/cover)、专辑聚合列表与批量编辑(/admin/media/albums、/album/items、/album/update)、条目可编辑字段扩充(选集/视频类型/季集/时长/外部ID) - 导入导出升级为 zip(media_export.json + covers/),导入兼容旧 JSON - Emby:多季合集按每集 season 拆分 Season,集 ID 带季号避免跨季重号 - fix(seed):中转转存部分文件失败时任务按失败收尾,不再一律标记成功 * fix(media): patch semantics for item update, transactional album update, concurrent cover export - UpdateMediaItemAdmin 改为 PATCH 语义(字段全部指针,只写出现过的键),修复只传 hidden 也会清空 cover/plot 的问题;cover 增加 12MB 上限 - 专辑批量更新走单事务(新增 db.UpdateMediaItems),失败整批回滚;旧封面文件在事务成功后才删除 - 导出封面改为并发读取(4 并发,单张 8MB / 总量 512MB / 5000 张上限),避免大库导出逐张串行 * fix(media,seed): unify episode ids, season fallback, cancellable seed tasks, periodic flush - Emby 集 ID 统一走 parseEpisodeID(新格式 ep-item-season-num,兼容旧两段),修掉封面/刷新/续播列表里仍假设旧格式的三处;续播能唯一定位时补季号 - 季号兜底 seasonFromText 与前端 episodeSeasonOf 规则对齐,老数据不会在 Emby 和网页端分到不同季 - 种子任务真正可取消:任务 ctx 重新绑定(tache Add 会覆盖)、保存 IO 改用任务 ctx、逐文件与哈希读取检查取消、取消后状态为 Canceled - mediaSaver 增加定时落盘协程,Close 时停表并收尾 Flush * feat(media): artist aggregation api and image exif lookup - 新增 GET /fs/media/artists(db.ListArtists):按 album_artist 聚合专辑数/曲目数/封面,供音乐库「按艺术家」分类 - /fs/media/albums 支持 album_artist 过滤,艺术家下钻时只取该艺术家的专辑 - 新增 GET /fs/media/exif:按需读取图片文件头解析 EXIF(设备/镜头/曝光/焦距/时间/GPS)并缓存,解析失败返回 available=false 而不是 500 * fix(emby): return full UserDto from /Users/Public (issue #3301) 严格类型的客户端会把 user['Policy'] / user['Configuration'] 直接强转成 Map, 之前 /Users/Public 只返回 5 个标量字段,转 null 时抛异常并中断渲染(封面全挂)。 - 删除 embyPublicUserDto,/Users/Public 直接复用 embyUserDtoOf,与登录接口结构一致 - 新增 embyUserConfiguration(),按官方 UserConfiguration 给全默认值(空 map 同样是缺键) - 补 TestEmbyUserDtoHasPolicyAndConfiguration 回归测试 * feat(media): pure-go pdf cover rendering, keep existing cover by default, same-dir thumbnails - PDF 封面改用纯 Go 光栅化(github.com/go-pdfkit/render,BSD-3、无 cgo):渲染第 1 页再缩到 300px,矢量/扫描件/Flate 压缩图都能出图;失败时仍退回原来的内嵌 JPEG 扫描。渲染带 MaxPixels/MaxDuration 上限,防止恶意或超大页面拖住扫描 - 新增设置 media_overwrite_cover(默认关闭):刮削不再覆盖条目已有封面,只负责补空;需要替换时手动打开。原先只对音乐做了保护,现在统一到所有媒体类型 - 缩略图存储新增 samedir 模式:封面写到媒体文件同目录,文件名为「原文件名.图片后缀」(song.flac.jpg),不覆盖原文件,也不需要配置 VFS 目录 - 依赖代价:go 指令 1.26.0 -> 1.26.4,新增 render 及其纯 Go 依赖(go-gfx/opentype 等),go.sum 由 tidy 收敛 * feat(media): add skip-file-metadata switch (default off) - 新设置 media_skip_file_metadata(默认关闭):开启后扫描与刮削都不读取媒体文件内容 - 音乐:扫描与刮削均跳过 ID3/Vorbis 解析,退回目录名/文件名,内嵌封面与内嵌歌词一并跳过 - 书籍:刮削时跳过 EPUB/PDF 内嵌封面提取 - 图片:刮削时跳过 EXIF(拍摄时间/地点/设备),缩略图仍生成 - 书籍封面依旧只在刮削阶段提取,扫描阶段完全不读文件 * feat(seed): support folder expansion, split mode and structure-preserving paths - 右键目录也能生成种子:后端递归展开目录下所有文件(深度/数量上限,逐目录校验权限) - 新增 preserve_structure(默认关闭):开启后种子内保留相对目录结构,关闭时拍平成文件名,重名自动加序号 - 新增 split(默认关闭):每个文件生成一个种子;关闭时全部合并(默认) - 默认命名:单文件/单目录用其名字;多选合并固定为 torrent - 能力探测接口同步支持目录,前端按展开后的文件列表展示哈希/流量 - 单测覆盖命名规则、保留/拍平路径与重名处理 * feat(seed): compute missing hashes from source files when converting - ConvertSeed 新增 compute_missing / file_base_path:缺哈希时按种子内相对路径读取源目录文件补算,而不是直接返回不可转换 - torrent 目标按整包拼接计算 SHA-1 pieces(解决 piece boundary crosses the next file),CAS 目标按 10 MiB 分片补 MD5 - 补算后仍不满足时返回 400 并带具体原因,避免前端误判成功 * feat(seed): persist overall comment when converting - /fs/seed/convert 新增 comment 字段(指针,允许清空) - 转换与保存注释合并为一次请求,前端不必先保存再转换 * feat(seed): convert to multiple target formats in one request - /fs/seed/convert 新增 formats 数组(去重、bt 别名、最多 3 个),逐个编码并写入目标目录,返回 artifacts - 每个目标独立解码,避免 CAS 补算修改 PieceSize 后污染 torrent pieces - 预检仍保留「不可转换 + 原因」的响应;单目标响应字段保持兼容 - 新增 TestSeedConvertTargets * fix(seed): identity conversion is always feasible and folder roots no longer nest twice - seedConversionStates 现在接收源格式:目标等于源格式时直接可行,不再用「按文件 pieces」去诊断整包结构。合法 torrent(pieces 跨文件)之前被误报 piece boundary crosses the next file,导致预览页对当前格式打叉\n- ConvertSeed 对同一格式直接复制原始字节,跳过诊断与重新编码\n- 保留目录结构时,只选一个目录以该目录为根,修复「剧/剧/S01/...」重复嵌套\n- 新增回归测试:身份转换可行、跨格式仍诊断、单目录/多目录保留结构路径 * fix(seed): keep the torrent's global pieces so it can be re-encoded - Seed 新增运行时字段 GlobalPieces:解析 .torrent 时保留整包 SHA-1 pieces(含 x-openlist 种子),重新编码直接复用,不再按文件拼接\n- DiagnoseConversion 在存在整包 pieces 时跳过「piece 跨文件」检查;否则合法 torrent 会被判成不可转换(Cannot convert to torrent: piece boundary crosses the next file)\n- TorrentFromSeed 优先使用整包 pieces,并对无效哈希返回诊断而不是静默拼接\n- 移除文件 / 重算哈希后清空 GlobalPieces,避免用对不上的旧 pieces 编码\n- 新增往返测试:跨文件 pieces 编码→解析→再编码字节一致;逐文件 pieces 仍拒绝跨文件拼接 * fix(seed): expose seed-level hash availability for torrents BT 的 pieces 是整包的,跨文件时无法拆到单个文件(ValidateSeed 要求每文件片数 = ceil(size/piece)),此前这些文件拿不到 pieces,前端按文件判断就全显示 needs file;现在 SeedFromTorrent 汇总 available_hashes / available_piece_hashes,前端优先按种子级标记显示,并补生成到解析的往返测试 * fix(seed): accept single-file torrent name differing from x-openlist 单文件 torrent 的 info.name 是文件名(带扩展名),x-openlist 的 seed.name 可以不带扩展名;一致性校验此前直接比较两者,判定种子损坏,导致解析 400、前端兜底本地解析(无 conversions/无哈希,全部显示 needs file)。现在单文件允许 info.name == base(seed.Files[0].Path),并补回归测试 * fix(media-seed): address audit findings and review feedback - Enforce seed source visibility, bounded hashing, and stream cleanup. - Apply conversion selections and hash matrices, preserve comments and global pieces, and restore legacy episode IDs. - Correct task cancellation and retries, scan persistence, and cover protection. - Bound and validate media ZIP import/export, authorize public aggregates, and handle cover edit patches. - Add regression tests and extend the CI test scope. --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: pikachuren <pikachuren@example.com> |
||
|
|
0497ee8538 | fix(mysql): add size constraint to WebDAVProperty string fields for MySQL compatibility (#3259) | ||
|
|
25e4eb663f |
feat(func): media library (#2210)
* feat(func): media library
* feat(func): media library
* feat(func): media library
* feat(func): media library build test
* feat(func): media library build test
* feat(func): media library fix remote fetch error
* feat(func): media library fix remote fetch error
* feat(func): media library fix remote fetch error
* feat(func): media library support select
* feat(func): media library support select
* feat(func): media library support select
* feat(func): media library support select
* feat(func): media library support change api url
* feat(func): media library support change api url
* feat(func): media library support change api url
* feat(media): 并发刮削(默认 5)+ 单条落库
增强 TMDB 搜索:模糊匹配 + 多候选关键词
管理页面新增导入/导出媒体库(全部 / 按扫描路径)
缩略图路径默认值改为 imgs
* feat(media): 清空刮削、删除已失效
* fix(media): fix api proxy path
* fix(media): fix lrc file display & music id3
* fix(media): fix media scan sub path error
* feat(media): support cloud codec via ffmpeg
* feat(media): support cloud codec via ffmpeg
* feat(media): support cloud codec via ffmpeg
* feat(media): support cloud codec via ffmpeg
* feat(media): 提升刮削精准度,支持模糊刮削
* fix(media): clean up imports and improve FetchFileReader logic
* feat(media): 提升刮削精准度,支持模糊刮削
* feat(media): 刮削支持自定义刮削数量,避免太占性能
* feat(media): 刮削支持自定义刮削数量,避免太占性能
* feat(media): 刮削修复写入作品名问题
* fix(media): return 404 on missing item_id and fix unscraped item query
- Validate GetMediaItemByID result before spawning goroutine in
StartMediaScrape; return 404 when item_id > 0 but item is not found
- Replace `description` check with `plot` check in GetUnscrappedItems
since scrapers populate Plot, not Description, to avoid re-selecting
already-scraped items on every run
* Apply remaining changes
* feat(media): add master switch, app keys, STRM, Emby and OpenSubsonic APIs
* feat(media): allow any logged-in user to manage their own media app keys
* feat(media): allow signing arbitrary media path for local player
* fix(media): always return an array for media status types
* fix(media): persist per-type scraper config and apply it to thumbnails
* feat(media): add local thumbnail endpoint and cover proxy with fallback gateway
* fix(media): allow guest media access, per-file local thumbnails and optional cover proxy
* feat(media): thumbnail storage modes and STRM same-directory output
* feat(media): Google Books/OpenLibrary sources and remote cover download
* chore(media): rename transcode cache dir to ctmp and log thumbnail storage dir
* feat(media): progress and favorites API shared with Emby/Subsonic
* chore: ignore runtime thumbnail directory
* feat(media): add preferred scrape language and namespace protocol endpoints under @
* fix(media): harden anonymous emby images, pagination and cover proxy SSRF
* fix(emby): allow anonymous user discovery and login before auth
* chore: drop redundant media build workflow and protocol doc
* fix(media): ID3v2.4 syncsafe frame size and preserve Hidden flag on rescan
* fix(media): address security review (path traversal, guest bypass, cover XSS, auth rate limit, SSRF, quotas, migration)
* fix(media): 清理失效条目时只删除确认不存在的记录
此前 fs.Get 返回任何错误都视为失效并硬删除,驱动故障/超时/鉴权失败时会误删有效媒体记录。现在仅 errs.IsObjectNotFound 才删除,其余错误跳过并在响应中返回 skipped 计数。
* fix(transcode): 播放凭据与 Worker 回写凭据分离,并收紧 profile 与鉴权校验
- 新增 Job.PlayToken(json 标签为 -),master/playlist/切片只认播放凭据,播放器不再拿到可上传、可结束任务的 callback_token
- Worker 上传切片时校验 profile 必须属于任务声明的档位
- TCMaster 与 WorkerJobFinish 改用恒定时间比较,避免时序侧信道
* fix(transcode): 含冒号的本地文件名可转码,补基址缺失与重新激活配额
- ValidSourceInput 不再按冒号位置判协议:本地输入只要求以 / 开头或 Windows 盘符路径,concat:/subfile: 等前缀仍被拒且由 -protocol_whitelist 兜底(修复 /mnt/x/Star Wars: IV.mkv 被误判)
- trustedInternalBaseURL 返回空串时直接 503 并给出明确原因,不再拼出 /d/xxx 让 ffmpeg 报文件不存在
- 远程输入白名单收窄为 http,https,tcp,tls(去掉 file 与 crypto)
- Reactivate 复用同一套单用户配额,避免「先让任务闲置取消、再批量激活」绕过 SubmitLimited;配额不足返回 429
- OwnerID 改为配额键:普通用户 user:<id>,访客 guest:<clientIP>,避免单个匿名访客占满全部匿名配额;补充对应单测
* fix(media): 收紧缩略图解码内存、跳过超长条目可见化,并补 CI 单测
- MaxImagePixels 从 64MP 降到 32MP,宽高改 int64 相乘防 32 位溢出,解码阶段加 12 路全局信号量
- 封面解码失败退回原始字节时限制 512KB,避免十几 MB 的 base64 写进 cover 列(豆瓣/本地书籍三处)
- 扫描进度新增 Skipped 计数,入库被跳过的超长路径会在完成消息与日志中体现
- 数据库迁移失败日志补充 OPENLIST_MEDIA_MIGRATE_WIPE=1 的处置提示
- Subsonic 认证只对「确实带了凭据却校验失败」计数,裸探测不再刷新 IP 锁定
- goexif 从 indirect 调整为直接依赖(internal/media/scraper/image.go 直接 import)
- CI 新增 go test ./internal/db/... ./internal/transcode/... ./internal/media/...
* fix(transcode): 配额/队列满时仍放行已缓存切片,并同步 worker 协议白名单
- TCSegment/TCPlaylist: Reactivate 返回 ErrUserQuota/ErrQueueFull 时不再直接 429,改为标记 quotaBlocked,缓存命中的切片与 playlist 仍可读,只有缓存缺失才返回 429
- Reactivate: 补充全局排队上限 (MaxPendingJobs) 检查,避免批量激活顶爆队列,并补单测
- cmd/worker: 远程输入协议白名单与 master 同步为 http,https,tcp,tls(去掉 file/crypto)
- scraper: decodeSem 容量 12 -> 3,避免信号量大于默认刮削并发而形同失效
* feat(emby): 完善客户端兼容层并修复认证锁定,Subsonic 复用统一密钥校验
- Emby: 用户 ID 改用 GUID 并兼容数字/旧 ID;补齐 /Users/{id}/Authenticate、Sessions 与 WebSocket、首页分区、合集/播放列表、字幕流与歌词、Series/Season 结构
- Emby: 版本号返回客户端可接受的兼容版本,/Users/Public 返回可登录用户以渲染用户选择
- Subsonic: 支持 enc: 十六进制密码编码;app key 校验与 Emby 共用 LookUpAppKeyUser
- 限流: 认证被拒时不再刷新锁定过期时间,避免客户端持续轮询把 IP 永久锁死
* fix(media): 认证失败计数增加用户名维度,防止伪造 X-Forwarded-For 绕过锁定
- media_ratelimit: 新增 mediaAuthLockedFor / mediaAuthFailedFor / mediaAuthSucceededFor,IP 与用户名双维度计数;达到上限同样锁定 5 分钟且被拒时不续期
- emby: 按用户名登录与按 id 登录都检查用户名维度;失败计入两个维度,成功清除两个维度
- subsonic: subAuth 与 429 分支改用双维度判定;成功时用真实用户名清理计数(apiKey 认证时 u 参数为空)
- 仍保留主干 5 次/5 分钟的策略,代理信任范围(SetTrustedProxies)留给项目层面单独处理
* fix(media): 匿名封面按访客身份过滤,认证日志脱敏并收紧限流计数
- embyImage: 匿名封面不再走 loadEmbyLibraryAll(全库可见),改为 loadEmbyLibrary(guest):
hidden / base_path 之外 / meta 受保护的条目都不可见,访客被禁用时直接 401
- embyUnauthorized: 只记录 Path、UA 与是否带 token,避免 query 里的 Pw/Password/api_key
和 X-Emby-Authorization 里的设备令牌写进日志
- media_ratelimit: 失败计数 Set 时带 5min TTL,避免 IP/用户名 key 无限增长(用户名来自请求参数)
- auth.loginHash: 锁定期间不再续期,失败计数同样带 TTL,与媒体侧语义一致
- /System/Endpoint: 按 RemoteAddr 判断 IsLocal/IsInNetwork;/System/Info 不再返回真实监听端口
* feat(media): PDF 批注持久化
- 新增 MediaAnnotation 模型:按 (user_id, item_id, remote_id) 唯一,anchor 原样保存查看器批注对象,不重复建模页码/坐标
- GET/POST /fs/media/annotations:读取当前用户批注、按 remote_id 增量 upsert/delete(单条 512KB、单次 8MB、最多 500 条)
- 批注为用户私有数据:未登录返回空列表,访客写入 403,并校验条目可见性与访问权限
- 条目删除 / 清空类型 / 清空扫描路径 / 批量删除时,在同一事务内清理对应批注
* fix(media): 选集签名前校验最终文件权限;转码在 ffprobe 前预检配额
- GetMediaStreamURL / GetMediaStrm: 解析选集后对最终 rawPath 再执行 CanUserAccessPath,避免「目录可见但 meta 隐藏规则禁止其中某个文件」时仍能拿到有效签名(签名之后下载链路不会重跑隐藏规则)
- TranscodePlay: ProbeSource 之前调用 Scheduler.Capacity 预检配额,已满直接 429,不再先起最长 30s 的 ffprobe
- 新增探测并发闸门(全局 8 / 每用户 3),覆盖预检与 SubmitLimited 之间的并发窗口;用 defer 释放,探测 panic 也不会占死槽位
- 补 Capacity 单测
---------
Co-authored-by: j2rong4cn <j2rong@qq.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: pikachuren <pikachuren@example.com>
|
||
|
|
2caa4f5d15 |
feat(seed): add advanced transfer seed UI (generate/preview/manage) (#3058)
* feat: add system initialization (setup wizard) support * Squashed commit of the following: commit |
||
|
|
4a7acaee61 |
fix(wopan): apply browser user agent and refresh tokens before init (#3222)
WoPan (China Unicom Cloud Drive) storages failed to initialize with `failed get objs: failed to list objs: request failed with status: 403 Forbidden`. Two independent defects in the driver's initialization path: * The SDK keeps the browser User-Agent in a private field (WithUA/SetUA) and only applies it to upload2C, so every dispatcher request went out with resty's default `go-resty/...` User-Agent. The WoPan edge rejects non-browser agents with HTTP 403. Apply wopan.DefaultUA to the resty client before the first request. * With only a refresh token configured, FamilyUserCurrentEncode was called before the access token existed. Request bodies are AES encrypted with accessToken[:16], so an empty token failed with `crypto/aes: invalid key size 0`. Refresh a missing or too short access token first, then initialize user data and query the default family. Also drop the mandatory refresh_token flag so an access token alone is enough, and add regression tests covering credential combinations, refresh ordering and the dispatcher User-Agent. Co-authored-by: pikachuren <pikachuren@example.com> |
||
|
|
3b28270a40 | feat(drivers/139): make the API client type configurable (#3196) | ||
|
|
2d51c9ab4b |
feat!(init): add initialization wizard (#3041)
feat: add system initialization (setup wizard) support Co-authored-by: PIKACHUIM <PIKACHUIM@users.noreply.github.com> |
||
|
|
6ad44605c0 |
feat(drivers/guangyapan): add md5-based instant upload support (#3034)
feat(guangyapan): add md5-based instant upload support Co-authored-by: PIKACHUIM <PIKACHUIM@users.noreply.github.com> |
||
|
|
6f80df2827 |
feat(drivers): add GuangYaPan driver with offline download support (#2882)
* feat(drivers): add GuangYaPan driver with offline download support * fix(drivers): GuangYaPan driver multipartUploadToOSS |
||
|
|
f63a5e15ee | fix(deps): update module github.com/stangelandcl/ppmd v0.1.1 (#2698) | ||
|
|
bfbc441fa6 |
fix(drivers/189pc): sync .torrent file when copy/move/rename/upload (#2522)
* fix(torrent): sync .torrent file when copy/move/rename/upload * fix(torrent): prevent recursive torrent generation * fix(189pc): address review comments on torrent sidecar handling - Only append SHA-1 piece hash when n > 0, preventing spurious piece for empty files (BitTorrent v1 requires 0 pieces for 0-byte files) - Explicitly guard torrent generation with size > 0 - Log findFileByName errors in torrentFollowCopy/Move/Rename instead of silently discarding them - Log WaitBatchTask failure for follow-move operation - Rename Cloud189File.ParentId to ParentID to match Go initialism conventions (consistent with Cloud189Folder.ParentID, Cloud189File.ID) * revert(ci): go .sum 115 sdk --------- Co-authored-by: Suyunmeng <Susus0175@proton.me> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |
||
|
|
d4aa8b6a15 | fix(driver): 123pan url www.123pan.com -> yun.123pan.com (#2678) | ||
|
|
64d39114ee | chore(doc): add sponsors (#2531) | ||
|
|
ba6f96ca4e | fix(driver): json: cannot unmarshal number into Go struct field RenameResp.id of type string (#2526) | ||
|
|
b28208bd76 | fix(189pc): handle numeric res_code in RenameResp to fix JSON unmarshal error (#2489) | ||
|
|
1d071c0fd8 |
feat(func): support ed2k & magnet & torrent offline download (#2452)
Add end-to-end offline download support for torrent files, magnet links, and ed2k links, including torrent parse and generate APIs, CAS-based rapid upload for Cloud189, and protocol-aware tool routing with transfer flow improvements. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com> Co-authored-by: j2rong4cn <j2rong@qq.com> Co-authored-by: Suyunjing <suyunmeng@oplist.org.cn> |
||
|
|
7feec2b7d9 |
fix(driver): fix 189 & 189pc fastcopy form local storage (#2471)
* fix(driver): fix 189 & 189pc fastcopy form local storage * fix(driver): fix 189 & 189pc fastcopy form local storage * fix(driver): fix 189 & 189pc fastcopy form local storage |
||
|
|
9fdba3a730 |
feat(drivers/123_open): support 123 official app api (#2293)
* feat(driver): support 123 official app api * fix(123_open): migrate api refresh to token.go Signed-off-by: MadDogOwner <xiaoran@xrgzs.top> * fix(drivers/123_open): trigger proactive refresh with client credentials * fix(drivers/123_open): use client-credential token endpoint for local refresh Keep renewapi parsing for expires_in and map it to internal expiry time handling. * fix(drivers/123_open): limit proactive refresh to client credentials * fix(drivers/123_open): allow renewapi refresh token proactive init * fix(drivers/123_open): update API address to use renewapi endpoint * fix(drivers/123_open): simplify token refresh parsing * fix(drivers/123_open): unify token expiration to expiredAt --------- Signed-off-by: MadDogOwner <xiaoran@xrgzs.top> Co-authored-by: MadDogOwner <xiaoran@xrgzs.top> Co-authored-by: Suyunmeng <Susus0175@proton.me> Co-authored-by: Suyunjing <suyunmeng@oplist.org.cn> |
||
|
|
d598ef7569 |
refactor(db)!: replace SQLite Driver with glebarez/sqlite to avoid CGO (#2211)
* mod(db): driver/sqlite ->glebarez/sqlite * mod(db): driver/sqlite ->glebarez/sqlite * [WIP] Refactor SQLite Driver with glebarez/sqlite to avoid CGO (#2213) * Initial plan * fix: address review comments - fix import order, update test, remove CGO sqlite deps Co-authored-by: PIKACHUIM <40362270+PIKACHUIM@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: PIKACHUIM <40362270+PIKACHUIM@users.noreply.github.com> --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> |
||
|
|
648079ae24 |
remove upx (#750)
Update build.sh Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com> |
||
|
|
890297aa27 |
add(driver): quark 302 test (#367)
* add(driver): quark 302 test * del(driver): baidu share * add(driver): revert quark 302 test |
||
|
|
652e4ba1cb | add dropbox api (#295) | ||
|
|
ca55b89322 |
remove alist from repo (#230)
* remove alist from repo * remove alist from repo * remove alist from repo |
||
|
|
0f8545133b |
add text output for error message (#210)
* mod rank for AccessToken * del alist_v2 * add error message from remote --------- Co-authored-by: Suyunmeng <sumengjing@outlook.com> |
||
|
|
b7ce7f172b |
Dev pika (#202)
* mod rank for AccessToken * del alist_v2 --------- Co-authored-by: Suyunmeng <sumengjing@outlook.com> |
||
|
|
c7c0bfe810 | mod rank for AccessToken (#181) | ||
|
|
8822eef97e |
chore(api):Add online api refresh method (#143)
* Add Official API Refresh Interface(Baiduyun) * add UseOnlineAPI & APIAddress add _refreshToken using APIAddress * fix return * Modify the frontend display using the default API refresh method * Fixed display and operation related issues * fixed aliyundrive_open old refresh --------- Co-authored-by: Suyunmeng <sumengjing@outlook.com> |