namingpaper 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. namingpaper-0.1.0/.agent/workflows/openspec-apply.md +20 -0
  2. namingpaper-0.1.0/.agent/workflows/openspec-archive.md +24 -0
  3. namingpaper-0.1.0/.agent/workflows/openspec-proposal.md +25 -0
  4. namingpaper-0.1.0/.claude/commands/openspec/apply.md +23 -0
  5. namingpaper-0.1.0/.claude/commands/openspec/archive.md +27 -0
  6. namingpaper-0.1.0/.claude/commands/openspec/proposal.md +28 -0
  7. namingpaper-0.1.0/.claude/settings.local.json +51 -0
  8. namingpaper-0.1.0/.gitignore +54 -0
  9. namingpaper-0.1.0/.python-version +1 -0
  10. namingpaper-0.1.0/AGENTS.md +18 -0
  11. namingpaper-0.1.0/CLAUDE.md +18 -0
  12. namingpaper-0.1.0/PKG-INFO +336 -0
  13. namingpaper-0.1.0/README.md +313 -0
  14. namingpaper-0.1.0/openspec/AGENTS.md +456 -0
  15. namingpaper-0.1.0/openspec/changes/add-batch-processing/proposal.md +22 -0
  16. namingpaper-0.1.0/openspec/changes/add-batch-processing/specs/batch-processing/spec.md +107 -0
  17. namingpaper-0.1.0/openspec/changes/add-batch-processing/tasks.md +35 -0
  18. namingpaper-0.1.0/openspec/project.md +111 -0
  19. namingpaper-0.1.0/pyproject.toml +39 -0
  20. namingpaper-0.1.0/src/namingpaper/__init__.py +3 -0
  21. namingpaper-0.1.0/src/namingpaper/batch.py +272 -0
  22. namingpaper-0.1.0/src/namingpaper/cli.py +536 -0
  23. namingpaper-0.1.0/src/namingpaper/config.py +91 -0
  24. namingpaper-0.1.0/src/namingpaper/extractor.py +72 -0
  25. namingpaper-0.1.0/src/namingpaper/formatter.py +97 -0
  26. namingpaper-0.1.0/src/namingpaper/models.py +76 -0
  27. namingpaper-0.1.0/src/namingpaper/pdf_reader.py +86 -0
  28. namingpaper-0.1.0/src/namingpaper/providers/__init__.py +77 -0
  29. namingpaper-0.1.0/src/namingpaper/providers/base.py +52 -0
  30. namingpaper-0.1.0/src/namingpaper/providers/claude.py +87 -0
  31. namingpaper-0.1.0/src/namingpaper/providers/gemini.py +69 -0
  32. namingpaper-0.1.0/src/namingpaper/providers/ollama.py +138 -0
  33. namingpaper-0.1.0/src/namingpaper/providers/openai.py +92 -0
  34. namingpaper-0.1.0/src/namingpaper/renamer.py +136 -0
  35. namingpaper-0.1.0/src/namingpaper/template.py +125 -0
  36. namingpaper-0.1.0/tests/__init__.py +1 -0
  37. namingpaper-0.1.0/tests/conftest.py +111 -0
  38. namingpaper-0.1.0/tests/test_batch.py +211 -0
  39. namingpaper-0.1.0/tests/test_cli.py +92 -0
  40. namingpaper-0.1.0/tests/test_formatter.py +98 -0
  41. namingpaper-0.1.0/tests/test_renamer.py +161 -0
  42. namingpaper-0.1.0/tests/test_template.py +157 -0
@@ -0,0 +1,20 @@
1
+ ---
2
+ description: Implement an approved OpenSpec change and keep tasks in sync.
3
+ ---
4
+ <!-- OPENSPEC:START -->
5
+ **Guardrails**
6
+ - Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
7
+ - Keep changes tightly scoped to the requested outcome.
8
+ - Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
9
+
10
+ **Steps**
11
+ Track these steps as TODOs and complete them one by one.
12
+ 1. Read `changes/<id>/proposal.md`, `design.md` (if present), and `tasks.md` to confirm scope and acceptance criteria.
13
+ 2. Work through tasks sequentially, keeping edits minimal and focused on the requested change.
14
+ 3. Confirm completion before updating statuses—make sure every item in `tasks.md` is finished.
15
+ 4. Update the checklist after all work is done so each task is marked `- [x]` and reflects reality.
16
+ 5. Reference `openspec list` or `openspec show <item>` when additional context is required.
17
+
18
+ **Reference**
19
+ - Use `openspec show <id> --json --deltas-only` if you need additional context from the proposal while implementing.
20
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,24 @@
1
+ ---
2
+ description: Archive a deployed OpenSpec change and update specs.
3
+ ---
4
+ <!-- OPENSPEC:START -->
5
+ **Guardrails**
6
+ - Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
7
+ - Keep changes tightly scoped to the requested outcome.
8
+ - Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
9
+
10
+ **Steps**
11
+ 1. Determine the change ID to archive:
12
+ - If this prompt already includes a specific change ID (for example inside a `<ChangeId>` block populated by slash-command arguments), use that value after trimming whitespace.
13
+ - If the conversation references a change loosely (for example by title or summary), run `openspec list` to surface likely IDs, share the relevant candidates, and confirm which one the user intends.
14
+ - Otherwise, review the conversation, run `openspec list`, and ask the user which change to archive; wait for a confirmed change ID before proceeding.
15
+ - If you still cannot identify a single change ID, stop and tell the user you cannot archive anything yet.
16
+ 2. Validate the change ID by running `openspec list` (or `openspec show <id>`) and stop if the change is missing, already archived, or otherwise not ready to archive.
17
+ 3. Run `openspec archive <id> --yes` so the CLI moves the change and applies spec updates without prompts (use `--skip-specs` only for tooling-only work).
18
+ 4. Review the command output to confirm the target specs were updated and the change landed in `changes/archive/`.
19
+ 5. Validate with `openspec validate --strict --no-interactive` and inspect with `openspec show <id>` if anything looks off.
20
+
21
+ **Reference**
22
+ - Use `openspec list` to confirm change IDs before archiving.
23
+ - Inspect refreshed specs with `openspec list --specs` and address any validation issues before handing off.
24
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,25 @@
1
+ ---
2
+ description: Scaffold a new OpenSpec change and validate strictly.
3
+ ---
4
+ <!-- OPENSPEC:START -->
5
+ **Guardrails**
6
+ - Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
7
+ - Keep changes tightly scoped to the requested outcome.
8
+ - Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
9
+ - Identify any vague or ambiguous details and ask the necessary follow-up questions before editing files.
10
+ - Do not write any code during the proposal stage. Only create design documents (proposal.md, tasks.md, design.md, and spec deltas). Implementation happens in the apply stage after approval.
11
+
12
+ **Steps**
13
+ 1. Review `openspec/project.md`, run `openspec list` and `openspec list --specs`, and inspect related code or docs (e.g., via `rg`/`ls`) to ground the proposal in current behaviour; note any gaps that require clarification.
14
+ 2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, and `design.md` (when needed) under `openspec/changes/<id>/`.
15
+ 3. Map the change into concrete capabilities or requirements, breaking multi-scope efforts into distinct spec deltas with clear relationships and sequencing.
16
+ 4. Capture architectural reasoning in `design.md` when the solution spans multiple systems, introduces new patterns, or demands trade-off discussion before committing to specs.
17
+ 5. Draft spec deltas in `changes/<id>/specs/<capability>/spec.md` (one folder per capability) using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement and cross-reference related capabilities when relevant.
18
+ 6. Draft `tasks.md` as an ordered list of small, verifiable work items that deliver user-visible progress, include validation (tests, tooling), and highlight dependencies or parallelizable work.
19
+ 7. Validate with `openspec validate <id> --strict --no-interactive` and resolve every issue before sharing the proposal.
20
+
21
+ **Reference**
22
+ - Use `openspec show <id> --json --deltas-only` or `openspec show <spec> --type spec` to inspect details when validation fails.
23
+ - Search existing requirements with `rg -n "Requirement:|Scenario:" openspec/specs` before writing new ones.
24
+ - Explore the codebase with `rg <keyword>`, `ls`, or direct file reads so proposals align with current implementation realities.
25
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: OpenSpec: Apply
3
+ description: Implement an approved OpenSpec change and keep tasks in sync.
4
+ category: OpenSpec
5
+ tags: [openspec, apply]
6
+ ---
7
+ <!-- OPENSPEC:START -->
8
+ **Guardrails**
9
+ - Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
10
+ - Keep changes tightly scoped to the requested outcome.
11
+ - Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
12
+
13
+ **Steps**
14
+ Track these steps as TODOs and complete them one by one.
15
+ 1. Read `changes/<id>/proposal.md`, `design.md` (if present), and `tasks.md` to confirm scope and acceptance criteria.
16
+ 2. Work through tasks sequentially, keeping edits minimal and focused on the requested change.
17
+ 3. Confirm completion before updating statuses—make sure every item in `tasks.md` is finished.
18
+ 4. Update the checklist after all work is done so each task is marked `- [x]` and reflects reality.
19
+ 5. Reference `openspec list` or `openspec show <item>` when additional context is required.
20
+
21
+ **Reference**
22
+ - Use `openspec show <id> --json --deltas-only` if you need additional context from the proposal while implementing.
23
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: OpenSpec: Archive
3
+ description: Archive a deployed OpenSpec change and update specs.
4
+ category: OpenSpec
5
+ tags: [openspec, archive]
6
+ ---
7
+ <!-- OPENSPEC:START -->
8
+ **Guardrails**
9
+ - Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
10
+ - Keep changes tightly scoped to the requested outcome.
11
+ - Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
12
+
13
+ **Steps**
14
+ 1. Determine the change ID to archive:
15
+ - If this prompt already includes a specific change ID (for example inside a `<ChangeId>` block populated by slash-command arguments), use that value after trimming whitespace.
16
+ - If the conversation references a change loosely (for example by title or summary), run `openspec list` to surface likely IDs, share the relevant candidates, and confirm which one the user intends.
17
+ - Otherwise, review the conversation, run `openspec list`, and ask the user which change to archive; wait for a confirmed change ID before proceeding.
18
+ - If you still cannot identify a single change ID, stop and tell the user you cannot archive anything yet.
19
+ 2. Validate the change ID by running `openspec list` (or `openspec show <id>`) and stop if the change is missing, already archived, or otherwise not ready to archive.
20
+ 3. Run `openspec archive <id> --yes` so the CLI moves the change and applies spec updates without prompts (use `--skip-specs` only for tooling-only work).
21
+ 4. Review the command output to confirm the target specs were updated and the change landed in `changes/archive/`.
22
+ 5. Validate with `openspec validate --strict --no-interactive` and inspect with `openspec show <id>` if anything looks off.
23
+
24
+ **Reference**
25
+ - Use `openspec list` to confirm change IDs before archiving.
26
+ - Inspect refreshed specs with `openspec list --specs` and address any validation issues before handing off.
27
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: OpenSpec: Proposal
3
+ description: Scaffold a new OpenSpec change and validate strictly.
4
+ category: OpenSpec
5
+ tags: [openspec, change]
6
+ ---
7
+ <!-- OPENSPEC:START -->
8
+ **Guardrails**
9
+ - Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
10
+ - Keep changes tightly scoped to the requested outcome.
11
+ - Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
12
+ - Identify any vague or ambiguous details and ask the necessary follow-up questions before editing files.
13
+ - Do not write any code during the proposal stage. Only create design documents (proposal.md, tasks.md, design.md, and spec deltas). Implementation happens in the apply stage after approval.
14
+
15
+ **Steps**
16
+ 1. Review `openspec/project.md`, run `openspec list` and `openspec list --specs`, and inspect related code or docs (e.g., via `rg`/`ls`) to ground the proposal in current behaviour; note any gaps that require clarification.
17
+ 2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, and `design.md` (when needed) under `openspec/changes/<id>/`.
18
+ 3. Map the change into concrete capabilities or requirements, breaking multi-scope efforts into distinct spec deltas with clear relationships and sequencing.
19
+ 4. Capture architectural reasoning in `design.md` when the solution spans multiple systems, introduces new patterns, or demands trade-off discussion before committing to specs.
20
+ 5. Draft spec deltas in `changes/<id>/specs/<capability>/spec.md` (one folder per capability) using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement and cross-reference related capabilities when relevant.
21
+ 6. Draft `tasks.md` as an ordered list of small, verifiable work items that deliver user-visible progress, include validation (tests, tooling), and highlight dependencies or parallelizable work.
22
+ 7. Validate with `openspec validate <id> --strict --no-interactive` and resolve every issue before sharing the proposal.
23
+
24
+ **Reference**
25
+ - Use `openspec show <id> --json --deltas-only` or `openspec show <spec> --type spec` to inspect details when validation fails.
26
+ - Search existing requirements with `rg -n "Requirement:|Scenario:" openspec/specs` before writing new ones.
27
+ - Explore the codebase with `rg <keyword>`, `ls`, or direct file reads so proposals align with current implementation realities.
28
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,51 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "mcp__context7__resolve-library-id",
5
+ "mcp__context7__query-docs",
6
+ "Bash(uv sync:*)",
7
+ "Bash(uv run pytest:*)",
8
+ "Bash(uv pip install:*)",
9
+ "Bash(uv run namingpaper --help:*)",
10
+ "Bash(uv run namingpaper rename --help:*)",
11
+ "Bash(uv run:*)",
12
+ "Bash(uv pip list:*)",
13
+ "Bash(ls:*)",
14
+ "Bash(cat:*)",
15
+ "Bash(/Users/tsaipingjui/Documents/Namingpaper/.venv/bin/python3:*)",
16
+ "Bash(.venv/bin/python:*)",
17
+ "Bash(uv venv:*)",
18
+ "Bash(.venv/bin/namingpaper:*)",
19
+ "Bash(uv lock:*)",
20
+ "Bash(echo:*)",
21
+ "Bash(curl:*)",
22
+ "Bash(python3:*)",
23
+ "Bash(ollama pull:*)",
24
+ "Bash(NAMINGPAPER_MODEL_NAME=qwen3:1.7b uv run:*)",
25
+ "Bash(NAMINGPAPER_MODEL_NAME=qwen3:0.6b uv run:*)",
26
+ "Bash(NAMINGPAPER_MODEL_NAME=qwen3:4b uv run:*)",
27
+ "Bash(openspec list:*)",
28
+ "Bash(openspec validate:*)",
29
+ "Bash(python -m pytest:*)",
30
+ "Bash(uv python install:*)",
31
+ "mcp__github__get_me",
32
+ "mcp__github__create_repository",
33
+ "Bash(gh auth status:*)",
34
+ "Bash(gh repo create:*)",
35
+ "Bash(git -C /Users/tsaipingjui/Documents/Namingpaper add .gitignore .python-version AGENTS.md CLAUDE.md README.md openspec/ pyproject.toml src/ tests/)",
36
+ "Bash(git -C /Users/tsaipingjui/Documents/Namingpaper diff --cached --stat)",
37
+ "Bash(git -C /Users/tsaipingjui/Documents/Namingpaper commit -m \"$\\(cat <<''EOF''\nInitial commit: namingpaper CLI tool\n\nA CLI tool that renames academic PDF papers using AI-extracted metadata.\nSupports Claude, OpenAI, Gemini, and Ollama providers with batch processing,\ncustom templates, and dry-run safety.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
38
+ "Bash(git -C /Users/tsaipingjui/Documents/Namingpaper branch:*)",
39
+ "Bash(git -C /Users/tsaipingjui/Documents/Namingpaper push -u origin main)",
40
+ "Bash(git -C /Users/tsaipingjui/Documents/Namingpaper status)",
41
+ "Bash(git -C /Users/tsaipingjui/Documents/Namingpaper diff)",
42
+ "Bash(git -C /Users/tsaipingjui/Documents/Namingpaper log --oneline -5)",
43
+ "Bash(git -C /Users/tsaipingjui/Documents/Namingpaper add README.md pyproject.toml)",
44
+ "Bash(git -C /Users/tsaipingjui/Documents/Namingpaper commit -m \"$\\(cat <<''EOF''\nFix installation docs and add missing httpx dependency\n\n- Add httpx to pyproject.toml \\(required by Ollama provider\\)\n- Fix Ollama model names to match code defaults \\(deepseek-ocr + llama3.1:8b\\)\n- Replace placeholder GitHub URLs with actual repo URL\n- Clarify Claude is included by default, use uv sync --extra for optional providers\n- Remove uv add instructions since package is not yet on PyPI\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
45
+ "Bash(git -C /Users/tsaipingjui/Documents/Namingpaper push)",
46
+ "Bash(git -C /Users/tsaipingjui/Documents/Namingpaper tag -a v0.1.0 -m \"v0.1.0: Initial release\")",
47
+ "Bash(git -C /Users/tsaipingjui/Documents/Namingpaper push origin v0.1.0)",
48
+ "Bash(gh release create:*)"
49
+ ]
50
+ }
51
+ }
@@ -0,0 +1,54 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ .venv/
25
+ venv/
26
+ ENV/
27
+
28
+ # Testing
29
+ .pytest_cache/
30
+ .coverage
31
+ htmlcov/
32
+ .tox/
33
+ .nox/
34
+
35
+ # IDEs
36
+ .idea/
37
+ .vscode/
38
+ *.swp
39
+ *.swo
40
+ *~
41
+
42
+ # OS
43
+ .DS_Store
44
+ Thumbs.db
45
+
46
+ # Environment
47
+ .env
48
+ .env.local
49
+
50
+ # Config with secrets
51
+ .namingpaper/
52
+
53
+ # uv
54
+ uv.lock
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,18 @@
1
+ <!-- OPENSPEC:START -->
2
+ # OpenSpec Instructions
3
+
4
+ These instructions are for AI assistants working in this project.
5
+
6
+ Always open `@/openspec/AGENTS.md` when the request:
7
+ - Mentions planning or proposals (words like proposal, spec, change, plan)
8
+ - Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
9
+ - Sounds ambiguous and you need the authoritative spec before coding
10
+
11
+ Use `@/openspec/AGENTS.md` to learn:
12
+ - How to create and apply change proposals
13
+ - Spec format and conventions
14
+ - Project structure and guidelines
15
+
16
+ Keep this managed block so 'openspec update' can refresh the instructions.
17
+
18
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,18 @@
1
+ <!-- OPENSPEC:START -->
2
+ # OpenSpec Instructions
3
+
4
+ These instructions are for AI assistants working in this project.
5
+
6
+ Always open `@/openspec/AGENTS.md` when the request:
7
+ - Mentions planning or proposals (words like proposal, spec, change, plan)
8
+ - Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
9
+ - Sounds ambiguous and you need the authoritative spec before coding
10
+
11
+ Use `@/openspec/AGENTS.md` to learn:
12
+ - How to create and apply change proposals
13
+ - Spec format and conventions
14
+ - Project structure and guidelines
15
+
16
+ Keep this managed block so 'openspec update' can refresh the instructions.
17
+
18
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,336 @@
1
+ Metadata-Version: 2.4
2
+ Name: namingpaper
3
+ Version: 0.1.0
4
+ Summary: CLI tool to rename academic papers using AI-extracted metadata
5
+ Requires-Python: <3.14,>=3.11
6
+ Requires-Dist: anthropic>=0.30.0
7
+ Requires-Dist: httpx>=0.27.0
8
+ Requires-Dist: pdf2image>=1.16.0
9
+ Requires-Dist: pdfplumber>=0.10.0
10
+ Requires-Dist: pillow>=10.0.0
11
+ Requires-Dist: pydantic-settings>=2.0.0
12
+ Requires-Dist: pydantic>=2.0.0
13
+ Requires-Dist: rich>=13.0.0
14
+ Requires-Dist: typer>=0.9.0
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
17
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
18
+ Provides-Extra: gemini
19
+ Requires-Dist: google-generativeai>=0.5.0; extra == 'gemini'
20
+ Provides-Extra: openai
21
+ Requires-Dist: openai>=1.0.0; extra == 'openai'
22
+ Description-Content-Type: text/markdown
23
+
24
+ # namingpaper
25
+
26
+ A CLI tool that renames academic PDF papers using AI-extracted metadata.
27
+
28
+ **Before:** `1-s2.0-S0304405X13000044-main.pdf`
29
+
30
+ **After:** `Fama, French, (1993, JFE), Common risk factors in the returns....pdf`
31
+
32
+ ## Features
33
+
34
+ - Extracts metadata (authors, year, journal, title) from PDFs using AI
35
+ - Supports multiple AI providers: Claude, OpenAI, Gemini, and Ollama (local)
36
+ - **Batch processing** - rename entire directories at once
37
+ - **Custom templates** - flexible filename formatting
38
+ - Dry-run mode by default for safety
39
+ - Copy to output directory (keeps original file)
40
+ - Handles filename collisions (skip, increment, or overwrite)
41
+ - Common journal abbreviations (JFE, AER, QJE, etc.)
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ # Install from source
47
+ git clone https://github.com/DanTsai0903/namingpaper.git
48
+ cd namingpaper
49
+ uv sync
50
+
51
+ # With optional providers
52
+ uv sync --extra openai # OpenAI support
53
+ uv sync --extra gemini # Gemini support
54
+ ```
55
+
56
+ ## Quick Start
57
+
58
+ ```bash
59
+ # Default uses Ollama (local, no API key needed)
60
+ # Make sure Ollama is running with the required models
61
+ ollama pull deepseek-ocr
62
+ ollama pull llama3.1:8b
63
+
64
+ # Preview the rename (dry run)
65
+ namingpaper rename paper.pdf
66
+
67
+ # Actually rename the file
68
+ namingpaper rename paper.pdf --execute
69
+
70
+ # Batch rename all PDFs in a directory
71
+ namingpaper batch ~/Downloads/papers --execute
72
+ ```
73
+
74
+ ### Using Cloud Providers
75
+
76
+ If you want to use Claude, OpenAI, or Gemini instead of local Ollama:
77
+
78
+ ```bash
79
+ # Option 1: Set environment variable (temporary, current session only)
80
+ export NAMINGPAPER_ANTHROPIC_API_KEY=sk-ant-api03-xxxxx
81
+ namingpaper rename paper.pdf -p claude
82
+
83
+ # Option 2: Add to shell profile (permanent)
84
+ # For zsh (macOS default):
85
+ echo 'export NAMINGPAPER_ANTHROPIC_API_KEY=sk-ant-api03-xxxxx' >> ~/.zshrc
86
+ source ~/.zshrc
87
+
88
+ # For bash:
89
+ echo 'export NAMINGPAPER_ANTHROPIC_API_KEY=sk-ant-api03-xxxxx' >> ~/.bashrc
90
+ source ~/.bashrc
91
+
92
+ # Option 3: Use config file (~/.namingpaper/config.toml)
93
+ mkdir -p ~/.namingpaper
94
+ cat > ~/.namingpaper/config.toml << EOF
95
+ ai_provider = "claude"
96
+ anthropic_api_key = "sk-ant-api03-xxxxx"
97
+ EOF
98
+ ```
99
+
100
+ ## Usage
101
+
102
+ ### Rename Command
103
+
104
+ Rename a single PDF file.
105
+
106
+ ```bash
107
+ namingpaper rename <pdf_path> [OPTIONS]
108
+
109
+ Options:
110
+ -x, --execute Actually rename (default is dry-run)
111
+ -y, --yes Skip confirmation prompt
112
+ -p, --provider TEXT AI provider (claude, openai, gemini, ollama)
113
+ -o, --output-dir DIR Copy to directory (keeps original)
114
+ -c, --collision STRATEGY Handle collisions: skip, increment, overwrite
115
+ ```
116
+
117
+ ### Batch Command
118
+
119
+ Rename multiple PDF files in a directory.
120
+
121
+ ```bash
122
+ namingpaper batch <directory> [OPTIONS]
123
+
124
+ Options:
125
+ -x, --execute Actually rename (default is dry-run)
126
+ -y, --yes Skip confirmation prompt
127
+ -r, --recursive Scan subdirectories
128
+ -f, --filter PATTERN Only process files matching pattern (e.g., '2023*')
129
+ -p, --provider TEXT AI provider (claude, openai, gemini, ollama)
130
+ -t, --template TEXT Filename template or preset name
131
+ -o, --output-dir DIR Copy to directory (keeps originals)
132
+ -c, --collision STRATEGY Handle collisions: skip, increment, overwrite
133
+ --parallel N Concurrent extractions (default: 1)
134
+ --json Output results as JSON
135
+ ```
136
+
137
+ ### Templates Command
138
+
139
+ Show available filename templates.
140
+
141
+ ```bash
142
+ namingpaper templates
143
+ ```
144
+
145
+ ## Examples
146
+
147
+ ### Single File
148
+
149
+ ```bash
150
+ # Dry run with Ollama (default)
151
+ namingpaper rename paper.pdf
152
+
153
+ # Execute rename
154
+ namingpaper rename paper.pdf --execute
155
+
156
+ # Copy to a different folder (keeps original)
157
+ namingpaper rename paper.pdf -o ~/Papers --execute
158
+
159
+ # Use Claude
160
+ namingpaper rename paper.pdf -p claude --execute
161
+
162
+ # Use OpenAI
163
+ namingpaper rename paper.pdf -p openai --execute
164
+
165
+ # Auto-increment on collision
166
+ namingpaper rename paper.pdf -c increment --execute
167
+
168
+ # Skip confirmation
169
+ namingpaper rename paper.pdf -xy
170
+ ```
171
+
172
+ ### Batch Processing
173
+
174
+ ```bash
175
+ # Preview all renames in a directory
176
+ namingpaper batch ~/Downloads/papers
177
+
178
+ # Execute batch rename
179
+ namingpaper batch ~/Downloads/papers --execute
180
+
181
+ # Recursive scan with subdirectories
182
+ namingpaper batch ~/Downloads/papers -r --execute
183
+
184
+ # Filter by pattern (only 2023 papers)
185
+ namingpaper batch ~/Downloads/papers -f "2023*" --execute
186
+
187
+ # Use compact template
188
+ namingpaper batch ~/Downloads/papers -t compact --execute
189
+
190
+ # Custom template
191
+ namingpaper batch ~/Downloads/papers -t "{year} - {authors} - {title}" --execute
192
+
193
+ # Copy to organized folder
194
+ namingpaper batch ~/Downloads -o ~/Papers/Organized --execute
195
+
196
+ # Parallel processing (faster)
197
+ namingpaper batch ~/Downloads/papers --parallel 4 --execute
198
+
199
+ # Output as JSON (for scripting)
200
+ namingpaper batch ~/Downloads/papers --json
201
+ ```
202
+
203
+ ### View Configuration
204
+
205
+ ```bash
206
+ namingpaper config --show
207
+ ```
208
+
209
+ ## Filename Templates
210
+
211
+ Templates control how the output filename is formatted.
212
+
213
+ ### Preset Templates
214
+
215
+ | Name | Pattern | Example |
216
+ |------|---------|---------|
217
+ | `default` | `{authors}, ({year}, {journal}), {title}` | `Fama, French, (1993, JFE), Common risk....pdf` |
218
+ | `compact` | `{authors} ({year}) {title}` | `Fama, French (1993) Common risk....pdf` |
219
+ | `full` | `{authors}, ({year}, {journal_full}), {title}` | `Fama, French, (1993, Journal of Financial Economics), Common....pdf` |
220
+ | `simple` | `{authors}_{year}_{title}` | `Fama, French_1993_Common risk....pdf` |
221
+
222
+ ### Template Placeholders
223
+
224
+ | Placeholder | Description |
225
+ |-------------|-------------|
226
+ | `{authors}` | Author surnames (comma-separated, "et al" if >3) |
227
+ | `{year}` | Publication year |
228
+ | `{journal}` | Journal abbreviation (or full name if no abbrev) |
229
+ | `{journal_abbrev}` | Journal abbreviation only |
230
+ | `{journal_full}` | Full journal name |
231
+ | `{title}` | Paper title (truncated) |
232
+
233
+ ### Custom Templates
234
+
235
+ ```bash
236
+ # Year-first format
237
+ namingpaper batch ~/papers -t "{year} - {authors} - {title}"
238
+
239
+ # Minimal format
240
+ namingpaper batch ~/papers -t "{authors} {year}"
241
+
242
+ # Full journal name
243
+ namingpaper batch ~/papers -t "{authors}, ({year}, {journal_full}), {title}"
244
+ ```
245
+
246
+ ## Configuration
247
+
248
+ ### Environment Variables
249
+
250
+ | Variable | Description |
251
+ |----------|-------------|
252
+ | `NAMINGPAPER_ANTHROPIC_API_KEY` | Anthropic API key (for Claude) |
253
+ | `NAMINGPAPER_OPENAI_API_KEY` | OpenAI API key |
254
+ | `NAMINGPAPER_GEMINI_API_KEY` | Google Gemini API key |
255
+ | `NAMINGPAPER_AI_PROVIDER` | Provider: `ollama` (default), `claude`, `openai`, `gemini` |
256
+ | `NAMINGPAPER_MODEL_NAME` | Override default model for provider |
257
+ | `NAMINGPAPER_OLLAMA_BASE_URL` | Ollama API URL (default: `http://localhost:11434`) |
258
+ | `NAMINGPAPER_MAX_AUTHORS` | Max authors before "et al" (default: 3) |
259
+ | `NAMINGPAPER_MAX_FILENAME_LENGTH` | Max filename length (default: 200) |
260
+
261
+ ### Config File
262
+
263
+ Create `~/.namingpaper/config.toml`:
264
+
265
+ ```toml
266
+ # Default provider (ollama requires no API key)
267
+ ai_provider = "ollama"
268
+ ollama_base_url = "http://localhost:11434"
269
+
270
+ # Or use cloud providers
271
+ # ai_provider = "claude"
272
+ # anthropic_api_key = "sk-ant-..."
273
+
274
+ # Formatting options
275
+ max_authors = 3
276
+ max_filename_length = 200
277
+ ```
278
+
279
+ ## AI Providers
280
+
281
+ ### Ollama (Default)
282
+
283
+ Local LLM, no API key needed. Just have Ollama running.
284
+
285
+ ```bash
286
+ # Pull a vision model
287
+ ollama pull llama3.2-vision
288
+
289
+ # Use it (default provider)
290
+ namingpaper rename paper.pdf
291
+
292
+ # Or specify a different model
293
+ NAMINGPAPER_MODEL_NAME=deepseek-ocr namingpaper rename paper.pdf
294
+ ```
295
+
296
+ ### Claude (included by default)
297
+
298
+ ```bash
299
+ export NAMINGPAPER_ANTHROPIC_API_KEY=sk-ant-...
300
+ namingpaper rename paper.pdf -p claude
301
+ ```
302
+
303
+ ### OpenAI
304
+
305
+ ```bash
306
+ uv sync --extra openai
307
+ export NAMINGPAPER_OPENAI_API_KEY=sk-...
308
+ namingpaper rename paper.pdf -p openai
309
+ ```
310
+
311
+ ### Gemini
312
+
313
+ ```bash
314
+ uv sync --extra gemini
315
+ export NAMINGPAPER_GEMINI_API_KEY=...
316
+ namingpaper rename paper.pdf -p gemini
317
+ ```
318
+
319
+ ## Development
320
+
321
+ ```bash
322
+ # Clone and setup
323
+ git clone https://github.com/DanTsai0903/namingpaper.git
324
+ cd namingpaper
325
+ uv sync --extra dev
326
+
327
+ # Run tests
328
+ uv run pytest -v
329
+
330
+ # Run a specific test
331
+ uv run pytest tests/test_formatter.py -v
332
+ ```
333
+
334
+ ## License
335
+
336
+ MIT