name change and local sync added
This commit is contained in:
@@ -14,6 +14,8 @@ log = logging.getLogger(__name__)
|
||||
_lock = threading.Lock()
|
||||
_running = False
|
||||
|
||||
_BOOK_EXTENSIONS = {".epub", ".pdf", ".mobi", ".cbz"}
|
||||
|
||||
|
||||
def is_running() -> bool:
|
||||
return _running
|
||||
@@ -130,6 +132,69 @@ def run_sync(limit: int | None = None) -> None:
|
||||
_lock.release()
|
||||
|
||||
|
||||
def run_local_import(folder_path: str) -> None:
|
||||
"""Process a local folder of book files using the same duplicate-check + bookdrop flow."""
|
||||
global _running
|
||||
if not _lock.acquire(blocking=False):
|
||||
log.warning("Sync already running, skipping local import")
|
||||
return
|
||||
|
||||
_running = True
|
||||
run_id = db.start_sync_run()
|
||||
counters = dict(zips_found=0, zips_new=0, books_imported=0, books_skipped=0, books_errored=0)
|
||||
|
||||
try:
|
||||
cfg = config.load()
|
||||
if not cfg.grimmory.bookdrop_path:
|
||||
raise ValueError("Grimmory bookdrop path not configured")
|
||||
|
||||
folder = Path(folder_path)
|
||||
if not folder.is_dir():
|
||||
raise ValueError(f"Not a directory: {folder_path}")
|
||||
|
||||
books = [p for p in folder.rglob("*") if p.is_file() and p.suffix.lower() in _BOOK_EXTENSIONS]
|
||||
log.info("Local import: found %d book file(s) in %s", len(books), folder_path)
|
||||
counters["zips_found"] = len(books)
|
||||
counters["zips_new"] = len(books)
|
||||
|
||||
for book in books:
|
||||
try:
|
||||
sha256 = grimmory_module.compute_sha256(book)
|
||||
if db.is_book_processed(sha256):
|
||||
log.info("Skipping '%s' — sha256 already processed", book.name)
|
||||
counters["books_skipped"] += 1
|
||||
db.record_book(None, book.name, sha256, status="skipped")
|
||||
continue
|
||||
result = grimmory_module.place_book(
|
||||
book,
|
||||
cfg.grimmory.bookdrop_path,
|
||||
cfg.grimmory.url,
|
||||
cfg.grimmory.user,
|
||||
cfg.grimmory.password,
|
||||
sha256=sha256,
|
||||
)
|
||||
if result.status == "success":
|
||||
counters["books_imported"] += 1
|
||||
elif result.status == "skipped":
|
||||
counters["books_skipped"] += 1
|
||||
db.record_book(None, book.name, result.sha256,
|
||||
status=result.status, error_msg=result.error_msg)
|
||||
except Exception as e:
|
||||
log.error("Error importing '%s': %s", book.name, e)
|
||||
counters["books_errored"] += 1
|
||||
db.record_book(None, book.name, "", status="error", error_msg=str(e))
|
||||
|
||||
db.finish_sync_run(run_id, status="success", **counters)
|
||||
log.info("Local import done. Imported: %d, Skipped: %d, Errors: %d",
|
||||
counters["books_imported"], counters["books_skipped"], counters["books_errored"])
|
||||
except Exception as e:
|
||||
log.exception("Local import failed: %s", e)
|
||||
db.finish_sync_run(run_id, status="error", error_msg=str(e), **counters)
|
||||
finally:
|
||||
_running = False
|
||||
_lock.release()
|
||||
|
||||
|
||||
def _validate_config(cfg) -> None:
|
||||
missing = []
|
||||
if not cfg.sftp.host:
|
||||
|
||||
Reference in New Issue
Block a user