mirror of
https://github.com/noDRM/DeDRM_tools.git
synced 2025-01-12 03:14:43 +06:00
tools v5.5.3
This commit is contained in:
parent
c010e3f77a
commit
602ff30b3a
@ -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
|
||||||
|
@ -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),
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Binary file not shown.
@ -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.\
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
|
|
||||||
|
@ -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 2010–2012 by Apprentice Alf and others.</string>
|
<string>DeDRM 5.5.3. AppleScript written 2010–2012 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>
|
||||||
|
@ -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),
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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),
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user