Fixed a bug that would cause no playback on newloy loaded books. Added .mobi support.
This commit is contained in:
101
src/mobi_parser.py
Normal file
101
src/mobi_parser.py
Normal file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
MOBI Parser
|
||||
|
||||
Parses MOBI/Mobipocket format ebooks and extracts text content.
|
||||
Uses Calibre's ebook-convert to convert MOBI to EPUB, then parses the EPUB.
|
||||
"""
|
||||
|
||||
import tempfile
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from src.book import Book, Chapter
|
||||
from src.epub_parser import EpubParser
|
||||
|
||||
|
||||
class MobiParser:
|
||||
"""Parser for MOBI/Mobipocket format ebooks"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize MOBI parser"""
|
||||
self.tempDir = None
|
||||
self.epubParser = None
|
||||
|
||||
def parse(self, mobiPath):
|
||||
"""
|
||||
Parse MOBI file
|
||||
|
||||
Args:
|
||||
mobiPath: Path to MOBI file
|
||||
|
||||
Returns:
|
||||
Book object
|
||||
|
||||
Raises:
|
||||
Exception: If parsing fails
|
||||
"""
|
||||
mobiPath = Path(mobiPath)
|
||||
|
||||
# Create temp directory for conversion
|
||||
self.tempDir = tempfile.mkdtemp(prefix='bookstorm_mobi_')
|
||||
tempPath = Path(self.tempDir)
|
||||
|
||||
try:
|
||||
# Convert MOBI to EPUB using Calibre's ebook-convert
|
||||
epubPath = tempPath / f"{mobiPath.stem}.epub"
|
||||
|
||||
# Check if ebook-convert is available
|
||||
convertCmd = ['ebook-convert', str(mobiPath), str(epubPath)]
|
||||
|
||||
try:
|
||||
# Run ebook-convert with error capture
|
||||
result = subprocess.run(
|
||||
convertCmd,
|
||||
capture_output=True, # pylint: disable=subprocess-run-check
|
||||
text=True,
|
||||
timeout=60
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
raise Exception(f"ebook-convert failed: {result.stderr}")
|
||||
|
||||
except FileNotFoundError:
|
||||
raise Exception(
|
||||
"Calibre's ebook-convert tool is required for MOBI support. "
|
||||
"Install Calibre: sudo pacman -S calibre (Arch) or "
|
||||
"sudo apt install calibre (Debian/Ubuntu)"
|
||||
)
|
||||
except subprocess.TimeoutExpired:
|
||||
raise Exception("MOBI conversion timed out (>60 seconds)")
|
||||
|
||||
# Verify the EPUB was created
|
||||
if not epubPath.exists():
|
||||
raise Exception("Failed to convert MOBI to EPUB")
|
||||
|
||||
# Parse the converted EPUB
|
||||
self.epubParser = EpubParser()
|
||||
book = self.epubParser.parse(epubPath)
|
||||
|
||||
# Set the original MOBI path as the book path
|
||||
book.path = mobiPath
|
||||
|
||||
return book
|
||||
|
||||
except Exception as e:
|
||||
raise Exception(f"Error parsing MOBI: {e}")
|
||||
|
||||
def cleanup(self):
|
||||
"""Clean up temporary files"""
|
||||
# Clean up EPUB parser
|
||||
if self.epubParser:
|
||||
self.epubParser.cleanup()
|
||||
|
||||
# Clean up our temp directory
|
||||
if self.tempDir and Path(self.tempDir).exists():
|
||||
try:
|
||||
shutil.rmtree(self.tempDir)
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not remove temp directory: {e}")
|
||||
@@ -382,14 +382,18 @@ class MpvPlayer:
|
||||
return False
|
||||
|
||||
try:
|
||||
# Seek to start position (including 0)
|
||||
# Always seek to ensure we're at the right position, even for position 0
|
||||
if startPosition >= 0:
|
||||
self.player.seek(startPosition, reference='absolute')
|
||||
|
||||
# Start playback
|
||||
# Start playback first (this ensures mpv begins loading/decoding)
|
||||
self.player.pause = False
|
||||
self.isPaused = False
|
||||
|
||||
# Only seek if we have a non-zero start position
|
||||
# Seeking to position 0 immediately after load can fail if file isn't ready
|
||||
if startPosition > 0:
|
||||
# Wait a moment for file to be ready before seeking
|
||||
import time
|
||||
time.sleep(0.1)
|
||||
self.player.seek(startPosition, reference='absolute')
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user