several (small) tools to deal with org-mode files outside of emacs
Find a file
Ralph Mayer 6af707e4b6
All checks were successful
Run Tests / test (push) Successful in 19s
Add property-based testing to ideas.md
- Add Testing & Quality section
- Document property-based testing with Hypothesis
- Specify modules for property testing:
  - Date calculations
  - Org-mode parsing
  - File exclusion logic
  - Version comparison

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 13:36:32 +01:00
.forgejo/workflows Move workflow example to src/ directory 2025-12-26 15:58:19 +01:00
examples Option --header-only hinzugefügt 2025-12-11 16:13:51 +01:00
src Integrate ignore_utils into all existing scripts 2025-12-26 21:15:20 +01:00
tests Integrate ignore_utils into all existing scripts 2025-12-26 21:15:20 +01:00
.gitignore .gitignore angepasst 2025-12-11 11:54:12 +01:00
CHANGELOG.md Update version from 0.2.4 to 0.2.0 2025-12-26 21:21:04 +01:00
CLAUDE_CODE.md erster commit 2025-12-11 10:24:14 +01:00
ideas.md Add property-based testing to ideas.md 2025-12-27 13:36:32 +01:00
LICENSE Initial commit 2025-12-11 10:05:13 +01:00
pyproject.toml Update version from 0.2.4 to 0.2.0 2025-12-26 21:21:04 +01:00
README.md Update README with new tools documentation 2025-12-26 21:06:56 +01:00
repository-federation.md Update repository-federation.md 2025-12-11 17:24:51 +01:00
uv.lock Add pytest test suite for version 0.1 2025-12-11 17:04:06 +01:00

My Org Helpers

A collection of Python tools for managing org-mode files. Designed for network engineers and security managers who need to maintain audit trails, track document reviews, and automate org-mode file maintenance across large infrastructure documentation.

Tools Included

Review & Compliance Tools

check_reviews.py

  • 🔍 Recursive scanning - Scans entire directory trees for .org files
  • Compliance tracking - Identifies documents with missing review properties
  • ⚠️ Overdue detection - Flags documents past their review date
  • 📅 Upcoming reviews - Shows reviews due in the next 30 days
  • 📊 Clear reporting - Generates prioritized compliance reports

set_created_dates.py

  • 🔧 Git integration - Automatically sets Created dates from git commit history
  • 📅 Batch processing - Process entire directories of org files at once
  • 🔍 Dry-run mode - Preview changes before applying them

update_next_review.py

  • 📅 Auto-calculation - Automatically calculates NextReview dates based on ReviewCycle
  • 🔄 Smart updates - Only updates files that need changes
  • 🤖 CI/CD integration - Can be automated via Forgejo/GitHub workflows

Template Management Tools

init_template.py

  • 📝 Template initialization - Create new org files from predefined templates
  • 🔑 UUID generation - Automatically replace :ID: changeme with unique UUIDs
  • 📅 Date updates - Set current date automatically
  • 🎯 Placeholder replacement - Replace description and other placeholders
  • 💬 Interactive selection - Choose templates interactively or via command-line

check_template_version.py

  • 🔍 Version tracking - Check template versions across org files
  • 📊 Semantic versioning - Compare versions using semantic version rules
  • ⚠️ Outdated detection - Identify files with outdated template versions
  • 📈 Compliance reporting - Report files without version metadata
  • 🔄 Multi-template support - Handle multiple template types (person, project, dokument)

Tag Management Tools

list_tags.py

  • 📊 Tag statistics - Show usage statistics for all FILETAGS
  • 🔍 Format support - Handle both :tag1:tag2: and tag1 tag2 formats
  • 📈 Usage percentages - Display how many files use each tag
  • 🗂️ Multiple views - Sort alphabetically or by usage frequency
  • 📄 File listing - Optionally show which files use each tag

find_untagged.py

  • 🔍 Missing tags detection - Find org files without FILETAGS
  • Compliance checking - Ensure all files are properly tagged
  • 📊 Clear reporting - Distinguish between empty and missing tags
  • 🎯 Quick identification - Identify files that need tagging

Version History

See CHANGELOG.md for detailed version history and release notes.

Requirements

  • Python 3.8+
  • uv for dependency management

Installation

# Clone or download this project
cd my-org-helpers

# Install dependencies
uv sync

# Dependencies:
# - packaging>=20.0 (for semantic version comparison in check_template_version.py)

Usage

Basic usage (check_reviews.py)

# Scan current directory
uv run src/check_reviews.py

# Scan specific directory
uv run src/check_reviews.py /path/to/your/org/files

# Scan with examples
uv run src/check_reviews.py ./examples

# Only check file headers (ignore individual headings)
uv run src/check_reviews.py --header-only ./examples

Org file structure

Each org heading that represents a reviewable document should have these properties:

* Document Title
:PROPERTIES:
:Created: 2024-01-15
:Revisited: 2024-12-01
:NextReview: 2025-03-01
:ReviewCycle: 90
:Status: Current
:END:

Alternatively, you can add properties to the file header (before any headings) to track the entire file as a single document:

#+TITLE: Network Infrastructure Documentation
#+AUTHOR: Ralph
#+DATE: 2024-01-15

:PROPERTIES:
:Created: 2024-01-15
:Revisited: 2024-12-01
:NextReview: 2025-03-01
:ReviewCycle: 90
:Status: Current
:END:

Your content here...

Use --header-only to only check file-level properties and ignore individual headings.

Required properties:

  • :Created: - Original document creation date (YYYY-MM-DD)
  • :Revisited: - Last review date (YYYY-MM-DD)
  • :NextReview: - Next scheduled review date (YYYY-MM-DD)

Optional properties:

  • :ReviewCycle: - Days between reviews (e.g., 90, 180)
  • :Status: - Current status (e.g., Current, Needs Review, Critical)
  • :Owner: - Responsible team or person

Output example

================================================================================
DOCUMENT REVIEW STATUS REPORT
================================================================================

Files scanned: 3
Documents with missing properties: 4
Overdue reviews: 2
Upcoming reviews (next 30 days): 2

⚠️  OVERDUE REVIEWS
--------------------------------------------------------------------------------

📄 examples/example.org
  • Incident Response Plan
    Due: 2024-09-01 (102 days overdue)
    Last reviewed: 2024-06-01
  • Server Infrastructure Documentation
    Due: 2024-11-01 (40 days overdue)
    Last reviewed: 2024-08-01

❌ MISSING REVIEW PROPERTIES
--------------------------------------------------------------------------------

📄 examples/example.org
  • Backup Procedures
    Missing: Created, Revisited, NextReview
  • Password Policy
    Missing: Created, Revisited, NextReview

📅 UPCOMING REVIEWS (Next 30 days)
--------------------------------------------------------------------------------

📄 examples/example.org
  • Network Diagram
    Due: 2025-01-05 (in 25 days)
  • Compliance Checklist
    Due: 2025-01-15 (in 35 days)

✅ 2 documents are current (reviews > 30 days away)

Tool Details

Setting Created dates from git history (set_created_dates.py)

The set_created_dates.py script automatically sets the Created property in your org files based on the first git commit date of each file.

Updating NextReview dates (update_next_review.py)

The update_next_review.py script automatically calculates and updates the NextReview property based on the more recent of Created or Revisited dates plus the ReviewCycle days.

Calculation formula: NextReview = max(Created, Revisited) + ReviewCycle days

Usage (update_next_review.py)

# Preview changes (dry-run)
uv run src/update_next_review.py --dry-run file.org

# Update a single file's header
uv run src/update_next_review.py file.org

# Update all headings in a file (not just the header)
uv run src/update_next_review.py --all-headings file.org

# Process all org files in a directory
uv run src/update_next_review.py --directory ./docs

# Dry-run on entire directory
uv run src/update_next_review.py --dry-run --directory ./examples

Options (update_next_review.py)

  • --directory, -d - Treat path as directory and process all .org files recursively
  • --all-headings - Update NextReview dates in all heading properties, not just file header
  • --dry-run, -n - Preview changes without modifying files

How it works (update_next_review.py)

  1. Reads the Created, Revisited, and ReviewCycle properties from each document
  2. Calculates the next review date using: max(Created, Revisited) + ReviewCycle days
  3. Updates or adds the NextReview: property with the calculated date
  4. Skips documents that are already up-to-date
  5. Reports which documents were updated and the new dates

This is useful when:

  • You've updated the Revisited date after reviewing a document
  • You've changed the ReviewCycle and need to recalculate review dates
  • You want to ensure all NextReview dates are consistent with the review policy
  • Initializing org files with proper review dates

Automated Updates with Forgejo Workflow

For org-mode repositories hosted on Forgejo, you can automate NextReview updates using the included example workflow file.

Setup:

  1. Copy src/update_next_review.py to your org-mode repository
  2. Copy src/update-nextreview.yml-example to .forgejo/workflows/update-nextreview.yml in your org-mode repository
  3. Ensure Forgejo Actions are enabled for your repository

How it works:

  • Triggers on every push to the main branch
  • Runs src/update_next_review.py --directory . to update all org files
  • Automatically commits changes with message "nextreview updated by script"
  • Skips commit if no files were modified (prevents empty commits)

This ensures your NextReview dates are always calculated correctly without manual intervention

Usage (set_created_dates.py)

# Preview changes (dry-run)
uv run src/set_created_dates.py --dry-run file.org

# Update a single file's header
uv run src/set_created_dates.py file.org

# Update all headings in a file (not just the header)
uv run src/set_created_dates.py --all-headings file.org

# Process all org files in a directory
uv run src/set_created_dates.py --directory ./docs

# Dry-run on entire directory
uv run src/set_created_dates.py --dry-run --directory ./examples

Options

  • --directory, -d - Treat path as directory and process all .org files recursively
  • --all-headings - Update Created dates in all heading properties, not just file header
  • --dry-run, -n - Preview changes without modifying files

How it works

  1. Queries git history to find the first commit that added each file
  2. Updates or adds the Created: property in the file header to match that date
  3. Optionally updates Created: in all heading property drawers with --all-headings
  4. Skips common excluded directories (.git, archive, drafts, etc.)

This is useful when:

  • Initializing org files for review tracking
  • Your files were created before you started tracking review dates
  • You want historically accurate creation dates from your version control

Initialize from templates (init_template.py)

The init_template.py script creates new org files from predefined templates with automatic placeholder replacement.

Usage (init_template.py)

# List available templates
uv run src/init_template.py --list

# Create file from template interactively
uv run src/init_template.py output.org

# Create file from specific template
uv run src/init_template.py -t templates/project_vorlage.org output.org

# Preview without creating file
uv run src/init_template.py -t templates/dokument_vorlage.org output.org --dry-run

# Specify description
uv run src/init_template.py -t templates/project_vorlage.org output.org -d "My new project"

How it works (init_template.py)

  1. Copies content from selected template file
  2. Replaces all :ID: changeme with unique UUIDs (different UUID for each occurrence)
  3. Replaces Beschreibung-changeme with provided description
  4. Updates #+DATE: to current date
  5. Creates output file with all placeholders filled

This is useful when:

  • Creating new org files with consistent structure
  • Ensuring all files have unique IDs
  • Maintaining template standards across documentation

Check template versions (check_template_version.py)

The check_template_version.py script checks template versions across org files and identifies outdated files.

Usage (check_template_version.py)

# Scan current directory
uv run src/check_template_version.py

# Scan specific directory
uv run src/check_template_version.py /path/to/org/files

# Specify template directory
uv run src/check_template_version.py --template-dir /path/to/templates

# Scan directory recursively
uv run src/check_template_version.py -d /path/to/org/files

Version format

Templates and org files should have a :Version: property in this format:

:PROPERTIES:
:Version: templatename.major.minor.patch
:END:

For example: person.1.0.2 means template type "person" at version "1.0.2"

How it works (check_template_version.py)

  1. Reads template versions from templates directory
  2. Scans org files for :Version: property
  3. Compares versions using semantic versioning
  4. Reports outdated, current, missing, and unknown versions

This is useful when:

  • Updating template standards across documentation
  • Identifying files that need template upgrades
  • Maintaining consistency in file structure

List all tags (list_tags.py)

The list_tags.py script collects and displays statistics about FILETAGS usage across org files.

Usage (list_tags.py)

# Scan current directory
uv run src/list_tags.py

# Scan specific directory
uv run src/list_tags.py /path/to/org/files

# Show which files use each tag
uv run src/list_tags.py --show-files

# Scan directory recursively
uv run src/list_tags.py -d /path/to/org/files

How it works (list_tags.py)

  1. Scans all org files for #+FILETAGS: directives
  2. Supports both :tag1:tag2: and tag1 tag2 formats
  3. Counts tag usage and calculates percentages
  4. Displays tags sorted by usage or alphabetically

This is useful when:

  • Understanding tag usage across documentation
  • Identifying popular or underused tags
  • Maintaining consistent tagging standards

Find untagged files (find_untagged.py)

The find_untagged.py script identifies org files without FILETAGS.

Usage (find_untagged.py)

# Scan current directory
uv run src/find_untagged.py

# Scan specific directory
uv run src/find_untagged.py /path/to/org/files

# Scan directory recursively
uv run src/find_untagged.py -d /path/to/org/files

# Check single file
uv run src/find_untagged.py myfile.org

How it works (find_untagged.py)

  1. Scans org files for #+FILETAGS: directive
  2. Identifies files with missing or empty tags
  3. Reports untagged files for review

This is useful when:

  • Ensuring all files are properly tagged
  • Maintaining tagging compliance
  • Identifying files that need categorization

Configuration

Excluded directories

By default, these directories are skipped:

  • archive
  • .git
  • drafts
  • backup
  • __pycache__
  • examples
  • templates

Using .orgignore files

All new scripts support .orgignore files for custom exclusions (similar to .gitignore format):

# Create .orgignore file
cat > .orgignore <<EOF
# Exclude specific directories
old_archive
temp_files

# Exclude patterns
*.tmp
test_*
EOF

The .orgignore file supports:

  • Comments (lines starting with #)
  • Directory names
  • Wildcard patterns (* and ?)
  • One pattern per line

To use with scripts:

# Scripts automatically look for .orgignore in the scanned directory
uv run src/list_tags.py -d /path/to/org/files

Use cases

For compliance audits

Run before quarterly audits to identify documentation gaps:

uv run src/check_reviews.py /infrastructure/docs > audit_prep_report.txt

File-level tracking

If you track entire files (not individual sections), use header-only mode:

uv run src/check_reviews.py --header-only /policies > policy_review_status.txt

Weekly team reports

Add to cron for weekly review reminders:

0 9 * * 1 cd /docs && uv run /path/to/my-org-helpers/src/check_reviews.py . | mail -s "Weekly Doc Reviews" team@example.com

Integration with org-agenda

Use output to create TODO items in Emacs org-mode for overdue reviews.

Development with Claude Code

This project is designed to work seamlessly with Claude Code for iterative development.

Project structure

my-org-helpers/
├── src/                                # Source code directory
│   ├── check_reviews.py                    # Review compliance checking
│   ├── set_created_dates.py                # Set Created dates from git history
│   ├── update_next_review.py               # Calculate NextReview dates
│   ├── init_template.py                    # Initialize files from templates
│   ├── check_template_version.py           # Check template versions
│   ├── list_tags.py                        # List all FILETAGS with statistics
│   ├── find_untagged.py                    # Find files without FILETAGS
│   ├── ignore_utils.py                     # .orgignore file support
│   └── update-nextreview.yml-example       # Example Forgejo workflow
├── tests/                              # Test suite (148 tests)
│   ├── test_check_reviews.py                # Tests for check_reviews.py
│   ├── test_set_created_dates.py            # Tests for set_created_dates.py
│   ├── test_update_next_review.py           # Tests for update_next_review.py
│   ├── test_init_template.py                # Tests for init_template.py
│   ├── test_check_template_version.py       # Tests for check_template_version.py
│   ├── test_list_tags.py                    # Tests for list_tags.py
│   ├── test_find_untagged.py                # Tests for find_untagged.py
│   └── test_ignore_utils.py                 # Tests for ignore_utils.py
├── templates/                          # Template org files
│   ├── dokument_vorlage.org                # Document template
│   ├── person_vorlage.org                  # Person template
│   └── project_vorlage.org                 # Project template
├── examples/                           # Example org files
│   ├── example.org                         # Test data with various review states
│   └── header-example.org                  # File-level tracking example
├── .forgejo/workflows/                 # CI/CD workflows
│   └── test.yml                            # Automated testing workflow
├── CHANGELOG.md                        # Version history (Keep a Changelog format)
├── README.md                           # This file
├── pyproject.toml                      # Project configuration (with dependencies)
└── uv.lock                             # Dependency lock file

Working with Claude Code

# Start Claude Code session
claude-code

# Ask Claude to:
# - Add CSV export functionality
# - Implement email notifications
# - Add support for custom date formats
# - Create unit tests
# - Add colorized terminal output

Roadmap

Completed

  • Automatic NextReview calculation based on ReviewCycle
  • Batch update tool for setting Created dates from git history
  • Batch update tool for NextReview calculation
  • Template initialization system
  • Template version tracking
  • Tag management and statistics
  • .orgignore support for all tools

Planned

  • CSV/JSON export for external processing
  • Email notifications for overdue reviews
  • Integration with calendar systems (ical export)
  • Web dashboard for team visibility
  • Support for custom property names
  • Interactive template upgrade tool
  • Tag suggestion based on file content

Contributing

Suggestions and improvements welcome! This tool is designed for network operations and security compliance use cases.

License

MIT License - feel free to use and modify for your organization's needs.

Author

Created for network engineers and security managers who manage documentation compliance across large infrastructures.