This commit is contained in:
Kovid Goyal 2009-04-12 12:24:36 -07:00
commit 9de708c70b
7 changed files with 416 additions and 427 deletions

View File

@ -51,8 +51,7 @@ class EPUBInput(InputFormatPlugin):
traceback.print_exc() traceback.print_exc()
return False return False
def convert(self, stream, options, file_ext, parse_cache, log, def convert(self, stream, options, file_ext, log, accelerators):
accelerators):
from calibre.utils.zipfile import ZipFile from calibre.utils.zipfile import ZipFile
from calibre import walk from calibre import walk
from calibre.ebooks import DRMError from calibre.ebooks import DRMError
@ -73,5 +72,4 @@ class EPUBInput(InputFormatPlugin):
if not self.process_encryption(encfile, opf, log): if not self.process_encryption(encfile, opf, log):
raise DRMError(os.path.basename(path)) raise DRMError(os.path.basename(path))
return opf return os.path.join(os.getcwd(), opf)

View File

@ -306,5 +306,7 @@ HTML_SYMBOLS = {
u'ý' : ['ý', 'ý'], # latin small letter y with acute u'ý' : ['ý', 'ý'], # latin small letter y with acute
u'þ' : ['þ', 'þ'], # latin small letter thorn u'þ' : ['þ', 'þ'], # latin small letter thorn
u'ÿ' : ['ÿ', 'ÿ'], # latin small letter y with diaeresis u'ÿ' : ['ÿ', 'ÿ'], # latin small letter y with diaeresis
# More
u' ' : [' '],
} }

View File

@ -51,23 +51,18 @@ def get_metadata(stream, extract_cover=True):
def set_metadata(stream, mi): def set_metadata(stream, mi):
stream.seek(0) stream.seek(0)
# Use a StringIO object for the pdf because we will want to over # Use a StringIO object for the pdf because we will want to over
# write it later and if we are working on the stream directly it # write it later and if we are working on the stream directly it
# could cause some issues. # could cause some issues.
raw = StringIO.StringIO(stream.read()) raw = StringIO.StringIO(stream.read())
orig_pdf = PdfFileReader(raw) orig_pdf = PdfFileReader(raw)
title = mi.title if mi.title else orig_pdf.documentInfo.title title = mi.title if mi.title else orig_pdf.documentInfo.title
author = authors_to_string(mi.authors) if mi.authors else orig_pdf.documentInfo.author author = authors_to_string(mi.authors) if mi.authors else orig_pdf.documentInfo.author
out_pdf = PdfFileWriter(title=title, author=author) out_pdf = PdfFileWriter(title=title, author=author)
for page in orig_pdf.pages: for page in orig_pdf.pages:
out_pdf.addPage(page) out_pdf.addPage(page)
out_str = StringIO.StringIO() out_str = StringIO.StringIO()
out_pdf.write(out_str) out_pdf.write(out_str)
stream.seek(0) stream.seek(0)
stream.truncate() stream.truncate()
out_str.seek(0) out_str.seek(0)

View File

@ -158,22 +158,19 @@ class BookHeader(object):
class MetadataHeader(BookHeader): class MetadataHeader(BookHeader):
def __init__(self, stream): def __init__(self, stream, log):
self.stream = stream self.stream = stream
self.ident = self.identity() self.ident = self.identity()
self.num_sections = self.section_count() self.num_sections = self.section_count()
if self.num_sections >= 2: if self.num_sections >= 2:
header = self.header() header = self.header()
BookHeader.__init__(self, header, self.ident, None) BookHeader.__init__(self, header, self.ident, None, log)
else: else:
self.exth = None self.exth = None
def identity(self): def identity(self):
self.stream.seek(60) self.stream.seek(60)
ident = self.stream.read(8).upper() ident = self.stream.read(8).upper()
if ident not in ['BOOKMOBI', 'TEXTREAD']: if ident not in ['BOOKMOBI', 'TEXTREAD']:
raise MobiError('Unknown book type: %s' % ident) raise MobiError('Unknown book type: %s' % ident)
return ident return ident
@ -188,7 +185,6 @@ class MetadataHeader(BookHeader):
def header(self): def header(self):
section_headers = [] section_headers = []
# First section with the metadata # First section with the metadata
section_headers.append(self.section_offset(0)) section_headers.append(self.section_offset(0))
# Second section used to get the lengh of the first # Second section used to get the lengh of the first
@ -196,20 +192,16 @@ class MetadataHeader(BookHeader):
end_off = section_headers[1] end_off = section_headers[1]
off = section_headers[0] off = section_headers[0]
self.stream.seek(off) self.stream.seek(off)
return self.stream.read(end_off - off) return self.stream.read(end_off - off)
def section_data(self, number): def section_data(self, number):
start = self.section_offset(number) start = self.section_offset(number)
if number == self.num_sections -1: if number == self.num_sections -1:
end = os.stat(self.stream.name).st_size end = os.stat(self.stream.name).st_size
else: else:
end = self.section_offset(number + 1) end = self.section_offset(number + 1)
self.stream.seek(start) self.stream.seek(start)
return self.stream.read(end - start) return self.stream.read(end - start)
@ -470,7 +462,7 @@ class MobiReader(object):
def create_opf(self, htmlfile, guide=None, root=None): def create_opf(self, htmlfile, guide=None, root=None):
mi = getattr(self.book_header.exth, 'mi', self.embedded_mi) mi = getattr(self.book_header.exth, 'mi', self.embedded_mi)
if mi is None: if mi is None:
mi = MetaInformation(self.title, [_('Unknown')]) mi = MetaInformation(self.book_header.title, [_('Unknown')])
opf = OPFCreator(os.path.dirname(htmlfile), mi) opf = OPFCreator(os.path.dirname(htmlfile), mi)
if hasattr(self.book_header.exth, 'cover_offset'): if hasattr(self.book_header.exth, 'cover_offset'):
opf.cover = 'images/%05d.jpg'%(self.book_header.exth.cover_offset+1) opf.cover = 'images/%05d.jpg'%(self.book_header.exth.cover_offset+1)
@ -649,20 +641,23 @@ class MobiReader(object):
im.convert('RGB').save(open(path, 'wb'), format='JPEG') im.convert('RGB').save(open(path, 'wb'), format='JPEG')
def get_metadata(stream): def get_metadata(stream):
from calibre.utils.logging import Log
log = Log()
mi = MetaInformation(os.path.basename(stream.name), [_('Unknown')]) mi = MetaInformation(os.path.basename(stream.name), [_('Unknown')])
try: try:
mh = MetadataHeader(stream) mh = MetadataHeader(stream, log)
if mh.exth is not None: if mh.exth is not None:
if mh.exth.mi is not None: if mh.exth.mi is not None:
mi = mh.exth.mi mi = mh.exth.mi
else: else:
with TemporaryDirectory('_mobi_meta_reader') as tdir: with TemporaryDirectory('_mobi_meta_reader') as tdir:
mr = MobiReader(stream) mr = MobiReader(stream, log)
mr.extract_content(tdir, {}) parse_cache = {}
mr.extract_content(tdir, parse_cache)
if mr.embedded_mi is not None: if mr.embedded_mi is not None:
mi = mr.embedded_mi mi = mr.embedded_mi
if hasattr(mh.exth, 'cover_offset'): if hasattr(mh.exth, 'cover_offset'):
cover_index = mh.first_image_index + mh.exth.cover_offset cover_index = mh.first_image_index + mh.exth.cover_offset
data = mh.section_data(int(cover_index)) data = mh.section_data(int(cover_index))
@ -674,9 +669,5 @@ def get_metadata(stream):
im.convert('RGBA').save(obuf, format='JPEG') im.convert('RGBA').save(obuf, format='JPEG')
mi.cover_data = ('jpg', obuf.getvalue()) mi.cover_data = ('jpg', obuf.getvalue())
except: except:
import traceback log.exception()
traceback.print_exc()
return mi return mi

View File

@ -1,3 +1,4 @@
from __future__ import with_statement
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008 Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008 Kovid Goyal <kovid at kovidgoyal.net>'

View File

@ -18,7 +18,7 @@ from calibre.utils.config import prefs
from calibre.gui2.widgets import FilenamePattern from calibre.gui2.widgets import FilenamePattern
from calibre.gui2.library import BooksModel from calibre.gui2.library import BooksModel
from calibre.ebooks import BOOK_EXTENSIONS from calibre.ebooks import BOOK_EXTENSIONS
from calibre.ebooks.epub.iterator import is_supported from calibre.ebooks.oeb.iterator import is_supported
from calibre.library import server_config from calibre.library import server_config
from calibre.customize.ui import initialized_plugins, is_disabled, enable_plugin, \ from calibre.customize.ui import initialized_plugins, is_disabled, enable_plugin, \
disable_plugin, customize_plugin, \ disable_plugin, customize_plugin, \

View File

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0" > <ui version="4.0" >
<author>Kovid Goyal</author> <author>Kovid Goyal</author>
<class>Dialog</class> <class>Dialog</class>
@ -24,7 +23,7 @@
<item> <item>
<widget class="QListView" name="category_view" > <widget class="QListView" name="category_view" >
<property name="sizePolicy" > <property name="sizePolicy" >
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding"> <sizepolicy vsizetype="Expanding" hsizetype="MinimumExpanding" >
<horstretch>1</horstretch> <horstretch>1</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
@ -35,6 +34,9 @@
<bold>true</bold> <bold>true</bold>
</font> </font>
</property> </property>
<property name="editTriggers" >
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="tabKeyNavigation" > <property name="tabKeyNavigation" >
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -67,7 +69,7 @@
<item> <item>
<widget class="QStackedWidget" name="stackedWidget" > <widget class="QStackedWidget" name="stackedWidget" >
<property name="sizePolicy" > <property name="sizePolicy" >
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
<horstretch>100</horstretch> <horstretch>100</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
@ -563,7 +565,7 @@
<item> <item>
<widget class="QLineEdit" name="email_from" > <widget class="QLineEdit" name="email_from" >
<property name="toolTip" > <property name="toolTip" >
<string>&lt;p&gt;This is what will be present in the From: field of emails sent by calibre.&lt;br&gt; Set it to your email address</string> <string>&lt;p>This is what will be present in the From: field of emails sent by calibre.&lt;br> Set it to your email address</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -640,7 +642,7 @@
<item row="3" column="0" > <item row="3" column="0" >
<widget class="QGroupBox" name="groupBox_5" > <widget class="QGroupBox" name="groupBox_5" >
<property name="toolTip" > <property name="toolTip" >
<string>&lt;p&gt;A mail server is useful if the service you are sending mail to only accepts email from well know mail services.</string> <string>&lt;p>A mail server is useful if the service you are sending mail to only accepts email from well know mail services.</string>
</property> </property>
<property name="title" > <property name="title" >
<string>Mail &amp;Server</string> <string>Mail &amp;Server</string>
@ -649,7 +651,7 @@
<item row="0" column="0" colspan="4" > <item row="0" column="0" colspan="4" >
<widget class="QLabel" name="label_16" > <widget class="QLabel" name="label_16" >
<property name="text" > <property name="text" >
<string>calibre can &lt;b&gt;optionally&lt;/b&gt; use a server to send mail</string> <string>calibre can &lt;b>optionally&lt;/b> use a server to send mail</string>
</property> </property>
<property name="wordWrap" > <property name="wordWrap" >
<bool>true</bool> <bool>true</bool>