Metadata-Version: 2.4
Name: zotcli
Version: 0.1.2
Summary: A read-only CLI for browsing and exporting a Zotero library
Author-email: MohamedNumair <mo7amednumair@gmail.com>
License: MIT
Requires-Python: >=3.10
Requires-Dist: click>=8.1
Requires-Dist: platformdirs>=4.0
Requires-Dist: pydantic>=2.0
Requires-Dist: python-dateutil>=2.9
Requires-Dist: rich>=13.0
Provides-Extra: all
Requires-Dist: jinja2>=3.1; extra == 'all'
Requires-Dist: pybtex>=0.24; extra == 'all'
Provides-Extra: bibtex
Requires-Dist: pybtex>=0.24; extra == 'bibtex'
Provides-Extra: export
Requires-Dist: jinja2>=3.1; extra == 'export'
Description-Content-Type: text/markdown

# zotcli (`zot`)
![alt text](zot.png)

A "crazy" good read-only command-line interface for your local [Zotero](https://www.zotero.org/) library. Queries `zotero.sqlite` directly — no Zotero app running, no API key, no internet required. Never writes to the database.

**Library stats on this machine:** 3,771 items · 200 collections · 3,201 tags · 6.2 GB storage

---

## Installation

```bash
pip install zotcli
```

Verify:
```bash
zot --help
```

The database at `~/Zotero/zotero.sqlite` is auto-detected on WSL. Override anytime with `--db PATH`.

depending on the operating system the Zotero folder can be in different locations. By default, zotcli looks for the database at `~/Zotero/zotero.sqlite`, which works for most setups. for Windows users, the Zotero folder is typically located in `C:\Users\<YourUsername>\Zotero`. For macOS users, it is usually found in `~/Zotero`. If you have a custom setup or want to specify a different path, you can use the `--db` option to point zotcli to the correct location of your `zotero.sqlite` file. 

---

## Repository layout

```
zotcli/
├── PLAN.md                          # Original design document
├── SKILL.md                         # Agent skill descriptor
├── pyproject.toml                   # Package metadata and dependencies
├── docs/
│   └── commands.md                  # Full command reference
├── src/
│   └── zotcli/
│       ├── __init__.py
│       ├── __main__.py              # python -m zotcli entrypoint
│       ├── db.py                    # Read-only SQLite connection + auto-discovery
│       ├── config.py                # TOML config (~/.config/zotcli/config.toml)
│       ├── models.py                # Pydantic v2 models: Item, Collection, Creator, Attachment, Note
│       ├── queries/
│       │   ├── items.py             # Core item fetch (_build_items — fields, creators, tags,
│       │   │                        #   collections, attachments, notes in one go)
│       │   ├── collections.py       # Collection tree queries
│       │   ├── attachments.py       # Attachment path resolution helpers
│       │   ├── tags.py              # Tag queries
│       │   └── search.py           # Field search, author search, DOI, year, fulltext
│       ├── export/
│       │   ├── json_.py             # Full-fidelity JSON dump
│       │   ├── csv_.py              # Flat CSV (one row per item)
│       │   ├── bibtex.py            # BibTeX with auto citation keys
│       │   └── markdown.py          # Markdown table report
│       └── cli/
│           ├── main.py              # Root Click group + global options
│           ├── render.py            # Shared Rich helpers (tables, panels, trees)
│           ├── collections.py       # `zot collections` subcommands
│           ├── items.py             # `zot items` subcommands
│           ├── attachments.py       # `zot attachments` subcommands
│           ├── search.py            # `zot search`
│           ├── stats.py             # `zot stats` subcommands
│           └── export.py            # `zot export` subcommands
└── tests/
    ├── conftest.py                  # In-memory SQLite fixture with seeded test data
    ├── test_db.py                   # Database layer tests
    ├── test_queries.py              # Query layer tests (items, collections, search, tags)
    ├── test_export.py               # Export format tests (JSON, CSV, BibTeX, Markdown)
    └── test_cli.py                  # CLI integration tests via CliRunner
```

---

## Architecture

```
CLI layer  (cli/)
    ↓  Click commands call query functions
Query layer  (queries/)
    ↓  Batch SQL via sqlite3.Row
Database layer  (db.py)       ← read-only URI: file:zotero.sqlite?mode=ro
    ↓
zotero.sqlite
```

Every item fetch runs 6 batched queries in one call — fields, creators, tags, collection memberships, attachments (with resolved absolute paths), and notes — so all data is available everywhere without extra round-trips.

---

## Global options

These go **before** the subcommand:

```
zot [--db PATH] [--library ID] [--format table|json|csv] [--no-color] <command>
```

---

## Examples with output

### `zot stats` — library overview

```bash
zot stats
```
```
   Library Summary
┌─────────────┬──────┐
│ Items       │ 3771 │
│ Collections │  200 │
│ Tags        │ 3201 │
│ Creators    │ 3959 │
└─────────────┴──────┘
       Items by Type
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Type             ┃ Count ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ annotation       │  2188 │
│ journalArticle   │   864 │
│ conferencePaper  │   234 │
│ webpage          │   179 │
│ book             │    77 │
│ report           │    75 │
│ preprint         │    43 │
│ thesis           │    32 │
│ bookSection      │    25 │
└──────────────────┴───────┘
```

```bash
zot stats years
```
```
              Publications by Year
┏━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Year ┃ Count ┃ Bar                            ┃
┡━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ 2026 │    10 │                                │
│ 2025 │    36 │ ██                             │
│ 2024 │   110 │ █████████                      │
│ 2023 │   361 │ ██████████████████████████████ │
│ 2022 │   144 │ ███████████                    │
│ 2021 │   120 │ █████████                      │
│ 2020 │   101 │ ████████                       │
│ 2019 │    96 │ ███████                        │
└──────┴───────┴────────────────────────────────┘
```

```bash
zot stats tags --top 10
```
```
           Top 10 Tags
┏━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Tag                   ┃ Items ┃
┡━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ Topology              │    89 │
│ Voltage measurement   │    77 │
│ Network topology      │    75 │
│ State estimation      │    65 │
│ Distribution networks │    53 │
│ thesis                │    50 │
│ Smart meters          │    48 │
│ notion                │    47 │
│ Real-time systems     │    46 │
│ _EndnoteXML import    │    38 │
└───────────────────────┴───────┘
```

---

### `zot collections` — browse the library tree

```bash
zot collections list
```
```
Collections
├── 00_Reading Tracker (2)
│   ├── Read (12)
│   ├── Reading (15)
│   └── To Read (31)
├── Energy Management (6)
│   ├── AI based Energy Management (2)
│   ├── Demand Response (14)
│   │   └── Home Energy Management System (3)
│   ├── Energy Market (75)
│   ├── Energy Storage (4)
│   ├── Felixibility (8)
│   └── Power Flow (16)
├── PhD Research (...)
│   ├── Distribution Systems (...)
│   └── State Estimation (...)
└── ...
```

```bash
zot collections items "Energy Market"
```
```
                            Energy Market (73 items)
┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━┓
┃  # ┃ Key       ┃ Type               ┃ Title                               ┃ Authors      ┃ Year   ┃
┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━┩
│  1 │ RBUU6AM2  │ journalArticle     │ New coordination framework for      │ Hussain      │ 2023   │
│    │           │                    │ smart home peer-to-peer trading…    │ et al.       │        │
│  2 │ 8DE2V7ZZ  │ journalArticle     │ Integrating Distributed Flexibility │ Tsaousoglou  │ 2023   │
│    │           │                    │ into TSO-DSO Coordinated Markets…   │ et al.       │        │
│  3 │ GKG9XUBE  │ thesis             │ Adoption of Blockchain in European  │ Meyer        │ 2023   │
│    │           │                    │ Electricity Markets                 │              │        │
└────┴───────────┴────────────────────┴─────────────────────────────────────┴──────────────┴────────┘
```

Include all sub-collections recursively:
```bash
zot collections items "Energy Management" --recursive
```

---

### `zot items` — inspect individual items

```bash
zot items list --limit 5
```
```
┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┓
┃  # ┃ Key       ┃ Type               ┃ Title                                       ┃ Authors     ┃ Year   ┃
┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━┩
│  1 │ L54VEEWV  │ journalArticle     │ Three-phase feeder parameter estimation…    │ Yang et al. │ 2026   │
│  2 │ B8CNX4LI  │ journalArticle     │ Coordinated State Estimation of Power…      │ Sharma      │ 2025   │
│  3 │ MXYF8V3J  │ journalArticle     │ Towards Digital Twin of Distribution…       │ Idlbi       │ 2026   │
│  4 │ YN89DKH4  │ book               │ 41st European Photovoltaic Solar Energy…    │             │ 2024   │
│  5 │ 5UFZMSLU  │ journalArticle     │ UNLOCKING DATA CENTRE HOSTING CAPACITY…     │ Numair      │ 2026   │
└────┴───────────┴────────────────────┴─────────────────────────────────────────────┴─────────────┴────────┘
```

```bash
zot items show 5UFZMSLU
```
```
╭────────────────── journalArticle #6439  5UFZMSLU ──────────────────╮
│ Title    UNLOCKING DATA CENTRE HOSTING CAPACITY AND FLEXIBILITY     │
│          THROUGH DYNAMIC CABLE RATING                               │
│ Authors  Numair, Mohamed; ElKholy, Ahmed M; Martins-Britto,         │
│          Amauri G; Hertem, Dirk Van; Vanin, Marta                   │
│ Year     2026                                                       │
│ abstractNote  The unprecedented pace of Distributed Energy          │
│               Resource (DER) integration and electr…               │
│ language      en                                                    │
│                                                                     │
│ Attachments                                                         │
│   ✓ Numair et al. - 2026 - UNLOCKING DATA CENTRE…pdf               │
│                                                                     │
│ Notes (1)                                                           │
│   • Annotations(2/25/2026) (Numair et al., 2026, p. 1) …           │
╰─────────────────────────────────────────────────────────────────────╯
```

---

### `zot search` — find items

**By title keyword:**
```bash
zot search "bayesian" --field title
```
```
                                5 result(s)
┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━┓
┃  # ┃ Key       ┃ Type            ┃ Title                                     ┃ Authors        ┃ Year   ┃
┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━┩
│  1 │ LVTG4KLQ  │ journalArticle  │ An Improved Recursive Bayesian Approach   │ Chen et al.    │ 2013   │
│    │           │                 │ for Transformer Tap Position Estimation   │                │        │
│  2 │ 6BR3CYQA  │ conferencePaper │ Bayesian distribution system state        │ Angioni et al. │ 2016   │
│    │           │                 │ estimation in presence of non-Gaussian…   │                │        │
│  3 │ K2YXXPX7  │ journalArticle  │ A Recursive Bayesian Approach for         │ Singh et al.   │ 2010   │
│    │           │                 │ Identification of Network Configuration…  │                │        │
│  4 │ CRJWMH2X  │ journalArticle  │ Real-Time Topology Estimation Using       │ Liu et al.     │ 2023   │
│    │           │                 │ Graph-Bank Transformer…                   │                │        │
│  5 │ TJH8CGUT  │ conferencePaper │ Bayesian Methods for the Identification   │ Brouillon      │ 2021   │
│    │           │                 │ of Distribution Networks                  │ et al.         │        │
└────┴───────────┴─────────────────┴───────────────────────────────────────────┴────────────────┴────────┘
```

**By author name** (queries the creators table, partial match):
```bash
zot search --author "Numair"
```
```
                               12 result(s)
┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━┓
┃  # ┃ Key       ┃ Type            ┃ Title                                     ┃ Authors       ┃ Year   ┃
┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━┩
│  1 │ MDLX3G4P  │ conferencePaper │ A Proposed IoT Architecture for Effective │ Numair et al. │ 2020   │
│    │           │                 │ Energy Management in Smart Microgrids     │               │        │
│  2 │ W3P98AE9  │ conferencePaper │ On the UK smart metering system and value │ Numair et al. │ 2023   │
│    │           │                 │ of data for distribution system…          │               │        │
│  3 │ UIMHSHNV  │ journalArticle  │ Fault Detection and Localisation in LV    │ Numair et al. │ 2023   │
│    │           │                 │ Distribution Networks Using Smart Meter…  │               │        │
│  4 │ TAVRNAY6  │ bookSection     │ Infrastructure for the 4th Industrial     │ Numair et al. │ 2024   │
│    │           │                 │ Revolution Technologies                   │               │        │
│  5 │ 5UFZMSLU  │ journalArticle  │ UNLOCKING DATA CENTRE HOSTING CAPACITY…   │ Numair et al. │ 2026   │
│  … │ …         │ …               │ …                                         │ …             │ …      │
└────┴───────────┴─────────────────┴───────────────────────────────────────────┴───────────────┴────────┘
```

**By DOI:**
```bash
zot search --doi "10.1016/j.epsr.2020.106394"
```
```
                                1 result(s)
┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━┓
┃  # ┃ Key       ┃ Type           ┃ Title                                     ┃ Authors          ┃ Year   ┃
┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━┩
│  1 │ ZGYGL35J  │ journalArticle │ Preventative high impedance fault         │ Langeroudi       │ 2020   │
│    │           │                │ detection using distribution system…      │ et al.           │        │
└────┴───────────┴────────────────┴───────────────────────────────────────────┴──────────────────┴────────┘
```

**By year range:**
```bash
zot search --year 2023 --type conferencePaper
```
```
361 result(s)  [truncated to first 5 shown]
┏━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━┓
┃  # ┃ Key       ┃ Type            ┃ Title                                     ┃ Authors         ┃ Year   ┃
┡━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━┩
│  1 │ ZRF8IFPI  │ journalArticle  │ Fault Location Method for an Active       │ Zhao et al.     │ 2023   │
│    │           │                 │ Distribution Network Based on…            │                 │        │
│  2 │ G3USAIB9  │ journalArticle  │ PMU Measurements-Based Short-Term         │ Li et al.       │ 2023   │
│    │           │                 │ Voltage Stability Assessment…             │                 │        │
│  3 │ RBUU6AM2  │ journalArticle  │ New coordination framework for smart      │ Hussain et al.  │ 2023   │
│    │           │                 │ home peer-to-peer trading…                │                 │        │
└────┴───────────┴─────────────────┴───────────────────────────────────────────┴─────────────────┴────────┘
```

---

### `zot attachments` — locate files

**Get the PDF path for a single item:**
```bash
zot attachments path 5UFZMSLU
```
```
~/Zotero/storage/RIB344FW/Numair et al. - 2026 - UNLOCKING DATA CENTRE HOSTING CAPACITY AND FLEXIBILITY THROUGH DYNAMIC CABLE RATING.pdf
```

**List all attachments for an item (with existence check):**
```bash
zot items attachments W3P98AE9
```
```
                       Attachments for W3P98AE9
┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Key      ┃ Type            ┃ Mode         ┃ Exists ┃ Path                                      ┃
┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ GKHSKIP4 │ text/html       │ imported_url │ ✓      │ …/storage/GKHSKIP4/10136487.html          │
│ 7PZKGWIJ │ application/pdf │ imported_url │ ✓      │ …/storage/7PZKGWIJ/Numair et al. - 2023…  │
└──────────┴─────────────────┴──────────────┴────────┴───────────────────────────────────────────┘
```

**Find all missing attachments:**
```bash
zot attachments list --missing
```

**Open a PDF in the system viewer:**
```bash
zot attachments open 5UFZMSLU
# Opening: ~/Zotero/storage/RIB344FW/Numair et al. - 2026 - ...pdf
```

---

### `zot export` — export to files

**BibTeX:**
```bash
zot export bib --collection "Energy Market" --output refs.bib
```
```bibtex
@article{hussain_new_2023,
  title = {New coordination framework for smart home peer-to-peer trading…},
  author = {Hussain, Sadam and Azim, M. Imran and Lai, Chunyan and Eicker, Ursula},
  year = {2023},
  journal = {Energy},
  volume = {284},
  pages = {129297},
  doi = {10.1016/j.energy.2023.129297},
}

@article{tsaousoglou_integrating_2023,
  title = {Integrating Distributed Flexibility into TSO-DSO Coordinated Electricity Markets},
  author = {Tsaousoglou, Georgios and Junker, Rune and …},
  year = {2023},
  doi = {10.1109/TEMPR.2023.3319673},
}
…
```

**CSV:**
```bash
zot export csv --collection "Energy Market" --output refs.csv
```
```
item_id,key,item_type,title,year,doi,journal,…,author_1,author_2,…,tags
10,RBUU6AM2,journalArticle,New coordination framework…,2023,10.1016/…,Energy,…,"Hussain, Sadam","Azim, M. Imran",…,Smart grid;Flexibility
18,8DE2V7ZZ,journalArticle,Integrating Distributed Flexibility…,2023,10.1109/…,…
```

**JSON** (includes fully resolved attachment paths and notes):
```bash
zot export json --collection "Energy Market" --output refs.json
```
```json
[
  {
    "item_id": 10,
    "key": "RBUU6AM2",
    "item_type": "journalArticle",
    "title": "New coordination framework for smart home peer-to-peer trading…",
    "year": "2023",
    "attachments": [
      {
        "key": "PXW7M26P",
        "content_type": "application/pdf",
        "file_exists": true,
        "absolute_path": "~/Zotero/storage/PXW7M26P/Hussain et al. - 2023 - …pdf"
      }
    ],
    "notes": [],
    "tags": ["Smart grid", "Distribution transformer", "Flexibility"],
    …
  }
]
```

**Markdown:**
```bash
zot export markdown --collection "Energy Market" --output refs.md
zot export markdown --all --notes --output full-library.md   # include notes sections
```

---

### Workflow: search → get attachment paths

Find all papers with "bayesian" in the title **or** authored by "Numair", then print the PDF path for each:

```python
from zotcli.db import ZoteroDatabase
from zotcli.queries.search import search_items, search_by_author

DB = "~/Zotero/zotero.sqlite"

with ZoteroDatabase(DB) as db:
    bayesian = search_items(db, "bayesian", fields=["title"])
    numair   = search_by_author(db, "Numair")

    seen = set()
    for item in bayesian + numair:
        if item.item_id in seen:
            continue
        seen.add(item.item_id)
        for att in item.attachments:
            if att.file_exists and "pdf" in att.content_type.lower():
                print(f"{item.key}\t{att.absolute_path}")
```

```
LVTG4KLQ    ~/Zotero/storage/LVTG4KLQ/Chen2013_BayesianTap.pdf
5UFZMSLU    ~/Zotero/storage/RIB344FW/Numair et al. - 2026 - UNLOCKING DATA CENTRE…pdf
W3P98AE9    ~/Zotero/storage/7PZKGWIJ/Numair et al. - 2023 - On the UK smart metering…pdf
…
```

---

## Running tests

```bash
python3 -m pytest tests/ -q
```
```
........................................
40 passed in 31s
```

Tests use an in-memory SQLite fixture seeded with synthetic Zotero data. No real database needed.

---

## Configuration

Optional persistent config at `~/.config/zotcli/config.toml`:

```toml
[database]
path = "~/Zotero/zotero.sqlite"
library_id = 1

[output]
default_format = "table"
color = true
page_size = 50
```

---

## Safety

- Database opened with `sqlite3://…?mode=ro` — the OS-level read-only URI flag makes writes impossible
- WAL journal detection warns if Zotero is currently open (pending writes may not be visible yet)
- No network calls, no Zotero API, no authentication
