• This repository has been archived on 01/Jul/2024
  • Stars
    star
    137
  • Rank 266,121 (Top 6 %)
  • Language
    Python
  • License
    GNU Affero Genera...
  • Created almost 2 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Batch updates to metadata in an Obsidian vault

PyPI version PyPI - Python Version Python Code Checker codecov

obsidian-metadata

A script to make batch updates to metadata in an Obsidian vault. No changes are made to the Vault until they are explicitly committed.

asciicast

Important Disclaimer

It is strongly recommended that you back up your vault prior to committing changes. This script makes changes directly to the markdown files in your vault. Once the changes are committed, there is no ability to recreate the original information unless you have a backup. Follow the instructions in the script to create a backup of your vault if needed. The author of this script is not responsible for any data loss that may occur. Use at your own risk.

Install

Requires Python v3.10 or above.

pip install obsidian-metadata

Usage

CLI Commands

  • --config-file: Specify a custom configuration file location
  • --dry-run: Make no destructive changes
  • --import-csv Import a CSV file with bulk updates
  • --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
  • --vault-path: Specify a path to an Obsidian Vault
  • --verbose: Set verbosity level (0=WARN, 1=INFO, 2=DEBUG, 3=TRACE)
  • --version: Prints the version number and exits

Running the script

Once installed, run obsidian-metadata in your terminal to enter an interactive menu of sub-commands.

Vault Actions

  • Backup: Create a backup of the vault.
  • Delete Backup: Delete a backup of the vault.

Export Metadata

  • Export all metadata to a CSV organized by metadata type
  • Export all metadata to a CSV organized by note path
  • Export all metadata to a JSON file organized by metadata type

Inspect Metadata

  • View all metadata in the vault
  • View all frontmatter
  • View all inline metadata
  • View all inline tags

Filter Notes in Scope: Limit the scope of notes to be processed with one or more filters.

  • Path filter (regex): Limit scope based on the path or filename
  • Metadata filter: Limit scope based on a key or key/value pair
  • Tag filter: Limit scope based on an in-text tag
  • 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 Make Bulk Updates section below)

Add Metadata: Add new metadata to your vault.

When adding a new key to inline metadata, the insert location value in the config file will specify where in the note it will be inserted.

  • Add new metadata to the frontmatter
  • Add new inline metadata - Set insert_location in the config to control where the new metadata is inserted. (Default: Bottom)
  • Add new inline tag - Set insert_location in the config to control where the new tag is inserted. (Default: Bottom)

Rename Metadata: Rename either a key and all associated values, a specific value within a key. or an in-text tag.

  • Rename a key
  • Rename a value
  • Rename an inline tag

Delete Metadata: Delete either a key and all associated values, or a specific value.

  • Delete a key and associated values
  • Delete a value from a key
  • Delete an inline tag

Move Inline Metadata: Move inline metadata to a specified location with a note

  • Move to Top: Move all inline metadata beneath the frontmatter
  • Move to After Title: Move all inline metadata beneath the first markdown header
  • Move to Bottom: Move all inline metadata to the bottom of the note

Transpose Metadata: Move metadata from inline to frontmatter or the reverse.

When transposing to inline metadata, the insert location value in the config file will specify where in the note it will be inserted.

  • Transpose all metadata - Moves all frontmatter to inline metadata, or the reverse
  • Transpose key - Transposes a specific key and all it's values
  • Transpose value- Transpose a specific key:value pair

Review Changes: Prior to committing changes, review all changes that will be made.

  • View a diff of the changes that will be made

Commit Changes: Write the changes to disk. This step is not undoable.

  • Commit changes to the vault

Known Limitations

Multi-level frontmatter is not supported.

# This works perfectly well
---
key: "value"
key2:
    - one
    - two
    - three
key3: ["foo", "bar", "baz"]
key4: value

# This will not work
---
key1:
    key2:
        - one
        - two
        - three
    key3:
        - one
        - two
        - three
---

Configuration

obsidian-metadata requires a configuration file at ~/.obsidian_metadata.toml. On first run, this file will be created. You can specify a new location for the configuration file with the --config-file option.

To add additional vaults, copy the default section and add the appropriate information. The script will prompt you to select a vault if multiple exist in the configuration file

Below is an example with two vaults.

["Vault One"] # Name of the vault.

    # Path to your obsidian vault
    # Note for Windows users: Windows paths must use `\\` as the path separator due to a limitation with how TOML parses strings.
    #       Example: "C:\\Users\\username\\Documents\\Obsidian"
    path = "/path/to/vault"

    # Folders within the vault to ignore when indexing metadata
    exclude_paths = [".git", ".obsidian"]

    # Location to add metadata. One of:
    #    TOP:            Directly after frontmatter.
    #    AFTER_TITLE:    After the first header following frontmatter.
    #    BOTTOM:         The bottom of the note
    insert_location = "BOTTOM"

["Vault Two"]
    path = "/path/to/second_vault"
    exclude_paths = [".git", ".obsidian", "daily_notes"]
    insert_location = "AFTER_TITLE"

To bypass the configuration file and specify a vault to use at runtime use the --vault-path option.

Note for Windows users: Due to how TOMML parses strings, Windows paths must use \\ as the path separator. For example: C:\\Users\\username\\Documents\\Obsidian

Make Bulk Updates

Bulk edits are supported by importing a CSV file containing the following columns. Column headers must be lowercase.

  1. path - Path to note relative to the vault root folder
  2. type - Type of metadata. One of frontmatter, inline_metadata, or tag
  3. key - The key to add (leave blank for a tag)
  4. value - the value to add to the key

An example valid CSV file is

path,type,key,value
folder 1/note1.md,frontmatter,fruits,apple
folder 1/note1.md,frontmatter,fruits,banana
folder 1/note1.md,inline_metadata,cars,toyota
folder 1/note1.md,inline_metadata,cars,honda
folder 1/note1.md,tag,,tag1
folder 1/note1.md,tag,,tag2

How bulk imports work:

  • Only notes which match the path in the CSV file are updated
  • Effected notes will have ALL of their metadata changed to reflect the values in the CSV file
  • 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

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

Once you have a template created you can import it using the --import-csv flag or by navigating to the Import bulk changes from CSV option.

Contributing

Setup: Once per project

There are two ways to contribute to this project.

1. Containerized development

  1. Clone this repository. git clone https://github.com/natelandau/obsidian-metadata
  2. Open the repository in Visual Studio Code
  3. Start the Dev Container. Run Ctrl/⌘ + ⇧ + P → Remote-Containers: Reopen in Container.
  4. Run poetry env info -p to find the PATH to the Python interpreter if needed by VSCode.

2. Local development

  1. Install Python 3.10 and Poetry
  2. Clone this repository. git clone https://github.com/natelandau/obsidian-metadata
  3. Install the Poetry environment with poetry install.
  4. Activate your Poetry environment with poetry shell.
  5. Install the pre-commit hooks with pre-commit install --install-hooks.

Developing

  • This project follows the Conventional Commits standard to automate Semantic Versioning and Keep A Changelog with Commitizen.
    • When you're ready to commit changes run cz c
  • Run poe from within the development environment to print a list of Poe the Poet tasks available to run on this project. Common commands:
    • poe lint runs all linters
    • poe test runs all tests with Pytest
  • Run poetry add {package} from within the development environment to install a run time dependency and add it to pyproject.toml and poetry.lock.
  • Run poetry remove {package} from within the development environment to uninstall a run time dependency and remove it from pyproject.toml and poetry.lock.
  • Run poetry update from within the development environment to upgrade all dependencies to the latest versions allowed by pyproject.toml.