PalmDoc pdb output.

This commit is contained in:
John Schember 2009-05-03 15:05:55 -04:00
parent e447b69bd2
commit d7e20bb1e5
8 changed files with 160 additions and 19 deletions

View file

@ -302,6 +302,7 @@ def set_metadata(self, stream, mi, type):
from calibre.ebooks.oeb.output import OEBOutput
from calibre.ebooks.epub.output import EPUBOutput
from calibre.ebooks.mobi.output import MOBIOutput
from calibre.ebooks.pdb.output import PDBOutput
from calibre.ebooks.lrf.output import LRFOutput
from calibre.ebooks.lit.output import LITOutput
from calibre.ebooks.txt.output import TXTOutput
@ -323,7 +324,7 @@ def set_metadata(self, stream, mi, type):
plugins = [HTML2ZIP, EPUBInput, MOBIInput, PDBInput, PDFInput, HTMLInput,
TXTInput, OEBOutput, TXTOutput, PDFOutput, LITInput, ComicInput,
FB2Input, ODTInput, RTFInput, EPUBOutput, RecipeInput, PMLInput,
PMLOutput, MOBIOutput, LRFOutput, LITOutput]
PMLOutput, MOBIOutput, PDBOutput, LRFOutput, LITOutput]
plugins += [PRS500, PRS505, PRS700, CYBOOKG3, KINDLE, KINDLE2, BLACKBERRY,
EB600, JETBOOK]
plugins += [x for x in list(locals().values()) if isinstance(x, type) and \

View file

@ -5,15 +5,25 @@
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'
from calibre.ebooks.pdb.ereader.reader import Reader as eReader
from calibre.ebooks.pdb.ztxt.reader import Reader as zTXT
from calibre.ebooks.pdb.palmdoc.reader import Reader as PalmDoc
class PDBError(Exception):
pass
FORMATS = {
'PNPdPPrs' : eReader,
'PNRdPPrs' : eReader,
'zTXTGPlm' : zTXT,
'TEXtREAd' : PalmDoc,
from calibre.ebooks.pdb.ereader.reader import Reader as ereader_reader
from calibre.ebooks.pdb.ztxt.reader import Reader as ztxt_reader
from calibre.ebooks.pdb.palmdoc.reader import Reader as palmdoc_reader
FORMAT_READERS = {
'PNPdPPrs' : ereader_reader,
'PNRdPPrs' : ereader_reader,
'zTXTGPlm' : ztxt_reader,
'TEXtREAd' : palmdoc_reader,
}
from calibre.ebooks.pdb.palmdoc.writer import Writer as palmdoc_writer
FORMAT_WRITERS = {
'doc' : palmdoc_writer,
}
IDENTITY_TO_NAME = {
@ -48,15 +58,15 @@
'BDOCWrdS' : 'WordSmith',
}
class PDBError(Exception):
pass
def get_reader(identity):
'''
Returns None if no reader is found for the identity.
'''
if identity in FORMATS.keys():
return FORMATS[identity]
else:
return None
return FORMAT_READERS.get(identity, None)
def get_writer(extension):
'''
Returns None if no writer is found for extension.
'''
return FORMAT_WRITERS.get(extension, None)

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
'''
Interface defining the necessary public functions for a pdb format reader.
'''

View file

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
'''
Interface defining the necessary public functions for a pdb format writer.
'''
__license__ = 'GPL v3'
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'
class FormatWriter(object):
def __init__(self, opts, log):
raise NotImplementedError()
def write_content(self, oeb_book, output_stream, ):
raise NotImplementedError()

View file

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
__license__ = 'GPL v3'
__copyright__ = '2009, John Schember <john@nachtimwald.com>'

View file

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
__license__ = 'GPL 3'
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'
import os
from calibre.customize.conversion import OutputFormatPlugin
from calibre.ebooks.pdb import PDBError, get_writer
class PDBOutput(OutputFormatPlugin):
name = 'PDB Output'
author = 'John Schember'
file_type = 'pdb'
def convert(self, oeb_book, output_path, input_plugin, opts, log):
close = False
if not hasattr(output_path, 'write'):
# Determine the format to write based upon the sub extension
format = os.path.splitext(os.path.splitext(output_path)[0])[1][1:]
close = True
if not os.path.exists(os.path.dirname(output_path)) and os.path.dirname(output_path) != '':
os.makedirs(os.path.dirname(output_path))
out_stream = open(output_path, 'wb')
else:
format = os.path.splitext(os.path.splitext(output_path.name)[0])[1][1:]
out_stream = output_path
Writer = get_writer(format)
if Writer is None:
raise PDBError('No writer avaliable for format %s.' % format)
writer = Writer(opts, log)
out_stream.seek(0)
out_stream.truncate()
writer.write_content(oeb_book, out_stream)
if close:
out_stream.close()

View file

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
'''
Writer content to palmdoc pdb file.
'''
__license__ = 'GPL v3'
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'
import struct
from calibre.ebooks.pdb.formatwriter import FormatWriter
from calibre.ebooks.txt.writer import TxtWriter, TxtNewlines, TxtMetadata
from calibre.ebooks.mobi.palmdoc import compress_doc
from calibre.ebooks.pdb.header import PdbHeaderBuilder
MAX_RECORD_SIZE = 4096
class Writer(FormatWriter):
def __init__(self, opts, log):
self.opts = opts
self.log = log
def write_content(self, oeb_book, out_stream):
title = self.opts.title if self.opts.title else oeb_book.metadata.title[0].value if oeb_book.metadata.title != [] else _('Unknown')
txt_records, txt_length = self._generate_text(oeb_book.spine)
header_record = self._header_record(txt_length, len(txt_records))
section_lengths = [len(header_record)]
for i in range(0, len(txt_records)):
txt_records[i] = compress_doc(txt_records[i].encode('utf-8'))
section_lengths.append(len(txt_records[i]))
out_stream.seek(0)
hb = PdbHeaderBuilder('TEXtREAd', title)
hb.build_header(section_lengths, out_stream)
for record in [header_record]+txt_records:
out_stream.write(record)
def _generate_text(self, spine):
txt_writer = TxtWriter(TxtNewlines('system').newline, self.log)
txt = txt_writer.dump(spine, TxtMetadata())
txt_length = len(txt)
txt_records = []
for i in range(0, (len(txt) / MAX_RECORD_SIZE) + 1):
txt_records.append(txt[i * MAX_RECORD_SIZE : (i * MAX_RECORD_SIZE) + MAX_RECORD_SIZE])
return txt_records, txt_length
def _header_record(self, txt_length, record_count):
record = ''
record += struct.pack('>H', 2) # [0:2], PalmDoc compression. (1 = No compression).
record += struct.pack('>H', 0) # [2:4], Always 0.
record += struct.pack('>L', txt_length) # [4:8], Uncompressed length of the entire text of the book.
record += struct.pack('>H', record_count) # [8:10], Number of PDB records used for the text of the book.
record += struct.pack('>H', MAX_RECORD_SIZE) # [10-12], Maximum size of each record containing text, always 4096.
record += struct.pack('>L', 0) # [12-16], Current reading position, as an offset into the uncompressed text.
return record

View file

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
__license__ = 'GPL 3'
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'