146 lines
3.8 KiB
Python
Executable File
146 lines
3.8 KiB
Python
Executable File
#!/Applications/calibre.app/Contents/MacOS/calibre-debug calibre_to_torrent.py
|
|
# See: https://manual.calibre-ebook.com/db_api.html
|
|
import os
|
|
import json
|
|
import copy
|
|
import shutil
|
|
import pathlib
|
|
import hashlib
|
|
import urllib
|
|
import calibre.library
|
|
|
|
import config
|
|
|
|
class CalibreLibrary: pass
|
|
|
|
class CalibreLibraryBook:
|
|
_db: CalibreLibrary
|
|
|
|
id: int
|
|
title: str
|
|
authors: str
|
|
filepath: str
|
|
filehash: str
|
|
filename: str
|
|
cover: str
|
|
|
|
def __init__(self, db: CalibreLibrary):
|
|
self._db = db
|
|
self.cover = None
|
|
self.filehash = None
|
|
|
|
""" Get book properties for JSON serialize """
|
|
def to_json(self):
|
|
data = {}
|
|
for key in list(self.__dict__.keys()):
|
|
if key.startswith("_"):
|
|
continue
|
|
data[key] = self.__dict__[key]
|
|
|
|
return data
|
|
|
|
""" Generate the ebook filename based on the ebook file hash """
|
|
def ebook_filename(self) -> str:
|
|
title = self.title
|
|
ext = pathlib.Path(self.filepath).suffix
|
|
self.filename = f"{title}{ext}"
|
|
self.filename = self.filename.replace(",", ".")
|
|
self.filename = self.filename.replace(";", "")
|
|
self.filename = self.filename.replace(":", ".")
|
|
self.filename = self.filename.replace("/", "-")
|
|
self.filename = self.filename.replace("'", "")
|
|
self.filename = self.filename.replace(" ", ".")
|
|
self.filename = self.filename.replace("..", ".")
|
|
return self.filename
|
|
|
|
""" Save the ebook from the calibre library to the path """
|
|
def ebook_save(self, path: str) -> str:
|
|
filepath = os.path.join(path, self.ebook_filename())
|
|
|
|
if os.path.exists(filepath):
|
|
return
|
|
|
|
print(f"COPY {self.filepath} -> {filepath}")
|
|
shutil.copyfile(self.filepath, filepath)
|
|
return filepath
|
|
|
|
|
|
class CalibreLibrary:
|
|
def __init__(self, library_path: str):
|
|
# First open the Calibre library and get a list of the book IDs
|
|
self._db = calibre.library.db(library_path).new_api
|
|
|
|
@staticmethod
|
|
def _get_filesize_str(path: str) -> str:
|
|
size = os.path.getsize(path)
|
|
if size < 1024:
|
|
return f"{size} bytes"
|
|
elif size < pow(1024,2):
|
|
return f"{round(size/1024, 2)} KB"
|
|
elif size < pow(1024,3):
|
|
return f"{round(size/(pow(1024,2)), 2)} MB"
|
|
elif size < pow(1024,4):
|
|
return f"{round(size/(pow(1024,3)), 2)} GB"
|
|
|
|
def books(self) -> 'list[CalibreLibraryBook]':
|
|
books = []
|
|
book_ids = self._db.all_book_ids()
|
|
|
|
for book_id in book_ids:
|
|
# TODO check loaded state with state of calibre based on book.id
|
|
# hashing takes way to long...
|
|
book = CalibreLibraryBook(self._db)
|
|
book.id = book_id
|
|
book.title = self._db.field_for("title", book.id)
|
|
book.authors = self._db.field_for("authors", book.id)
|
|
book.comments = self._db.field_for("comments", book.id)
|
|
book._metadata = self._db.get_metadata(book.id)
|
|
book.ids = book._metadata.get_identifiers()
|
|
|
|
# Select only first ebook format
|
|
formats = self._db.formats(book.id, verify_formats=True)
|
|
if len(formats) > 0:
|
|
book.filepath = self._db.format_abspath(book.id, formats[0])
|
|
book.filesize = self._get_filesize_str(book.filepath)
|
|
else:
|
|
book.filepath = None
|
|
book.filesize = 0
|
|
|
|
books.append(book)
|
|
|
|
return books
|
|
|
|
class PyroTechnyEbookLibraryTorrent:
|
|
_calibre_library : CalibreLibrary
|
|
_path: str
|
|
_tempdir: str
|
|
_google_drive_file_db: list
|
|
|
|
def __init__(self, path: str, calibre_library: CalibreLibrary):
|
|
self._books = []
|
|
self._calibre_library = calibre_library
|
|
self._path = path
|
|
self._state = {}
|
|
self._state["books"] = []
|
|
|
|
# Create cache pat
|
|
if not os.path.exists(self._path):
|
|
print(f"CREATE {self._path}")
|
|
os.makedirs(self._path, 0o755)
|
|
|
|
def synchronize(self):
|
|
# Load books from calibre
|
|
books = self._calibre_library.books()
|
|
for book in books:
|
|
#print(f"{book.to_json()}")
|
|
book.ebook_save(self._path)
|
|
|
|
def main():
|
|
calibre_library = CalibreLibrary(config.CALIBRE_LIBRARY_PATH)
|
|
pyrotechny_library = PyroTechnyEbookLibraryTorrent(config.EBOOK_LIBRARY_TORRENT_CACHE_DIR, calibre_library)
|
|
pyrotechny_library.synchronize()
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|