feat: store tags in plain-text .otag files with .otag.toml config and document all commands
This commit is contained in:
parent
f04554a52c
commit
b2ab1421df
8 changed files with 222 additions and 369 deletions
126
README.md
126
README.md
|
|
@ -26,18 +26,128 @@ So a as an example an audio-file could be assigned to project `+album` and have
|
|||
$ uv tool install 'orvanitag[all]'
|
||||
```
|
||||
|
||||
The core only needs PyYAML and rich. Reading and writing embedded metadata uses optional extras: `audio` (pytaglib, needs the TagLib C library), `pdf` (pypdf), `office` (olefile, only for legacy `.doc`/`.xls`/`.ppt`) and `markdown` (python-frontmatter). Plugins whose extra is not installed are skipped.
|
||||
Requires Python 3.11 or newer. The core only needs rich. Reading and writing embedded metadata uses optional extras: `audio` (pytaglib, needs the TagLib C library), `pdf` (pypdf), `office` (olefile, only for legacy `.doc`/`.xls`/`.ppt`) and `markdown` (python-frontmatter). Plugins whose extra is not installed are skipped.
|
||||
|
||||
## Command Line Tool
|
||||
|
||||
### Assigning Contextual Tags
|
||||
|
||||
Let's
|
||||
```
|
||||
$ otag add <file/path> [contextual tags ...]
|
||||
$ otag <command> [arguments ...] [flags]
|
||||
```
|
||||
|
||||
Removing contextual tags from a file
|
||||
Every command has a short alias, listed in brackets. `otag -h` prints an overview. Words starting with `+`, `@` or `#` become projects, contexts and tags; all other words form the note. Quote hashtags in the shell (`'#lofi'`), because an unquoted `#` starts a comment.
|
||||
|
||||
### Tagging
|
||||
|
||||
`add` (`a`) adds projects, contexts, tags and a note to an existing file or folder. Adding to an already tagged file merges the tags and replaces the note.
|
||||
|
||||
```
|
||||
$ otag remove <file/path> [contextual tags ...]
|
||||
```
|
||||
$ otag add song.mp3 +album @drums '#lofi' '#snare' first take
|
||||
```
|
||||
|
||||
`remove` (`r`) removes the given projects, contexts and tags. Without any, it removes the whole entry.
|
||||
|
||||
```
|
||||
$ otag remove song.mp3 '#snare'
|
||||
$ otag remove song.mp3
|
||||
```
|
||||
|
||||
### Searching
|
||||
|
||||
`list` (`ls`, `l`) searches the current directory tree and prints the matching files with their tags. Without a query it lists every tagged file.
|
||||
|
||||
```
|
||||
$ otag ls '#lofi' @drums
|
||||
```
|
||||
|
||||
A term with a prefix only matches that category; a term without a prefix matches any category and the note. Terms match partially (`lof` finds `#lofi`) and all terms have to match.
|
||||
|
||||
| Flag | Effect |
|
||||
|---|---|
|
||||
| `-e`, `--exact` | Match whole terms only |
|
||||
| `-or`, `--either` | Match any term instead of all |
|
||||
| `--files` | Only show files |
|
||||
| `-d`, `--dirs` | Only show folders |
|
||||
| `-p`, `--path PATH` | Search another directory tree |
|
||||
| `-r`, `--recursive` | Skip subdirectories (despite its name; subdirectories are included by default) |
|
||||
| `-c`, `--cache` | Read the index from `.otag.cache.json`, which is rebuilt whenever an `.otag` file changed |
|
||||
| `-dc`, `--delete-cache` | Delete `.otag.cache.json` before searching |
|
||||
|
||||
### Copying, Moving and Deleting
|
||||
|
||||
`copy` (`cp`) and `move` (`mv`) transfer the tags of a file to another path. By default only the tags are transferred; `-f` (`--file-operation`) also copies or moves the file itself. The destination needs a directory part, so write `./new.mp3` rather than `new.mp3`. With `-f`, a destination ending in `/` keeps the file name.
|
||||
|
||||
```
|
||||
$ otag cp song.mp3 ./song-copy.mp3
|
||||
$ otag mv -f song.mp3 archive/
|
||||
```
|
||||
|
||||
`del` (`rm`) removes the entry of a file; `-f` also deletes the file.
|
||||
|
||||
```
|
||||
$ otag rm -f song.mp3
|
||||
```
|
||||
|
||||
### Maintenance
|
||||
|
||||
`clean` (`c`) removes entries whose files no longer exist, in the given folder (default: current) and its subdirectories.
|
||||
|
||||
`purge` (`p`) deletes all `.otag` and `.otag.cache.json` files in the given folder and its subdirectories. This removes every tag in that tree and cannot be undone.
|
||||
|
||||
```
|
||||
$ otag clean
|
||||
$ otag purge old-project/
|
||||
```
|
||||
|
||||
### Embedded Metadata
|
||||
|
||||
`scan` (`s`) reads tags that are embedded in files and adds them to their entries, in the given folder (default: current) and its subdirectories.
|
||||
|
||||
`write` (`w`) writes the entry of a file into the file itself, using the named plugin.
|
||||
|
||||
```
|
||||
$ otag scan music/
|
||||
$ otag write id3 song.mp3
|
||||
```
|
||||
|
||||
| Plugin | File types | Where the tags are stored |
|
||||
|---|---|---|
|
||||
| `id3` | `.mp3` `.wav` `.flac` `.ogg` | The comment tag |
|
||||
| `pdf` | `.pdf` | The keywords field |
|
||||
| `office` | `.docx` `.xlsx` `.pptx` `.odt` `.ods` `.odp`, reading also `.doc` `.xls` `.ppt` | The description field |
|
||||
| `frontmatter` | `.md` `.txt` `.markdown` `.rst` | `projects`, `contexts`, `tags` and `note` keys of the YAML front matter |
|
||||
| `hash//` | Source code such as `.py` `.js` `.c` `.rs`, plus `.md` `.txt` | A `#// +project @context #tag note` line within the first five lines |
|
||||
|
||||
### Import and Export
|
||||
|
||||
`export` (`e`) writes all entries of the file's directory tree to a text file (default: `context.txt`), one `path --- tags` line per file. `import` (`i`) reads such a file back and adds the tags that are missing.
|
||||
|
||||
```
|
||||
$ otag export backup.txt
|
||||
$ otag import backup.txt
|
||||
```
|
||||
|
||||
## How Tags Are Stored
|
||||
|
||||
Each folder keeps the entries of its files and subfolders in a plain text `.otag` file, so tags travel with the folder when it is copied, synced or archived. Every line holds one entry in the same syntax as the command line: the name, ` --- `, then projects, contexts, tags and the note. Folder names end with `/`.
|
||||
|
||||
```
|
||||
Boombap Loop.wav --- +album @drums #boombap #lofi
|
||||
song.mp3 --- +album @drums #lofi #snare first take
|
||||
stems/ --- @archive
|
||||
```
|
||||
|
||||
The file can be edited by hand. A line without ` --- ` stops otag with an error naming the file and line, so nothing gets overwritten until it is fixed. Note words starting with `+`, `@` or `#` are read as tags.
|
||||
|
||||
An optional `.otag.toml` in the same folder configures `scan` and `write` there:
|
||||
|
||||
```toml
|
||||
plugins = ["id3", "pdf"]
|
||||
|
||||
[id3]
|
||||
types = [".mp3", ".flac"]
|
||||
|
||||
[id3.map]
|
||||
tags = "genre"
|
||||
```
|
||||
|
||||
`plugins` limits which plugins run (`hash//` is listed as `hashdoubleslash`), `types` overrides the file types a plugin handles, and `id3.map` additionally reads an audio tag (here `GENRE`) into a category.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue