1 个稳定版本
使用旧的 Rust 2015
1.0.0 | 2016年8月4日 |
---|
#2075 在 密码学
3.5MB
2.5K SLoC
# _ _
# | |_| |__ ___ ___ __ _
# | __| _ \ / _ \/ __/ _` |
# | |_| | | | __/ (_| (_| |
# \__|_| |_|\___|\___\__,_|
#
用 Rust 编写的简单、功能齐全的命令行笔记工具。
功能
- 支持多个配置文件
- 明文或256位AES加密配置文件
- JSON 配置文件格式,易于脚本/集成
- 传统和紧凑打印模式
- 添加/编辑/删除笔记
- 使用命令行参数、
STDIN
或通过$VISUAL
或$EDITOR
设置的编辑器添加/编辑笔记正文 - 在配置文件之间传输笔记
- 搜索笔记(标题或正文使用关键字或正则表达式模式)
内容
安装
从 crates.io 安装
theca
可从 crates.io 获取,因此您可以执行 cargo install theca
将二进制文件安装到您的 $CARGO_HOME/bin
目录。
从源安装
构建theca所需的全部内容只是一个rustc
编译器和cargo
打包工具的副本,这些都可以直接从Rust网站下载,或者通过运行以下命令来获取夜间版rustc
和cargo
二进制文件:
$ curl https://sh.rustup.rs -sSf | sh
一旦这些构建完成,我们就可以克隆并构建theca
$ git clone https://github.com/pwoolcoc/theca.git
...
$ cd theca
$ cargo build [--release]
...
$ sudo bash tools/build.sh install [--release, --man, --bash-complete, --zsh-complete]
cargo
标志--release
启用rustc
优化。或者,使用install
标志,--man
将额外安装手册页,而--bash-complete
和--zsh-complete
将额外安装bash或zsh的自动补全脚本。cargo
将自动为您下载和编译theca
的依赖项。
用法
$ theca --help
theca - simple cli note taking tool
Usage:
theca [options] new-profile [<name>]
theca [options] encrypt-profile [--new-key KEY]
theca [options] decrypt-profile
theca [options] info
theca [options] clear
theca [options]
theca [options] <id>
theca [options] search [--regex, --search-body] <pattern>
theca [options] transfer <id> to <name>
theca [options] import <id> from <name>
theca [options] add <title> [-s|-u] [-b BODY|-t|-]
theca [options] edit <id> [<title>] [-s|-u|-n] [-b BODY|-t|-]
theca [options] del <id>...
Profiles:
-f PATH, --profile-folder PATH Path to folder containing profile.json
files [default can be set with env var
THECA_PROFILE_FOLDER].
-p PROFILE, --profile PROFILE Specify non-default profile [default
can be set with env var
THECA_DEFAULT_PROFILE].
Printing format:
-c, --condensed Use the condensed printing format.
-j, --json Print list output as a JSON object.
Note list formatting:
-l LIMIT, --limit LIMIT Limit output to LIMIT notes
[default: 0].
-d, --datesort Sort notes by date.
-r, --reverse Reverse list.
Input:
-y, --yes Silently agree to any [y/n] prompts.
Statuses:
-n, --none No status. (note default)
-s, --started Started status.
-u, --urgent Urgent status.
Body:
-b BODY, --body BODY Set body of the note to BODY.
-t, --editor Drop to $EDITOR to set/edit note body.
- Set body of the note from STDIN.
Encryption:
-e, --encrypted Specifies using an encrypted profile.
-k KEY, --key KEY Encryption key to use for encryption/
decryption, a prompt will be
displayed if no key is provided.
--new-key KEY Specifies the encryption key for a
profile when using `encrypt-profile`,
a prompt will be displayed if no key
is provided.
Search:
--search-body Search the body of notes instead of
the title.
--regex Set search pattern to regex (default
is keyword).
Miscellaneous:
-h, --help Display this help and exit.
-v, --version Display the version of theca and exit.
首次运行
theca new-profile
将创建~/.theca
文件夹以及默认的笔记配置文件在~/.theca/default.json
中。如果您想使用非标准配置文件文件夹,可以使用--profile-folder PATH
。
添加笔记
theca add <title>
将添加一个没有正文或状态的笔记到默认配置文件。这些标志可用于添加具有状态和/或正文的笔记。
Statuses:
-s, --started Started status.
-u, --urgent Urgent status.
Body:
-b BODY, --body BODY Set body of the note to BODY.
-t, --editor Drop to $EDITOR to set/edit note body.
- Set body of the note from STDIN.
编辑笔记
theca edit <id>
用于编辑笔记的标题、状态或正文。
Statuses:
-n, --none No status. (note default)
-s, --started Started status.
-u, --urgent Urgent status.
Body:
-b BODY, --body BODY Set body of the note to BODY.
-t, --editor Drop to $EDITOR to set/edit note body.
- Set body of the note from STDIN.
删除笔记
theca del <id>..
删除一个或多个通过空格分隔的笔记ID指定的笔记。
列出所有笔记
theca
打印出当前配置文件中的所有笔记,可以使用以下选项来限制/排序结果列表
Printing format:
-c, --condensed Use the condensed printing format.
-j, --json Print list output as a JSON object.
Note list formatting:
-l LIMIT, --limit LIMIT Limit output to LIMIT notes.
[default: 0].
-d, --datesort Sort notes by date.
-r, --reverse Reverse list.
查看单个笔记
theca <id>
打印出单个笔记,包括状态和正文,可以使用以下选项来更改输出样式
Printing format:
-c, --condensed Use the condensed printing format.
-j, --json Print list output as a JSON object.
搜索笔记
可以使用theca search
使用关键字或正则表达式匹配笔记标题或正文来搜索笔记。theca不支持任何类型的标签(除两种基本状态外),但您可以通过在笔记标题或正文中附加或前置一个“标签”来非常简单地实现这一点,例如"(THECA) something about theca"
,然后进行关键字搜索"(THECA)"
以获取所有标记为这样的笔记。
Search:
--search-body Search the body of notes instead of
the title.
--regex Set search pattern to regex (default
is keyword).
关于 状态 的简要说明
在theca的初期开发过程中,我花了很多时间去想我应该包含哪些状态(或者是否应该允许完全自定义状态),在玩过很多之后,我最终意识到我只用了三个(好吧,实际上是两个)。
- 没有任何状态(
-n
或--none
) Started
(-s
或--started
)Urgent
(-u
或--urgent
)
这些标志可以在添加笔记、编辑笔记、搜索笔记和列出事件时使用,以指定笔记状态或根据状态筛选列表。
非默认配置文件
可以使用theca new-profile <name>
命令创建新的命名配置文件,并将与default.json
一起存储在~/.theca/
或由--profile-folder PATH
指定的文件夹中。
设置默认配置文件
theca
加载的默认配置文件(通常是default
)可以通过设置环境变量THECA_DEFAULT_PROFILE
进行更改。
设置默认配置文件文件夹
默认配置文件文件夹也可以通过环境变量THECA_PROFILE_FOLDER
设置。
列出所有配置文件
可以使用theca list-profiles
命令查看当前配置文件文件夹中的所有配置文件。
将笔记转移到另一个配置文件
theca transfer <id> to <name>
命令将笔记从当前配置文件(在这种情况下为default
)传输到另一个配置文件。
从另一个配置文件导入笔记
theca import <id> from <name>
命令将笔记从名为<name>
的配置文件传输到当前配置文件(在这种情况下为default
)。
加密配置文件
使用--encrypted
告诉theca应该处理加密配置文件,因此使用theca --encrypted new-profile secrets
,theca将知道创建一个加密配置文件,并要求您输入一个密钥来加密生成的secrets.json
。如果您不希望被提示,可以指定它使用参数--key KEY
。
--encrypted
和--key
可以与所有其他读取或写入配置文件的命令一起使用,指定您想要使用的配置文件需要加密/解密。
Encryption:
-e, --encrypted Specifies using an encrypted profile.
-k KEY, --key KEY Encryption key to use for encryption/
decryption, a prompt will be
displayed if no key is provided.
解密加密配置文件
您可以使用theca decrypt-profile
命令就地解密加密配置文件。
加密明文配置文件
您还可以使用theca encrypt-profile [--new-key KEY]
就地加密配置文件,如果不使用--new-key
,您将需要输入用于加密配置文件的加密密钥。
--new-key KEY Specifies the encryption key for a
profile when using `encrypt-profile`,
a prompt will be displayed if no key
is provided.
更改已加密配置文件的加密密钥
您还可以使用theca encrypt-profile --new-key KEY
更改已加密配置文件的加密密钥,这非常酷,避免了用户必须执行encrypted with old key -> plaintext -> encrypted with new key
!
同步配置文件
如果您使用Dropbox、ownCloud、BitTorrent Sync或某些神秘的rsync
配置等同步工具,您可以通过使用--profile-folder
指定配置文件同步文件夹,轻松地在机器之间共享笔记配置文件。由于theca
对配置文件执行事务性*ish*更新,因此应该非常安全,除非您同时编辑配置文件,尽管theca
会尝试在发生这种情况时合并更改。如果您真的想,您甚至可以将配置文件存储在git存储库中。
JSON 输出模式
您可以通过使用 theca
或 theca search
来查看单个笔记或笔记列表,并通过传递 --json
或 -j
标志将结果输出为 JSON 对象或 JSON 对象列表。这可以与标准限制格式参数一起使用,例如 -r
、-d
和 -l LIMIT
。
Printing format:
-j, --json Print list output as a JSON object.
Note list formatting:
-l LIMIT, --limit LIMIT Limit output to LIMIT notes
[default: 0].
-d, --datesort Sort notes by date.
-r, --reverse Reverse list.
Tab 补全
在 completion/
目录中有初步的 bash
和 zsh
命令补全脚本,可以手动安装或使用 --bash-complete
或 --zsh-complete
标志与 sudo bash tools/build.sh install
一起安装,在安装 theca
二进制文件时或在默认情况下使用二进制文件 installer.sh
。它们都需要大量工作,但到目前为止相对可用。
man 页面
theca
使用来自 md2man 的 md2man-roff
将 docs/THECA.1.md
转换为 roff 格式的手册页面 docs/THECA.1
。
贡献
如果您认为我遗漏了一些必要的功能,请随时打开一个问题或分叉项目并修复它。
我非常确定有很多地方可以进行内存优化,以及其他各种性能和(广泛的)设计改进。
所有和任何的拉取请求都将被考虑,并且会受到极大的欢迎。
错误
theca
几乎肯定包含错误,我没有时间编写足够的测试用例来完全覆盖代码库。如果您发现一个错误,请提交一个问题说明如何触发错误,如果您真的很棒,请提交一个暴露错误的测试用例。
待办事项
- 几乎在所有地方都需要清理和优化
Profile
、Item
及相关函数应从src/theca/lib.rs
移动到它们自己的文件中list-profiles
应按字母顺序排列bash_complete.sh
需要很多改进,_theca
也是,但更少...save_to_file
和transfer_note
(以及内在的import
逻辑)需要进行一些工作,特别是关于配置文件更改的内容... <-- 由于这一点,我们几乎传递了所有的Args
结构体- 可能是打印粗体/普通行的方式可能可以做得更干净...(宏可能?)
- (长期)
remote
加密存储(某种简单的独立 REST API 来存储加密的配置文件块,以及集成到theca
中的客户端以检索它们)
开发
JSON 配置文件格式
如 docs/schema.json
中所述得更加详细,这是一个笔记配置文件可能的样子
{
"encrypted": false,
"notes": [
{
"id": 1,
"title": "\\(◕ ◡ ◕\\)",
"status": "",
"body": "",
"last_touched": "2015-01-22 15:01:39 -0800"
},
{
"id": 3,
"title": "(THECA) add super secret stuff",
"status": "",
"body": "",
"last_touched": "2015-01-22 15:21:01 -0800"
}
]
}
密码学设计
theca
使用 AES CBC 模式对称加密(由 rust-crypto 提供)和 256 位密钥来加密/解密配置文件。密钥通过 pbkdf2(使用 sha-256 PRF,同样来自 rust-crypto)生成,使用 sha256 哈希的密码进行盐化,用于密钥派生(可能不是最好的主意)。
基本的 Python 实现
在开发过程中,使用Python等脚本语言加密/解密配置文件非常有用。可以使用hashlib
和passlib
快速生成密钥。
from hashlib import sha256
from passlib.utils.pbkdf2 import pbkdf2
passphrase = "DEBUG"
key = pbkdf2(
bytes(passphrase.encode("utf-8")),
sha256(bytes(passphrase.encode("utf-8"))).hexdigest().encode("utf-8"),
2056,
32,
"hmac-sha256"
)
使用pycrypto
的AES实现可以解密密文。
from Crypto.Cipher import AES
# the IV makes up the first 16 bytes of the ciphertext
iv = ciphertext[0:16]
decryptor = AES.new(key, AES.MODE_CBC, iv)
plaintext = decryptor.decrypt(ciphertext[16:])
# remove any padding from the end of the final block
plaintext = plaintext[:-plaintext[-1]].decode("utf-8")
tools/build.sh
build.sh
是一个相对简单的bash
脚本,它替代了Makefile
(呃),因为我记忆力不好,会忘记一些应该记住的命令。它还将设置构建版本环境变量(THECA_BUILD_VER
),该变量用于设置版本theca -v
。
使用方法非常简单
$ bash tools/build.sh
Usage: build.sh {build|build-man|test|install|clean}
build
将任何参数传递给cargo build
,因此--release
和--verbose
等参数都可以正常工作。build-man
需要md2man-roff
工具将Markdown手册页转换为roff手册页格式。test
运行所有Rust测试(cargo test
)和所有Python测试套件。install
将二进制文件复制到/usr/local/bin
。它还可以与--man
、--bash-complete
或--zsh-complete
一起使用,以手动安装手册页、bash
完成脚本或zsh
完成脚本。clean
删除当前目录下的二进制文件、target/
文件夹中的文件以及docs/
中的手册页(如果存在)。
tools/theca_test_harness.py
theca_test_harness.py
是一个相对简单的Python 3测试套件,用于编译后的theca
二进制文件。它读取描述测试用例的JSON文件并执行它们,提供相对简单的信息,如通过/失败/耗时。
该套件可以对三种不同的输出进行检查:
- 生成的配置文件
- view、list和search命令的JSON输出
- add、edit、delete等命令的文本输出
Python脚本有多个可能有用或无用的参数。
$ python3 tools/theca_test_harness.py -h
usage: theca_test_harness.py [-h] [-tc THECA_COMMAND] [-tf TEST_FILE] [-pt]
[-jt] [-tt]
test harness for the theca cli binary.
optional arguments:
-h, --help show this help message and exit
-tc THECA_COMMAND, --theca-command THECA_COMMAND
where is the theca binary
-tf TEST_FILE, --test-file TEST_FILE
path to specific test file to run
-pt, --profile-tests only run the profile output tests
-jt, --json-tests only run the json output tests
-tt, --text-tests only run the text output tests
测试套件文件格式
theca_test_harness.py
的JSON测试套件文件看起来像这样:
{
"title": "GOOD DEFAULT TESTS",
"desc": "testing correct input with the default profile.",
"tests": [
...
]
}
测试格式
-
配置结果测试看起来像这样:
{ "name": "add note", "cmds": [ ["new-profile"], ["add", "this is the title"] ], "result_path": "default.json", "result": { "encrypted": false, "notes": [ { "id": 1, "title": "this is the title", "status": "", "body": "" } ] } }
-
JSON输出测试看起来像这样:
{ "name": "list", "cmds": [ ["new-profile"], ["add", "a title this is"], ["add", "another title this is"], ["-j"] ], "result_type": "json", "results": [ null, null, null, [ { "id": 1, "title": "a title this is", "status": "", "body": "" },{ "id": 2, "title": "another title this is", "status": "", "body": "" } ] ] }
-
文本输出测试看起来像这样:
{ "name": "new-profile", "cmds": [ ["new-profile"] ], "result_type": "text", "results": [ "creating profile 'default'\n" ] }
作者
theca
最初由roland shoemaker编写([email protected]),后来由Paul Woolcock([email protected])接手。
许可证
theca
使用MIT许可证,完整文本可在http://opensource.org/licenses/MIT或LICENSE
中找到。
依赖关系
~8MB
~143K SLoC