mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
pdb/eReader metadata writer
This commit is contained in:
parent
c52966ffa4
commit
d16b8274c6
@ -297,6 +297,17 @@ class PDFMetadataWriter(MetadataWriterPlugin):
|
|||||||
from calibre.ebooks.metadata.pdf import set_metadata
|
from calibre.ebooks.metadata.pdf import set_metadata
|
||||||
set_metadata(stream, mi)
|
set_metadata(stream, mi)
|
||||||
|
|
||||||
|
class PDBMetadataWriter(MetadataWriterPlugin):
|
||||||
|
|
||||||
|
name = 'Set PDB metadata'
|
||||||
|
file_types = set(['pdb'])
|
||||||
|
description = _('Set metadata from %s files') % 'PDB'
|
||||||
|
author = 'John Schember'
|
||||||
|
|
||||||
|
def set_metadata(self, stream, mi, type):
|
||||||
|
from calibre.ebooks.metadata.pdb import set_metadata
|
||||||
|
set_metadata(stream, mi)
|
||||||
|
|
||||||
|
|
||||||
from calibre.ebooks.epub.input import EPUBInput
|
from calibre.ebooks.epub.input import EPUBInput
|
||||||
from calibre.ebooks.mobi.input import MOBIInput
|
from calibre.ebooks.mobi.input import MOBIInput
|
||||||
|
@ -10,8 +10,8 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation, authors_to_string
|
||||||
from calibre.ebooks.pdb.header import PdbHeaderReader
|
from calibre.ebooks.pdb.header import PdbHeaderReader, PdbHeaderBuilder
|
||||||
from calibre.ebooks.pdb.ereader.reader import HeaderRecord
|
from calibre.ebooks.pdb.ereader.reader import HeaderRecord
|
||||||
|
|
||||||
def get_metadata(stream, extract_cover=True):
|
def get_metadata(stream, extract_cover=True):
|
||||||
@ -24,8 +24,8 @@ def get_metadata(stream, extract_cover=True):
|
|||||||
pheader = PdbHeaderReader(stream)
|
pheader = PdbHeaderReader(stream)
|
||||||
hr = HeaderRecord(pheader.section_data(0))
|
hr = HeaderRecord(pheader.section_data(0))
|
||||||
|
|
||||||
if hr.version in (2, 10):
|
if hr.version in (2, 10) and hr.has_metadata == 1:
|
||||||
try:
|
try:
|
||||||
mdata = pheader.section_data(hr.metadata_offset)
|
mdata = pheader.section_data(hr.metadata_offset)
|
||||||
|
|
||||||
mdata = mdata.split('\x00')
|
mdata = mdata.split('\x00')
|
||||||
@ -41,3 +41,42 @@ def get_metadata(stream, extract_cover=True):
|
|||||||
|
|
||||||
return mi
|
return mi
|
||||||
|
|
||||||
|
def set_metadata(stream, mi):
|
||||||
|
pheader = PdbHeaderReader(stream)
|
||||||
|
sections = [pheader.section_data(x) for x in range(0, pheader.section_count())]
|
||||||
|
hr = HeaderRecord(sections[0])
|
||||||
|
|
||||||
|
if hr.version not in (2, 10):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Create a metadata record for the file if one does not alreay exist
|
||||||
|
if not hr.has_metadata:
|
||||||
|
sections += ['', 'MeTaInFo\x00']
|
||||||
|
last_data = len(sections) - 1
|
||||||
|
|
||||||
|
for i in range(0, 132, 2):
|
||||||
|
val, = struct.unpack('>H', sections[0][i:i+2])
|
||||||
|
if val >= hr.last_data_offset:
|
||||||
|
sections[0][i:i+2] = struct.pack('>H', last_data)
|
||||||
|
|
||||||
|
sections[0][24:26] = struct.pack('>H', 1) # Set has metadata
|
||||||
|
sections[0][44:46] = struct.pack('>H', last_data - 1) # Set location of metadata
|
||||||
|
sections[0][52:54] = struct.pack('>H', last_data) # Ensure last data offset is updated
|
||||||
|
|
||||||
|
# Merge the metadata into the file
|
||||||
|
file_mi = get_metadata(stream, False)
|
||||||
|
file_mi.smart_update(mi)
|
||||||
|
sections[hr.metadata_offset] = '%s\x00%s\x00%s\x00%s\x00%s\x00' % \
|
||||||
|
(file_mi.title, authors_to_string(file_mi.authors), '', file_mi.publisher, file_mi.isbn)
|
||||||
|
|
||||||
|
# Rebuild the PDB wrapper because the offsets have changed due to the
|
||||||
|
# new metadata.
|
||||||
|
pheader_builder = PdbHeaderBuilder(pheader.ident, pheader.title)
|
||||||
|
stream.seek(0)
|
||||||
|
stream.truncate(0)
|
||||||
|
pheader_builder.build_header([len(x) for x in sections], stream)
|
||||||
|
|
||||||
|
# Write the data back to the file
|
||||||
|
for item in sections:
|
||||||
|
stream.write(item)
|
||||||
|
|
||||||
|
@ -12,11 +12,18 @@ import re
|
|||||||
|
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation
|
||||||
from calibre.ebooks.pdb.header import PdbHeaderReader
|
from calibre.ebooks.pdb.header import PdbHeaderReader
|
||||||
from calibre.ebooks.metadata.ereader import get_metadata as eReader
|
from calibre.ebooks.metadata.ereader import get_metadata as get_eReader
|
||||||
|
|
||||||
MREADER = {
|
MREADER = {
|
||||||
'PNPdPPrs' : eReader,
|
'PNPdPPrs' : get_eReader,
|
||||||
'PNRdPPrs' : eReader,
|
'PNRdPPrs' : get_eReader,
|
||||||
|
}
|
||||||
|
|
||||||
|
from calibre.ebooks.metadata.ereader import set_metadata as set_eReader
|
||||||
|
|
||||||
|
MWRITER = {
|
||||||
|
'PNPdPPrs' : set_eReader,
|
||||||
|
'PNRdPPrs' : set_eReader,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_metadata(stream, extract_cover=True):
|
def get_metadata(stream, extract_cover=True):
|
||||||
@ -34,3 +41,16 @@ def get_metadata(stream, extract_cover=True):
|
|||||||
|
|
||||||
return MetadataReader(stream, extract_cover)
|
return MetadataReader(stream, extract_cover)
|
||||||
|
|
||||||
|
def set_metadata(stream, mi):
|
||||||
|
stream.seek(0)
|
||||||
|
|
||||||
|
pheader = PdbHeaderReader(stream)
|
||||||
|
|
||||||
|
MetadataWriter = MWRITER.get(pheader.ident, None)
|
||||||
|
|
||||||
|
if MetadataWriter:
|
||||||
|
MetadataWriter(stream, mi)
|
||||||
|
|
||||||
|
stream.seek(0)
|
||||||
|
stream.write(re.sub('[^-A-Za-z0-9]+', '_', mi.title).ljust(32, '\x00')[:32])
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ import os, re, struct, zlib
|
|||||||
|
|
||||||
from calibre import CurrentDir
|
from calibre import CurrentDir
|
||||||
from calibre.ebooks import DRMError
|
from calibre.ebooks import DRMError
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
|
||||||
from calibre.ebooks.pdb.formatreader import FormatReader
|
from calibre.ebooks.pdb.formatreader import FormatReader
|
||||||
from calibre.ebooks.pdb.ereader import EreaderError
|
from calibre.ebooks.pdb.ereader import EreaderError
|
||||||
from calibre.ebooks.pml.pmlconverter import pml_to_html, \
|
from calibre.ebooks.pml.pmlconverter import pml_to_html, \
|
||||||
@ -31,6 +30,7 @@ class HeaderRecord(object):
|
|||||||
def __init__(self, raw):
|
def __init__(self, raw):
|
||||||
self.version, = struct.unpack('>H', raw[0:2])
|
self.version, = struct.unpack('>H', raw[0:2])
|
||||||
self.non_text_offset, = struct.unpack('>H', raw[12:14])
|
self.non_text_offset, = struct.unpack('>H', raw[12:14])
|
||||||
|
self.has_metadata, = struct.unpack('>H', raw[24:26])
|
||||||
self.footnote_rec, = struct.unpack('>H', raw[28:30])
|
self.footnote_rec, = struct.unpack('>H', raw[28:30])
|
||||||
self.sidebar_rec, = struct.unpack('>H', raw[30:32])
|
self.sidebar_rec, = struct.unpack('>H', raw[30:32])
|
||||||
self.bookmark_offset, = struct.unpack('>H', raw[32:34])
|
self.bookmark_offset, = struct.unpack('>H', raw[32:34])
|
||||||
@ -62,6 +62,9 @@ class Reader(FormatReader):
|
|||||||
else:
|
else:
|
||||||
raise EreaderError('Unknown book version %i.' % self.header_record.version)
|
raise EreaderError('Unknown book version %i.' % self.header_record.version)
|
||||||
|
|
||||||
|
from calibre.ebooks.metadata.pdb import get_metadata
|
||||||
|
self.mi = get_metadata(stream, False)
|
||||||
|
|
||||||
def section_data(self, number):
|
def section_data(self, number):
|
||||||
return self.sections[number]
|
return self.sections[number]
|
||||||
|
|
||||||
@ -144,10 +147,8 @@ class Reader(FormatReader):
|
|||||||
return opf_path
|
return opf_path
|
||||||
|
|
||||||
def create_opf(self, output_dir, images):
|
def create_opf(self, output_dir, images):
|
||||||
mi = MetaInformation(None, None)
|
|
||||||
|
|
||||||
with CurrentDir(output_dir):
|
with CurrentDir(output_dir):
|
||||||
opf = OPFCreator(output_dir, mi)
|
opf = OPFCreator(output_dir, self.mi)
|
||||||
|
|
||||||
manifest = [('index.html', None)]
|
manifest = [('index.html', None)]
|
||||||
|
|
||||||
|
@ -18,11 +18,7 @@ from calibre.ebooks.pdb.header import PdbHeaderBuilder
|
|||||||
from calibre.ebooks.pdb.ereader import image_name
|
from calibre.ebooks.pdb.ereader import image_name
|
||||||
from calibre.ebooks.pml.pmlconverter import html_to_pml
|
from calibre.ebooks.pml.pmlconverter import html_to_pml
|
||||||
|
|
||||||
# We are using the older identity because we do not user newer features
|
IDENTITY = 'PNRdPPrs'
|
||||||
# (sidebar, footnotes). This will ensure compatibility with older readers.
|
|
||||||
# If newer features are used (anything supported by dropbook but not by makebook
|
|
||||||
# change the identity to the newer PNRdPPrs.
|
|
||||||
IDENTITY = 'PNPdPPrs'
|
|
||||||
|
|
||||||
# This is an arbitrary number that is small enough to work. The actual maximum
|
# This is an arbitrary number that is small enough to work. The actual maximum
|
||||||
# record size is unknown.
|
# record size is unknown.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user