ebk 0.1.0__py3-none-any.whl → 0.3.2__py3-none-any.whl
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.
Potentially problematic release.
This version of ebk might be problematic. Click here for more details.
- ebk/__init__.py +35 -0
- ebk/ai/__init__.py +23 -0
- ebk/ai/knowledge_graph.py +443 -0
- ebk/ai/llm_providers/__init__.py +21 -0
- ebk/ai/llm_providers/base.py +230 -0
- ebk/ai/llm_providers/ollama.py +362 -0
- ebk/ai/metadata_enrichment.py +396 -0
- ebk/ai/question_generator.py +328 -0
- ebk/ai/reading_companion.py +224 -0
- ebk/ai/semantic_search.py +434 -0
- ebk/ai/text_extractor.py +394 -0
- ebk/cli.py +2828 -680
- ebk/config.py +260 -22
- ebk/db/__init__.py +37 -0
- ebk/db/migrations.py +180 -0
- ebk/db/models.py +526 -0
- ebk/db/session.py +144 -0
- ebk/decorators.py +132 -0
- ebk/exports/base_exporter.py +218 -0
- ebk/exports/html_library.py +1390 -0
- ebk/exports/html_utils.py +117 -0
- ebk/exports/hugo.py +7 -3
- ebk/exports/jinja_export.py +287 -0
- ebk/exports/multi_facet_export.py +164 -0
- ebk/exports/symlink_dag.py +479 -0
- ebk/extract_metadata.py +76 -7
- ebk/library_db.py +899 -0
- ebk/plugins/__init__.py +42 -0
- ebk/plugins/base.py +502 -0
- ebk/plugins/hooks.py +444 -0
- ebk/plugins/registry.py +500 -0
- ebk/repl/__init__.py +9 -0
- ebk/repl/find.py +126 -0
- ebk/repl/grep.py +174 -0
- ebk/repl/shell.py +1677 -0
- ebk/repl/text_utils.py +320 -0
- ebk/search_parser.py +413 -0
- ebk/server.py +1633 -0
- ebk/services/__init__.py +11 -0
- ebk/services/import_service.py +442 -0
- ebk/services/tag_service.py +282 -0
- ebk/services/text_extraction.py +317 -0
- ebk/similarity/__init__.py +77 -0
- ebk/similarity/base.py +154 -0
- ebk/similarity/core.py +445 -0
- ebk/similarity/extractors.py +168 -0
- ebk/similarity/metrics.py +376 -0
- ebk/vfs/__init__.py +101 -0
- ebk/vfs/base.py +301 -0
- ebk/vfs/library_vfs.py +124 -0
- ebk/vfs/nodes/__init__.py +54 -0
- ebk/vfs/nodes/authors.py +196 -0
- ebk/vfs/nodes/books.py +480 -0
- ebk/vfs/nodes/files.py +155 -0
- ebk/vfs/nodes/metadata.py +385 -0
- ebk/vfs/nodes/root.py +100 -0
- ebk/vfs/nodes/similar.py +165 -0
- ebk/vfs/nodes/subjects.py +184 -0
- ebk/vfs/nodes/tags.py +371 -0
- ebk/vfs/resolver.py +228 -0
- ebk-0.3.2.dist-info/METADATA +755 -0
- ebk-0.3.2.dist-info/RECORD +69 -0
- {ebk-0.1.0.dist-info → ebk-0.3.2.dist-info}/WHEEL +1 -1
- ebk-0.3.2.dist-info/licenses/LICENSE +21 -0
- ebk/imports/__init__.py +0 -0
- ebk/imports/calibre.py +0 -144
- ebk/imports/ebooks.py +0 -116
- ebk/llm.py +0 -58
- ebk/manager.py +0 -44
- ebk/merge.py +0 -308
- ebk/streamlit/__init__.py +0 -0
- ebk/streamlit/__pycache__/__init__.cpython-310.pyc +0 -0
- ebk/streamlit/__pycache__/display.cpython-310.pyc +0 -0
- ebk/streamlit/__pycache__/filters.cpython-310.pyc +0 -0
- ebk/streamlit/__pycache__/utils.cpython-310.pyc +0 -0
- ebk/streamlit/app.py +0 -185
- ebk/streamlit/display.py +0 -168
- ebk/streamlit/filters.py +0 -151
- ebk/streamlit/utils.py +0 -58
- ebk/utils.py +0 -311
- ebk-0.1.0.dist-info/METADATA +0 -457
- ebk-0.1.0.dist-info/RECORD +0 -29
- {ebk-0.1.0.dist-info → ebk-0.3.2.dist-info}/entry_points.txt +0 -0
- {ebk-0.1.0.dist-info → ebk-0.3.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,755 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ebk
|
|
3
|
+
Version: 0.3.2
|
|
4
|
+
Summary: A lightweight, extensible tool for managing eBook metadata
|
|
5
|
+
Home-page: https://github.com/queelius/ebk
|
|
6
|
+
Author: Alex Towell
|
|
7
|
+
Author-email: Alex Towell <lex@metafunctor.com>
|
|
8
|
+
Maintainer-email: Alex Towell <lex@metafunctor.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
Project-URL: Homepage, https://github.com/queelius/ebk
|
|
11
|
+
Project-URL: Documentation, https://github.com/queelius/ebk/wiki
|
|
12
|
+
Project-URL: Repository, https://github.com/queelius/ebk.git
|
|
13
|
+
Project-URL: Issues, https://github.com/queelius/ebk/issues
|
|
14
|
+
Project-URL: Changelog, https://github.com/queelius/ebk/blob/main/CHANGELOG.md
|
|
15
|
+
Keywords: ebook,metadata,library,books,management,calibre
|
|
16
|
+
Classifier: Development Status :: 4 - Beta
|
|
17
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
18
|
+
Classifier: Intended Audience :: Developers
|
|
19
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
25
|
+
Classifier: Topic :: Text Processing :: Markup
|
|
26
|
+
Classifier: Topic :: Utilities
|
|
27
|
+
Requires-Python: >=3.8
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: typer>=0.9.0
|
|
31
|
+
Requires-Dist: rich>=13.0.0
|
|
32
|
+
Requires-Dist: lxml>=4.9.0
|
|
33
|
+
Requires-Dist: python-slugify>=8.0.0
|
|
34
|
+
Requires-Dist: pyyaml>=6.0
|
|
35
|
+
Requires-Dist: pypdf>=3.0.0
|
|
36
|
+
Requires-Dist: PyMuPDF>=1.23.0
|
|
37
|
+
Requires-Dist: ebooklib>=0.18
|
|
38
|
+
Requires-Dist: Pillow>=10.0.0
|
|
39
|
+
Requires-Dist: jmespath>=1.0.0
|
|
40
|
+
Requires-Dist: jinja2>=3.0.0
|
|
41
|
+
Requires-Dist: xmltodict>=0.13.0
|
|
42
|
+
Provides-Extra: ai
|
|
43
|
+
Requires-Dist: sentence-transformers>=2.2.0; extra == "ai"
|
|
44
|
+
Requires-Dist: scikit-learn>=1.3.0; extra == "ai"
|
|
45
|
+
Requires-Dist: networkx>=3.0; extra == "ai"
|
|
46
|
+
Requires-Dist: beautifulsoup4>=4.12.0; extra == "ai"
|
|
47
|
+
Requires-Dist: numpy>=1.24.0; extra == "ai"
|
|
48
|
+
Provides-Extra: streamlit
|
|
49
|
+
Requires-Dist: streamlit>=1.28.0; extra == "streamlit"
|
|
50
|
+
Requires-Dist: pandas>=2.0.0; extra == "streamlit"
|
|
51
|
+
Requires-Dist: altair>=5.0.0; extra == "streamlit"
|
|
52
|
+
Provides-Extra: metadata
|
|
53
|
+
Requires-Dist: aiohttp>=3.8.0; extra == "metadata"
|
|
54
|
+
Requires-Dist: beautifulsoup4>=4.12.0; extra == "metadata"
|
|
55
|
+
Requires-Dist: httpx>=0.24.0; extra == "metadata"
|
|
56
|
+
Provides-Extra: google-books
|
|
57
|
+
Requires-Dist: aiohttp>=3.8.0; extra == "google-books"
|
|
58
|
+
Provides-Extra: network
|
|
59
|
+
Provides-Extra: network-advanced
|
|
60
|
+
Requires-Dist: networkx>=3.0; extra == "network-advanced"
|
|
61
|
+
Requires-Dist: matplotlib>=3.5.0; extra == "network-advanced"
|
|
62
|
+
Requires-Dist: pyvis>=0.3.0; extra == "network-advanced"
|
|
63
|
+
Requires-Dist: plotly>=5.0.0; extra == "network-advanced"
|
|
64
|
+
Provides-Extra: llm
|
|
65
|
+
Requires-Dist: httpx>=0.24.0; extra == "llm"
|
|
66
|
+
Requires-Dist: pydantic>=2.0.0; extra == "llm"
|
|
67
|
+
Provides-Extra: mcp
|
|
68
|
+
Requires-Dist: mcp>=0.1.0; extra == "mcp"
|
|
69
|
+
Requires-Dist: pydantic>=2.0.0; extra == "mcp"
|
|
70
|
+
Provides-Extra: dev
|
|
71
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
72
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
73
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
74
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
75
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
76
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
77
|
+
Requires-Dist: pre-commit>=3.0.0; extra == "dev"
|
|
78
|
+
Provides-Extra: docs
|
|
79
|
+
Requires-Dist: mkdocs>=1.5.0; extra == "docs"
|
|
80
|
+
Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
|
|
81
|
+
Requires-Dist: mkdocstrings[python]>=0.24.0; extra == "docs"
|
|
82
|
+
Provides-Extra: all
|
|
83
|
+
Requires-Dist: sentence-transformers>=2.2.0; extra == "all"
|
|
84
|
+
Requires-Dist: scikit-learn>=1.3.0; extra == "all"
|
|
85
|
+
Requires-Dist: streamlit>=1.28.0; extra == "all"
|
|
86
|
+
Requires-Dist: pandas>=2.0.0; extra == "all"
|
|
87
|
+
Requires-Dist: altair>=5.0.0; extra == "all"
|
|
88
|
+
Requires-Dist: aiohttp>=3.8.0; extra == "all"
|
|
89
|
+
Requires-Dist: beautifulsoup4>=4.12.0; extra == "all"
|
|
90
|
+
Requires-Dist: httpx>=0.24.0; extra == "all"
|
|
91
|
+
Requires-Dist: networkx>=3.0; extra == "all"
|
|
92
|
+
Requires-Dist: matplotlib>=3.5.0; extra == "all"
|
|
93
|
+
Requires-Dist: pyvis>=0.3.0; extra == "all"
|
|
94
|
+
Requires-Dist: plotly>=5.0.0; extra == "all"
|
|
95
|
+
Requires-Dist: numpy>=1.24.0; extra == "all"
|
|
96
|
+
Provides-Extra: viz
|
|
97
|
+
Requires-Dist: ebk[network-advanced]; extra == "viz"
|
|
98
|
+
Dynamic: author
|
|
99
|
+
Dynamic: home-page
|
|
100
|
+
Dynamic: license-file
|
|
101
|
+
Dynamic: requires-python
|
|
102
|
+
|
|
103
|
+
# ebk
|
|
104
|
+
|
|
105
|
+
**ebk** is a powerful eBook metadata management tool with a SQLAlchemy + SQLite database backend. It provides a comprehensive fluent API for programmatic use, a rich Typer-based CLI (with colorized output courtesy of [Rich](https://github.com/Textualize/rich)), full-text search with FTS5 indexing, automatic text extraction and chunking for semantic search, hash-based file deduplication, and optional AI-powered features including knowledge graphs and semantic search.
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Table of Contents
|
|
111
|
+
|
|
112
|
+
- [Features](#features)
|
|
113
|
+
- [Installation](#installation)
|
|
114
|
+
- [Quick Start](#quick-start)
|
|
115
|
+
- [Configuration](#configuration)
|
|
116
|
+
- [CLI Usage](#cli-usage)
|
|
117
|
+
- [Database Commands](#database-commands)
|
|
118
|
+
- [Web Server](#web-server)
|
|
119
|
+
- [AI-Powered Features](#ai-powered-features)
|
|
120
|
+
- [Configuration Management](#configuration-management)
|
|
121
|
+
- [Legacy Commands](#legacy-commands)
|
|
122
|
+
- [Python API](#python-api)
|
|
123
|
+
- [Integrations](#integrations)
|
|
124
|
+
- [Architecture](#architecture)
|
|
125
|
+
- [Development](#development)
|
|
126
|
+
- [Contributing](#contributing)
|
|
127
|
+
- [License](#license)
|
|
128
|
+
- [Documentation](#documentation)
|
|
129
|
+
- [Stay Updated](#stay-updated)
|
|
130
|
+
- [Support](#support)
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Features
|
|
135
|
+
|
|
136
|
+
- **SQLAlchemy + SQLite Backend**: Robust database with normalized schema, proper relationships, and FTS5 full-text search
|
|
137
|
+
- **Fluent Python API**: Comprehensive programmatic interface with method chaining and query builders
|
|
138
|
+
- **Typer + Rich CLI**: A colorized, easy-to-use command-line interface
|
|
139
|
+
- **Automatic Text Extraction**: Extract and index text from PDFs, EPUBs, and plaintext files
|
|
140
|
+
- PyMuPDF (primary) with pypdf fallback for PDFs
|
|
141
|
+
- ebooklib with HTML parsing for EPUBs
|
|
142
|
+
- Automatic chunking (500-word overlapping chunks) for semantic search
|
|
143
|
+
- **Hash-based Deduplication**: SHA256-based file deduplication
|
|
144
|
+
- Same file (same hash) = skipped
|
|
145
|
+
- Same book, different format = added as additional format
|
|
146
|
+
- Hash-prefixed directory storage for scalability
|
|
147
|
+
- **Advanced Search**: Powerful search with field-specific queries and boolean logic
|
|
148
|
+
- Field searches: `title:Python`, `author:Knuth`, `tag:programming`
|
|
149
|
+
- Boolean operators: `AND` (implicit), `OR`, `NOT`/`-prefix`
|
|
150
|
+
- Comparison filters: `rating:>=4`, `rating:3-5`
|
|
151
|
+
- Exact filters: `language:en`, `format:pdf`, `favorite:true`
|
|
152
|
+
- Phrase searches: `"machine learning"`
|
|
153
|
+
- Fast FTS5-powered full-text search across titles, descriptions, and extracted text
|
|
154
|
+
- **Import from Multiple Sources**:
|
|
155
|
+
- Calibre libraries (reads metadata.opf files)
|
|
156
|
+
- Individual ebook files with auto-metadata extraction
|
|
157
|
+
- Batch import with progress tracking
|
|
158
|
+
- **Cover Extraction**: Automatic cover extraction and thumbnail generation
|
|
159
|
+
- PDFs: First page rendered as image
|
|
160
|
+
- EPUBs: Cover from metadata or naming patterns
|
|
161
|
+
- **AI-Powered Features** (optional):
|
|
162
|
+
- **LLM Provider Abstraction**: Support for multiple LLM backends (Ollama, OpenAI-compatible APIs)
|
|
163
|
+
- **Metadata Enrichment**: Auto-generate tags, categories, and enhanced descriptions using LLMs
|
|
164
|
+
- **Local & Remote LLM**: Connect to local Ollama or remote GPU servers
|
|
165
|
+
- **Knowledge Graph**: NetworkX-based concept extraction and relationship mapping
|
|
166
|
+
- **Semantic Search**: Vector embeddings for similarity search (with TF-IDF fallback)
|
|
167
|
+
- **Reading Companion**: Track reading sessions with timestamps
|
|
168
|
+
- **Question Generator**: Generate active recall questions
|
|
169
|
+
- **Web Server Interface**:
|
|
170
|
+
- FastAPI-based REST API for library management
|
|
171
|
+
- URL-based navigation with filters, pagination, and sorting
|
|
172
|
+
- Clickable covers and file formats to open books
|
|
173
|
+
- Book details modal with comprehensive metadata display
|
|
174
|
+
- **Flexible Exports**:
|
|
175
|
+
- **HTML Export**: Self-contained interactive catalog with pagination (50 books/page)
|
|
176
|
+
- Client-side search and filtering
|
|
177
|
+
- URL state tracking for bookmarkable pages
|
|
178
|
+
- Optional file copying with `--copy` flag (includes covers)
|
|
179
|
+
- Export to ZIP archives
|
|
180
|
+
- Hugo-compatible Markdown with multiple organization options
|
|
181
|
+
- Jinja2 template support for customizable export formats
|
|
182
|
+
- **Integrations** (optional):
|
|
183
|
+
- **Streamlit Dashboard**: Interactive web interface
|
|
184
|
+
- **MCP Server**: AI assistant integration
|
|
185
|
+
- **Visualizations**: Network graphs for analysis
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Installation
|
|
190
|
+
|
|
191
|
+
### Basic Installation
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
pip install ebk
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### From Source
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
git clone https://github.com/queelius/ebk.git
|
|
201
|
+
cd ebk
|
|
202
|
+
pip install .
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### With Optional Features
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# With Streamlit dashboard
|
|
209
|
+
pip install ebk[streamlit]
|
|
210
|
+
|
|
211
|
+
# With visualization tools
|
|
212
|
+
pip install ebk[viz]
|
|
213
|
+
|
|
214
|
+
# With all optional features
|
|
215
|
+
pip install ebk[all]
|
|
216
|
+
|
|
217
|
+
# For development
|
|
218
|
+
pip install ebk[dev]
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
> **Note**: Requires Python 3.10+
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Quick Start
|
|
226
|
+
|
|
227
|
+
### 1. Initialize Configuration
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Create default configuration file at ~/.config/ebk/config.json
|
|
231
|
+
ebk config init
|
|
232
|
+
|
|
233
|
+
# View current configuration
|
|
234
|
+
ebk config show
|
|
235
|
+
|
|
236
|
+
# Set default library path
|
|
237
|
+
ebk config set library.default_path ~/my-library
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### 2. Create and Populate Library
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Initialize a new library
|
|
244
|
+
ebk init ~/my-library
|
|
245
|
+
|
|
246
|
+
# Import a single ebook with auto-metadata extraction
|
|
247
|
+
ebk import book.pdf ~/my-library
|
|
248
|
+
|
|
249
|
+
# Import from Calibre library
|
|
250
|
+
ebk import-calibre ~/Calibre/Library --output ~/my-library
|
|
251
|
+
|
|
252
|
+
# Search using full-text search
|
|
253
|
+
ebk search "python programming" ~/my-library
|
|
254
|
+
|
|
255
|
+
# List books with filtering
|
|
256
|
+
ebk list ~/my-library --author "Knuth" --limit 20
|
|
257
|
+
|
|
258
|
+
# Get statistics
|
|
259
|
+
ebk stats ~/my-library
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### 3. Launch Web Interface
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
# Start web server (uses config defaults)
|
|
266
|
+
ebk serve ~/my-library
|
|
267
|
+
|
|
268
|
+
# Custom port and host
|
|
269
|
+
ebk serve ~/my-library --port 8080 --host 127.0.0.1
|
|
270
|
+
|
|
271
|
+
# Auto-open browser
|
|
272
|
+
ebk config set server.auto_open_browser true
|
|
273
|
+
ebk serve ~/my-library
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### 4. AI-Powered Metadata Enrichment
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# Configure LLM provider
|
|
280
|
+
ebk config set llm.provider ollama
|
|
281
|
+
ebk config set llm.model llama3.2
|
|
282
|
+
ebk config set llm.host localhost
|
|
283
|
+
|
|
284
|
+
# Enrich library metadata using LLM
|
|
285
|
+
ebk enrich ~/my-library
|
|
286
|
+
|
|
287
|
+
# Enrich with all features
|
|
288
|
+
ebk enrich ~/my-library --generate-tags --categorize --enhance-descriptions
|
|
289
|
+
|
|
290
|
+
# Use remote GPU server
|
|
291
|
+
ebk enrich ~/my-library --host 192.168.1.100
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Configuration
|
|
297
|
+
|
|
298
|
+
ebk uses a centralized configuration system stored at `~/.config/ebk/config.json`. This configuration file manages settings for LLM providers, web server, CLI defaults, and library preferences.
|
|
299
|
+
|
|
300
|
+
### Configuration File Structure
|
|
301
|
+
|
|
302
|
+
```json
|
|
303
|
+
{
|
|
304
|
+
"llm": {
|
|
305
|
+
"provider": "ollama",
|
|
306
|
+
"model": "llama3.2",
|
|
307
|
+
"host": "localhost",
|
|
308
|
+
"port": 11434,
|
|
309
|
+
"api_key": null,
|
|
310
|
+
"temperature": 0.7,
|
|
311
|
+
"max_tokens": null
|
|
312
|
+
},
|
|
313
|
+
"server": {
|
|
314
|
+
"host": "0.0.0.0",
|
|
315
|
+
"port": 8000,
|
|
316
|
+
"auto_open_browser": false,
|
|
317
|
+
"page_size": 50
|
|
318
|
+
},
|
|
319
|
+
"cli": {
|
|
320
|
+
"verbose": false,
|
|
321
|
+
"color": true,
|
|
322
|
+
"page_size": 50
|
|
323
|
+
},
|
|
324
|
+
"library": {
|
|
325
|
+
"default_path": null
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Configuration Management
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
# Initialize configuration (creates default config file)
|
|
334
|
+
ebk config init
|
|
335
|
+
|
|
336
|
+
# View current configuration
|
|
337
|
+
ebk config show
|
|
338
|
+
|
|
339
|
+
# Edit configuration in your default editor
|
|
340
|
+
ebk config edit
|
|
341
|
+
|
|
342
|
+
# Set specific values
|
|
343
|
+
ebk config set llm.provider ollama
|
|
344
|
+
ebk config set llm.model mistral
|
|
345
|
+
ebk config set server.port 8080
|
|
346
|
+
ebk config set library.default_path ~/my-library
|
|
347
|
+
|
|
348
|
+
# Get specific value
|
|
349
|
+
ebk config get llm.model
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### LLM Provider Configuration
|
|
353
|
+
|
|
354
|
+
Configure LLM providers for metadata enrichment:
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
# Local Ollama (default)
|
|
358
|
+
ebk config set llm.provider ollama
|
|
359
|
+
ebk config set llm.host localhost
|
|
360
|
+
ebk config set llm.port 11434
|
|
361
|
+
ebk config set llm.model llama3.2
|
|
362
|
+
|
|
363
|
+
# Remote GPU server
|
|
364
|
+
ebk config set llm.host 192.168.1.100
|
|
365
|
+
|
|
366
|
+
# OpenAI-compatible API (future)
|
|
367
|
+
ebk config set llm.provider openai
|
|
368
|
+
ebk config set llm.api_key sk-...
|
|
369
|
+
ebk config set llm.model gpt-4
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### CLI Overrides
|
|
373
|
+
|
|
374
|
+
All commands support CLI arguments that override configuration defaults:
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
# These override config settings
|
|
378
|
+
ebk serve ~/library --port 9000 --host 127.0.0.1
|
|
379
|
+
ebk enrich ~/library --host 192.168.1.50 --model mistral
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
## CLI Usage
|
|
383
|
+
|
|
384
|
+
ebk uses [Typer](https://typer.tiangolo.com/) with [Rich](https://github.com/Textualize/rich) for a beautiful, colorized CLI experience.
|
|
385
|
+
|
|
386
|
+
### General CLI Structure
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
ebk --help # See all available commands
|
|
390
|
+
ebk <command> --help # See specific command usage
|
|
391
|
+
ebk --verbose <command> # Enable verbose output
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Database Commands
|
|
395
|
+
|
|
396
|
+
Core library management with SQLAlchemy + SQLite backend:
|
|
397
|
+
|
|
398
|
+
```bash
|
|
399
|
+
# Initialize library
|
|
400
|
+
ebk init ~/my-library
|
|
401
|
+
|
|
402
|
+
# Import books
|
|
403
|
+
ebk import book.pdf ~/my-library
|
|
404
|
+
ebk import ~/books/*.epub ~/my-library
|
|
405
|
+
ebk import-calibre ~/Calibre/Library --output ~/my-library
|
|
406
|
+
|
|
407
|
+
# Search with advanced syntax
|
|
408
|
+
ebk search "machine learning" ~/my-library # Plain full-text search
|
|
409
|
+
ebk search "title:Python rating:>=4" ~/my-library # Field-specific with filters
|
|
410
|
+
ebk search "author:Knuth format:pdf" ~/my-library # Multiple criteria
|
|
411
|
+
ebk search "tag:programming NOT java" ~/my-library # Boolean operators
|
|
412
|
+
ebk search '"deep learning" language:en' ~/my-library # Phrase search with filter
|
|
413
|
+
|
|
414
|
+
# List and filter
|
|
415
|
+
ebk list ~/my-library
|
|
416
|
+
ebk list ~/my-library --author "Knuth" --language en --limit 20
|
|
417
|
+
ebk list ~/my-library --format pdf --rating 4
|
|
418
|
+
|
|
419
|
+
# Statistics
|
|
420
|
+
ebk stats ~/my-library
|
|
421
|
+
ebk stats ~/my-library --format json
|
|
422
|
+
|
|
423
|
+
# Manage reading status
|
|
424
|
+
ebk rate ~/my-library <book-id> 5
|
|
425
|
+
ebk favorite ~/my-library <book-id>
|
|
426
|
+
ebk tag ~/my-library <book-id> --add "must-read" "technical"
|
|
427
|
+
|
|
428
|
+
# Remove books
|
|
429
|
+
ebk purge ~/my-library --rating 1 --confirm
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Web Server
|
|
433
|
+
|
|
434
|
+
Launch FastAPI-based web interface:
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
# Start server (uses config defaults)
|
|
438
|
+
ebk serve ~/my-library
|
|
439
|
+
|
|
440
|
+
# Custom host and port
|
|
441
|
+
ebk serve ~/my-library --host 127.0.0.1 --port 8080
|
|
442
|
+
|
|
443
|
+
# Auto-open browser
|
|
444
|
+
ebk serve ~/my-library --auto-open
|
|
445
|
+
|
|
446
|
+
# Configure defaults in config
|
|
447
|
+
ebk config set server.port 8080
|
|
448
|
+
ebk config set server.auto_open_browser true
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### AI-Powered Features
|
|
452
|
+
|
|
453
|
+
Enrich metadata using LLMs:
|
|
454
|
+
|
|
455
|
+
```bash
|
|
456
|
+
# Basic enrichment (uses config settings)
|
|
457
|
+
ebk enrich ~/my-library
|
|
458
|
+
|
|
459
|
+
# Full enrichment
|
|
460
|
+
ebk enrich ~/my-library \
|
|
461
|
+
--generate-tags \
|
|
462
|
+
--categorize \
|
|
463
|
+
--enhance-descriptions \
|
|
464
|
+
--assess-difficulty
|
|
465
|
+
|
|
466
|
+
# Enrich specific book
|
|
467
|
+
ebk enrich ~/my-library --book-id 42
|
|
468
|
+
|
|
469
|
+
# Use remote GPU server
|
|
470
|
+
ebk enrich ~/my-library --host 192.168.1.100 --model mistral
|
|
471
|
+
|
|
472
|
+
# Dry run (preview changes without saving)
|
|
473
|
+
ebk enrich ~/my-library --dry-run
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Configuration Management
|
|
477
|
+
|
|
478
|
+
Manage global configuration:
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
# Initialize configuration
|
|
482
|
+
ebk config init
|
|
483
|
+
|
|
484
|
+
# View configuration
|
|
485
|
+
ebk config show
|
|
486
|
+
ebk config show --section llm
|
|
487
|
+
|
|
488
|
+
# Edit in default editor
|
|
489
|
+
ebk config edit
|
|
490
|
+
|
|
491
|
+
# Set values
|
|
492
|
+
ebk config set llm.model llama3.2
|
|
493
|
+
ebk config set server.port 8080
|
|
494
|
+
ebk config set library.default_path ~/books
|
|
495
|
+
|
|
496
|
+
# Get values
|
|
497
|
+
ebk config get llm.model
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### Export and Advanced Features
|
|
501
|
+
|
|
502
|
+
```bash
|
|
503
|
+
# Export library
|
|
504
|
+
ebk export html ~/my-library ~/library.html # Self-contained HTML with pagination
|
|
505
|
+
ebk export html ~/my-library ~/site/lib.html --copy --base-url /library # Copy files + covers
|
|
506
|
+
ebk export zip ~/my-library ~/backup.zip
|
|
507
|
+
ebk export json ~/my-library ~/metadata.json
|
|
508
|
+
|
|
509
|
+
# Virtual libraries (filtered views)
|
|
510
|
+
ebk vlib create ~/my-library "python-books" --subject Python
|
|
511
|
+
ebk vlib list ~/my-library
|
|
512
|
+
|
|
513
|
+
# Notes and annotations
|
|
514
|
+
ebk note add ~/my-library <book-id> "Great chapter on algorithms"
|
|
515
|
+
ebk note list ~/my-library <book-id>
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
## Documentation
|
|
521
|
+
|
|
522
|
+
Comprehensive documentation is available at: **[https://queelius.github.io/ebk/](https://queelius.github.io/ebk/)**
|
|
523
|
+
|
|
524
|
+
### Documentation Contents
|
|
525
|
+
|
|
526
|
+
- **Getting Started**
|
|
527
|
+
- [Installation](https://queelius.github.io/ebk/getting-started/installation/)
|
|
528
|
+
- [Quick Start](https://queelius.github.io/ebk/getting-started/quickstart/)
|
|
529
|
+
- [Configuration Guide](https://queelius.github.io/ebk/getting-started/configuration/)
|
|
530
|
+
|
|
531
|
+
- **User Guide**
|
|
532
|
+
- [CLI Reference](https://queelius.github.io/ebk/user-guide/cli/)
|
|
533
|
+
- [Python API](https://queelius.github.io/ebk/user-guide/api/)
|
|
534
|
+
- [LLM Features](https://queelius.github.io/ebk/user-guide/llm-features/)
|
|
535
|
+
- [Web Server](https://queelius.github.io/ebk/user-guide/server/)
|
|
536
|
+
- [Import/Export](https://queelius.github.io/ebk/user-guide/import-export/)
|
|
537
|
+
- [Search & Query](https://queelius.github.io/ebk/user-guide/search/)
|
|
538
|
+
|
|
539
|
+
- **Advanced Topics**
|
|
540
|
+
- [Hugo Export](https://queelius.github.io/ebk/advanced/hugo-export/)
|
|
541
|
+
- [Symlink DAG](https://queelius.github.io/ebk/advanced/symlink-dag/)
|
|
542
|
+
- [Recommendations](https://queelius.github.io/ebk/advanced/recommendations/)
|
|
543
|
+
- [Batch Operations](https://queelius.github.io/ebk/advanced/batch-operations/)
|
|
544
|
+
|
|
545
|
+
- **Development**
|
|
546
|
+
- [Architecture](https://queelius.github.io/ebk/development/architecture/)
|
|
547
|
+
- [Contributing](https://queelius.github.io/ebk/development/contributing/)
|
|
548
|
+
- [API Reference](https://queelius.github.io/ebk/development/api-reference/)
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
## Python API
|
|
554
|
+
|
|
555
|
+
ebk provides a comprehensive SQLAlchemy-based API for programmatic library management:
|
|
556
|
+
|
|
557
|
+
```python
|
|
558
|
+
from pathlib import Path
|
|
559
|
+
from ebk.library_db import Library
|
|
560
|
+
|
|
561
|
+
# Open or create a library
|
|
562
|
+
lib = Library.open(Path("~/my-library"))
|
|
563
|
+
|
|
564
|
+
# Import books with automatic metadata extraction
|
|
565
|
+
book = lib.add_book(
|
|
566
|
+
Path("book.pdf"),
|
|
567
|
+
metadata={"title": "My Book", "creators": ["Author Name"]},
|
|
568
|
+
extract_text=True,
|
|
569
|
+
extract_cover=True
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
# Fluent query interface
|
|
573
|
+
results = (lib.query()
|
|
574
|
+
.filter_by_language("en")
|
|
575
|
+
.filter_by_author("Knuth")
|
|
576
|
+
.filter_by_subject("Algorithms")
|
|
577
|
+
.order_by("title", desc=False)
|
|
578
|
+
.limit(20)
|
|
579
|
+
.all())
|
|
580
|
+
|
|
581
|
+
# Full-text search (FTS5)
|
|
582
|
+
results = lib.search("machine learning", limit=50)
|
|
583
|
+
|
|
584
|
+
# Get book by ID
|
|
585
|
+
book = lib.get_book(42)
|
|
586
|
+
print(f"{book.title} by {', '.join([a.name for a in book.authors])}")
|
|
587
|
+
|
|
588
|
+
# Update reading status
|
|
589
|
+
lib.update_reading_status(book.id, "reading", progress=50, rating=4)
|
|
590
|
+
|
|
591
|
+
# Add tags
|
|
592
|
+
lib.add_tags(book.id, ["must-read", "technical"])
|
|
593
|
+
|
|
594
|
+
# Get statistics
|
|
595
|
+
stats = lib.stats()
|
|
596
|
+
print(f"Total books: {stats['total_books']}")
|
|
597
|
+
print(f"Total authors: {stats['total_authors']}")
|
|
598
|
+
print(f"Languages: {', '.join(stats['languages'])}")
|
|
599
|
+
|
|
600
|
+
# Query with filters
|
|
601
|
+
from ebk.db.models import Book, Author
|
|
602
|
+
from sqlalchemy import and_
|
|
603
|
+
|
|
604
|
+
books = lib.session.query(Book).join(Book.authors).filter(
|
|
605
|
+
and_(
|
|
606
|
+
Author.name.like("%Knuth%"),
|
|
607
|
+
Book.language == "en"
|
|
608
|
+
)
|
|
609
|
+
).all()
|
|
610
|
+
|
|
611
|
+
# Always close when done
|
|
612
|
+
lib.close()
|
|
613
|
+
|
|
614
|
+
# Or use context manager
|
|
615
|
+
with Library.open(Path("~/my-library")) as lib:
|
|
616
|
+
results = lib.search("Python programming")
|
|
617
|
+
for book in results:
|
|
618
|
+
print(book.title)
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
### AI-Powered Metadata Enrichment
|
|
622
|
+
|
|
623
|
+
```python
|
|
624
|
+
from ebk.ai.llm_providers.ollama import OllamaProvider
|
|
625
|
+
from ebk.ai.metadata_enrichment import MetadataEnrichmentService
|
|
626
|
+
|
|
627
|
+
# Initialize provider (local or remote)
|
|
628
|
+
provider = OllamaProvider.remote(
|
|
629
|
+
host="192.168.1.100",
|
|
630
|
+
model="llama3.2"
|
|
631
|
+
)
|
|
632
|
+
|
|
633
|
+
service = MetadataEnrichmentService(provider)
|
|
634
|
+
|
|
635
|
+
async with provider:
|
|
636
|
+
# Generate tags
|
|
637
|
+
tags = await service.generate_tags(
|
|
638
|
+
title="Introduction to Algorithms",
|
|
639
|
+
authors=["Cormen", "Leiserson"],
|
|
640
|
+
description="Comprehensive algorithms textbook"
|
|
641
|
+
)
|
|
642
|
+
|
|
643
|
+
# Categorize
|
|
644
|
+
categories = await service.categorize(
|
|
645
|
+
title="Introduction to Algorithms",
|
|
646
|
+
subjects=["Algorithms", "Data Structures"]
|
|
647
|
+
)
|
|
648
|
+
|
|
649
|
+
# Enhance description
|
|
650
|
+
description = await service.enhance_description(
|
|
651
|
+
title="Introduction to Algorithms",
|
|
652
|
+
text_sample="Chapter 1: The Role of Algorithms..."
|
|
653
|
+
)
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
See the [CLAUDE.md](CLAUDE.md) file for architectural details and [API documentation](https://queelius.github.io/ebk/user-guide/api/) for complete reference.
|
|
657
|
+
|
|
658
|
+
---
|
|
659
|
+
|
|
660
|
+
## Contributing
|
|
661
|
+
|
|
662
|
+
Contributions are welcome! Here’s how to get involved:
|
|
663
|
+
|
|
664
|
+
1. **Fork the Repo**
|
|
665
|
+
2. **Create a Branch** for your feature or fix
|
|
666
|
+
3. **Commit & Push** your changes
|
|
667
|
+
4. **Open a Pull Request** describing the changes
|
|
668
|
+
|
|
669
|
+
We appreciate code contributions, bug reports, and doc improvements alike.
|
|
670
|
+
|
|
671
|
+
---
|
|
672
|
+
|
|
673
|
+
## License
|
|
674
|
+
|
|
675
|
+
Distributed under the [MIT License](https://github.com/queelius/ebk/blob/main/LICENSE).
|
|
676
|
+
|
|
677
|
+
---
|
|
678
|
+
|
|
679
|
+
## Integrations
|
|
680
|
+
|
|
681
|
+
ebk follows a modular architecture where the core library remains lightweight, with optional integrations available:
|
|
682
|
+
|
|
683
|
+
### Streamlit Dashboard
|
|
684
|
+
```bash
|
|
685
|
+
pip install ebk[streamlit]
|
|
686
|
+
streamlit run ebk/integrations/streamlit/app.py
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
### MCP Server (AI Assistants)
|
|
690
|
+
```bash
|
|
691
|
+
pip install ebk[mcp]
|
|
692
|
+
# Configure your AI assistant to use the MCP server
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
### Visualizations
|
|
696
|
+
```bash
|
|
697
|
+
pip install ebk[viz]
|
|
698
|
+
# Visualization tools will be available as a separate script
|
|
699
|
+
# Documentation coming soon in integrations/viz/
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
See the [Integrations Guide](integrations/README.md) for detailed setup instructions.
|
|
703
|
+
|
|
704
|
+
---
|
|
705
|
+
|
|
706
|
+
## Architecture
|
|
707
|
+
|
|
708
|
+
ebk is designed with a clean, layered architecture:
|
|
709
|
+
|
|
710
|
+
1. **Core Library** (`ebk.library`): Fluent API for all operations
|
|
711
|
+
2. **CLI** (`ebk.cli`): Typer-based commands using the fluent API
|
|
712
|
+
3. **Import/Export** (`ebk.imports`, `ebk.exports`): Modular format support
|
|
713
|
+
4. **Integrations** (`integrations/`): Optional add-ons (web UI, AI, viz)
|
|
714
|
+
|
|
715
|
+
This design ensures the core remains lightweight while supporting powerful extensions.
|
|
716
|
+
|
|
717
|
+
---
|
|
718
|
+
|
|
719
|
+
## Development
|
|
720
|
+
|
|
721
|
+
```bash
|
|
722
|
+
# Clone the repository
|
|
723
|
+
git clone https://github.com/queelius/ebk.git
|
|
724
|
+
cd ebk
|
|
725
|
+
|
|
726
|
+
# Create virtual environment
|
|
727
|
+
make venv
|
|
728
|
+
|
|
729
|
+
# Install in development mode
|
|
730
|
+
make setup
|
|
731
|
+
|
|
732
|
+
# Run tests
|
|
733
|
+
make test
|
|
734
|
+
|
|
735
|
+
# Check coverage
|
|
736
|
+
make coverage
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
---
|
|
740
|
+
|
|
741
|
+
## Stay Updated
|
|
742
|
+
|
|
743
|
+
- **GitHub**: [https://github.com/queelius/ebk](https://github.com/queelius/ebk)
|
|
744
|
+
- **Website**: [https://metafunctor.com](https://metafunctor.com)
|
|
745
|
+
|
|
746
|
+
---
|
|
747
|
+
|
|
748
|
+
## Support
|
|
749
|
+
|
|
750
|
+
- **Issues**: [Open an Issue](https://github.com/queelius/ebk/issues) on GitHub
|
|
751
|
+
- **Contact**: <lex@metafunctor.com>
|
|
752
|
+
|
|
753
|
+
---
|
|
754
|
+
|
|
755
|
+
Happy eBook managing! 📚✨
|