ebk 0.3.1__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.

Files changed (61) hide show
  1. ebk/ai/__init__.py +23 -0
  2. ebk/ai/knowledge_graph.py +443 -0
  3. ebk/ai/llm_providers/__init__.py +21 -0
  4. ebk/ai/llm_providers/base.py +230 -0
  5. ebk/ai/llm_providers/ollama.py +362 -0
  6. ebk/ai/metadata_enrichment.py +396 -0
  7. ebk/ai/question_generator.py +328 -0
  8. ebk/ai/reading_companion.py +224 -0
  9. ebk/ai/semantic_search.py +434 -0
  10. ebk/ai/text_extractor.py +394 -0
  11. ebk/cli.py +1097 -9
  12. ebk/db/__init__.py +37 -0
  13. ebk/db/migrations.py +180 -0
  14. ebk/db/models.py +526 -0
  15. ebk/db/session.py +144 -0
  16. ebk/exports/__init__.py +0 -0
  17. ebk/exports/base_exporter.py +218 -0
  18. ebk/exports/html_library.py +1390 -0
  19. ebk/exports/html_utils.py +117 -0
  20. ebk/exports/hugo.py +59 -0
  21. ebk/exports/jinja_export.py +287 -0
  22. ebk/exports/multi_facet_export.py +164 -0
  23. ebk/exports/symlink_dag.py +479 -0
  24. ebk/exports/zip.py +25 -0
  25. ebk/library_db.py +155 -0
  26. ebk/repl/__init__.py +9 -0
  27. ebk/repl/find.py +126 -0
  28. ebk/repl/grep.py +174 -0
  29. ebk/repl/shell.py +1677 -0
  30. ebk/repl/text_utils.py +320 -0
  31. ebk/services/__init__.py +11 -0
  32. ebk/services/import_service.py +442 -0
  33. ebk/services/tag_service.py +282 -0
  34. ebk/services/text_extraction.py +317 -0
  35. ebk/similarity/__init__.py +77 -0
  36. ebk/similarity/base.py +154 -0
  37. ebk/similarity/core.py +445 -0
  38. ebk/similarity/extractors.py +168 -0
  39. ebk/similarity/metrics.py +376 -0
  40. ebk/vfs/__init__.py +101 -0
  41. ebk/vfs/base.py +301 -0
  42. ebk/vfs/library_vfs.py +124 -0
  43. ebk/vfs/nodes/__init__.py +54 -0
  44. ebk/vfs/nodes/authors.py +196 -0
  45. ebk/vfs/nodes/books.py +480 -0
  46. ebk/vfs/nodes/files.py +155 -0
  47. ebk/vfs/nodes/metadata.py +385 -0
  48. ebk/vfs/nodes/root.py +100 -0
  49. ebk/vfs/nodes/similar.py +165 -0
  50. ebk/vfs/nodes/subjects.py +184 -0
  51. ebk/vfs/nodes/tags.py +371 -0
  52. ebk/vfs/resolver.py +228 -0
  53. {ebk-0.3.1.dist-info → ebk-0.3.2.dist-info}/METADATA +1 -1
  54. ebk-0.3.2.dist-info/RECORD +69 -0
  55. ebk-0.3.2.dist-info/entry_points.txt +2 -0
  56. ebk-0.3.2.dist-info/top_level.txt +1 -0
  57. ebk-0.3.1.dist-info/RECORD +0 -19
  58. ebk-0.3.1.dist-info/entry_points.txt +0 -6
  59. ebk-0.3.1.dist-info/top_level.txt +0 -2
  60. {ebk-0.3.1.dist-info → ebk-0.3.2.dist-info}/WHEEL +0 -0
  61. {ebk-0.3.1.dist-info → ebk-0.3.2.dist-info}/licenses/LICENSE +0 -0
ebk/vfs/resolver.py ADDED
@@ -0,0 +1,228 @@
1
+ """Path resolution for the Virtual File System.
2
+
3
+ Handles path parsing and navigation (cd, ls semantics).
4
+ """
5
+
6
+ from pathlib import PurePosixPath
7
+ from typing import Optional, List, Tuple
8
+
9
+ from ebk.vfs.base import Node, DirectoryNode, SymlinkNode
10
+
11
+
12
+ class PathResolver:
13
+ """Resolves paths in the VFS and handles navigation.
14
+
15
+ This class provides the core navigation logic for cd, ls, etc.
16
+ It handles:
17
+ - Absolute paths: /books/42/title
18
+ - Relative paths: ../other, ./files
19
+ - Special paths: ., .., ~
20
+ - Symlink resolution
21
+ """
22
+
23
+ def __init__(self, root: DirectoryNode):
24
+ """Initialize path resolver.
25
+
26
+ Args:
27
+ root: Root node of the VFS
28
+ """
29
+ self.root = root
30
+
31
+ def resolve(
32
+ self,
33
+ path: str,
34
+ current: DirectoryNode,
35
+ follow_symlinks: bool = True,
36
+ ) -> Optional[Node]:
37
+ """Resolve a path to a node.
38
+
39
+ Args:
40
+ path: Path to resolve (absolute or relative)
41
+ current: Current working directory
42
+ follow_symlinks: Whether to follow symlinks
43
+
44
+ Returns:
45
+ Resolved node or None if path doesn't exist
46
+ """
47
+ # Handle empty path
48
+ if not path or path == ".":
49
+ return current
50
+
51
+ # Parse path
52
+ parts = self._parse_path(path)
53
+
54
+ # Start from root or current directory
55
+ if path.startswith("/"):
56
+ node = self.root
57
+ else:
58
+ node = current
59
+
60
+ # Navigate through path parts
61
+ for part in parts:
62
+ if part == "." or part == "":
63
+ continue
64
+ elif part == "..":
65
+ # Go to parent
66
+ if node.parent is not None:
67
+ node = node.parent
68
+ # Stay at root if already at root
69
+ else:
70
+ # Navigate to child
71
+ if not isinstance(node, DirectoryNode):
72
+ # Can't cd into a file
73
+ return None
74
+
75
+ child = node.get_child(part)
76
+ if child is None:
77
+ return None
78
+
79
+ # Follow symlinks if requested
80
+ if follow_symlinks and isinstance(child, SymlinkNode):
81
+ child = self.resolve(child.target_path, current, follow_symlinks=True)
82
+ if child is None:
83
+ return None
84
+
85
+ node = child
86
+
87
+ return node
88
+
89
+ def resolve_directory(
90
+ self,
91
+ path: str,
92
+ current: DirectoryNode,
93
+ ) -> Optional[DirectoryNode]:
94
+ """Resolve a path to a directory node.
95
+
96
+ Args:
97
+ path: Path to resolve
98
+ current: Current working directory
99
+
100
+ Returns:
101
+ Directory node or None if path doesn't exist or isn't a directory
102
+ """
103
+ node = self.resolve(path, current)
104
+ if node is None or not isinstance(node, DirectoryNode):
105
+ return None
106
+ return node
107
+
108
+ def normalize_path(self, path: str, current: DirectoryNode) -> str:
109
+ """Normalize a path to absolute form.
110
+
111
+ Args:
112
+ path: Path to normalize
113
+ current: Current working directory
114
+
115
+ Returns:
116
+ Normalized absolute path
117
+ """
118
+ # Resolve to node first
119
+ node = self.resolve(path, current)
120
+ if node is None:
121
+ # Path doesn't exist, do best effort normalization
122
+ return self._normalize_nonexistent(path, current)
123
+
124
+ return node.get_path()
125
+
126
+ def complete_path(
127
+ self,
128
+ partial: str,
129
+ current: DirectoryNode,
130
+ ) -> List[str]:
131
+ """Get completion candidates for a partial path.
132
+
133
+ Used for tab completion.
134
+
135
+ Args:
136
+ partial: Partial path to complete
137
+ current: Current working directory
138
+
139
+ Returns:
140
+ List of completion candidates
141
+ """
142
+ # Split into directory part and filename part
143
+ if "/" in partial:
144
+ dir_part, file_part = partial.rsplit("/", 1)
145
+ if partial.startswith("/"):
146
+ dir_part = "/" + dir_part if dir_part else "/"
147
+ else:
148
+ dir_part = ""
149
+ file_part = partial
150
+
151
+ # Resolve directory
152
+ if dir_part:
153
+ dir_node = self.resolve_directory(dir_part, current)
154
+ else:
155
+ dir_node = current
156
+
157
+ if dir_node is None:
158
+ return []
159
+
160
+ # Get children and filter by prefix
161
+ children = dir_node.list_children()
162
+ candidates = []
163
+
164
+ for child in children:
165
+ if child.name.startswith(file_part):
166
+ if dir_part:
167
+ candidates.append(f"{dir_part}/{child.name}")
168
+ else:
169
+ candidates.append(child.name)
170
+
171
+ # Add trailing slash for directories
172
+ if isinstance(child, DirectoryNode):
173
+ candidates[-1] += "/"
174
+
175
+ return candidates
176
+
177
+ def _parse_path(self, path: str) -> List[str]:
178
+ """Parse a path into parts.
179
+
180
+ Args:
181
+ path: Path to parse
182
+
183
+ Returns:
184
+ List of path components
185
+ """
186
+ # Use PurePosixPath for Unix-style path handling
187
+ posix_path = PurePosixPath(path)
188
+
189
+ # Get parts (excluding the root /)
190
+ parts = posix_path.parts
191
+ if parts and parts[0] == "/":
192
+ parts = parts[1:]
193
+
194
+ return list(parts)
195
+
196
+ def _normalize_nonexistent(self, path: str, current: DirectoryNode) -> str:
197
+ """Normalize a path that doesn't exist.
198
+
199
+ Args:
200
+ path: Path to normalize
201
+ current: Current working directory
202
+
203
+ Returns:
204
+ Best-effort normalized path
205
+ """
206
+ if path.startswith("/"):
207
+ # Already absolute
208
+ return str(PurePosixPath(path))
209
+
210
+ # Make relative path absolute
211
+ current_path = current.get_path()
212
+ combined = PurePosixPath(current_path) / path
213
+ return str(combined)
214
+
215
+
216
+ class PathError(Exception):
217
+ """Error resolving a path."""
218
+ pass
219
+
220
+
221
+ class NotADirectoryError(PathError):
222
+ """Attempted to cd into a non-directory."""
223
+ pass
224
+
225
+
226
+ class NotFoundError(PathError):
227
+ """Path does not exist."""
228
+ pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ebk
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: A lightweight, extensible tool for managing eBook metadata
5
5
  Home-page: https://github.com/queelius/ebk
6
6
  Author: Alex Towell
@@ -0,0 +1,69 @@
1
+ ebk/__init__.py,sha256=KK5aFY07PvPB8LjfNJ_xAuWft6uyIMsiK6vrvhyyg14,790
2
+ ebk/cli.py,sha256=oAG25LPGJH0QZPQJVGEpiHCcgdaPw4sn5mN0knhRX_M,112835
3
+ ebk/config.py,sha256=P090sNH2YSnNNteXjim2_WYN9j2BC_GU5o0wQIwSbT4,7364
4
+ ebk/decorators.py,sha256=MpAD1Wwy3o4l0sEiq4EIy5YtKMKf_nXtu7jpV64Uvyc,5179
5
+ ebk/extract_metadata.py,sha256=epMn9_4zQYiytBwj25_-rYl0QmPN4cP25DuxMnijNMU,12228
6
+ ebk/ident.py,sha256=yRIKVA0rpyhdPCxl0Vx7iu3YOebE8Yvbv32iCJmKk-Y,3324
7
+ ebk/library_db.py,sha256=BEwqvoR8Ayec53ptmVcRsL2oTTlHj1_w0WP_j1ONfSA,29535
8
+ ebk/search_parser.py,sha256=NRVbGnaOWxbc1WtsoFVINjHqCMBEubrKBxY2b_HQqJY,14848
9
+ ebk/server.py,sha256=x5vpQmZjGAwJVgmUq8l8Z1owfoqg2weuUVBovEWVE-s,59036
10
+ ebk/ai/__init__.py,sha256=-0vfDHdht8ZasYvl33nyGoWCaZxKIn_en0PxZdRQMkw,686
11
+ ebk/ai/knowledge_graph.py,sha256=Xp4Ao1fVwp6oKyBG1hDroAqPTADyyUGG86WczvLRDzg,16504
12
+ ebk/ai/metadata_enrichment.py,sha256=jQrqwjTzZkxzkJdxdwQCN1Cchkwa6jibHd8r5hjYosw,12364
13
+ ebk/ai/question_generator.py,sha256=ev1wEmgIDxnb_kaZdiLh0Z1TW7HUjb_HR1NlsBmdduQ,11363
14
+ ebk/ai/reading_companion.py,sha256=8GHiA9tR-vb28eCS3FmpDmRMX2OMyg5IP8AhPZ7c-Vg,7948
15
+ ebk/ai/semantic_search.py,sha256=i0qY6cEr_89RWxTdJpnMoHu-l4csYIdDi6nh17asyfQ,15218
16
+ ebk/ai/text_extractor.py,sha256=SOi7VgiAupZTfh4GG8XDB5N2AMeEP727o_eVlTdlhiQ,13918
17
+ ebk/ai/llm_providers/__init__.py,sha256=dqXtt2zh2iAHfpBLRQWpyDIOrJ8IggcxwvD0isHplcI,438
18
+ ebk/ai/llm_providers/base.py,sha256=am-TO4LTYLNeyMop9qy4TQdS7LJ2VTNvqy4iri1YvNk,5694
19
+ ebk/ai/llm_providers/ollama.py,sha256=MwXhJSsAc7cYfKyrmiXvk25QzIpvfNOZcugs9TNZta8,10132
20
+ ebk/db/__init__.py,sha256=CN1R77Ut5ai8kGSh1ohprGaS5qvOUMdtMT-y--5DIpw,792
21
+ ebk/db/migrations.py,sha256=H0nAl8I-hUKctV7sPj14iockSL9IL0qHihy3krxZPsc,5513
22
+ ebk/db/models.py,sha256=PGcq9knATE06_MStiCpg7zNvO2nDhU592xDt0vhNCxg,19967
23
+ ebk/db/session.py,sha256=3Oc7Xo1gb7B430JtKRtF4JFyFi8hdIKz1GQq-Bjjz_o,3549
24
+ ebk/exports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ ebk/exports/base_exporter.py,sha256=OQFmuyP9vxB5SVErTacOGonjD2Kyc1j1_1G9VcpdlDY,6783
26
+ ebk/exports/html_library.py,sha256=L8b__nU_c_4nZYym-W_M90Eb-GRVZfb3OqLm0nE-0Lk,54107
27
+ ebk/exports/html_utils.py,sha256=ft4PLHBKjx6OFD3bxCEI9tpaEUEqWzhLNqwKc196ulo,3899
28
+ ebk/exports/hugo.py,sha256=0rKNCegtm_Xd2g7IU77DmzlNiHZkoHTd2Wyr_y2gLRk,2209
29
+ ebk/exports/jinja_export.py,sha256=wWy_eQIp16yuZ0i-Ssj8PaGHSNiSdjOwjt5OpKuv-q0,10996
30
+ ebk/exports/multi_facet_export.py,sha256=xgy5Vjkow49ESVUXcjmLcTbMa-nSyaAlYW8HH-SeB4U,6364
31
+ ebk/exports/symlink_dag.py,sha256=ChTSp9qA5Ibui4eIFfbWNDeYBfYh--RtOI4RvP54-Vs,20499
32
+ ebk/exports/zip.py,sha256=erteF1NcymUbka5m_pnXWaRZmkUihALXe4A_cYg8hXs,779
33
+ ebk/plugins/__init__.py,sha256=-YhhLSqVI6lZSCoW-8fJfib7qL12AO3h4IGOFGcs_qU,765
34
+ ebk/plugins/base.py,sha256=x523_EFtHiFgBBTJqzgArIF8D8KtmD20jJUTqew29eM,14121
35
+ ebk/plugins/hooks.py,sha256=ym7fkmqqirc17Q5GYtOO6ahfyYMJHUX1QwRUkwaZs20,14442
36
+ ebk/plugins/registry.py,sha256=xCmKMc1ioSpXM8nBPcep5RxUy-BZQMKYCInDp2NqzWY,15497
37
+ ebk/repl/__init__.py,sha256=zSAp76GfAEtxYsXe8W2m-PtDFeHX668y6jnpzz2yeWA,252
38
+ ebk/repl/find.py,sha256=Yl-4qv_uKl8dJefHzCyNpjJxngtB_fxj4MqXbMGEkKc,3799
39
+ ebk/repl/grep.py,sha256=VIFdcMrFqSHBB2rmLllf9PDW4UjBelf60znUPfBh-AA,4802
40
+ ebk/repl/shell.py,sha256=emzjK1aXiGnYdEAwUybntnaXS62tQhtQZkDeQ3sDIGg,60896
41
+ ebk/repl/text_utils.py,sha256=nSCE-qPL3xHyXjt_5ltjYnOCBXpyPqJiyaKztrfAKuQ,8382
42
+ ebk/services/__init__.py,sha256=j6Gqdqp7MRRWIuSjJH_3TxL7JA5nID4kcNGbWXKXcDs,199
43
+ ebk/services/import_service.py,sha256=WThx2sEuooFQwgFmjyuOZPlIo8FQ-08g-CzVr5r6QaQ,16478
44
+ ebk/services/tag_service.py,sha256=KhuYqSUalOmQc1ikfrfEZ1__wf9f-VVEoWPpFSSGMi0,7982
45
+ ebk/services/text_extraction.py,sha256=jUPBolw45w5cKuL0m92K1i2Qo0FrqCwoX8p7GuBxvzU,10525
46
+ ebk/similarity/__init__.py,sha256=ySprbU_qfMuOEFyUqnBHe-4HSyvGyZHjRUZ4y6Z20-A,1942
47
+ ebk/similarity/base.py,sha256=uWY1whl1jdjvntnuOaB9Mal3f3yiLt7HqjHSBZyM324,4473
48
+ ebk/similarity/core.py,sha256=ohXY61L3xUOjcbtIkfqLwRKiiEST_oTRt8TFLdXIReQ,13340
49
+ ebk/similarity/extractors.py,sha256=UqxnIWM2sBdY_d6mse_NYTuOxdT2f7rtPDfe9b8QR0k,4220
50
+ ebk/similarity/metrics.py,sha256=2rbX10xXauebBSH7fKN9fCSMgSOuxRHKwUyJhd_hFfU,10419
51
+ ebk/vfs/__init__.py,sha256=5d2jCVRNboJlD576IrFWKIUeOVVVv3zVdyMbSMZ0zEY,3129
52
+ ebk/vfs/base.py,sha256=NkOBkefa6I4O1_GY0SmBFHMHhQbt7edyNAR8ncZeVWM,8231
53
+ ebk/vfs/library_vfs.py,sha256=Lkrn1Wkx2f5qnegnmLGUKiHUfOOUoqnQOADq80xaJNg,3353
54
+ ebk/vfs/resolver.py,sha256=D_pvOzmeErl8oMxw73g4X4nKBzxc_OgoAmHDDP_fJA4,6228
55
+ ebk/vfs/nodes/__init__.py,sha256=W6MCMNUh8129Uw2xtNoWi00rrMHNreTXb26KS7IrXrA,1360
56
+ ebk/vfs/nodes/authors.py,sha256=Dqr8Leb2NM3W_qKwvEz8r3-C3uNFQVjNGxf56-qhm9c,5731
57
+ ebk/vfs/nodes/books.py,sha256=5YzFXFKrK1aUCzD7uAYPmuGCTVh_j4vj9VNfVFywo9o,15461
58
+ ebk/vfs/nodes/files.py,sha256=49kCsPFe5zBstcUcC44E-KEUHkoHTKT6AzQOXhirnDA,4673
59
+ ebk/vfs/nodes/metadata.py,sha256=wo2TDV2JshuWAzdjGEVOWM5-9S3XwqoRoqRIgSX3o1g,11392
60
+ ebk/vfs/nodes/root.py,sha256=4WkU3GnNcnnqg6dpkjUXI0pnWX4oAR6UJDNpEqIexLs,3030
61
+ ebk/vfs/nodes/similar.py,sha256=LJeFZigiu7dDyduGi9SJrxNJNP_qix661o8pyGsARFs,4866
62
+ ebk/vfs/nodes/subjects.py,sha256=7U9Raj0b2PXb6LfOo3zlHAqTD0lW3IQk7m5u0nU8WPU,5327
63
+ ebk/vfs/nodes/tags.py,sha256=uFJ5lWQYXD0dDmRP6v9NpfQDieTZJfGtSgaz2zzHVZo,11119
64
+ ebk-0.3.2.dist-info/licenses/LICENSE,sha256=1eh_aOAZz71hpva42M9f8Vqj_FtSUqzE-1EimifmM_8,1068
65
+ ebk-0.3.2.dist-info/METADATA,sha256=P7E6L37hRP087ibZqpd4EV4szzlIHLh_cgAGxkYHOk4,21712
66
+ ebk-0.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
67
+ ebk-0.3.2.dist-info/entry_points.txt,sha256=M24WNtCeBq-nmIDPU-3i0DtM9VP3bM_ul2nQIC1r_RA,36
68
+ ebk-0.3.2.dist-info/top_level.txt,sha256=OLATFvDsJQh-6TqJCili349OH47DoH-6dMih88BWcyg,4
69
+ ebk-0.3.2.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ebk = ebk.cli:app
@@ -0,0 +1 @@
1
+ ebk
@@ -1,19 +0,0 @@
1
- ebk/__init__.py,sha256=KK5aFY07PvPB8LjfNJ_xAuWft6uyIMsiK6vrvhyyg14,790
2
- ebk/cli.py,sha256=KkqLqenlNdTE3gJqVvlxTt1_yNfW1wqXc4N7222MkYo,73606
3
- ebk/config.py,sha256=P090sNH2YSnNNteXjim2_WYN9j2BC_GU5o0wQIwSbT4,7364
4
- ebk/decorators.py,sha256=MpAD1Wwy3o4l0sEiq4EIy5YtKMKf_nXtu7jpV64Uvyc,5179
5
- ebk/extract_metadata.py,sha256=epMn9_4zQYiytBwj25_-rYl0QmPN4cP25DuxMnijNMU,12228
6
- ebk/ident.py,sha256=yRIKVA0rpyhdPCxl0Vx7iu3YOebE8Yvbv32iCJmKk-Y,3324
7
- ebk/library_db.py,sha256=6CE00cLY2Ris-qxdS_sakJh4sI0rDA1kdQnk8hgL8Hg,24676
8
- ebk/search_parser.py,sha256=NRVbGnaOWxbc1WtsoFVINjHqCMBEubrKBxY2b_HQqJY,14848
9
- ebk/server.py,sha256=x5vpQmZjGAwJVgmUq8l8Z1owfoqg2weuUVBovEWVE-s,59036
10
- ebk/plugins/__init__.py,sha256=-YhhLSqVI6lZSCoW-8fJfib7qL12AO3h4IGOFGcs_qU,765
11
- ebk/plugins/base.py,sha256=x523_EFtHiFgBBTJqzgArIF8D8KtmD20jJUTqew29eM,14121
12
- ebk/plugins/hooks.py,sha256=ym7fkmqqirc17Q5GYtOO6ahfyYMJHUX1QwRUkwaZs20,14442
13
- ebk/plugins/registry.py,sha256=xCmKMc1ioSpXM8nBPcep5RxUy-BZQMKYCInDp2NqzWY,15497
14
- ebk-0.3.1.dist-info/licenses/LICENSE,sha256=1eh_aOAZz71hpva42M9f8Vqj_FtSUqzE-1EimifmM_8,1068
15
- ebk-0.3.1.dist-info/METADATA,sha256=Rr795fgxinK8mNJ8zLVKXGWNZ_D65xxE1CY5Gl0D58s,21712
16
- ebk-0.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
- ebk-0.3.1.dist-info/entry_points.txt,sha256=fFLItKyyaEk7Cmf5MRee7Nxubi3kahS2_CWS6GYNQh0,165
18
- ebk-0.3.1.dist-info/top_level.txt,sha256=9JCtHO8j1qyHWFBXG2BVMr16gg3rimwkVdt0PRVNIB4,17
19
- ebk-0.3.1.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- [console_scripts]
2
- ebk = ebk.cli:app
3
-
4
- [ebk.plugins]
5
- google_books = integrations.metadata:GoogleBooksExtractor
6
- network_analyzer = integrations.network:NetworkAnalyzer
@@ -1,2 +0,0 @@
1
- ebk
2
- integrations
File without changes