mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 02:34:06 -04:00
PalmDoc pdb output.
This commit is contained in:
parent
e447b69bd2
commit
d7e20bb1e5
@ -302,6 +302,7 @@ from calibre.web.feeds.input import RecipeInput
|
||||
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 @@ from calibre.devices.jetbook.driver import JETBOOK
|
||||
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 \
|
||||
|
@ -5,15 +5,25 @@ __license__ = 'GPL v3'
|
||||
__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 @@ IDENTITY_TO_NAME = {
|
||||
'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)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import with_statement
|
||||
|
||||
'''
|
||||
Interface defining the necessary public functions for a pdb format reader.
|
||||
'''
|
||||
|
18
src/calibre/ebooks/pdb/formatwriter.py
Normal file
18
src/calibre/ebooks/pdb/formatwriter.py
Normal 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()
|
@ -1,5 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import with_statement
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
|
||||
|
45
src/calibre/ebooks/pdb/output.py
Normal file
45
src/calibre/ebooks/pdb/output.py
Normal 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()
|
||||
|
67
src/calibre/ebooks/pdb/palmdoc/writer.py
Normal file
67
src/calibre/ebooks/pdb/palmdoc/writer.py
Normal 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
|
||||
|
@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
Loading…
x
Reference in New Issue
Block a user