Wuliu File Manager (五柳檔案管理腳本) Golang Scripts
- 档案(檔案) = 文件 = file
- 资料夹(資料夾) = 文件夹 = folder = directory
- 专案(專案) = 项目 = project
- 列印 = 打印/显示 = print
- 後綴名(副檔名) = 后缀名/扩展名
- 給檔案增加更多屬性,例如: 備注、標籤、關鍵詞、点赞。
有了这些属性,就能做到:
- 快速找出大文件
- 快速找出指定日期的文件
- 快速找出常用或精品文件(利用点赞功能)
- 根据标签或关键词搜索文件
- 随手给文件写一句备注或说明(利用备注属性)
- 多维度分类文件(利用关键词、集合、专辑等属性)
- 如果你懂编程(任何语言!不限语言!)你就能自行添加属性, 自行编程添加功能,因为每个文件的属性都是一个 json 文件。
- 檢查檔案完整性
- 方便地備份
- 方便地修復受損檔案
- 非常重视编程简单
- 运行效率和使用方便都是次要的
【注意】: 這些腳本為了編程方便,犧牲了易用性,因此在使用過程中必須 一邊閱讀本文 (README.md) 一邊使用。
- 安裝 Golang
- 下載 Wuliu 原始碼
- 添加環境變數
- wuliu-init (新建/初始化一个专案)
cat project.info
(查看专案信息)- wuliu-orphan (检查有无孤立档案)
- wuliu-add (添加档案)
- wuliu-delete (删除档案)
- wuliu-rename (更改檔案名稱)
- wuliu-list (列印档案、标签、备注、关键词等)
- wuliu-search (搜尋檔案)
- wuliu-db (数据库信息,更新缓存)
- wuliu-checksum (检查档案完整性)
- wuliu-backup (备份专案)
- wuliu-export (導出檔案或檔案屬性)
- wuliu-overwrite (更新單個檔案或檔案屬性)
- wuliu-metadata (批量修改多個檔案的屬性)
- wuliu-like (點讚,方便尋找精品或常用檔案)
- 新建/初始化一个专案,主要是新建一些资料夹和数据库、配置等。
- 只能对一个空资料夹进行初始化
- 使用方法: 进入一个空资料夹,执行
wuliu-init -name [NAME]
进行初始化。 - 注意,请为不同的专案设定不同的名称,备份时有用。
- 备份专案(详见关于
wuliu-backup
的说明)的专案名称必须与源专案一致。 wuliu-init -h
列印帮助信息wuliu-init -v
列印版本信息wuliu-init -where
列印 wuliu-init 的位置
初始化后,会得到一些资料夹。
- input (專用於添加新檔案)
- files (執行 wuliu-add 後, input 裏的檔案會移動到 files 裏)
- metadata (files 裏的每個檔案都有一個對應的屬性檔案 (json檔案))
- buffer (用於導出檔案或修改檔案)
- webpages (生成網頁便於檢索檔案)
- recyclebin (執行 wuliu-delete 刪除的檔案會被移進這裏)
其中,尤其需要注意 input 與 buffer 的區別, 一個是專用於添加新檔案,一個是用於更新檔案(或修改檔案屬性)。
並且, wuliu-add 和 wuliu-import 命令只能操作 input 資料夾, wuliu-export 和 wuliu-overwrite 命令只能操作 buffer 資料夾。
【注意】: 請勿直接修改 files 與 metadata 裏的檔案。 如需修改,請導出後修改,然後再使用 wuliu-overwrite 覆蓋舊檔案。
执行 cat project.json
可查看专案信息。
当然,也可直接打开 project.json 查看。
type ProjectInfo struct {
RepoName string // 用于判断资料夹是否 Wuliu 专案
ProjectName string // 备份时要求专案名称相同
IsBackup bool // 是否副本(副本禁止添加、删除等)
Projects []string // 第一个是主专案,然后是备份专案
LastBackupAt []string // 上次备份时间
CheckInterval int // 检查完整性, 单位: day
CheckSizeLimit int // 检查完整性, 单位: MB
ExportSizeLimit int // 導出檔案體積上限,單位: MB
ThumbSize [2]int // 縮略圖尺寸
}
其中 Projects
要注意必须确保第一个是 "."。
- 孤立档案: files 资料夹里的每个档案都有一个同名 json 在 metadata 资料夹中, 如果缺少同名 json, 就是孤立档案。
wuliu-orphan --check
命令会检查有无孤立档案,如果有,就提示处理- 如果在 metadata 中有 json, 但在 files 中找不到对应的档案,也会提示处理
- 建议在某些操作(例如添加档案)之前先检查有无孤立档案
- 该命令用于添加档案,同时也用于发现新档案
- 需要添加属性
--danger
才能真正添加新档案,否则就只是列出新档案 - 如果有一段时间未执行
wuliu-orphan
命令,建议先执行wuliu-orphan
- 请把需要添加的档案放到 input 资料夹中,然后执行
wuliu-add
- 执行
wuliu-add --newjson add.json
可在 input 资料夹中生成一个新的 add.json, 方便编辑 - 在 add.json 中会列出全部待添加的档案名称
- 在 add.json 中删除不需要添加的档案名称
- 执行命令
wuliu-add --json add.json
只添加指定的新档案
- 执行
wuliu-add --newjson add.json
可在 input 资料夹中生成一个新的 add.json, 方便编辑 - 执行
wuliu-add --json add.json
列出 add.json 中指定的待添加档案, 同时列出 add.json 里的档案属性,该属性将应用于全部待添加档案。 - 注意, add.json 应放在专案的根目录。
- 需要添加参数
-danger
才能真正添加新档案,否则就只是列印相关信息
- 生成 add.json 后,可删除其中的 filenames 的内容 (修改后是这样
"filenames": []
), 表示作用于 input 资料夹中的全部档案。 - 删除 filenames 的内容后,可执行
wuliu-add -json add.json
预览配置, 添加参数-danger
正式执行。
一旦成功添加檔案,在 metadata 資料夾中會自動生成同名 json, 在該 json 中 含有檔案屬性,但請勿直接修改 json 內容。
也不可直接修改檔案本身。
如需修改檔案本身 或 檔案屬性,請使用 wuliu-export 與 wuliu-overwrite (詳見後文的相關章節)
如需更改檔案名稱,請使用 wuliu-rename 命令。
{
ID string `json:"id"` // 档案名称的 CRC32
Filename string `json:"filename"` // 档案名称
Checksum string `json:"checksum"` // BLAKE2b
Size int64 `json:"size"` // length in bytes for regular files
Type string `json:"type"` // 檔案類型, 例: text/js, office/docx
Like int64 `json:"like"` // 點贊
Label string `json:"label"` // 标签,便於搜尋
Notes string `json:"notes"` // 備註,便於搜尋
Keywords []string `json:"keywords"` // 關鍵詞, 便於搜尋
Collections []string `json:"collections"` // 集合(分组),一个档案可属于多个集合
Albums []string `json:"albums"` // 相册(专辑),主要用于图片和音乐
CTime string `json:"ctime"` // RFC3339 檔案入庫時間
UTime string `json:"utime"` // RFC3339 檔案更新時間
// Checked string `json:"checked"` // RFC3339 上次校驗檔案完整性的時間
// Damaged bool `json:"damaged"` // 上次校驗結果 (檔案是否損壞)
}
- ID 是档案名称的 CRC32,有冲突的可能性,但可能性较低, 大不了冲突了再改档案名称,问题不大。 后续如果档案数量大了,可以考虑改用 CRC64
- 关于 CRC32 https://softwareengineering.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed
- Type, Label, Note, Keywords 等都是为了方便搜寻,请大胆灵活使用。
- Keywords, Collections 等
[]string
类型,都排序,排序后转为纯字符 (用逗号空格,
分隔)方便保存到 kv 数据库。 - 因此
[]string
类型在用户输入时不允许包含半角逗号和空格。 - 請勿直接修改 metadata 裏的檔案。 如需修改,請導出後修改,然後再使用 wuliu-overwrite 覆蓋舊檔案。
- 手動修改檔案屬性時,請勿直接修改 ID, Filename, Checksum, Size.
- ID 與 Filename 是相關的,修改檔案名稱會改變 ID. 如需更改檔案名稱,請使用 wuliu-rename 命令。
- 该命令删除档案,同时删除对应的 json 档案和数据库中的条目
wuliu-delete -id [ID]
通过档案 ID 指定需要删除的档案(只能指定一个)wuliu-delete -name [NAME]
通过档案名称指定需要删除的档案(只能指定一个)wuliu-delete --newjson delete.json
在专案根目录生成一个 delete.json 档案模板, 方便批量填写需要删除的档案。- 在 delete.json 中填写要删除的一个或多个档案的 id
wuliu-delete --json delete.json
通过 delete.json 指定需要删除的档案(可指定多个)- 需要添加属性
--danger
才能真正删除档案,否则就只是列出 delete.json 的内容
ID 與 Filename 是相關的,修改檔案名稱會改變 ID. 而且, files 與 metadata 的檔案名稱也要同時更改,因此, 如需更改檔案名稱,請使用 wuliu-rename 命令,不要手動更改。
wuliu-rename -id=[ID] -name [NAME]
其中 ID 是舊ID, NAME 是新檔名。- 注意檔名包括後綴名。
- 更改檔名不會修改 UTime(檔案更新時間)
wuliu-list
列印最近 15 个档案 (ID, 体积, 档案名称)wuliu-list n=100
列印最近 100 个档案,按 CTime 倒序排列 (CTime 是入库时间)- 默認按 CTime 排序,使用參數
-orderby [INDEX]
可按其他維度排序 (例如 size, like, utime 等) (注意,有時需要先執行wuliu-db -update=cache
更新數據庫緩存。)- 例:
wuliu-list -orderby utime
列印最近修改過的 15 个档案
- 例:
- 默認從大到小排序 (descending), 使用參數
-asc
改為從小到大排序 (ascending)。- 例:
wuliu-list -orderby size
列印體積最大的 15 个档案 - 例:
wuliu-list -orderby=size -asc
列印體積最小的 15 个档案
- 例:
- 默認列印簡單信息 (ID, 体积, 档案名称), 使用參數
-more
列印詳細信息。 wuliu-list > list.txt
可把結果保存到一個檔案中。
上面是 wuliu-list 列印檔案的功能,另外, wuliu-list 還有其他功能,如下所示:
(注意,有時需要先執行 wuliu-db -update=cache
更新數據庫緩存。)
wuliu-list -labels
列印全部標籤wuliu-list -notes
列印全部備註wuliu-list -keywords
列印全部關鍵詞wuliu-list -collections
列印全部集合wuliu-list -albums
列印全部相簿(專輯)
參數 labels/notes/keywords/collections/albums 可多個同時使用,例如
wuliu-list -labels -keywords -albums
另外,也可使用 wuliu-list -labels > labels.txt
的方式把結果保存到一個檔案中。
wuliu-search -keyword 小米
搜尋 keyword 為 "小米" 的檔案。- 可通過 filename/notes/label/keyword/collection/album 搜尋檔案。
- 其中 keyword/collection/album 默認精確匹配 (-match=exactly)
- 其中 filename/notes/label 默認前綴匹配 (-match=prefix)
- 匹配方式可選擇 exactly/prefix/contains/suffix
- 例如
wuliu-search -match=contains -filename 偵探
搜尋檔名包含 "偵探" 的檔案。 - 搜尋結果 (檔案清單) 默認按檔案入庫時間排序 (-orderby=ctime)
- 排序方式可選擇 ctime/utime/filename
- 默認從大到小排序 (descending), 使用參數
-asc
改為從小到大排序 (ascending)。 - 例如
wuliu-search -filename 金庸小說 -orderby=utime -asc
搜尋檔名以 "金庸" 開頭的檔案, 更新日期小的(舊的)檔案排在前面。 - 搜尋結果默認最多列印 15 個檔案,用參數 n 更改列印上限,例如
-n=50
- 搜尋結果默認以列印簡潔清單,用參數
-more
列印更多信息,例如wuliu-search -keyword 小米 -more
- 用參數
-idlist
只列印 ID 清單,方便用於 wuliu-delete 等命令,例如wuliu-search -keyword 小米 -idlist
- https://github.com/etcd-io/bbolt
- Please note that Bolt obtains a file lock on the data file so multiple processes cannot open the same database at the same time.
- If the key doesn't exist then it will return nil. It's important to note that you can have a zero-length value set to a key which is different than the key not existing.
- Please note that values returned from
Get()
are only valid while the transaction is open. If you need to use a value outside of the transaction then you must usecopy()
to copy it to another byte slice. - Note that, while RFC3339 is sortable, the Golang implementation of RFC3339Nano does not use a fixed number of digits after the decimal point and is therefore not sortable.
wuliu-db --info=count
查看数据库条目数量wuliu-db --info=size
查看全部档案的总体积wuliu-db -dump all
導出整個數據庫到一個 msgpack 格式的檔案wuliu-db -dump pics
導出圖片到 msgpackwuliu-db -dump docs
導出用瀏覽器能直接預覽的文檔到 msgpack
- 更新数据库,是指以 metadata 为准更新数据库,因此如果一段时间没执行 wuliu-orphan, 请先执行一次 wuliu-orphan 再更新数据库。
- 执行
wuliu-db --update=rebuild
根据 metadata(真实的 json 档案) 重建整个数据库。 执行wuliu-db --update=cache
根据缓存更新索引(不需要读取硬盘里的 json 档案)。 - 由于数据库缓存(即 files 索引和 filename 索引)在添加文件、修改文件属性、删除文件时
会自动更新,因此多数情况下只需要
--update=cache
, 不需要重建数据库。
例如 wuliu-db -keyword 叮噹貓 --rename-to 多啦A梦
把數據庫裡名為 "叮噹貓"
的 keyword 批量改為 "多啦A梦"。
collection 或 album 的更改也類似,例如 wuliu-db -album 歌曲 --rename-to 音樂
把數據庫裡名為 "歌曲" 的 album 批量改為 "音樂"。
wuliu-checksum --renew
将全部文件的 damaged 设为 false, 上次检查时间设为 epochwuliu-checksum --check
校验文件完整性(看文件是否损坏)wuliu-checksum --projects
列印全部专案wuliu-checksum -n [N]
通过序号选择专案,默认是 0 (即当前专案)
在执行 wuliu-checksum
命令时,有时会显示以下信息:
已選擇專案: .
數據庫檔案數量: 5
待檢查檔案數量: 5
如果发现 "數據庫檔案數量" 与 "待檢查檔案數量" 不一致,
可以执行 wuliu-checksum --renew
进行修正。
执行 wuliu-checksum --check
时,会根据 project.json 中的 CheckInterval (检查周期)
自动判断档案是否需要检查,根据 CheckSizeLimit (检查体积上限) 自动终止检查,防止
单次检查时间太长。
wuliu-checksum -same
該命令不可與參數 -n
同時使用,只能檢查當前專案。
创建新备份专案的方法: (差点就为这个功能写程序了,写到一半发现违反“编程简单第一”原则,就改成手动操作。)
- 请先进入一个空资料夹(新的备份专案的根目录,以下称为 backupRoot)
- 把现有专案(以下称为“主专案”)的 files, metadata 这两个资料夹, 以及 project.db, project.json 这两个档案复制到 backupRoot 中。 其他资料夹和档案可复制可不复制。
- 编辑 backupRoot 里的 project.json, 把 IsBackup 的值改为 true
- 编辑主专案中的 project.json, 把 backupRoot 的路径添加到 Projects 清單中。
注意,路径里的反斜杠改要为 "
\\
" 或 "/
" - 编辑主专案中的 project.json, 在 LastBackupAt 中添加一个时间 (可以是空字符串 "")
以上是创建新备份专案的方法,以下是 wuliu-backup 的其他命令:
wuliu-backup --projects
列印全部备份专案(目标专案)- “目标专案”是指专门用于备份的专案
- 本软件采用单向备份方式,备份时以“源专案”为准, 使目标专案里的档案变成与源专案一样。
wuliu-backup -n [N]
通过序号选择目标专案wuliu-backup -n [N] -danger
正式执行备份- 例如执行命令
wuliu-backup -n 1
会列印第 1 个备份专案的信息,但不会执行备份。 而执行命令wuliu-backup -n=1 -danger
则会正式执行备份。 - 建议在执行
wuliu-backup -n [N]
查看信息前,先执行wuliu-db -update=cache
- 有时还可能需要去目标专案的根目录里执行
wuliu-db -update=cache
- 当档案数量较少时,建议先在源专案与目标专案两边都执行
wuliu-orphan --check
和wuliu-db -update=rebuild
因为备份时需要使用数据库,而重建数据库有助于确保数据库与实际档案信息保持一致。 - 備份成功後,會自動更新數據庫。
- 如果發現受損檔案,可使用
wuliu-backup -fix
命令嘗試自動修復。 - 使用該命令時,需要同時使用參數
-n
指定目標專案。 - 如果自動修復失敗(通常因為兩邊專案裏的同一檔案都受損了), 可換一個目標專案再嘗試修復。
- 如果仍無法修復,則需要手動修復。
手動修復方法如下:
- 方法一:使用 wuliu-export 命令導出受損檔案,然後刪除受損檔案。
- 方法二:使用 wuliu-overwrite 覆蓋受損檔案。
wuliu-export 與 wuliu-overwrite 的使用方法詳見本文的其他章節。
wuliu-export -file [ID]
通過檔案 ID 指定要導出的檔案wuliu-export -meta [ID]
通過檔案 ID 指定要導出的檔案屬性 (json)wuliu-export -id [ID]
通過檔案 ID 導出的一個檔案及其屬性wuliu-export -batch [FILENAME]
通過一個 json 檔案進行批量導出。 (批量導出功能暫時不做,因為預估該功能需求不大) 【小技巧】手动把 metadata 里的 json 复制到 buffer 里,相当于批量导出。- 注意 默認只能導出 300MB 以下的檔案 (單檔案體積上限)。
- 修改 project.json 中的 ExportSizeLimit 可更改該限制 (單位:MB)
- 如需導出大體積檔案,建議手動複製。
被導出的檔案一律導出到 buffer 資料夾中。
- 執行
wuliu-overwrite
查看待覆蓋檔案清單。 (注意,待覆蓋檔案應存放在 buffer 資料夾中。) - 在該清單中可以看到,凡是 非json 檔案都將覆蓋 files, 凡是 json 檔案都將覆蓋 metadata.
- 如果其中有 json 檔案想覆蓋 files, 請執行
wuliu-overwrite -newjson overwrite.json
然後編輯 overwrite.json, 根據需要把其中的 "metadata" 改為 "files". (此時,還可以刪除 overwrite.json 裏的一部分檔案名稱,只有保留在清單中的檔案纔會被覆蓋。) - 經過上述操作後,執行
wuliu-overwrite -json overwrite.json
查看待覆蓋檔案清單 - 執行
wuliu-overwrite -json overwrite.json -danger
或wuliu-overwrite -danger
正式覆蓋。 - 如果不使用
-danger
參數,則只是查看待覆蓋檔案清單,不會真正發生覆蓋。 - 【注意】手動修改檔案屬性時,請勿直接修改 ID, Filename, Checksum, Size, Type, UTime.
- 請勿直接修改 metadata 裏的檔案。 如需修改,請導出後修改,然後再使用 wuliu-overwrite 覆蓋舊檔案。 另外,可以使用 wuliu-metadata 命令批量修改属性。
- 【小技巧】可以把 metadata 里的 json 复制到 buffer 里,修改后执行 wuliu-overwrite
- ID 與 Filename 是相關的,請勿直接修改檔案名稱,如需更改檔案名稱, 請使用 wuliu-rename 命令。
該命令用於批量修改多個檔案的屬性。
執行 wuliu-metadata --newjson metadata.json
可生成檔案 metadata.json, 其結構如下:
type EditFiles struct {
IDs []string `json:"ids"` // 通过 ID 指定档案
Filenames []string `json:"filenames"` // 通过档案名称指定档案
Like int64 `json:"like"` // 點贊
Label string `json:"label"` // 标签,便於搜尋
Notes string `json:"notes"` // 備註,便於搜尋
Keywords []string `json:"keywords"` // 關鍵詞, 便於搜尋
Collections []string `json:"collections"` // 集合(分组),一个档案可属于多个集合
Albums []string `json:"albums"` // 相册(专辑),主要用于图片和音乐
}
請在 metadata.json 中填寫內容,其中,通過 ids 指定要修改的檔案 ID,
請勿填寫 filenames. 然後執行 wuliu-metadata -json metadata.json
可預覽批量修改後的檔案屬性,尚未實際執行。
使用參數 -danger
纔會實際執行,
例如 wuliu-metadata -json metadata.json -danger
默認只有填寫了內容的項目會被修改,空值項目保持不變 (不會被改為空值)。
如果想讓空值也生效,請使用參數 -omitempty=false
,
例如 wuliu-metadata -json metadata.json -omitempty=false
wuliu-like -id ID -n=3
把一个文件的 like (小心心/点赞) 设为 3, 其中 ID 是文件的 ID, n 是一个整数,数字越大表示越喜欢/越重要。wuliu-like -id ID -n=0
把 n 设为零,取消点赞。- 也可以不輸入 n, 默認
-n=1
- 点赞或取消点赞后,需要执行
wuliu-db -update=cache
更新索引缓冲。
- 视频文件通常较大
- 大文件比较麻烦
- 尤其是比较大的视频文件,不建议使用本软件来管理
- 体积不大的视频文件,可以使用本软件,但没有优化,只当作普通文件处理 (没有预览和播放视频等功能)
- 可以考虑单独建立一个专案,专门用来管理视频文件,这样在 files 文件夹里 就只有视频文件,比较方便预览和播放
- 相册功能,就是针对图片文件的功能,方便预览和管理图片
- 相册功能采用 Python 语言实现,详情请看 <README-Python.md>
- 同时,相册功能也是一个演示,证明可以使用任何编程语言来扩展本软件的功能
- wuliu-db -update=add
- 检查 keywords 等,禁止空格等。
- wuliu-any-preview 創建一個網頁,便於預覽或下载档案 (不限格式)。
- wuliu-list -others 列印除圖片和可預覽文檔外的檔案
- wuliu-checksum -same
- wuliu-search -ctime="2024-02-01" 通過日期前綴後列印檔案
- 数据库改用 https://github.com/ostafen/clover ?
- https://tinydb.readthedocs.io/en/latest/usage.html