tools v5.5.3

This commit is contained in:
Apprentice Alf 2012-12-26 23:17:56 +00:00
parent c010e3f77a
commit 602ff30b3a
17 changed files with 142 additions and 63 deletions

View File

@ -21,13 +21,14 @@ __docformat__ = 'restructuredtext en'
# 0.4.10 - Another Topaz Fix (class added to page and group and region) # 0.4.10 - Another Topaz Fix (class added to page and group and region)
# 0.4.11 - Fixed Linux support of K4PC # 0.4.11 - Fixed Linux support of K4PC
# 0.4.12 - More Linux Wine fixes # 0.4.12 - More Linux Wine fixes
# 0.4.13 - Ancient Mobipocket files fix
""" """
Decrypt Amazon Kindle and Mobipocket encrypted ebooks. Decrypt Amazon Kindle and Mobipocket encrypted ebooks.
""" """
PLUGIN_NAME = u"Kindle and Mobipocket DeDRM" PLUGIN_NAME = u"Kindle and Mobipocket DeDRM"
PLUGIN_VERSION_TUPLE = (0, 4, 12) PLUGIN_VERSION_TUPLE = (0, 4, 13)
PLUGIN_VERSION = '.'.join([str(x) for x in PLUGIN_VERSION_TUPLE]) PLUGIN_VERSION = '.'.join([str(x) for x in PLUGIN_VERSION_TUPLE])
import sys, os, re import sys, os, re

View File

@ -277,6 +277,7 @@ class PageParser(object):
'word_semantic' : (1, 'snippets', 1, 1), 'word_semantic' : (1, 'snippets', 1, 1),
'word_semantic.type' : (1, 'scalar_text', 0, 0), 'word_semantic.type' : (1, 'scalar_text', 0, 0),
'word_semantic.class' : (1, 'scalar_text', 0, 0),
'word_semantic.firstWord' : (1, 'scalar_number', 0, 0), 'word_semantic.firstWord' : (1, 'scalar_number', 0, 0),
'word_semantic.lastWord' : (1, 'scalar_number', 0, 0), 'word_semantic.lastWord' : (1, 'scalar_number', 0, 0),
@ -287,6 +288,7 @@ class PageParser(object):
'word.lastGlyph' : (1, 'scalar_number', 0, 0), 'word.lastGlyph' : (1, 'scalar_number', 0, 0),
'_span' : (1, 'snippets', 1, 0), '_span' : (1, 'snippets', 1, 0),
'_span.class' : (1, 'scalar_text', 0, 0),
'_span.firstWord' : (1, 'scalar_number', 0, 0), '_span.firstWord' : (1, 'scalar_number', 0, 0),
'_span.lastWord' : (1, 'scalar_number', 0, 0), '_span.lastWord' : (1, 'scalar_number', 0, 0),
'_span.gridSize' : (1, 'scalar_number', 0, 0), '_span.gridSize' : (1, 'scalar_number', 0, 0),
@ -350,16 +352,18 @@ class PageParser(object):
'version.paragraph_continuation' : (1, 'scalar_text', 0, 0), 'version.paragraph_continuation' : (1, 'scalar_text', 0, 0),
'version.toc' : (1, 'scalar_text', 0, 0), 'version.toc' : (1, 'scalar_text', 0, 0),
'stylesheet' : (1, 'snippets', 1, 0), 'stylesheet' : (1, 'snippets', 1, 0),
'style' : (1, 'snippets', 1, 0), 'style' : (1, 'snippets', 1, 0),
'style._tag' : (1, 'scalar_text', 0, 0), 'style._tag' : (1, 'scalar_text', 0, 0),
'style.type' : (1, 'scalar_text', 0, 0), 'style.type' : (1, 'scalar_text', 0, 0),
'style._parent_type' : (1, 'scalar_text', 0, 0), 'style._after_type' : (1, 'scalar_text', 0, 0),
'style.class' : (1, 'scalar_text', 0, 0), 'style._parent_type' : (1, 'scalar_text', 0, 0),
'style._after_class' : (1, 'scalar_text', 0, 0), 'style._after_parent_type' : (1, 'scalar_text', 0, 0),
'rule' : (1, 'snippets', 1, 0), 'style.class' : (1, 'scalar_text', 0, 0),
'rule.attr' : (1, 'scalar_text', 0, 0), 'style._after_class' : (1, 'scalar_text', 0, 0),
'rule.value' : (1, 'scalar_text', 0, 0), 'rule' : (1, 'snippets', 1, 0),
'rule.attr' : (1, 'scalar_text', 0, 0),
'rule.value' : (1, 'scalar_text', 0, 0),
'original' : (0, 'number', 1, 1), 'original' : (0, 'number', 1, 1),
'original.pnum' : (1, 'number', 0, 0), 'original.pnum' : (1, 'number', 0, 0),

View File

@ -10,6 +10,7 @@ import re
from struct import pack from struct import pack
from struct import unpack from struct import unpack
debug = False
class DocParser(object): class DocParser(object):
def __init__(self, flatxml, fontsize, ph, pw): def __init__(self, flatxml, fontsize, ph, pw):
@ -113,7 +114,9 @@ class DocParser(object):
# process each style converting what you can # process each style converting what you can
if debug: print ' ', 'Processing styles.'
for j in xrange(stylecnt): for j in xrange(stylecnt):
if debug: print ' ', 'Processing style %d' %(j)
start = styleList[j] start = styleList[j]
end = styleList[j+1] end = styleList[j+1]
@ -132,6 +135,8 @@ class DocParser(object):
else : else :
sclass = '' sclass = ''
if debug: print 'sclass', sclass
# check for any "after class" specifiers # check for any "after class" specifiers
(pos, aftclass) = self.findinDoc('style._after_class',start,end) (pos, aftclass) = self.findinDoc('style._after_class',start,end)
if aftclass != None: if aftclass != None:
@ -140,6 +145,8 @@ class DocParser(object):
else : else :
aftclass = '' aftclass = ''
if debug: print 'aftclass', aftclass
cssargs = {} cssargs = {}
while True : while True :
@ -147,6 +154,9 @@ class DocParser(object):
(pos1, attr) = self.findinDoc('style.rule.attr', start, end) (pos1, attr) = self.findinDoc('style.rule.attr', start, end)
(pos2, val) = self.findinDoc('style.rule.value', start, end) (pos2, val) = self.findinDoc('style.rule.value', start, end)
if debug: print 'attr', attr
if debug: print 'val', val
if attr == None : break if attr == None : break
if (attr == 'display') or (attr == 'pos') or (attr == 'align'): if (attr == 'display') or (attr == 'pos') or (attr == 'align'):
@ -164,7 +174,7 @@ class DocParser(object):
scale = self.pw scale = self.pw
elif attr == 'line-space': elif attr == 'line-space':
scale = self.fontsize * 2.0 scale = self.fontsize * 2.0
if val == "": if val == "":
val = 0 val = 0
@ -179,6 +189,7 @@ class DocParser(object):
if aftclass != "" : keep = False if aftclass != "" : keep = False
if keep : if keep :
if debug: print 'keeping style'
# make sure line-space does not go below 100% or above 300% since # make sure line-space does not go below 100% or above 300% since
# it can be wacky in some styles # it can be wacky in some styles
if 'line-space' in cssargs: if 'line-space' in cssargs:
@ -256,7 +267,9 @@ def convert2CSS(flatxml, fontsize, ph, pw):
# create a document parser # create a document parser
dp = DocParser(flatxml, fontsize, ph, pw) dp = DocParser(flatxml, fontsize, ph, pw)
if debug: print ' ', 'Created DocParser.'
csspage = dp.process() csspage = dp.process()
if debug: print ' ', 'Processed DocParser.'
return csspage return csspage

View File

@ -69,6 +69,9 @@ def unicode_argv():
argvencoding = 'utf-8' argvencoding = 'utf-8'
return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv] return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv]
#global switch
debug = False
if 'calibre' in sys.modules: if 'calibre' in sys.modules:
inCalibre = True inCalibre = True
from calibre_plugins.k4mobidedrm import kgenpids from calibre_plugins.k4mobidedrm import kgenpids
@ -206,6 +209,7 @@ class TopazBook:
# Read and return the data of one header record at the current book file position # Read and return the data of one header record at the current book file position
# [[offset,decompressedLength,compressedLength],...] # [[offset,decompressedLength,compressedLength],...]
nbValues = bookReadEncodedNumber(self.fo) nbValues = bookReadEncodedNumber(self.fo)
if debug: print "%d records in header " % nbValues,
values = [] values = []
for i in range (0,nbValues): for i in range (0,nbValues):
values.append([bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo)]) values.append([bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo)])
@ -219,9 +223,10 @@ class TopazBook:
record = bookReadHeaderRecordData() record = bookReadHeaderRecordData()
return [tag,record] return [tag,record]
nbRecords = bookReadEncodedNumber(self.fo) nbRecords = bookReadEncodedNumber(self.fo)
if debug: print "Headers: %d" % nbRecords
for i in range (0,nbRecords): for i in range (0,nbRecords):
result = parseTopazHeaderRecord() result = parseTopazHeaderRecord()
# print result[0], result[1] if debug: print result[0], ": ", result[1]
self.bookHeaderRecords[result[0]] = result[1] self.bookHeaderRecords[result[0]] = result[1]
if ord(self.fo.read(1)) != 0x64 : if ord(self.fo.read(1)) != 0x64 :
raise DrmException(u"Parse Error : Invalid Header") raise DrmException(u"Parse Error : Invalid Header")
@ -235,12 +240,12 @@ class TopazBook:
raise DrmException(u"Parse Error : Record Names Don't Match") raise DrmException(u"Parse Error : Record Names Don't Match")
flags = ord(self.fo.read(1)) flags = ord(self.fo.read(1))
nbRecords = ord(self.fo.read(1)) nbRecords = ord(self.fo.read(1))
# print nbRecords if debug: print "Metadata Records: %d" % nbRecords
for i in range (0,nbRecords) : for i in range (0,nbRecords) :
keyval = bookReadString(self.fo) keyval = bookReadString(self.fo)
content = bookReadString(self.fo) content = bookReadString(self.fo)
# print keyval if debug: print keyval
# print content if debug: print content
self.bookMetadata[keyval] = content self.bookMetadata[keyval] = content
return self.bookMetadata return self.bookMetadata

View File

@ -41,7 +41,7 @@ Mac OS X 10.5 and above: You do
\i not \i not
\i0 need to install Python.\ \i0 need to install Python.\
\ \
Drag the DeDRM application from from tools_v5.5\\DeDRM_Applications\\Macintosh (the location of this ReadMe) to your Applications folder, or anywhere else you find convenient.\ Drag the DeDRM application from from tools_v5.5.3\\DeDRM_Applications\\Macintosh (the location of this ReadMe) to your Applications folder, or anywhere else you find convenient.\
\ \
\ \

View File

@ -24,17 +24,17 @@
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>droplet</string> <string>droplet</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>DeDRM 5.5. AppleScript written 20102012 by Apprentice Alf and others.</string> <string>DeDRM 5.5.3. AppleScript written 20102012 by Apprentice Alf and others.</string>
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>DeDRM</string> <string>DeDRM</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>DeDRM 5.5</string> <string>DeDRM 5.5.3</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>5.5</string> <string>5.5.3</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>dplt</string> <string>dplt</string>
<key>LSRequiresCarbon</key> <key>LSRequiresCarbon</key>

View File

@ -277,6 +277,7 @@ class PageParser(object):
'word_semantic' : (1, 'snippets', 1, 1), 'word_semantic' : (1, 'snippets', 1, 1),
'word_semantic.type' : (1, 'scalar_text', 0, 0), 'word_semantic.type' : (1, 'scalar_text', 0, 0),
'word_semantic.class' : (1, 'scalar_text', 0, 0),
'word_semantic.firstWord' : (1, 'scalar_number', 0, 0), 'word_semantic.firstWord' : (1, 'scalar_number', 0, 0),
'word_semantic.lastWord' : (1, 'scalar_number', 0, 0), 'word_semantic.lastWord' : (1, 'scalar_number', 0, 0),
@ -287,6 +288,7 @@ class PageParser(object):
'word.lastGlyph' : (1, 'scalar_number', 0, 0), 'word.lastGlyph' : (1, 'scalar_number', 0, 0),
'_span' : (1, 'snippets', 1, 0), '_span' : (1, 'snippets', 1, 0),
'_span.class' : (1, 'scalar_text', 0, 0),
'_span.firstWord' : (1, 'scalar_number', 0, 0), '_span.firstWord' : (1, 'scalar_number', 0, 0),
'_span.lastWord' : (1, 'scalar_number', 0, 0), '_span.lastWord' : (1, 'scalar_number', 0, 0),
'_span.gridSize' : (1, 'scalar_number', 0, 0), '_span.gridSize' : (1, 'scalar_number', 0, 0),
@ -350,16 +352,18 @@ class PageParser(object):
'version.paragraph_continuation' : (1, 'scalar_text', 0, 0), 'version.paragraph_continuation' : (1, 'scalar_text', 0, 0),
'version.toc' : (1, 'scalar_text', 0, 0), 'version.toc' : (1, 'scalar_text', 0, 0),
'stylesheet' : (1, 'snippets', 1, 0), 'stylesheet' : (1, 'snippets', 1, 0),
'style' : (1, 'snippets', 1, 0), 'style' : (1, 'snippets', 1, 0),
'style._tag' : (1, 'scalar_text', 0, 0), 'style._tag' : (1, 'scalar_text', 0, 0),
'style.type' : (1, 'scalar_text', 0, 0), 'style.type' : (1, 'scalar_text', 0, 0),
'style._parent_type' : (1, 'scalar_text', 0, 0), 'style._after_type' : (1, 'scalar_text', 0, 0),
'style.class' : (1, 'scalar_text', 0, 0), 'style._parent_type' : (1, 'scalar_text', 0, 0),
'style._after_class' : (1, 'scalar_text', 0, 0), 'style._after_parent_type' : (1, 'scalar_text', 0, 0),
'rule' : (1, 'snippets', 1, 0), 'style.class' : (1, 'scalar_text', 0, 0),
'rule.attr' : (1, 'scalar_text', 0, 0), 'style._after_class' : (1, 'scalar_text', 0, 0),
'rule.value' : (1, 'scalar_text', 0, 0), 'rule' : (1, 'snippets', 1, 0),
'rule.attr' : (1, 'scalar_text', 0, 0),
'rule.value' : (1, 'scalar_text', 0, 0),
'original' : (0, 'number', 1, 1), 'original' : (0, 'number', 1, 1),
'original.pnum' : (1, 'number', 0, 0), 'original.pnum' : (1, 'number', 0, 0),

View File

@ -11,15 +11,21 @@ __version__ = '1.01'
import sys import sys
class Unbuffered: class SafeUnbuffered:
def __init__(self, stream): def __init__(self, stream):
self.stream = stream self.stream = stream
self.encoding = stream.encoding
if self.encoding == None:
self.encoding = "utf-8"
def write(self, data): def write(self, data):
if isinstance(data,unicode):
data = data.encode(self.encoding,"replace")
self.stream.write(data) self.stream.write(data)
self.stream.flush() self.stream.flush()
def __getattr__(self, attr): def __getattr__(self, attr):
return getattr(self.stream, attr) return getattr(self.stream, attr)
sys.stdout=Unbuffered(sys.stdout) sys.stdout=SafeUnbuffered(sys.stdout)
sys.stderr=SafeUnbuffered(sys.stderr)
import os import os
import struct import struct
@ -41,7 +47,7 @@ def getK4PCpids(path_to_ebook):
mobi = False mobi = False
if mobi: if mobi:
mb = mobidedrm.MobiBook(path_to_ebook,False) mb = mobidedrm.MobiBook(path_to_ebook)
else: else:
mb = topazextract.TopazBook(path_to_ebook) mb = topazextract.TopazBook(path_to_ebook)

View File

@ -10,6 +10,7 @@ import re
from struct import pack from struct import pack
from struct import unpack from struct import unpack
debug = False
class DocParser(object): class DocParser(object):
def __init__(self, flatxml, fontsize, ph, pw): def __init__(self, flatxml, fontsize, ph, pw):
@ -113,7 +114,9 @@ class DocParser(object):
# process each style converting what you can # process each style converting what you can
if debug: print ' ', 'Processing styles.'
for j in xrange(stylecnt): for j in xrange(stylecnt):
if debug: print ' ', 'Processing style %d' %(j)
start = styleList[j] start = styleList[j]
end = styleList[j+1] end = styleList[j+1]
@ -132,6 +135,8 @@ class DocParser(object):
else : else :
sclass = '' sclass = ''
if debug: print 'sclass', sclass
# check for any "after class" specifiers # check for any "after class" specifiers
(pos, aftclass) = self.findinDoc('style._after_class',start,end) (pos, aftclass) = self.findinDoc('style._after_class',start,end)
if aftclass != None: if aftclass != None:
@ -140,6 +145,8 @@ class DocParser(object):
else : else :
aftclass = '' aftclass = ''
if debug: print 'aftclass', aftclass
cssargs = {} cssargs = {}
while True : while True :
@ -147,6 +154,9 @@ class DocParser(object):
(pos1, attr) = self.findinDoc('style.rule.attr', start, end) (pos1, attr) = self.findinDoc('style.rule.attr', start, end)
(pos2, val) = self.findinDoc('style.rule.value', start, end) (pos2, val) = self.findinDoc('style.rule.value', start, end)
if debug: print 'attr', attr
if debug: print 'val', val
if attr == None : break if attr == None : break
if (attr == 'display') or (attr == 'pos') or (attr == 'align'): if (attr == 'display') or (attr == 'pos') or (attr == 'align'):
@ -164,7 +174,7 @@ class DocParser(object):
scale = self.pw scale = self.pw
elif attr == 'line-space': elif attr == 'line-space':
scale = self.fontsize * 2.0 scale = self.fontsize * 2.0
if val == "": if val == "":
val = 0 val = 0
@ -179,6 +189,7 @@ class DocParser(object):
if aftclass != "" : keep = False if aftclass != "" : keep = False
if keep : if keep :
if debug: print 'keeping style'
# make sure line-space does not go below 100% or above 300% since # make sure line-space does not go below 100% or above 300% since
# it can be wacky in some styles # it can be wacky in some styles
if 'line-space' in cssargs: if 'line-space' in cssargs:
@ -256,7 +267,9 @@ def convert2CSS(flatxml, fontsize, ph, pw):
# create a document parser # create a document parser
dp = DocParser(flatxml, fontsize, ph, pw) dp = DocParser(flatxml, fontsize, ph, pw)
if debug: print ' ', 'Created DocParser.'
csspage = dp.process() csspage = dp.process()
if debug: print ' ', 'Processed DocParser.'
return csspage return csspage

View File

@ -69,6 +69,9 @@ def unicode_argv():
argvencoding = 'utf-8' argvencoding = 'utf-8'
return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv] return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv]
#global switch
debug = False
if 'calibre' in sys.modules: if 'calibre' in sys.modules:
inCalibre = True inCalibre = True
from calibre_plugins.k4mobidedrm import kgenpids from calibre_plugins.k4mobidedrm import kgenpids
@ -206,6 +209,7 @@ class TopazBook:
# Read and return the data of one header record at the current book file position # Read and return the data of one header record at the current book file position
# [[offset,decompressedLength,compressedLength],...] # [[offset,decompressedLength,compressedLength],...]
nbValues = bookReadEncodedNumber(self.fo) nbValues = bookReadEncodedNumber(self.fo)
if debug: print "%d records in header " % nbValues,
values = [] values = []
for i in range (0,nbValues): for i in range (0,nbValues):
values.append([bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo)]) values.append([bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo)])
@ -219,9 +223,10 @@ class TopazBook:
record = bookReadHeaderRecordData() record = bookReadHeaderRecordData()
return [tag,record] return [tag,record]
nbRecords = bookReadEncodedNumber(self.fo) nbRecords = bookReadEncodedNumber(self.fo)
if debug: print "Headers: %d" % nbRecords
for i in range (0,nbRecords): for i in range (0,nbRecords):
result = parseTopazHeaderRecord() result = parseTopazHeaderRecord()
# print result[0], result[1] if debug: print result[0], ": ", result[1]
self.bookHeaderRecords[result[0]] = result[1] self.bookHeaderRecords[result[0]] = result[1]
if ord(self.fo.read(1)) != 0x64 : if ord(self.fo.read(1)) != 0x64 :
raise DrmException(u"Parse Error : Invalid Header") raise DrmException(u"Parse Error : Invalid Header")
@ -235,12 +240,12 @@ class TopazBook:
raise DrmException(u"Parse Error : Record Names Don't Match") raise DrmException(u"Parse Error : Record Names Don't Match")
flags = ord(self.fo.read(1)) flags = ord(self.fo.read(1))
nbRecords = ord(self.fo.read(1)) nbRecords = ord(self.fo.read(1))
# print nbRecords if debug: print "Metadata Records: %d" % nbRecords
for i in range (0,nbRecords) : for i in range (0,nbRecords) :
keyval = bookReadString(self.fo) keyval = bookReadString(self.fo)
content = bookReadString(self.fo) content = bookReadString(self.fo)
# print keyval if debug: print keyval
# print content if debug: print content
self.bookMetadata[keyval] = content self.bookMetadata[keyval] = content
return self.bookMetadata return self.bookMetadata

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# DeDRM.pyw, version 5.5 # DeDRM.pyw, version 5.5.3
# By some_updates and Apprentice Alf # By some_updates and Apprentice Alf
import sys import sys
@ -24,7 +24,7 @@ import re
import simpleprefs import simpleprefs
__version__ = '5.5' __version__ = '5.5.3'
class DrmException(Exception): class DrmException(Exception):
pass pass
@ -441,10 +441,10 @@ class ConvDialog(Toplevel):
self.log += text self.log += text
self.log += msg self.log += msg
else: else:
msg = u"\nFailed\n"
text = self.p2.read().decode('utf8') text = self.p2.read().decode('utf8')
text += self.p2.readerr().decode('utf8') text += self.p2.readerr().decode('utf8')
msg += text msg += text
msg += u"\nFailed\n"
self.numbad += 1 self.numbad += 1
self.log += msg self.log += msg
self.showCmdOutput(msg) self.showCmdOutput(msg)

View File

@ -277,6 +277,7 @@ class PageParser(object):
'word_semantic' : (1, 'snippets', 1, 1), 'word_semantic' : (1, 'snippets', 1, 1),
'word_semantic.type' : (1, 'scalar_text', 0, 0), 'word_semantic.type' : (1, 'scalar_text', 0, 0),
'word_semantic.class' : (1, 'scalar_text', 0, 0),
'word_semantic.firstWord' : (1, 'scalar_number', 0, 0), 'word_semantic.firstWord' : (1, 'scalar_number', 0, 0),
'word_semantic.lastWord' : (1, 'scalar_number', 0, 0), 'word_semantic.lastWord' : (1, 'scalar_number', 0, 0),
@ -287,6 +288,7 @@ class PageParser(object):
'word.lastGlyph' : (1, 'scalar_number', 0, 0), 'word.lastGlyph' : (1, 'scalar_number', 0, 0),
'_span' : (1, 'snippets', 1, 0), '_span' : (1, 'snippets', 1, 0),
'_span.class' : (1, 'scalar_text', 0, 0),
'_span.firstWord' : (1, 'scalar_number', 0, 0), '_span.firstWord' : (1, 'scalar_number', 0, 0),
'_span.lastWord' : (1, 'scalar_number', 0, 0), '_span.lastWord' : (1, 'scalar_number', 0, 0),
'_span.gridSize' : (1, 'scalar_number', 0, 0), '_span.gridSize' : (1, 'scalar_number', 0, 0),
@ -350,16 +352,18 @@ class PageParser(object):
'version.paragraph_continuation' : (1, 'scalar_text', 0, 0), 'version.paragraph_continuation' : (1, 'scalar_text', 0, 0),
'version.toc' : (1, 'scalar_text', 0, 0), 'version.toc' : (1, 'scalar_text', 0, 0),
'stylesheet' : (1, 'snippets', 1, 0), 'stylesheet' : (1, 'snippets', 1, 0),
'style' : (1, 'snippets', 1, 0), 'style' : (1, 'snippets', 1, 0),
'style._tag' : (1, 'scalar_text', 0, 0), 'style._tag' : (1, 'scalar_text', 0, 0),
'style.type' : (1, 'scalar_text', 0, 0), 'style.type' : (1, 'scalar_text', 0, 0),
'style._parent_type' : (1, 'scalar_text', 0, 0), 'style._after_type' : (1, 'scalar_text', 0, 0),
'style.class' : (1, 'scalar_text', 0, 0), 'style._parent_type' : (1, 'scalar_text', 0, 0),
'style._after_class' : (1, 'scalar_text', 0, 0), 'style._after_parent_type' : (1, 'scalar_text', 0, 0),
'rule' : (1, 'snippets', 1, 0), 'style.class' : (1, 'scalar_text', 0, 0),
'rule.attr' : (1, 'scalar_text', 0, 0), 'style._after_class' : (1, 'scalar_text', 0, 0),
'rule.value' : (1, 'scalar_text', 0, 0), 'rule' : (1, 'snippets', 1, 0),
'rule.attr' : (1, 'scalar_text', 0, 0),
'rule.value' : (1, 'scalar_text', 0, 0),
'original' : (0, 'number', 1, 1), 'original' : (0, 'number', 1, 1),
'original.pnum' : (1, 'number', 0, 0), 'original.pnum' : (1, 'number', 0, 0),

View File

@ -11,15 +11,21 @@ __version__ = '1.01'
import sys import sys
class Unbuffered: class SafeUnbuffered:
def __init__(self, stream): def __init__(self, stream):
self.stream = stream self.stream = stream
self.encoding = stream.encoding
if self.encoding == None:
self.encoding = "utf-8"
def write(self, data): def write(self, data):
if isinstance(data,unicode):
data = data.encode(self.encoding,"replace")
self.stream.write(data) self.stream.write(data)
self.stream.flush() self.stream.flush()
def __getattr__(self, attr): def __getattr__(self, attr):
return getattr(self.stream, attr) return getattr(self.stream, attr)
sys.stdout=Unbuffered(sys.stdout) sys.stdout=SafeUnbuffered(sys.stdout)
sys.stderr=SafeUnbuffered(sys.stderr)
import os import os
import struct import struct
@ -41,7 +47,7 @@ def getK4PCpids(path_to_ebook):
mobi = False mobi = False
if mobi: if mobi:
mb = mobidedrm.MobiBook(path_to_ebook,False) mb = mobidedrm.MobiBook(path_to_ebook)
else: else:
mb = topazextract.TopazBook(path_to_ebook) mb = topazextract.TopazBook(path_to_ebook)

View File

@ -10,6 +10,7 @@ import re
from struct import pack from struct import pack
from struct import unpack from struct import unpack
debug = False
class DocParser(object): class DocParser(object):
def __init__(self, flatxml, fontsize, ph, pw): def __init__(self, flatxml, fontsize, ph, pw):
@ -113,7 +114,9 @@ class DocParser(object):
# process each style converting what you can # process each style converting what you can
if debug: print ' ', 'Processing styles.'
for j in xrange(stylecnt): for j in xrange(stylecnt):
if debug: print ' ', 'Processing style %d' %(j)
start = styleList[j] start = styleList[j]
end = styleList[j+1] end = styleList[j+1]
@ -132,6 +135,8 @@ class DocParser(object):
else : else :
sclass = '' sclass = ''
if debug: print 'sclass', sclass
# check for any "after class" specifiers # check for any "after class" specifiers
(pos, aftclass) = self.findinDoc('style._after_class',start,end) (pos, aftclass) = self.findinDoc('style._after_class',start,end)
if aftclass != None: if aftclass != None:
@ -140,6 +145,8 @@ class DocParser(object):
else : else :
aftclass = '' aftclass = ''
if debug: print 'aftclass', aftclass
cssargs = {} cssargs = {}
while True : while True :
@ -147,6 +154,9 @@ class DocParser(object):
(pos1, attr) = self.findinDoc('style.rule.attr', start, end) (pos1, attr) = self.findinDoc('style.rule.attr', start, end)
(pos2, val) = self.findinDoc('style.rule.value', start, end) (pos2, val) = self.findinDoc('style.rule.value', start, end)
if debug: print 'attr', attr
if debug: print 'val', val
if attr == None : break if attr == None : break
if (attr == 'display') or (attr == 'pos') or (attr == 'align'): if (attr == 'display') or (attr == 'pos') or (attr == 'align'):
@ -164,7 +174,7 @@ class DocParser(object):
scale = self.pw scale = self.pw
elif attr == 'line-space': elif attr == 'line-space':
scale = self.fontsize * 2.0 scale = self.fontsize * 2.0
if val == "": if val == "":
val = 0 val = 0
@ -179,6 +189,7 @@ class DocParser(object):
if aftclass != "" : keep = False if aftclass != "" : keep = False
if keep : if keep :
if debug: print 'keeping style'
# make sure line-space does not go below 100% or above 300% since # make sure line-space does not go below 100% or above 300% since
# it can be wacky in some styles # it can be wacky in some styles
if 'line-space' in cssargs: if 'line-space' in cssargs:
@ -256,7 +267,9 @@ def convert2CSS(flatxml, fontsize, ph, pw):
# create a document parser # create a document parser
dp = DocParser(flatxml, fontsize, ph, pw) dp = DocParser(flatxml, fontsize, ph, pw)
if debug: print ' ', 'Created DocParser.'
csspage = dp.process() csspage = dp.process()
if debug: print ' ', 'Processed DocParser.'
return csspage return csspage

View File

@ -69,6 +69,9 @@ def unicode_argv():
argvencoding = 'utf-8' argvencoding = 'utf-8'
return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv] return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv]
#global switch
debug = False
if 'calibre' in sys.modules: if 'calibre' in sys.modules:
inCalibre = True inCalibre = True
from calibre_plugins.k4mobidedrm import kgenpids from calibre_plugins.k4mobidedrm import kgenpids
@ -206,6 +209,7 @@ class TopazBook:
# Read and return the data of one header record at the current book file position # Read and return the data of one header record at the current book file position
# [[offset,decompressedLength,compressedLength],...] # [[offset,decompressedLength,compressedLength],...]
nbValues = bookReadEncodedNumber(self.fo) nbValues = bookReadEncodedNumber(self.fo)
if debug: print "%d records in header " % nbValues,
values = [] values = []
for i in range (0,nbValues): for i in range (0,nbValues):
values.append([bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo)]) values.append([bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo),bookReadEncodedNumber(self.fo)])
@ -219,9 +223,10 @@ class TopazBook:
record = bookReadHeaderRecordData() record = bookReadHeaderRecordData()
return [tag,record] return [tag,record]
nbRecords = bookReadEncodedNumber(self.fo) nbRecords = bookReadEncodedNumber(self.fo)
if debug: print "Headers: %d" % nbRecords
for i in range (0,nbRecords): for i in range (0,nbRecords):
result = parseTopazHeaderRecord() result = parseTopazHeaderRecord()
# print result[0], result[1] if debug: print result[0], ": ", result[1]
self.bookHeaderRecords[result[0]] = result[1] self.bookHeaderRecords[result[0]] = result[1]
if ord(self.fo.read(1)) != 0x64 : if ord(self.fo.read(1)) != 0x64 :
raise DrmException(u"Parse Error : Invalid Header") raise DrmException(u"Parse Error : Invalid Header")
@ -235,12 +240,12 @@ class TopazBook:
raise DrmException(u"Parse Error : Record Names Don't Match") raise DrmException(u"Parse Error : Record Names Don't Match")
flags = ord(self.fo.read(1)) flags = ord(self.fo.read(1))
nbRecords = ord(self.fo.read(1)) nbRecords = ord(self.fo.read(1))
# print nbRecords if debug: print "Metadata Records: %d" % nbRecords
for i in range (0,nbRecords) : for i in range (0,nbRecords) :
keyval = bookReadString(self.fo) keyval = bookReadString(self.fo)
content = bookReadString(self.fo) content = bookReadString(self.fo)
# print keyval if debug: print keyval
# print content if debug: print content
self.bookMetadata[keyval] = content self.bookMetadata[keyval] = content
return self.bookMetadata return self.bookMetadata

View File

@ -1,7 +1,7 @@
ReadMe_DeDRM_v5.5_WinApp ReadMe_DeDRM_v5.5.3_WinApp
======================== ========================
DeDRM_v5.5_WinApp is a pure python drag and drop application that allows users to drag and drop ebooks or folders of ebooks onto the DeDRM_Drop_Target to have the DRM removed. It repackages all the "tools" python software in one easy to use program that remembers preferences and settings. DeDRM_v5.5.3_WinApp is a pure python drag and drop application that allows users to drag and drop ebooks or folders of ebooks onto the DeDRM_Drop_Target to have the DRM removed. It repackages all the "tools" python software in one easy to use program that remembers preferences and settings.
It will work without manual configuration for Kindle for PC ebooks and Adobe Adept epub and pdf ebooks. It will work without manual configuration for Kindle for PC ebooks and Adobe Adept epub and pdf ebooks.
@ -23,9 +23,9 @@ Installation
0. If you don't already have a correct version of Python and PyCrypto installed, follow the "Installing Python on Windows" and "Installing PyCrypto on Windows" sections below before continuing. 0. If you don't already have a correct version of Python and PyCrypto installed, follow the "Installing Python on Windows" and "Installing PyCrypto on Windows" sections below before continuing.
1. Drag the DeDRM_5.5 folder from tools_v5.5/DeDRM_Applications/Windows to your "My Documents" folder. 1. Drag the DeDRM_5.5.3 folder from tools_v5.5.3/DeDRM_Applications/Windows to your "My Documents" folder.
2. Open the DeDRM_5.5 folder you've just dragged, and make a short-cut of the DeDRM_Drop_Target.bat file (right-click/Create Shortcut). Drag the shortcut file onto your Desktop. 2. Open the DeDRM_5.5.3 folder you've just dragged, and make a short-cut of the DeDRM_Drop_Target.bat file (right-click/Create Shortcut). Drag the shortcut file onto your Desktop.
3. To set the preferences simply double-click on your just created short-cut. 3. To set the preferences simply double-click on your just created short-cut.