mirror of
https://github.com/natelandau/obsidian-metadata.git
synced 2025-11-08 05:03:47 -05:00
feat: add --export-template cli option
This commit is contained in:
10
README.md
10
README.md
@@ -27,6 +27,7 @@ pip install obsidian-metadata
|
||||
- `--dry-run`: Make no destructive changes
|
||||
- `--export-csv`: Specify a path and create a CSV export of all metadata
|
||||
- `--export-json`: Specify a path and create a JSON export of all metadata
|
||||
- `--export-template`: Specify a path and export all notes with their associated metadata to a CSV file for use as a bulk import template
|
||||
- `--help`: Shows interactive help and exits
|
||||
- `--log-file`: Specify a log file location
|
||||
- `--log-to-file`: Will log to a file
|
||||
@@ -64,7 +65,7 @@ Once installed, run `obsidian-metadata` in your terminal to enter an interactive
|
||||
- **List and clear filters**: List all current filters and clear one or all
|
||||
- **List notes in scope**: List notes that will be processed.
|
||||
|
||||
**Bulk Edit Metadata** from a CSV file (See the _making bulk edits_ section below)
|
||||
**Bulk Edit Metadata** from a CSV file (See the _[Make Bulk Updates](https://github.com/natelandau/obsidian-metadata#make-bulk-updates)_ section below)
|
||||
|
||||
**Add Metadata**: Add new metadata to your vault.
|
||||
|
||||
@@ -139,7 +140,7 @@ Below is an example with two vaults.
|
||||
|
||||
To bypass the configuration file and specify a vault to use at runtime use the `--vault-path` option.
|
||||
|
||||
### Making bulk edits
|
||||
### Make Bulk Updates
|
||||
|
||||
Bulk edits are supported by importing a CSV file containing the following columns. Column headers must be lowercase.
|
||||
|
||||
@@ -167,7 +168,10 @@ How bulk imports work:
|
||||
- **Existing metadata in a matching note will be rewritten**. This may result in it's location and/or formatting within the note being changed
|
||||
- Inline tags ignore any value added to the `key` column
|
||||
|
||||
You can export all your notes with their associated metadata in this format from the "Export Metadata" section of the script to be used as a template for your bulk changes.
|
||||
Create a CSV template for making bulk updates containing all your notes and their associated metadata by
|
||||
|
||||
1. Using the `--export-template` cli command; or
|
||||
2. Selecting the `Metadata by note` option within the `Export Metadata` section of the app
|
||||
|
||||
# Contributing
|
||||
|
||||
|
||||
28
poetry.lock
generated
28
poetry.lock
generated
@@ -4,7 +4,7 @@
|
||||
name = "argcomplete"
|
||||
version = "2.0.6"
|
||||
description = "Bash tab completion for argparse"
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
@@ -100,7 +100,7 @@ files = [
|
||||
name = "charset-normalizer"
|
||||
version = "2.1.1"
|
||||
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6.0"
|
||||
files = [
|
||||
@@ -142,7 +142,7 @@ files = [
|
||||
name = "commitizen"
|
||||
version = "2.42.1"
|
||||
description = "Python commitizen client tool"
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6.2,<4.0.0"
|
||||
files = [
|
||||
@@ -231,7 +231,7 @@ toml = ["tomli"]
|
||||
name = "decli"
|
||||
version = "0.5.2"
|
||||
description = "Minimal, easy-to-use, declarative cli tool"
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
@@ -354,7 +354,7 @@ tests = ["pytest", "pytest-cov", "pytest-mock"]
|
||||
name = "jinja2"
|
||||
version = "3.1.2"
|
||||
description = "A very fast and expressive template engine."
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
@@ -416,7 +416,7 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
|
||||
name = "markupsafe"
|
||||
version = "2.1.2"
|
||||
description = "Safely add untrusted strings to HTML/XML markup."
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
@@ -562,7 +562,7 @@ setuptools = "*"
|
||||
name = "packaging"
|
||||
version = "23.0"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
@@ -596,14 +596,14 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pdoc"
|
||||
version = "13.0.0"
|
||||
version = "13.0.1"
|
||||
description = "API Documentation for Python Projects"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pdoc-13.0.0-py3-none-any.whl", hash = "sha256:f9088b1c10f3296f46a08796e05e307470af5f4253f71d536781f6c305baf912"},
|
||||
{file = "pdoc-13.0.0.tar.gz", hash = "sha256:aadbf6c757c6e65c4754d6c26c4eb6c1bf8c7a9fb893f1fbe5a7b879dde59e46"},
|
||||
{file = "pdoc-13.0.1-py3-none-any.whl", hash = "sha256:16a24914280ed318896ad798674e2b0d11832297fdea95632fa472e3d171e247"},
|
||||
{file = "pdoc-13.0.1.tar.gz", hash = "sha256:4d84056847728203b8789ca8a8d0c8003f25002b3caef3365f6f21a1e4228a1b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -839,7 +839,7 @@ testing = ["filelock"]
|
||||
name = "pyyaml"
|
||||
version = "6.0"
|
||||
description = "YAML parser and emitter for Python"
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
@@ -1172,7 +1172,7 @@ widechars = ["wcwidth"]
|
||||
name = "termcolor"
|
||||
version = "2.2.0"
|
||||
description = "ANSI color formatting for output in terminal"
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
@@ -1275,7 +1275,7 @@ files = [
|
||||
name = "typing-extensions"
|
||||
version = "4.5.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.7+"
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
@@ -1349,4 +1349,4 @@ dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"]
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "e9e2ff35a5ae15991d1d123dffa9f15fdf5afaf00624c26577412555d0464eaf"
|
||||
content-hash = "8fa62f96cc77eac773497573dcbdd5666173cbec56374fea73a814f3fb7f5338"
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
shellingham = "^1.5.0.post1"
|
||||
tomlkit = "^0.11.6"
|
||||
typer = "^0.7.0"
|
||||
commitizen = "^2.42.1"
|
||||
|
||||
[tool.poetry.group.test.dependencies]
|
||||
pytest = "^7.2.2"
|
||||
@@ -41,14 +40,14 @@
|
||||
coverage = "^7.2.2"
|
||||
interrogate = "^1.5.0"
|
||||
mypy = "^1.1.1"
|
||||
pdoc = "^13.0.0"
|
||||
pdoc = "^13.0.1"
|
||||
poethepoet = "^0.18.1"
|
||||
pre-commit = "^3.2.0"
|
||||
ruff = "0.0.257"
|
||||
ruff = "^0.0.257"
|
||||
sh = "2.0.3"
|
||||
typeguard = "^3.0.1"
|
||||
types-python-dateutil = "^2.8.19.10"
|
||||
vulture = "^2.7"
|
||||
sh = "2.0.3"
|
||||
|
||||
[tool.black]
|
||||
line-length = 100
|
||||
|
||||
@@ -143,7 +143,7 @@ for group in groups:
|
||||
notice(
|
||||
f"Updating {p} from {packages[p]['current_version']} to {packages[p]['new_version']}"
|
||||
)
|
||||
sh.poetry("add", f"{p}@{packages[p]['new_version']}", "--group", group, _fg=True)
|
||||
sh.poetry("add", f"{p}@latest", "--group", group, _fg=True)
|
||||
|
||||
sh.poetry("update", _fg=True)
|
||||
success("All dependencies are up to date")
|
||||
|
||||
@@ -34,14 +34,21 @@ def main(
|
||||
),
|
||||
export_csv: Path = typer.Option(
|
||||
None,
|
||||
help="Exports all metadata to a specified CSV file and exits. (Will overwrite any existing file)",
|
||||
help="Exports all metadata to a specified CSV file and exits.",
|
||||
show_default=False,
|
||||
dir_okay=False,
|
||||
file_okay=True,
|
||||
),
|
||||
export_json: Path = typer.Option(
|
||||
None,
|
||||
help="Exports all metadata to a specified JSON file and exits. (Will overwrite any existing file)",
|
||||
help="Exports all metadata to a specified JSON file and exits.",
|
||||
show_default=False,
|
||||
dir_okay=False,
|
||||
file_okay=True,
|
||||
),
|
||||
export_template: Path = typer.Option(
|
||||
None,
|
||||
help="Exports all notes and their metadata to a specified CSV file and exits. Use to create a template for batch updates.",
|
||||
show_default=False,
|
||||
dir_okay=False,
|
||||
file_okay=True,
|
||||
@@ -142,6 +149,10 @@ def main(
|
||||
path = Path(export_json).expanduser().resolve()
|
||||
application.noninteractive_export_csv(path)
|
||||
raise typer.Exit(code=0)
|
||||
if export_template is not None:
|
||||
path = Path(export_template).expanduser().resolve()
|
||||
application.noninteractive_export_csv(path)
|
||||
raise typer.Exit(code=0)
|
||||
|
||||
application.application_main()
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ def test_version() -> None:
|
||||
"""Test printing version and then exiting."""
|
||||
result = runner.invoke(app, ["--version"])
|
||||
assert result.exit_code == 0
|
||||
assert result.output == Regex(r"obsidian_metadata: v\d+\.\d+\.\d+$")
|
||||
assert "obsidian_metadata: v" in result.output
|
||||
|
||||
|
||||
def test_application(tmp_path) -> None:
|
||||
@@ -51,3 +51,25 @@ def test_application(tmp_path) -> None:
|
||||
|
||||
assert banner in result.output
|
||||
assert result.exit_code == 1
|
||||
|
||||
|
||||
def test_export_template(tmp_path) -> None:
|
||||
"""Test the export template command."""
|
||||
source_dir = Path(__file__).parent / "fixtures" / "test_vault"
|
||||
dest_dir = Path(tmp_path / "vault")
|
||||
|
||||
if not source_dir.exists():
|
||||
raise FileNotFoundError(f"Sample vault not found: {source_dir}")
|
||||
|
||||
shutil.copytree(source_dir, dest_dir)
|
||||
|
||||
config_path = tmp_path / "config.toml"
|
||||
export_path = tmp_path / "export_template.csv"
|
||||
result = runner.invoke(
|
||||
app,
|
||||
["--vault-path", dest_dir, "--config-file", config_path, "--export-template", export_path],
|
||||
)
|
||||
|
||||
assert "SUCCESS | Exported metadata to" in result.output
|
||||
assert result.exit_code == 0
|
||||
assert export_path.exists()
|
||||
|
||||
Reference in New Issue
Block a user