]> xmof Git - DeDRM.git/commitdiff
tools v3.3
authorApprentice Alf <apprenticealf@gmail.com>
Wed, 2 Feb 2011 14:41:15 +0000 (14:41 +0000)
committerApprentice Alf <apprenticealf@gmail.com>
Thu, 5 Mar 2015 07:42:05 +0000 (07:42 +0000)
38 files changed:
Calibre_Plugins/K4MobiDeDRM_plugin/flatxml2html.py
Calibre_Plugins/eReaderPDB2PML_plugin.zip
Calibre_Plugins/eReaderPDB2PML_plugin/erdr2pml.py
Calibre_Plugins/ignobleepub_plugin.zip
Calibre_Plugins/ignobleepub_plugin/ignobleepub_plugin.py
Calibre_Plugins/ignobleepub_plugin/zipfix.py
Calibre_Plugins/ineptepub_plugin.zip
Calibre_Plugins/ineptepub_plugin/ineptepub_plugin.py
Calibre_Plugins/ineptepub_plugin/zipfix.py
Calibre_Plugins/ineptpdf_plugin.zip
Calibre_Plugins/k4mobidedrm_plugin.zip
Calibre_Plugins/k4mobidedrm_plugin/k4mobidedrm_plugin.py
Calibre_Plugins/k4mobidedrm_plugin/k4mutils.py
DeDRM_Macintosh_Application/DeDRM.app.txt
DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/Scripts/main.scpt
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/cmbtc_v2.2.py [deleted file]
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/description.rtfd/TXT.rtf
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/flatxml2html.py
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/genxml.py [deleted file]
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignobleepub.py [moved from DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignobleepub.pyw with 98% similarity]
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeygen.py [moved from DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeygen.pyw with 98% similarity]
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py [moved from DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.pyw with 98% similarity]
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptkey.py [moved from DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptkey.pyw with 99% similarity]
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py [moved from DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.pyw with 99% similarity]
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/k4mobidedrm.py
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/k4mutils.py
DeDRM_Windows_Application/DeDRM_WinApp/DeDRM_lib/DeDRM_app.pyw
DeDRM_Windows_Application/DeDRM_WinApp/DeDRM_lib/lib/flatxml2html.py
DeDRM_Windows_Application/DeDRM_WinApp/DeDRM_lib/lib/k4mobidedrm.py
DeDRM_Windows_Application/DeDRM_WinApp/DeDRM_lib/lib/k4mutils.py
DeDRM_Windows_Application/ReadMe_DeDRM_WinApp.txt
KindleBooks_Tools/KindleBooks/KindleBooks.pyw
KindleBooks_Tools/KindleBooks/lib/flatxml2html.py
KindleBooks_Tools/KindleBooks/lib/k4mobidedrm.py
KindleBooks_Tools/KindleBooks/lib/k4mutils.py
ePub_Fixer/README_ePub_Fixer.txt
eReader_PDB_Tools/lib/eReaderPDB2PML_plugin.py

index 81d93bc89fb3a90d53ea651fee7ef985cf0f03d5..ae2c8dd8021def8f78baf35eb75e960482b4d1e7 100644 (file)
@@ -68,7 +68,7 @@ class DocParser(object):
         ys = []
         gdefs = []
 
-        # get path defintions, positions, dimensions for ecah glyph 
+        # get path defintions, positions, dimensions for each glyph 
         # that makes up the image, and find min x and min y to reposition origin
         minx = -1
         miny = -1
@@ -305,6 +305,15 @@ class DocParser(object):
                 lastGlyph = firstglyphList[last]
             else :
                 lastGlyph = len(gidList)
+
+            # handle case of white sapce paragraphs with no actual glyphs in them
+            # by reverting to text based paragraph
+            if firstGlyph >= lastGlyph:
+                # revert to standard text based paragraph
+                for wordnum in xrange(first, last):
+                    result.append(('ocr', wordnum))
+                return pclass, result
+
             for glyphnum in xrange(firstGlyph, lastGlyph):
                 glyphList.append(glyphnum)
             # include any extratokens if they exist
index 7174e7236a79c1f431c4e8dc6b86909039943800..c852068c1061b61563ad845de6619ac29dd76024 100644 (file)
Binary files a/Calibre_Plugins/eReaderPDB2PML_plugin.zip and b/Calibre_Plugins/eReaderPDB2PML_plugin.zip differ
index ce6945d149640fd95416e60f485d85e48b580d0c..6df9e138658662e7ac03b663fad3d6dbb22f5b6f 100644 (file)
@@ -57,8 +57,9 @@
 #  0.16 - convert to use openssl DES (very very fast) or pure python DES if openssl's libcrypto is not available
 #  0.17 - added support for pycrypto's DES as well
 #  0.18 - on Windows try PyCrypto first and OpenSSL next
+#  0.19 - Modify the interface to allow use of import
 
-__version__='0.18'
+__version__='0.19'
 
 class Unbuffered:
     def __init__(self, stream):
@@ -111,12 +112,14 @@ except ImportError:
     # older Python release
     import sha
     sha1 = lambda s: sha.new(s)
+
 import cgi
 import logging
 
 logging.basicConfig()
 #logging.basicConfig(level=logging.DEBUG)
 
+
 class Sectionizer(object):
     def __init__(self, filename, ident):
         self.contents = file(filename, 'rb').read()
@@ -364,7 +367,7 @@ def cleanPML(pml):
 def convertEreaderToPml(infile, name, cc, outdir):
     if not os.path.exists(outdir):
         os.makedirs(outdir)
-
+    bookname = os.path.splitext(os.path.basename(infile))[0]
     print "   Decoding File"
     sect = Sectionizer(infile, 'PNRdPPrs')
     er = EreaderProcessor(sect.loadSection, name, cc)
@@ -390,6 +393,47 @@ def convertEreaderToPml(infile, name, cc, outdir):
     #     file(os.path.join(outdir, 'bookinfo.txt'),'wb').write(bkinfo)
 
 
+                
+def decryptBook(infile, outdir, name, cc, make_pmlz):
+    if make_pmlz :
+        # ignore specified outdir, use tempdir instead
+        outdir = tempfile.mkdtemp()
+    try:
+        print "Processing..."
+        convertEreaderToPml(infile, name, cc, outdir)
+        if make_pmlz :
+            import zipfile
+            import shutil
+            print "   Creating PMLZ file"
+            zipname = infile[:-4] + '.pmlz'
+            myZipFile = zipfile.ZipFile(zipname,'w',zipfile.ZIP_STORED, False)
+            list = os.listdir(outdir)
+            for file in list:
+                localname = file
+                filePath = os.path.join(outdir,file)
+                if os.path.isfile(filePath):
+                    myZipFile.write(filePath, localname)
+                elif os.path.isdir(filePath):
+                    imageList = os.listdir(filePath)
+                    localimgdir = os.path.basename(filePath)
+                    for image in imageList:
+                        localname = os.path.join(localimgdir,image)
+                        imagePath = os.path.join(filePath,image)
+                        if os.path.isfile(imagePath):
+                            myZipFile.write(imagePath, localname)
+            myZipFile.close()
+            # remove temporary directory
+            shutil.rmtree(outdir, True)
+            print 'output is %s' % zipname
+        else :
+            print 'output in %s' % outdir 
+        print "done"
+    except ValueError, e:
+        print "Error: %s" % e
+        return 1
+    return 0
+
+
 def usage():
     print "Converts DRMed eReader books to PML Source"
     print "Usage:"
@@ -404,8 +448,8 @@ def usage():
     print "  It's enough to enter the last 8 digits of the credit card number"
     return
 
+
 def main(argv=None):
-    global bookname
     try:
         opts, args = getopt.getopt(sys.argv[1:], "h", ["make-pmlz"])
     except getopt.GetoptError, err:
@@ -413,75 +457,27 @@ def main(argv=None):
         usage()
         return 1
     make_pmlz = False
-    zipname = None
     for o, a in opts:
         if o == "-h":
             usage()
             return 0
         elif o == "--make-pmlz":
             make_pmlz = True
-            zipname = ''
     
     print "eRdr2Pml v%s. Copyright (c) 2009 The Dark Reverser" % __version__
 
     if len(args)!=3 and len(args)!=4:
         usage()
         return 1
-    else:
-        if len(args)==3:
-            infile, name, cc = args[0], args[1], args[2]
-            outdir = infile[:-4] + '_Source'
-        elif len(args)==4:
-            infile, outdir, name, cc = args[0], args[1], args[2], args[3]
 
-        if make_pmlz :
-            # ignore specified outdir, use tempdir instead
-            outdir = tempfile.mkdtemp()
-                
-        bookname = os.path.splitext(os.path.basename(infile))[0]
-
-        try:
-            print "Processing..."
-            import time
-            start_time = time.time()
-            convertEreaderToPml(infile, name, cc, outdir)
-
-            if make_pmlz :
-                import zipfile
-                import shutil
-                print "   Creating PMLZ file"
-                zipname = infile[:-4] + '.pmlz'
-                myZipFile = zipfile.ZipFile(zipname,'w',zipfile.ZIP_STORED, False)
-                list = os.listdir(outdir)
-                for file in list:
-                    localname = file
-                    filePath = os.path.join(outdir,file)
-                    if os.path.isfile(filePath):
-                        myZipFile.write(filePath, localname)
-                    elif os.path.isdir(filePath):
-                        imageList = os.listdir(filePath)
-                        localimgdir = os.path.basename(filePath)
-                        for image in imageList:
-                            localname = os.path.join(localimgdir,image)
-                            imagePath = os.path.join(filePath,image)
-                            if os.path.isfile(imagePath):
-                                myZipFile.write(imagePath, localname)
-                myZipFile.close()
-                # remove temporary directory
-                shutil.rmtree(outdir, True)
-
-            end_time = time.time()
-            search_time = end_time - start_time
-            print 'elapsed time: %.2f seconds' % (search_time, ) 
-            if make_pmlz :
-                print 'output is %s' % zipname
-            else :
-                print 'output in %s' % outdir 
-            print "done"
-        except ValueError, e:
-            print "Error: %s" % e
-            return 1
-    return 0
+    if len(args)==3:
+        infile, name, cc = args[0], args[1], args[2]
+        outdir = infile[:-4] + '_Source'
+    elif len(args)==4:
+        infile, outdir, name, cc = args[0], args[1], args[2], args[3]
+
+    return decryptBook(infile, outdir, name, cc, make_pmlz)
+
 
 if __name__ == "__main__":
     sys.exit(main())
index 5ef5c414857509329b3999fa3273073d77c92728..8eba53394f6ccefb0487f472a3eccf4f7f376708 100644 (file)
Binary files a/Calibre_Plugins/ignobleepub_plugin.zip and b/Calibre_Plugins/ignobleepub_plugin.zip differ
index 1e79c26deb7397a2f72e45b17d6b8ae6d48b3d51..50cb51f09af99058cb09ebcdc331149ef6b5918b 100644 (file)
@@ -271,7 +271,7 @@ class IgnobleDeDRM(FileTypePlugin):
                                 Credit given to I <3 Cabbages for the original stand-alone scripts.'
     supported_platforms     = ['linux', 'osx', 'windows']
     author                  = 'DiapDealer'
-    version                 = (0, 1, 3)
+    version                 = (0, 1, 4)
     minimum_calibre_version = (0, 6, 44)  # Compiled python libraries cannot be imported in earlier versions.
     file_types              = set(['epub'])
     on_import               = True
index 40c41d204f033ae058d79dadb010d60cb383c525..4c862a793fd55b6868874ff85fa39ab38aca2782 100644 (file)
@@ -81,23 +81,44 @@ class fixZip:
         # get the zipinfo for each member of the input archive
         # and copy member over to output archive
         # if problems exist with local vs central filename, fix them
-
-        for i, zinfo in enumerate(self.inzip.infolist()):
-            data = None
-            nzinfo = zinfo
-
-            try: 
-                data = self.inzip.read(zinfo)
-            except zipfile.BadZipfile or zipfile.error:
-                local_name = self.getlocalname(zinfo)
-                data = self.getfiledata(zinfo)
-                nzinfo.filename = local_name
-
-            nzinfo.date_time = zinfo.date_time
-            nzinfo.compress_type = zinfo.compress_type
-            nzinfo.flag_bits = 0
-            nzinfo.internal_attr = 0
-            self.outzip.writestr(nzinfo,data)
+        # also fix bad epub compression
+        
+        # write mimetype file first, if present, and with no compression
+        for zinfo in self.inzip.infolist():
+            if zinfo.filename == "mimetype":
+                nzinfo = zinfo
+                try: 
+                    data = self.inzip.read(zinfo.filename)
+                except zipfile.BadZipfile or zipfile.error:
+                    local_name = self.getlocalname(zinfo)
+                    data = self.getfiledata(zinfo)
+                    nzinfo.filename = local_name
+
+                nzinfo.date_time = zinfo.date_time
+                nzinfo.compress_type = zipfile.ZIP_STORED
+                nzinfo.flag_bits = 0
+                nzinfo.internal_attr = 0
+                nzinfo.extra = ""
+                self.outzip.writestr(nzinfo,data)
+                break
+
+        # write the rest of the files
+        for zinfo in self.inzip.infolist():
+            if zinfo.filename != "mimetype":
+                data = None
+                nzinfo = zinfo
+                try: 
+                    data = self.inzip.read(zinfo.filename)
+                except zipfile.BadZipfile or zipfile.error:
+                    local_name = self.getlocalname(zinfo)
+                    data = self.getfiledata(zinfo)
+                    nzinfo.filename = local_name
+
+                nzinfo.date_time = zinfo.date_time
+                nzinfo.compress_type = zinfo.compress_type
+                nzinfo.flag_bits = 0
+                nzinfo.internal_attr = 0
+                self.outzip.writestr(nzinfo,data)
 
         self.bzf.close()
         self.inzip.close()
@@ -111,14 +132,7 @@ def usage():
     """
     
 
-def main(argv=sys.argv):
-    if len(argv)!=3:
-        usage()
-        return 1
-    infile = None
-    outfile = None
-    infile = argv[1]
-    outfile = argv[2]
+def repairBook(infile, outfile):
     if not os.path.exists(infile):
         print "Error: Input Zip File does not exist"
         return 1
@@ -130,6 +144,16 @@ def main(argv=sys.argv):
         print "Error Occurred ", e
         return 2
 
+
+def main(argv=sys.argv):
+    if len(argv)!=3:
+        usage()
+        return 1
+    infile = argv[1]
+    outfile = argv[2]
+    return repairBook(infile, outfile)
+
+
 if __name__ == '__main__' :
     sys.exit(main())
 
index 4a8f8eb18f0c28007b2d56a3afc1b700a90b03f0..6c4d6f62b026bb8a4651e103d8d220e279b2035b 100644 (file)
Binary files a/Calibre_Plugins/ineptepub_plugin.zip and b/Calibre_Plugins/ineptepub_plugin.zip differ
index beb924e5749c6eaf68651b82f9ca52f6574a48b5..e155a3c8b0b44ea4b37188aab5f04497cba4c249 100644 (file)
@@ -371,7 +371,7 @@ class IneptDeDRM(FileTypePlugin):
                                 Credit given to I <3 Cabbages for the original stand-alone scripts.'
     supported_platforms     = ['linux', 'osx', 'windows']
     author                  = 'DiapDealer'
-    version                 = (0, 1, 4)
+    version                 = (0, 1, 5)
     minimum_calibre_version = (0, 6, 44)  # Compiled python libraries cannot be imported in earlier versions.
     file_types              = set(['epub'])
     on_import               = True
index 40c41d204f033ae058d79dadb010d60cb383c525..4c862a793fd55b6868874ff85fa39ab38aca2782 100644 (file)
@@ -81,23 +81,44 @@ class fixZip:
         # get the zipinfo for each member of the input archive
         # and copy member over to output archive
         # if problems exist with local vs central filename, fix them
-
-        for i, zinfo in enumerate(self.inzip.infolist()):
-            data = None
-            nzinfo = zinfo
-
-            try: 
-                data = self.inzip.read(zinfo)
-            except zipfile.BadZipfile or zipfile.error:
-                local_name = self.getlocalname(zinfo)
-                data = self.getfiledata(zinfo)
-                nzinfo.filename = local_name
-
-            nzinfo.date_time = zinfo.date_time
-            nzinfo.compress_type = zinfo.compress_type
-            nzinfo.flag_bits = 0
-            nzinfo.internal_attr = 0
-            self.outzip.writestr(nzinfo,data)
+        # also fix bad epub compression
+        
+        # write mimetype file first, if present, and with no compression
+        for zinfo in self.inzip.infolist():
+            if zinfo.filename == "mimetype":
+                nzinfo = zinfo
+                try: 
+                    data = self.inzip.read(zinfo.filename)
+                except zipfile.BadZipfile or zipfile.error:
+                    local_name = self.getlocalname(zinfo)
+                    data = self.getfiledata(zinfo)
+                    nzinfo.filename = local_name
+
+                nzinfo.date_time = zinfo.date_time
+                nzinfo.compress_type = zipfile.ZIP_STORED
+                nzinfo.flag_bits = 0
+                nzinfo.internal_attr = 0
+                nzinfo.extra = ""
+                self.outzip.writestr(nzinfo,data)
+                break
+
+        # write the rest of the files
+        for zinfo in self.inzip.infolist():
+            if zinfo.filename != "mimetype":
+                data = None
+                nzinfo = zinfo
+                try: 
+                    data = self.inzip.read(zinfo.filename)
+                except zipfile.BadZipfile or zipfile.error:
+                    local_name = self.getlocalname(zinfo)
+                    data = self.getfiledata(zinfo)
+                    nzinfo.filename = local_name
+
+                nzinfo.date_time = zinfo.date_time
+                nzinfo.compress_type = zinfo.compress_type
+                nzinfo.flag_bits = 0
+                nzinfo.internal_attr = 0
+                self.outzip.writestr(nzinfo,data)
 
         self.bzf.close()
         self.inzip.close()
@@ -111,14 +132,7 @@ def usage():
     """
     
 
-def main(argv=sys.argv):
-    if len(argv)!=3:
-        usage()
-        return 1
-    infile = None
-    outfile = None
-    infile = argv[1]
-    outfile = argv[2]
+def repairBook(infile, outfile):
     if not os.path.exists(infile):
         print "Error: Input Zip File does not exist"
         return 1
@@ -130,6 +144,16 @@ def main(argv=sys.argv):
         print "Error Occurred ", e
         return 2
 
+
+def main(argv=sys.argv):
+    if len(argv)!=3:
+        usage()
+        return 1
+    infile = argv[1]
+    outfile = argv[2]
+    return repairBook(infile, outfile)
+
+
 if __name__ == '__main__' :
     sys.exit(main())
 
index eccc1b868ce104a177592c078e2383d5046f78f4..d0b8f2aa656eaee865f581d1cd7c91ad0e7b7de2 100644 (file)
Binary files a/Calibre_Plugins/ineptpdf_plugin.zip and b/Calibre_Plugins/ineptpdf_plugin.zip differ
index 5ef572b264d3575d27fec5a87a42396f0322fa8e..1efffbbc1eb6b3bf84ed514b2d7f70d3d5964b20 100644 (file)
Binary files a/Calibre_Plugins/k4mobidedrm_plugin.zip and b/Calibre_Plugins/k4mobidedrm_plugin.zip differ
index 880690f2f64fc66e49fb02f96913f6f38a49463b..776ca6e2f0636fc6bf2e1d2e9fe92daea91bc156 100644 (file)
@@ -29,7 +29,7 @@ from __future__ import with_statement
 # and import that ZIP into Calibre using its plugin configuration GUI.
 
 
-__version__ = '2.1'
+__version__ = '2.2'
 
 class Unbuffered:
     def __init__(self, stream):
@@ -75,6 +75,7 @@ def zipUpDir(myzip, tempdir,localname):
 # borrowed from calibre from calibre/src/calibre/__init__.py
 # added in removal of non-printing chars
 # and removal of . at start
+# convert spaces to underscores
 def cleanup_name(name):
     _filename_sanitize = re.compile(r'[\xae\0\\|\?\*<":>\+/]')
     substitute='_'
@@ -89,6 +90,7 @@ def cleanup_name(name):
     # Mac and Unix don't like file names that begin with a full stop
     if len(one) > 0 and one[0] == '.':
         one = substitute+one[1:]
+    one = one.replace(' ','_')
     return one
 
 def decryptBook(infile, outdir, k4, kInfoFiles, serials, pids):
@@ -248,7 +250,7 @@ if not __name__ == "__main__" and inCalibre:
                                 Provided by the work of many including DiapDealer, SomeUpdates, IHeartCabbages, CMBDTC, Skindle, DarkReverser, ApprenticeAlf, etc.'
         supported_platforms = ['osx', 'windows', 'linux'] # Platforms this plugin will run on
         author              = 'DiapDealer, SomeUpdates' # The author of this plugin
-        version             = (0, 2, 1)   # The version number of this plugin
+        version             = (0, 2, 2)   # The version number of this plugin
         file_types          = set(['prc','mobi','azw','azw1','tpz']) # The file types that this plugin will be applied to
         on_import           = True # Run this plugin during the import
         priority            = 210  # run this plugin before mobidedrm, k4pcdedrm, k4dedrm
index 1b501ba41a39a1691d1e347ec79e25afca30c85b..5e57701cd37ec0bfa4a0fab0b647ff1a9dcab1cc 100644 (file)
@@ -189,6 +189,6 @@ def openKindleInfo(kInfoFile=None):
            raise DrmException('Error: .kindle-info file can not be found')
        return open(kinfopath,'r')
     else:
-       if not os.path.isfile(kinfoFile):
+       if not os.path.isfile(kInfoFile):
            raise DrmException('Error: kindle-info file can not be found')
         return open(kInfoFile, 'r')
index 62ba3533a7b654eeee53ef57023eb4c1ba61edea..865591507355223e12bf1af9e757e82099e3650b 100644 (file)
Binary files a/DeDRM_Macintosh_Application/DeDRM.app.txt and b/DeDRM_Macintosh_Application/DeDRM.app.txt differ
index 8d56e56e8808987e9407469b9484b6fa99b871df..dba28391b1431b65e7ee6ffd22403cdc20f23480 100644 (file)
@@ -24,7 +24,7 @@
        <key>CFBundleExecutable</key>
        <string>droplet</string>
        <key>CFBundleGetInfoString</key>
-       <string>DeDRM 2.0, Copyright Â© 2010–2011 by Apprentice Alf.</string>
+       <string>DeDRM 2.1, Copyright Â© 2010–2011 by Apprentice Alf and others.</string>
        <key>CFBundleIconFile</key>
        <string>droplet</string>
        <key>CFBundleInfoDictionaryVersion</key>
@@ -34,7 +34,7 @@
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
-       <string>2.0</string>
+       <string>2.1</string>
        <key>CFBundleSignature</key>
        <string>dplt</string>
        <key>LSMinimumSystemVersion</key>
        <true/>
        <key>WindowState</key>
        <dict>
+               <key>dividerCollapsed</key>
+               <true/>
+               <key>eventLogLevel</key>
+               <integer>-1</integer>
                <key>name</key>
                <string>ScriptWindowState</string>
                <key>positionOfDivider</key>
-               <real>709</real>
+               <real>0.0</real>
                <key>savedFrame</key>
-               <string>1617 62 862 788 1440 -150 1680 1050 </string>
+               <string>1578 27 862 788 1440 -150 1680 1050 </string>
                <key>selectedTabView</key>
-               <string>result</string>
+               <string>event log</string>
        </dict>
 </dict>
 </plist>
index 193f3821804402a44c6ffb9d38944abb16919ac9..16313fe16ec1c26549a7814006037555af799240 100644 (file)
Binary files a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/Scripts/main.scpt and b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/Scripts/main.scpt differ
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/cmbtc_v2.2.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/cmbtc_v2.2.py
deleted file mode 100644 (file)
index 764e38d..0000000
+++ /dev/null
@@ -1,900 +0,0 @@
-#! /usr/bin/python
-
-"""
-
-Comprehensive Mazama Book DRM with Topaz Cryptography V2.2
-
------BEGIN PUBLIC KEY-----
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdBHJ4CNc6DNFCw4MRCw4SWAK6
-M8hYfnNEI0yQmn5Ti+W8biT7EatpauE/5jgQMPBmdNrDr1hbHyHBSP7xeC2qlRWC
-B62UCxeu/fpfnvNHDN/wPWWH4jynZ2M6cdcnE5LQ+FfeKqZn7gnG2No1U9h7oOHx
-y2/pHuYme7U1TsgSjwIDAQAB
------END PUBLIC KEY-----
-
-"""
-
-from __future__ import with_statement
-
-import csv
-import sys
-import os
-import getopt
-import zlib
-from struct import pack
-from struct import unpack
-from ctypes import windll, c_char_p, c_wchar_p, c_uint, POINTER, byref, \
-    create_unicode_buffer, create_string_buffer, CFUNCTYPE, addressof, \
-    string_at, Structure, c_void_p, cast
-import _winreg as winreg
-import Tkinter
-import Tkconstants
-import tkMessageBox
-import traceback
-import hashlib
-
-MAX_PATH = 255
-
-kernel32 = windll.kernel32
-advapi32 = windll.advapi32
-crypt32 = windll.crypt32
-
-global kindleDatabase
-global bookFile
-global bookPayloadOffset
-global bookHeaderRecords
-global bookMetadata
-global bookKey
-global command
-
-#
-# Various character maps used to decrypt books. Probably supposed to act as obfuscation
-#
-
-charMap1 = "n5Pr6St7Uv8Wx9YzAb0Cd1Ef2Gh3Jk4M"
-charMap2 = "AaZzB0bYyCc1XxDdW2wEeVv3FfUuG4g-TtHh5SsIiR6rJjQq7KkPpL8lOoMm9Nn_"
-charMap3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
-charMap4 = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789"
-
-#
-# Exceptions for all the problems that might happen during the script
-#
-
-class CMBDTCError(Exception):
-    pass
-    
-class CMBDTCFatal(Exception):
-    pass
-    
-#
-# Stolen stuff
-#
-
-class DataBlob(Structure):
-    _fields_ = [('cbData', c_uint),
-                ('pbData', c_void_p)]
-DataBlob_p = POINTER(DataBlob)
-
-def GetSystemDirectory():
-    GetSystemDirectoryW = kernel32.GetSystemDirectoryW
-    GetSystemDirectoryW.argtypes = [c_wchar_p, c_uint]
-    GetSystemDirectoryW.restype = c_uint
-    def GetSystemDirectory():
-        buffer = create_unicode_buffer(MAX_PATH + 1)
-        GetSystemDirectoryW(buffer, len(buffer))
-        return buffer.value
-    return GetSystemDirectory
-GetSystemDirectory = GetSystemDirectory()
-
-
-def GetVolumeSerialNumber():
-    GetVolumeInformationW = kernel32.GetVolumeInformationW
-    GetVolumeInformationW.argtypes = [c_wchar_p, c_wchar_p, c_uint,
-                                      POINTER(c_uint), POINTER(c_uint),
-                                      POINTER(c_uint), c_wchar_p, c_uint]
-    GetVolumeInformationW.restype = c_uint
-    def GetVolumeSerialNumber(path):
-        vsn = c_uint(0)
-        GetVolumeInformationW(path, None, 0, byref(vsn), None, None, None, 0)
-        return vsn.value
-    return GetVolumeSerialNumber
-GetVolumeSerialNumber = GetVolumeSerialNumber()
-
-
-def GetUserName():
-    GetUserNameW = advapi32.GetUserNameW
-    GetUserNameW.argtypes = [c_wchar_p, POINTER(c_uint)]
-    GetUserNameW.restype = c_uint
-    def GetUserName():
-        buffer = create_unicode_buffer(32)
-        size = c_uint(len(buffer))
-        while not GetUserNameW(buffer, byref(size)):
-            buffer = create_unicode_buffer(len(buffer) * 2)
-            size.value = len(buffer)
-        return buffer.value.encode('utf-16-le')[::2]
-    return GetUserName
-GetUserName = GetUserName()
-
-
-def CryptUnprotectData():
-    _CryptUnprotectData = crypt32.CryptUnprotectData
-    _CryptUnprotectData.argtypes = [DataBlob_p, c_wchar_p, DataBlob_p,
-                                   c_void_p, c_void_p, c_uint, DataBlob_p]
-    _CryptUnprotectData.restype = c_uint
-    def CryptUnprotectData(indata, entropy):
-        indatab = create_string_buffer(indata)
-        indata = DataBlob(len(indata), cast(indatab, c_void_p))
-        entropyb = create_string_buffer(entropy)
-        entropy = DataBlob(len(entropy), cast(entropyb, c_void_p))
-        outdata = DataBlob()
-        if not _CryptUnprotectData(byref(indata), None, byref(entropy),
-                                   None, None, 0, byref(outdata)):
-            raise CMBDTCFatal("Failed to Unprotect Data")
-        return string_at(outdata.pbData, outdata.cbData)
-    return CryptUnprotectData
-CryptUnprotectData = CryptUnprotectData()
-
-#
-# Returns the MD5 digest of "message"
-#
-
-def MD5(message):
-    ctx = hashlib.md5()
-    ctx.update(message)
-    return ctx.digest()
-
-#
-# Returns the MD5 digest of "message"
-#
-
-def SHA1(message):
-    ctx = hashlib.sha1()
-    ctx.update(message)
-    return ctx.digest()
-
-#
-# Open the book file at path
-#
-
-def openBook(path):
-    try:
-        return open(path,'rb')
-    except:
-        raise CMBDTCFatal("Could not open book file: " + path)
-#
-# Encode the bytes in data with the characters in map
-#
-
-def encode(data, map):
-    result = ""
-    for char in data:
-        value = ord(char)
-        Q = (value ^ 0x80) // len(map)
-        R = value % len(map)
-        result += map[Q]
-        result += map[R]
-    return result
-  
-#
-# Hash the bytes in data and then encode the digest with the characters in map
-#
-  
-def encodeHash(data,map):
-    return encode(MD5(data),map)
-
-#
-# Decode the string in data with the characters in map. Returns the decoded bytes
-#
-   
-def decode(data,map):
-    result = ""
-    for i in range (0,len(data),2):
-        high = map.find(data[i])
-        low = map.find(data[i+1])
-        value = (((high * 0x40) ^ 0x80) & 0xFF) + low
-        result += pack("B",value)
-    return result
-  
-#
-# Locate and open the Kindle.info file (Hopefully in the way it is done in the Kindle application)
-#
-  
-def openKindleInfo():
-    regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\")
-    path = winreg.QueryValueEx(regkey, 'Local AppData')[0] 
-    return open(path+'\\Amazon\\Kindle For PC\\{AMAwzsaPaaZAzmZzZQzgZCAkZ3AjA_AY}\\kindle.info','r')
-
-#
-# Parse the Kindle.info file and return the records as a list of key-values
-#
-
-def parseKindleInfo():
-    DB = {}
-    infoReader = openKindleInfo()
-    infoReader.read(1)
-    data = infoReader.read()
-    items = data.split('{')
-    
-    for item in items:
-        splito = item.split(':')
-        DB[splito[0]] =splito[1]
-    return DB
-
-#
-# Find if the original string for a hashed/encoded string is known. If so return the original string othwise return an empty string. (Totally not optimal)
-#
-def findNameForHash(hash):
-    names = ["kindle.account.tokens","kindle.cookie.item","eulaVersionAccepted","login_date","kindle.token.item","login","kindle.key.item","kindle.name.info","kindle.device.info", "MazamaRandomNumber"]
-    result = ""
-    for name in names:
-        if hash == encodeHash(name, charMap2):
-           result = name
-           break
-    return name
-    
-#
-# Print all the records from the kindle.info file (option -i)
-#
-    
-def printKindleInfo():
-    for record in kindleDatabase:
-        name = findNameForHash(record)
-        if name != "" :
-            print (name)
-            print ("--------------------------\n")
-        else :
-            print ("Unknown Record")
-        print getKindleInfoValueForHash(record)
-        print "\n"
-#
-# Get a record from the Kindle.info file for the key "hashedKey" (already hashed and encoded). Return the decoded and decrypted record
-#
-
-def getKindleInfoValueForHash(hashedKey):
-    global kindleDatabase
-    encryptedValue = decode(kindleDatabase[hashedKey],charMap2)
-    return CryptUnprotectData(encryptedValue,"")
-#
-#  Get a record from the Kindle.info file for the string in "key" (plaintext). Return the decoded and decrypted record
-#
-   
-def getKindleInfoValueForKey(key):
-    return getKindleInfoValueForHash(encodeHash(key,charMap2))
-  
-#
-# Get a 7 bit encoded number from the book file
-#
-
-def bookReadEncodedNumber():
-    flag = False
-    data = ord(bookFile.read(1))
-    
-    if data == 0xFF:
-       flag = True
-       data = ord(bookFile.read(1))
-       
-    if data >= 0x80:
-        datax = (data & 0x7F)
-        while data >= 0x80 :
-            data = ord(bookFile.read(1))
-            datax = (datax <<7) + (data & 0x7F)
-        data = datax 
-    
-    if flag:
-       data = -data
-    return data
-    
-#
-# Encode a number in 7 bit format
-#
-
-def encodeNumber(number):
-   result = ""
-   negative = False
-   flag = 0
-   
-   if number < 0 :
-       number = -number + 1
-       negative = True
-   
-   while True:
-       byte = number & 0x7F
-       number = number >> 7
-       byte += flag
-       result += chr(byte)
-       flag = 0x80
-       if number == 0 : 
-           if (byte == 0xFF and negative == False) :
-               result += chr(0x80)
-           break
-   
-   if negative:
-       result += chr(0xFF)
-   
-   return result[::-1]
-  
-#
-# Get a length prefixed string from the file 
-#
-
-def bookReadString():
-    stringLength = bookReadEncodedNumber()
-    return unpack(str(stringLength)+"s",bookFile.read(stringLength))[0]  
-    
-#
-# Returns a length prefixed string
-#
-
-def lengthPrefixString(data):
-    return encodeNumber(len(data))+data
-    
-
-#
-# Read and return the data of one header record at the current book file position [[offset,compressedLength,decompressedLength],...]
-#
-    
-def bookReadHeaderRecordData():
-    nbValues = bookReadEncodedNumber()
-    values = []
-    for i in range (0,nbValues):
-        values.append([bookReadEncodedNumber(),bookReadEncodedNumber(),bookReadEncodedNumber()])
-    return values
-   
-#
-# Read and parse one header record at the current book file position and return the associated data [[offset,compressedLength,decompressedLength],...]
-#
-
-def parseTopazHeaderRecord():
-    if ord(bookFile.read(1)) != 0x63:
-        raise CMBDTCFatal("Parse Error : Invalid Header")
-    
-    tag = bookReadString()
-    record = bookReadHeaderRecordData()
-    return [tag,record]
-
-#
-# Parse the header of a Topaz file, get all the header records and the offset for the payload
-#
-def parseTopazHeader():
-    global bookHeaderRecords
-    global bookPayloadOffset
-    magic = unpack("4s",bookFile.read(4))[0]
-    
-    if magic != 'TPZ0':
-        raise CMBDTCFatal("Parse Error : Invalid Header, not a Topaz file")
-        
-    nbRecords = bookReadEncodedNumber()
-    bookHeaderRecords = {}
-   
-    for i in range (0,nbRecords):
-        result = parseTopazHeaderRecord()
-        bookHeaderRecords[result[0]] = result[1]
-    
-    if ord(bookFile.read(1))  != 0x64 :
-        raise CMBDTCFatal("Parse Error : Invalid Header")
-    
-    bookPayloadOffset = bookFile.tell()
-   
-#
-# Get a record in the book payload, given its name and index. If necessary the record is decrypted. The record is not decompressed
-#
-
-def getBookPayloadRecord(name, index):   
-    encrypted = False
-    
-    try: 
-        recordOffset = bookHeaderRecords[name][index][0]
-    except:
-        raise CMBDTCFatal("Parse Error : Invalid Record, record not found")
-    
-    bookFile.seek(bookPayloadOffset + recordOffset)
-    
-    tag = bookReadString()
-    if tag != name :
-        raise CMBDTCFatal("Parse Error : Invalid Record, record name doesn't match")
-    
-    recordIndex = bookReadEncodedNumber()
-    
-    if recordIndex < 0 :
-        encrypted = True
-        recordIndex = -recordIndex -1
-    
-    if recordIndex != index :
-      raise CMBDTCFatal("Parse Error : Invalid Record, index doesn't match")
-
-    if bookHeaderRecords[name][index][2] != 0 :
-        record = bookFile.read(bookHeaderRecords[name][index][2])
-    else:
-        record = bookFile.read(bookHeaderRecords[name][index][1])
-    
-    if encrypted:
-       ctx = topazCryptoInit(bookKey)
-       record = topazCryptoDecrypt(record,ctx)
-    
-    return record
-
-#
-# Extract, decrypt and decompress a book record indicated by name and index and print it or save it in "filename"
-#
-
-def extractBookPayloadRecord(name, index, filename):
-    compressed = False
-
-    try:
-        compressed = bookHeaderRecords[name][index][2] != 0
-        record = getBookPayloadRecord(name,index)
-    except:
-        print("Could not find record")
-    
-    if compressed:
-        try:
-            record = zlib.decompress(record)
-        except:
-            raise CMBDTCFatal("Could not decompress record")
-            
-    if filename != "":
-        try:
-            file = open(filename,"wb")
-            file.write(record)
-            file.close()
-        except:
-            raise CMBDTCFatal("Could not write to destination file")
-    else:
-        print(record)
-    
-#
-# return next record [key,value] from the book metadata from the current book position
-#  
-
-def readMetadataRecord():
-    return [bookReadString(),bookReadString()]
-    
-#
-# Parse the metadata record from the book payload and return a list of [key,values]
-#
-
-def parseMetadata():
-    global bookHeaderRecords
-    global bookPayloadAddress
-    global bookMetadata
-    bookMetadata = {}
-    bookFile.seek(bookPayloadOffset + bookHeaderRecords["metadata"][0][0])
-    tag = bookReadString()
-    if tag != "metadata" :
-        raise CMBDTCFatal("Parse Error : Record Names Don't Match")
-    
-    flags = ord(bookFile.read(1))
-    nbRecords = ord(bookFile.read(1))
-    
-    for i in range (0,nbRecords) :
-        record =readMetadataRecord()
-        bookMetadata[record[0]] = record[1]
-
-#
-# Returns two bit at offset from a bit field
-#
-   
-def getTwoBitsFromBitField(bitField,offset):
-    byteNumber = offset // 4
-    bitPosition = 6 - 2*(offset % 4)
-    
-    return ord(bitField[byteNumber]) >> bitPosition & 3
-
-#
-# Returns the six bits at offset from a bit field
-#    
-
-def getSixBitsFromBitField(bitField,offset):
-     offset *= 3
-     value = (getTwoBitsFromBitField(bitField,offset) <<4) + (getTwoBitsFromBitField(bitField,offset+1) << 2) +getTwoBitsFromBitField(bitField,offset+2)
-     return value
-     
-#
-# 8 bits to six bits encoding from hash to generate PID string
-#
-
-def encodePID(hash):
-    global charMap3
-    PID = ""
-    for position in range (0,8):
-        PID += charMap3[getSixBitsFromBitField(hash,position)]
-    return PID
-    
-#
-# Context initialisation for the Topaz Crypto
-#
-
-def topazCryptoInit(key):
-    ctx1 = 0x0CAFFE19E
-    
-    for keyChar in key:
-        keyByte = ord(keyChar)
-        ctx2 = ctx1 
-        ctx1 = ((((ctx1 >>2) * (ctx1 >>7))&0xFFFFFFFF) ^ (keyByte * keyByte * 0x0F902007)& 0xFFFFFFFF )
-    return [ctx1,ctx2]
-    
-#
-# decrypt data with the context prepared by topazCryptoInit()
-#
-    
-def topazCryptoDecrypt(data, ctx):
-    ctx1 = ctx[0]
-    ctx2 = ctx[1]
-    
-    plainText = ""
-    
-    for dataChar in data:
-        dataByte = ord(dataChar)
-        m = (dataByte ^ ((ctx1 >> 3) &0xFF) ^ ((ctx2<<3) & 0xFF)) &0xFF
-        ctx2 = ctx1
-        ctx1 = (((ctx1 >> 2) * (ctx1 >> 7)) &0xFFFFFFFF) ^((m * m * 0x0F902007) &0xFFFFFFFF)
-        plainText += chr(m)
-        
-    return plainText
-
-#
-# Decrypt a payload record with the PID
-#
-
-def decryptRecord(data,PID):
-    ctx = topazCryptoInit(PID)
-    return topazCryptoDecrypt(data, ctx)
-
-#
-# Try to decrypt a dkey record (contains the book PID)
-#
-
-def decryptDkeyRecord(data,PID):
-    record = decryptRecord(data,PID)
-    fields = unpack("3sB8sB8s3s",record)
-    
-    if fields[0] != "PID" or fields[5] != "pid" :
-        raise CMBDTCError("Didn't find PID magic numbers in record")
-    elif fields[1] != 8 or fields[3] != 8 :
-        raise CMBDTCError("Record didn't contain correct length fields")
-    elif fields[2] != PID :
-        raise CMBDTCError("Record didn't contain PID")
-    
-    return fields[4]
-    
-#
-# Decrypt all the book's dkey records (contain the book PID)
-#
-  
-def decryptDkeyRecords(data,PID):
-    nbKeyRecords = ord(data[0])
-    records = []
-    data = data[1:]
-    for i in range (0,nbKeyRecords):
-        length = ord(data[0])
-        try:
-            key = decryptDkeyRecord(data[1:length+1],PID)
-            records.append(key)
-        except CMBDTCError:
-            pass
-        data = data[1+length:]
-        
-    return records
-    
-#
-# Encryption table used to generate the device PID
-#
-    
-def generatePidEncryptionTable() :
-    table = []
-    for counter1 in range (0,0x100):
-        value = counter1
-        for counter2 in range (0,8):
-            if (value & 1 == 0) :
-                value = value >> 1
-            else :
-                value = value >> 1
-                value = value ^ 0xEDB88320
-        table.append(value)
-    return table
-#
-# Seed value used to generate the device PID
-#
-   
-def generatePidSeed(table,dsn) :
-    value = 0
-    for counter in range (0,4) :
-       index = (ord(dsn[counter]) ^ value) &0xFF
-       value = (value >> 8) ^ table[index]
-    return value
-   
-#
-# Generate the device PID
-#
-
-def generateDevicePID(table,dsn,nbRoll):
-    seed = generatePidSeed(table,dsn)
-    pidAscii = ""
-    pid = [(seed >>24) &0xFF,(seed >> 16) &0xff,(seed >> 8) &0xFF,(seed) & 0xFF,(seed>>24) & 0xFF,(seed >> 16) &0xff,(seed >> 8) &0xFF,(seed) & 0xFF]
-    index = 0
-    
-    for counter in range (0,nbRoll):
-        pid[index] = pid[index] ^ ord(dsn[counter])
-        index = (index+1) %8
-    for counter in range (0,8):
-        index = ((((pid[counter] >>5) & 3) ^ pid[counter]) & 0x1f) + (pid[counter] >> 7)
-        pidAscii += charMap4[index]
-    return pidAscii
-    
-#
-# Create decrypted book payload
-#
-
-def createDecryptedPayload(payload):
-   
-   # store data to be able to create the header later 
-    headerData= []
-    currentOffset = 0
-   
-    # Add social DRM to decrypted files
-    
-    try:
-        data = getKindleInfoValueForKey("kindle.name.info")+":"+ getKindleInfoValueForKey("login")
-        if payload!= None:
-            payload.write(lengthPrefixString("sdrm"))
-            payload.write(encodeNumber(0))
-            payload.write(data)
-        else:
-            currentOffset += len(lengthPrefixString("sdrm"))
-            currentOffset += len(encodeNumber(0))
-            currentOffset += len(data)
-    except:
-        pass
-    
-    for headerRecord in bookHeaderRecords:
-       name = headerRecord
-       newRecord = []
-
-       if name != "dkey" :
-       
-           for index in range (0,len(bookHeaderRecords[name])) :
-               offset = currentOffset
-               
-               if payload != None: 
-                   # write tag
-                   payload.write(lengthPrefixString(name))
-                   # write data
-                   payload.write(encodeNumber(index))
-                   payload.write(getBookPayloadRecord(name, index))
-                   
-               else :
-                   currentOffset += len(lengthPrefixString(name))
-                   currentOffset += len(encodeNumber(index))
-                   currentOffset += len(getBookPayloadRecord(name, index))
-                   newRecord.append([offset,bookHeaderRecords[name][index][1],bookHeaderRecords[name][index][2]])
-               
-       headerData.append([name,newRecord])
-       
-
-    return headerData    
-           
-#
-# Create decrypted book
-#
-
-def createDecryptedBook(outputFile):
-    outputFile = open(outputFile,"wb")
-    # Write the payload in a temporary file
-    headerData = createDecryptedPayload(None)
-    outputFile.write("TPZ0")
-    outputFile.write(encodeNumber(len(headerData)))
-    
-    for header in headerData :
-        outputFile.write(chr(0x63))
-        outputFile.write(lengthPrefixString(header[0]))
-        outputFile.write(encodeNumber(len(header[1])))
-        for numbers in header[1] :
-            outputFile.write(encodeNumber(numbers[0]))
-            outputFile.write(encodeNumber(numbers[1]))
-            outputFile.write(encodeNumber(numbers[2]))
-            
-    outputFile.write(chr(0x64))
-    createDecryptedPayload(outputFile)
-    outputFile.close()
-
-#
-# Set the command to execute by the programm according to cmdLine parameters
-#
-
-def setCommand(name) :
-    global command
-    if command != "" :
-         raise CMBDTCFatal("Invalid command line parameters")
-    else :
-        command = name
-
-# 
-# Program usage
-#
-   
-def usage():
-    print("\nUsage:")
-    print("\nCMBDTC.py [options] bookFileName\n")
-    print("-p Adds a PID to the list of PIDs that are tried to decrypt the book key (can be used several times)")
-    print("-d Saves a decrypted copy of the book")
-    print("-r Prints or writes to disk a record indicated in the form name:index (e.g \"img:0\")")
-    print("-o Output file name to write records and decrypted books")
-    print("-v Verbose (can be used several times)")
-    print("-i Prints kindle.info database")
-#
-# Main
-#   
-
-def main(argv=sys.argv):
-    global kindleDatabase
-    global bookMetadata
-    global bookKey
-    global bookFile
-    global command
-    
-    progname = os.path.basename(argv[0])
-    
-    verbose = 0
-    recordName = ""
-    recordIndex = 0
-    outputFile = ""
-    PIDs = []
-    kindleDatabase = None
-    command = ""
-    
-    
-    try:
-        opts, args = getopt.getopt(sys.argv[1:], "vdir:o:p:")
-    except getopt.GetoptError, err:
-        # print help information and exit:
-        print str(err) # will print something like "option -a not recognized"
-        usage()
-        sys.exit(2)
-    
-    if len(opts) == 0 and len(args) == 0 :
-        usage()
-        sys.exit(2) 
-       
-    for o, a in opts:
-        if o == "-v":
-            verbose+=1
-        if o == "-i":
-            setCommand("printInfo")
-        if o =="-o":
-            if a == None :
-                raise CMBDTCFatal("Invalid parameter for -o")
-            outputFile = a
-        if o =="-r":
-            setCommand("printRecord")
-            try:
-                recordName,recordIndex = a.split(':')
-            except:
-                raise CMBDTCFatal("Invalid parameter for -r")
-        if o =="-p":
-            PIDs.append(a)
-        if o =="-d":
-            setCommand("doit")
-            
-    if command == "" :
-        raise CMBDTCFatal("No action supplied on command line")
-   
-    #
-    # Read the encrypted database
-    #
-    
-    try:
-        kindleDatabase = parseKindleInfo()
-    except Exception, message:
-        if verbose>0:
-            print(message)
-    
-    if kindleDatabase != None :
-        if command == "printInfo" :
-            printKindleInfo()
-     
-    #
-    # Compute the DSN
-    #
-    
-    # Get the Mazama Random number
-        MazamaRandomNumber = getKindleInfoValueForKey("MazamaRandomNumber")
-    
-    # Get the HDD serial
-        encodedSystemVolumeSerialNumber = encodeHash(str(GetVolumeSerialNumber(GetSystemDirectory().split('\\')[0] + '\\')),charMap1)
-    
-    # Get the current user name
-        encodedUsername = encodeHash(GetUserName(),charMap1)
-    
-    # concat, hash and encode
-        DSN = encode(SHA1(MazamaRandomNumber+encodedSystemVolumeSerialNumber+encodedUsername),charMap1)
-       
-        if verbose >1:
-            print("DSN: " + DSN)
-    
-    #
-    # Compute the device PID
-    #
-     
-        table =  generatePidEncryptionTable()
-        devicePID = generateDevicePID(table,DSN,4)
-        PIDs.append(devicePID)
-    
-        if verbose > 0:
-            print("Device PID: " + devicePID)
-    
-    #
-    # Open book and parse metadata
-    #
-        
-    if len(args) == 1:
-    
-        bookFile = openBook(args[0])
-        parseTopazHeader()
-        parseMetadata()
-    
-    #
-    # Compute book PID
-    # 
-    
-    # Get the account token
-    
-        if kindleDatabase != None:
-            kindleAccountToken = getKindleInfoValueForKey("kindle.account.tokens")
-    
-            if verbose >1:
-                print("Account Token: " + kindleAccountToken)
-
-            keysRecord = bookMetadata["keys"]
-            keysRecordRecord = bookMetadata[keysRecord]
-    
-            pidHash = SHA1(DSN+kindleAccountToken+keysRecord+keysRecordRecord)
-   
-            bookPID = encodePID(pidHash)
-            PIDs.append(bookPID)
-    
-            if verbose > 0:
-                print ("Book PID: " + bookPID )
-    
-    #
-    #  Decrypt book key
-    #
-    
-        dkey = getBookPayloadRecord('dkey', 0) 
-        
-        bookKeys = []
-        for PID in PIDs :
-            bookKeys+=decryptDkeyRecords(dkey,PID)
-            
-        if len(bookKeys) == 0 :
-            if verbose > 0 :
-                print ("Book key could not be found. Maybe this book is not registered with this device.")
-        else :
-            bookKey = bookKeys[0]
-            if verbose > 0:
-                print("Book key: " + bookKey.encode('hex'))
-                
-            
-                  
-            if command == "printRecord" :
-                extractBookPayloadRecord(recordName,int(recordIndex),outputFile)
-                if outputFile != "" and verbose>0 :
-                    print("Wrote record to file: "+outputFile) 
-            elif command == "doit" :
-                if outputFile!="" :
-                    createDecryptedBook(outputFile)
-                    if verbose >0 :
-                        print ("Decrypted book saved. Don't pirate!")
-                elif verbose > 0:
-                    print("Output file name was not supplied.")
-    
-    return 0
-
-if __name__ == '__main__':
-    sys.exit(main())
-
index 0f8be61c4ef5a03538444534b5d6fddd1d0162af..33192eae3ef01b4c6e7ec4f66810ff0a2f3a6d75 100644 (file)
@@ -1,4 +1,4 @@
-{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf540
+{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350
 {\fonttbl}
 {\colortbl;\red255\green255\blue255;}
 }
\ No newline at end of file
index 81d93bc89fb3a90d53ea651fee7ef985cf0f03d5..ae2c8dd8021def8f78baf35eb75e960482b4d1e7 100644 (file)
@@ -68,7 +68,7 @@ class DocParser(object):
         ys = []
         gdefs = []
 
-        # get path defintions, positions, dimensions for ecah glyph 
+        # get path defintions, positions, dimensions for each glyph 
         # that makes up the image, and find min x and min y to reposition origin
         minx = -1
         miny = -1
@@ -305,6 +305,15 @@ class DocParser(object):
                 lastGlyph = firstglyphList[last]
             else :
                 lastGlyph = len(gidList)
+
+            # handle case of white sapce paragraphs with no actual glyphs in them
+            # by reverting to text based paragraph
+            if firstGlyph >= lastGlyph:
+                # revert to standard text based paragraph
+                for wordnum in xrange(first, last):
+                    result.append(('ocr', wordnum))
+                return pclass, result
+
             for glyphnum in xrange(firstGlyph, lastGlyph):
                 glyphList.append(glyphnum)
             # include any extratokens if they exist
diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/genxml.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/genxml.py
deleted file mode 100644 (file)
index be542f0..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-#! /usr/bin/python
-# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
-# For use with Topaz Scripts Version 2.6
-
-class Unbuffered:
-    def __init__(self, stream):
-        self.stream = stream
-    def write(self, data):
-        self.stream.write(data)
-        self.stream.flush()
-    def __getattr__(self, attr):
-        return getattr(self.stream, attr)
-
-import sys
-sys.stdout=Unbuffered(sys.stdout)
-
-
-import os, getopt
-
-# local routines
-import convert2xml
-import flatxml2html
-import decode_meta
-
-
-def usage():
-    print 'Usage: '
-    print ' '
-    print '   genxml.py dict0000.dat unencryptedBookDir'
-    print '  '
-
-
-
-def main(argv):
-    bookDir = ''
-
-    if len(argv) == 0:
-        argv = sys.argv
-
-    try:
-        opts, args = getopt.getopt(argv[1:], "h:")
-
-    except getopt.GetoptError, err:
-        print str(err)
-        usage()
-        sys.exit(1)
-    
-    if len(opts) == 0 and len(args) == 0 :
-        usage()
-        sys.exit(1) 
-       
-    for o, a in opts:
-        if o =="-h":
-            usage()
-            sys.exit(0)
-
-    bookDir = args[0]
-
-    if not os.path.exists(bookDir) :
-        print "Can not find directory with unencrypted book"
-        sys.exit(1)
-
-    dictFile = os.path.join(bookDir,'dict0000.dat')
-    if not os.path.exists(dictFile) :
-        print "Can not find dict0000.dat file"
-        sys.exit(1)
-
-    pageDir = os.path.join(bookDir,'page')
-    if not os.path.exists(pageDir) :
-        print "Can not find page directory in unencrypted book"
-        sys.exit(1)
-
-    glyphsDir = os.path.join(bookDir,'glyphs')
-    if not os.path.exists(glyphsDir) :
-        print "Can not find glyphs directory in unencrypted book"
-        sys.exit(1)
-
-    otherFile = os.path.join(bookDir,'other0000.dat')
-    if not os.path.exists(otherFile) :
-        print "Can not find other0000.dat in unencrypted book"
-        sys.exit(1)
-
-    metaFile = os.path.join(bookDir,'metadata0000.dat')
-    if not os.path.exists(metaFile) :
-        print "Can not find metadata0000.dat in unencrypted book"
-        sys.exit(1)
-
-    xmlDir = os.path.join(bookDir,'xml')
-    if not os.path.exists(xmlDir):
-        os.makedirs(xmlDir)
-
-
-    print 'Processing ... '
-
-    print '     ', 'metadata0000.dat'
-    fname = os.path.join(bookDir,'metadata0000.dat')
-    xname = os.path.join(xmlDir, 'metadata.txt')
-    metastr = decode_meta.getMetaData(fname)
-    file(xname, 'wb').write(metastr)
-
-    print '     ', 'other0000.dat'
-    fname = os.path.join(bookDir,'other0000.dat')
-    xname = os.path.join(xmlDir, 'stylesheet.xml')
-    pargv=[]
-    pargv.append('convert2xml.py')
-    pargv.append(dictFile)
-    pargv.append(fname)
-    xmlstr = convert2xml.main(pargv)
-    file(xname, 'wb').write(xmlstr)
-    
-    filenames = os.listdir(pageDir)
-    filenames = sorted(filenames)
-
-    for filename in filenames:
-        print '     ', filename
-        fname = os.path.join(pageDir,filename)
-        xname = os.path.join(xmlDir, filename.replace('.dat','.xml'))
-        pargv=[]
-        pargv.append('convert2xml.py')
-        pargv.append(dictFile)
-        pargv.append(fname)
-        xmlstr = convert2xml.main(pargv)
-        file(xname, 'wb').write(xmlstr)
-
-    filenames = os.listdir(glyphsDir)
-    filenames = sorted(filenames)
-
-    for filename in filenames:
-        print '     ', filename
-        fname = os.path.join(glyphsDir,filename)
-        xname = os.path.join(xmlDir, filename.replace('.dat','.xml'))
-        pargv=[]
-        pargv.append('convert2xml.py')
-        pargv.append(dictFile)
-        pargv.append(fname)
-        xmlstr = convert2xml.main(pargv)
-        file(xname, 'wb').write(xmlstr)
-
-    print 'Processing Complete'
-
-    return 0
-
-if __name__ == '__main__':
-    sys.exit(main(''))
similarity index 98%
rename from DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignobleepub.pyw
rename to DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignobleepub.py
index 0afc2bc521a13a0420addfc019a92fdbc5bb4484..a7c48c9620d0f3442b0903e76e36c36a305f1fc9 100644 (file)
@@ -1,6 +1,8 @@
 #! /usr/bin/python
 
-# ignobleepub.pyw, version 3.3
+from __future__ import with_statement
+
+# ignobleepub.pyw, version 3.4
 
 # To run this program install Python 2.6 from <http://www.python.org/download/>
 # and OpenSSL or PyCrypto from http://www.voidspace.org.uk/python/modules.shtml#pycrypto
 #   3.1 - Allow Windows versions of libcrypto to be found
 #   3.2 - add support for encoding to 'utf-8' when building up list of files to cecrypt from encryption.xml 
 #   3.3 - On Windows try PyCrypto first and OpenSSL next
+#   3.4 - Modify interace to allow use with import
 
 
-from __future__ import with_statement
-
 __license__ = 'GPL v3'
 
 import sys
@@ -170,49 +171,6 @@ class Decryptor(object):
         return data
 
 
-
-def cli_main(argv=sys.argv):
-    progname = os.path.basename(argv[0])
-    if AES is None:
-        print "%s: This script requires OpenSSL or PyCrypto, which must be installed " \
-              "separately.  Read the top-of-script comment for details." % \
-              (progname,)
-        return 1
-    if len(argv) != 4:
-        print "usage: %s KEYFILE INBOOK OUTBOOK" % (progname,)
-        return 1
-    keypath, inpath, outpath = argv[1:]
-    with open(keypath, 'rb') as f:
-        keyb64 = f.read()
-    key = keyb64.decode('base64')[:16]
-    # aes = AES.new(key, AES.MODE_CBC)
-    aes = AES(key)
-
-    with closing(ZipFile(open(inpath, 'rb'))) as inf:
-        namelist = set(inf.namelist())
-        if 'META-INF/rights.xml' not in namelist or \
-           'META-INF/encryption.xml' not in namelist:
-            raise IGNOBLEError('%s: not an B&N ADEPT EPUB' % (inpath,))
-        for name in META_NAMES:
-            namelist.remove(name)
-        rights = etree.fromstring(inf.read('META-INF/rights.xml'))
-        adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag)
-        expr = './/%s' % (adept('encryptedKey'),)
-        bookkey = ''.join(rights.findtext(expr))
-        bookkey = aes.decrypt(bookkey.decode('base64'))
-        bookkey = bookkey[:-ord(bookkey[-1])]
-        encryption = inf.read('META-INF/encryption.xml')
-        decryptor = Decryptor(bookkey[-16:], encryption)
-        kwds = dict(compression=ZIP_DEFLATED, allowZip64=False)
-        with closing(ZipFile(open(outpath, 'wb'), 'w', **kwds)) as outf:
-            zi = ZipInfo('mimetype', compress_type=ZIP_STORED)
-            outf.writestr(zi, inf.read('mimetype'))
-            for path in namelist:
-                data = inf.read(path)
-                outf.writestr(path, decryptor.decrypt(path, data))
-    return 0
-
-
 class DecryptionDialog(Tkinter.Frame):
     def __init__(self, root):
         Tkinter.Frame.__init__(self, root, border=5)
@@ -308,6 +266,53 @@ class DecryptionDialog(Tkinter.Frame):
             return
         self.status['text'] = 'File successfully decrypted'
 
+
+def decryptBook(keypath, inpath, outpath):
+    with open(keypath, 'rb') as f:
+        keyb64 = f.read()
+    key = keyb64.decode('base64')[:16]
+    # aes = AES.new(key, AES.MODE_CBC)
+    aes = AES(key)
+
+    with closing(ZipFile(open(inpath, 'rb'))) as inf:
+        namelist = set(inf.namelist())
+        if 'META-INF/rights.xml' not in namelist or \
+           'META-INF/encryption.xml' not in namelist:
+            raise IGNOBLEError('%s: not an B&N ADEPT EPUB' % (inpath,))
+        for name in META_NAMES:
+            namelist.remove(name)
+        rights = etree.fromstring(inf.read('META-INF/rights.xml'))
+        adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag)
+        expr = './/%s' % (adept('encryptedKey'),)
+        bookkey = ''.join(rights.findtext(expr))
+        bookkey = aes.decrypt(bookkey.decode('base64'))
+        bookkey = bookkey[:-ord(bookkey[-1])]
+        encryption = inf.read('META-INF/encryption.xml')
+        decryptor = Decryptor(bookkey[-16:], encryption)
+        kwds = dict(compression=ZIP_DEFLATED, allowZip64=False)
+        with closing(ZipFile(open(outpath, 'wb'), 'w', **kwds)) as outf:
+            zi = ZipInfo('mimetype', compress_type=ZIP_STORED)
+            outf.writestr(zi, inf.read('mimetype'))
+            for path in namelist:
+                data = inf.read(path)
+                outf.writestr(path, decryptor.decrypt(path, data))
+    return 0
+
+
+def cli_main(argv=sys.argv):
+    progname = os.path.basename(argv[0])
+    if AES is None:
+        print "%s: This script requires OpenSSL or PyCrypto, which must be installed " \
+              "separately.  Read the top-of-script comment for details." % \
+              (progname,)
+        return 1
+    if len(argv) != 4:
+        print "usage: %s KEYFILE INBOOK OUTBOOK" % (progname,)
+        return 1
+    keypath, inpath, outpath = argv[1:]
+    return decryptBook(keypath, inpath, outpath)
+
+
 def gui_main():
     root = Tkinter.Tk()
     if AES is None:
@@ -324,6 +329,7 @@ def gui_main():
     root.mainloop()
     return 0
 
+
 if __name__ == '__main__':
     if len(sys.argv) > 1:
         sys.exit(cli_main())
similarity index 98%
rename from DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeygen.pyw
rename to DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeygen.py
index b2607ea52f27217e5788ae18ad8e188faee58a5a..cdedc48b698d5f6fcd3fb07478e7479580d410be 100644 (file)
@@ -1,6 +1,8 @@
 #! /usr/bin/python
 
-# ignoblekeygen.pyw, version 2.2
+from __future__ import with_statement
+
+# ignoblekeygen.pyw, version 2.3
 
 # To run this program install Python 2.6 from <http://www.python.org/download/>
 # and OpenSSL or PyCrypto from http://www.voidspace.org.uk/python/modules.shtml#pycrypto
 #   2 - Add OS X support by using OpenSSL when available (taken/modified from ineptepub v5)
 #   2.1 - Allow Windows versions of libcrypto to be found
 #   2.2 - On Windows try PyCrypto first and then OpenSSL next
+#   2.3 - Modify interface to allow use of import
+
 """
 Generate Barnes & Noble EPUB user key from name and credit card number.
 """
 
-from __future__ import with_statement
-
 __license__ = 'GPL v3'
 
 import sys
@@ -120,6 +122,7 @@ AES = _load_crypto()
 def normalize_name(name):
     return ''.join(x for x in name.lower() if x != ' ')
 
+
 def generate_keyfile(name, ccn, outpath):
     name = normalize_name(name) + '\x00'
     ccn = ccn + '\x00'
@@ -133,19 +136,6 @@ def generate_keyfile(name, ccn, outpath):
         f.write(userkey.encode('base64'))
     return userkey
 
-def cli_main(argv=sys.argv):
-    progname = os.path.basename(argv[0])
-    if AES is None:
-        print "%s: This script requires OpenSSL or PyCrypto, which must be installed " \
-              "separately.  Read the top-of-script comment for details." % \
-              (progname,)
-        return 1
-    if len(argv) != 4:
-        print "usage: %s NAME CC# OUTFILE" % (progname,)
-        return 1
-    name, ccn, outpath = argv[1:]
-    generate_keyfile(name, ccn, outpath)
-    return 0
 
 class DecryptionDialog(Tkinter.Frame):
     def __init__(self, root):
@@ -211,6 +201,22 @@ class DecryptionDialog(Tkinter.Frame):
             return
         self.status['text'] = 'Keyfile successfully generated'
 
+
+def cli_main(argv=sys.argv):
+    progname = os.path.basename(argv[0])
+    if AES is None:
+        print "%s: This script requires OpenSSL or PyCrypto, which must be installed " \
+              "separately.  Read the top-of-script comment for details." % \
+              (progname,)
+        return 1
+    if len(argv) != 4:
+        print "usage: %s NAME CC# OUTFILE" % (progname,)
+        return 1
+    name, ccn, outpath = argv[1:]
+    generate_keyfile(name, ccn, outpath)
+    return 0
+
+
 def gui_main():
     root = Tkinter.Tk()
     if AES is None:
similarity index 98%
rename from DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.pyw
rename to DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py
index 9d95720cbdd2181f1ec3db9292b1331838d5ac8f..48a75f996cdd84139fbcab9e9506cf8c68d1eef7 100644 (file)
@@ -1,7 +1,9 @@
 #! /usr/bin/python
 # -*- coding: utf-8 -*-
 
-# ineptepub.pyw, version 5.5
+from __future__ import with_statement
+
+# ineptepub.pyw, version 5.6
 # Copyright Â© 2009-2010 i♥cabbages
 
 # Released under the terms of the GNU General Public Licence, version 3 or
 #   5.3 - add support for OpenSSL on Windows, fix bug with some versions of libcrypto 0.9.8 prior to path level o
 #   5.4 - add support for encoding to 'utf-8' when building up list of files to decrypt from encryption.xml
 #   5.5 - On Windows try PyCrypto first, OpenSSL next
-
+#   5.6 - Modify interface to allow use with import
 """
 Decrypt Adobe ADEPT-encrypted EPUB books.
 """
 
-from __future__ import with_statement
-
 __license__ = 'GPL v3'
 
 import sys
@@ -312,45 +312,6 @@ class Decryptor(object):
             data = self.decompress(data)
         return data
 
-def cli_main(argv=sys.argv):
-    progname = os.path.basename(argv[0])
-    if AES is None:
-        print "%s: This script requires OpenSSL or PyCrypto, which must be" \
-              " installed separately.  Read the top-of-script comment for" \
-              " details." % (progname,)
-        return 1
-    if len(argv) != 4:
-        print "usage: %s KEYFILE INBOOK OUTBOOK" % (progname,)
-        return 1
-    keypath, inpath, outpath = argv[1:]
-    with open(keypath, 'rb') as f:
-        keyder = f.read()
-    rsa = RSA(keyder)
-    with closing(ZipFile(open(inpath, 'rb'))) as inf:
-        namelist = set(inf.namelist())
-        if 'META-INF/rights.xml' not in namelist or \
-           'META-INF/encryption.xml' not in namelist:
-            raise ADEPTError('%s: not an ADEPT EPUB' % (inpath,))
-        for name in META_NAMES:
-            namelist.remove(name)
-        rights = etree.fromstring(inf.read('META-INF/rights.xml'))
-        adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag)
-        expr = './/%s' % (adept('encryptedKey'),)
-        bookkey = ''.join(rights.findtext(expr))
-        bookkey = rsa.decrypt(bookkey.decode('base64'))
-        # Padded as per RSAES-PKCS1-v1_5
-        if bookkey[-17] != '\x00':
-            raise ADEPTError('problem decrypting session key')
-        encryption = inf.read('META-INF/encryption.xml')
-        decryptor = Decryptor(bookkey[-16:], encryption)
-        kwds = dict(compression=ZIP_DEFLATED, allowZip64=False)
-        with closing(ZipFile(open(outpath, 'wb'), 'w', **kwds)) as outf:
-            zi = ZipInfo('mimetype', compress_type=ZIP_STORED)
-            outf.writestr(zi, inf.read('mimetype'))
-            for path in namelist:
-                data = inf.read(path)
-                outf.writestr(path, decryptor.decrypt(path, data))
-    return 0
 
 class DecryptionDialog(Tkinter.Frame):
     def __init__(self, root):
@@ -446,6 +407,52 @@ class DecryptionDialog(Tkinter.Frame):
             return
         self.status['text'] = 'File successfully decrypted'
 
+
+def decryptBook(keypath, inpath, outpath):
+    with open(keypath, 'rb') as f:
+        keyder = f.read()
+    rsa = RSA(keyder)
+    with closing(ZipFile(open(inpath, 'rb'))) as inf:
+        namelist = set(inf.namelist())
+        if 'META-INF/rights.xml' not in namelist or \
+           'META-INF/encryption.xml' not in namelist:
+            raise ADEPTError('%s: not an ADEPT EPUB' % (inpath,))
+        for name in META_NAMES:
+            namelist.remove(name)
+        rights = etree.fromstring(inf.read('META-INF/rights.xml'))
+        adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag)
+        expr = './/%s' % (adept('encryptedKey'),)
+        bookkey = ''.join(rights.findtext(expr))
+        bookkey = rsa.decrypt(bookkey.decode('base64'))
+        # Padded as per RSAES-PKCS1-v1_5
+        if bookkey[-17] != '\x00':
+            raise ADEPTError('problem decrypting session key')
+        encryption = inf.read('META-INF/encryption.xml')
+        decryptor = Decryptor(bookkey[-16:], encryption)
+        kwds = dict(compression=ZIP_DEFLATED, allowZip64=False)
+        with closing(ZipFile(open(outpath, 'wb'), 'w', **kwds)) as outf:
+            zi = ZipInfo('mimetype', compress_type=ZIP_STORED)
+            outf.writestr(zi, inf.read('mimetype'))
+            for path in namelist:
+                data = inf.read(path)
+                outf.writestr(path, decryptor.decrypt(path, data))
+    return 0
+
+
+def cli_main(argv=sys.argv):
+    progname = os.path.basename(argv[0])
+    if AES is None:
+        print "%s: This script requires OpenSSL or PyCrypto, which must be" \
+              " installed separately.  Read the top-of-script comment for" \
+              " details." % (progname,)
+        return 1
+    if len(argv) != 4:
+        print "usage: %s KEYFILE INBOOK OUTBOOK" % (progname,)
+        return 1
+    keypath, inpath, outpath = argv[1:]
+    return decryptBook(keypath, inpath, outpath)
+
+
 def gui_main():
     root = Tkinter.Tk()
     if AES is None:
similarity index 99%
rename from DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptkey.pyw
rename to DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptkey.py
index fd90508f4a007c5fc8e843627efe1854696265b3..8eab14fb0200772d2f27cf6fc65239a99a6f7e92 100644 (file)
@@ -1,7 +1,9 @@
 #! /usr/bin/python
 # -*- coding: utf-8 -*-
 
-# ineptkey.pyw, version 5.3
+from __future__ import with_statement
+
+# ineptkey.pyw, version 5.4
 # Copyright Â© 2009-2010 i♥cabbages
 
 # Released under the terms of the GNU General Public Licence, version 3 or
 #   5.1 - add support for using OpenSSL on Windows in place of PyCrypto
 #   5.2 - added support for output of key to a particular file
 #   5.3 - On Windows try PyCrypto first, OpenSSL next
+#   5.4 - Modify interface to allow use of import
 
 """
 Retrieve Adobe ADEPT user key.
 """
 
-from __future__ import with_statement
-
 __license__ = 'GPL v3'
 
 import sys
@@ -415,10 +416,11 @@ class ExceptionDialog(Tkinter.Frame):
         label.pack(fill=Tkconstants.X, expand=0)
         self.text = Tkinter.Text(self)
         self.text.pack(fill=Tkconstants.BOTH, expand=1)
+
         self.text.insert(Tkconstants.END, text)
 
-def cli_main(argv=sys.argv):
-    keypath = argv[1]
+
+def extractKeyfile(keypath):
     try:
         success = retrieve_key(keypath)
     except ADEPTError, e:
@@ -431,6 +433,12 @@ def cli_main(argv=sys.argv):
         return 1
     return 0
 
+
+def cli_main(argv=sys.argv):
+    keypath = argv[1]
+    return extractKeyfile(keypath)
+
+
 def main(argv=sys.argv):
     root = Tkinter.Tk()
     root.withdraw()
similarity index 99%
rename from DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.pyw
rename to DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py
index d73e069f4e640f133c61c4a60ee25f1e1f0b2c9d..ccdd9e4fd6af8c9b3539842cf36d656f9d6382b0 100644 (file)
@@ -1,6 +1,8 @@
 #! /usr/bin/env python
 # ineptpdf.pyw, version 7.7
 
+from __future__ import with_statement
+
 # To run this program install Python 2.6 from http://www.python.org/download/
 # and OpenSSL (already installed on Mac OS X and Linux) OR 
 # PyCrypto from http://www.voidspace.org.uk/python/modules.shtml#pycrypto
 #         fixed minor typos
 #   7.6 - backported AES and other fixes from version 8.4.48
 #   7.7 - On Windows try PyCrypto first and OpenSSL next
+#   7.8 - Modify interface to allow use of import
 
 """
 Decrypts Adobe ADEPT-encrypted PDF files.
 """
 
-from __future__ import with_statement
-
 __license__ = 'GPL v3'
 
 import sys
@@ -2076,25 +2077,6 @@ class PDFSerializer(object):
             self.write('\n')
         self.write('endobj\n')
 
-def cli_main(argv=sys.argv):
-    progname = os.path.basename(argv[0])
-    if RSA is None:
-        print "%s: This script requires OpenSSL or PyCrypto, which must be installed " \
-              "separately.  Read the top-of-script comment for details." % \
-              (progname,)
-        return 1
-    if len(argv) != 4:
-        print "usage: %s KEYFILE INBOOK OUTBOOK" % (progname,)
-        return 1
-    keypath, inpath, outpath = argv[1:]
-    with open(inpath, 'rb') as inf:
-        serializer = PDFSerializer(inf, keypath)
-        # hope this will fix the 'bad file descriptor' problem
-        with open(outpath, 'wb') as outf:
-        # help construct to make sure the method runs to the end
-            serializer.dump(outf)
-    return 0
-
 
 class DecryptionDialog(Tkinter.Frame):
     def __init__(self, root):
@@ -2198,6 +2180,31 @@ class DecryptionDialog(Tkinter.Frame):
                               'Close this window or decrypt another pdf file.'
         return
 
+
+def decryptBook(keypath, inpath, outpath):
+    with open(inpath, 'rb') as inf:
+        serializer = PDFSerializer(inf, keypath)
+        # hope this will fix the 'bad file descriptor' problem
+        with open(outpath, 'wb') as outf:
+        # help construct to make sure the method runs to the end
+            serializer.dump(outf)
+    return 0
+
+
+def cli_main(argv=sys.argv):
+    progname = os.path.basename(argv[0])
+    if RSA is None:
+        print "%s: This script requires OpenSSL or PyCrypto, which must be installed " \
+              "separately.  Read the top-of-script comment for details." % \
+              (progname,)
+        return 1
+    if len(argv) != 4:
+        print "usage: %s KEYFILE INBOOK OUTBOOK" % (progname,)
+        return 1
+    keypath, inpath, outpath = argv[1:]
+    return decryptBook(keypath, inpath, outpath)
+
+
 def gui_main():
     root = Tkinter.Tk()
     if RSA is None:
index 7088c06281970bd6fecfcc0c48a44f96375833b4..776ca6e2f0636fc6bf2e1d2e9fe92daea91bc156 100644 (file)
@@ -29,7 +29,7 @@ from __future__ import with_statement
 # and import that ZIP into Calibre using its plugin configuration GUI.
 
 
-__version__ = '2.1'
+__version__ = '2.2'
 
 class Unbuffered:
     def __init__(self, stream):
@@ -75,21 +75,23 @@ def zipUpDir(myzip, tempdir,localname):
 # borrowed from calibre from calibre/src/calibre/__init__.py
 # added in removal of non-printing chars
 # and removal of . at start
+# convert spaces to underscores
 def cleanup_name(name):
-  _filename_sanitize = re.compile(r'[\xae\0\\|\?\*<":>\+/]')
-  substitute='_'
-  one = ''.join(char for char in name if char in string.printable)
-  one = _filename_sanitize.sub(substitute, one)
-  one = re.sub(r'\s', ' ', one).strip()
-  one = re.sub(r'^\.+$', '_', one)
-  one = one.replace('..', substitute)
-  # Windows doesn't like path components that end with a period
-  if one.endswith('.'):
-      one = one[:-1]+substitute
-  # Mac and Unix don't like file names that begin with a full stop
-  if len(one) > 0 and one[0] == '.':
-      one = substitute+one[1:]
-  return one
+    _filename_sanitize = re.compile(r'[\xae\0\\|\?\*<":>\+/]')
+    substitute='_'
+    one = ''.join(char for char in name if char in string.printable)
+    one = _filename_sanitize.sub(substitute, one)
+    one = re.sub(r'\s', ' ', one).strip()
+    one = re.sub(r'^\.+$', '_', one)
+    one = one.replace('..', substitute)
+    # Windows doesn't like path components that end with a period
+    if one.endswith('.'):
+        one = one[:-1]+substitute
+    # Mac and Unix don't like file names that begin with a full stop
+    if len(one) > 0 and one[0] == '.':
+        one = substitute+one[1:]
+    one = one.replace(' ','_')
+    return one
 
 def decryptBook(infile, outdir, k4, kInfoFiles, serials, pids):
     import mobidedrm
@@ -119,7 +121,7 @@ def decryptBook(infile, outdir, k4, kInfoFiles, serials, pids):
     filenametitle = cleanup_name(title)
     outfilename = bookname
     if len(bookname)>4 and len(filenametitle)>4 and bookname[:4] != filenametitle[:4]:
-        outfilename = outfilename + "_"+filenametitle
+        outfilename = outfilename + "_" + filenametitle
 
     # build pid list
     md1, md2 = mb.getPIDMetaInfo()
@@ -134,15 +136,17 @@ def decryptBook(infile, outdir, k4, kInfoFiles, serials, pids):
     except mobidedrm.DrmException, e:
         print "Error: " + str(e) + "\nDRM Removal Failed.\n"
         return 1
-    except topazextract.TpzDRMError, e:
-        print str(e)
-        print "   Creating DeBug Full Zip Archive of Book"
-        zipname = os.path.join(outdir, bookname + '_debug' + '.zip')
-        myzip = zipfile.ZipFile(zipname,'w',zipfile.ZIP_DEFLATED, False)
-        zipUpDir(myzip, tempdir, '')
-        myzip.close()
-        shutil.rmtree(tempdir, True)
-        return 1
+    except Exception, e:
+        if not mobi:
+            print "Error: " + str(e) + "\nDRM Removal Failed.\n"
+            print "   Creating DeBug Full Zip Archive of Book"
+            zipname = os.path.join(outdir, bookname + '_debug' + '.zip')
+            myzip = zipfile.ZipFile(zipname,'w',zipfile.ZIP_DEFLATED, False)
+            zipUpDir(myzip, tempdir, '')
+            myzip.close()
+            shutil.rmtree(tempdir, True)
+            return 1
+        pass
 
     if mobi:
         outfile = os.path.join(outdir,outfilename + '_nodrm' + '.mobi')
@@ -198,7 +202,7 @@ def main(argv=sys.argv):
     pids = []
     
     print ('K4MobiDeDrm v%(__version__)s '
-        'provided by the work of many including DiapDealer, SomeUpdates, IHeartCabbages, CMBDTC, Skindle, DarkReverser, ApprenticeAlf, etc .' % globals())
+          'provided by the work of many including DiapDealer, SomeUpdates, IHeartCabbages, CMBDTC, Skindle, DarkReverser, ApprenticeAlf, etc .' % globals())
 
     print ' '
     try:
@@ -246,7 +250,7 @@ if not __name__ == "__main__" and inCalibre:
                                 Provided by the work of many including DiapDealer, SomeUpdates, IHeartCabbages, CMBDTC, Skindle, DarkReverser, ApprenticeAlf, etc.'
         supported_platforms = ['osx', 'windows', 'linux'] # Platforms this plugin will run on
         author              = 'DiapDealer, SomeUpdates' # The author of this plugin
-        version             = (0, 2, 1)   # The version number of this plugin
+        version             = (0, 2, 2)   # The version number of this plugin
         file_types          = set(['prc','mobi','azw','azw1','tpz']) # The file types that this plugin will be applied to
         on_import           = True # Run this plugin during the import
         priority            = 210  # run this plugin before mobidedrm, k4pcdedrm, k4dedrm
@@ -272,15 +276,15 @@ if not __name__ == "__main__" and inCalibre:
             for customvalue in customvalues:
                 customvalue = str(customvalue)
                 customvalue = customvalue.strip()
-                if len(customvalue) == 10 or len(customvalue) == 8:
+               if len(customvalue) == 10 or len(customvalue) == 8:
                     pids.append(customvalue)
-                else :
+               else :
                     if len(customvalue) == 16 and customvalue[0] == 'B':
                         serials.append(customvalue)
                     else:
                         print "%s is not a valid Kindle serial number or PID." % str(customvalue)
-
-           # Load any kindle info files (*.info) included Calibre's config directory.
+                       
+            # Load any kindle info files (*.info) included Calibre's config directory.
             try:
                 # Find Calibre's configuration directory.
                 confpath = os.path.split(os.path.split(self.plugin_path)[0])[0]
@@ -288,7 +292,7 @@ if not __name__ == "__main__" and inCalibre:
                 files = os.listdir(confpath)
                 filefilter = re.compile("\.info$", re.IGNORECASE)
                 files = filter(filefilter.search, files)
-
+    
                 if files:
                     for filename in files:
                         fpath = os.path.join(confpath, filename)
index 1b501ba41a39a1691d1e347ec79e25afca30c85b..5e57701cd37ec0bfa4a0fab0b647ff1a9dcab1cc 100644 (file)
@@ -189,6 +189,6 @@ def openKindleInfo(kInfoFile=None):
            raise DrmException('Error: .kindle-info file can not be found')
        return open(kinfopath,'r')
     else:
-       if not os.path.isfile(kinfoFile):
+       if not os.path.isfile(kInfoFile):
            raise DrmException('Error: kindle-info file can not be found')
         return open(kInfoFile, 'r')
index d3d6bdaf444eaf224c84eb2bd27f148e5d0971d0..a3196311b557542679f629e197a2d9b3365510c5 100644 (file)
@@ -2,8 +2,8 @@
 # vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
 
 import sys
-sys.path.append('lib')
 import os, os.path
+sys.path.append(sys.path[0]+os.sep+'lib')
 import shutil
 import Tkinter
 from Tkinter import *
@@ -22,10 +22,11 @@ class DrmException(Exception):
     pass
 
 class MainApp(Tk):
-    def __init__(self, dnd=False, filenames=[]):
+    def __init__(self, apphome, dnd=False, filenames=[]):
         Tk.__init__(self)
         self.withdraw()
         self.dnd = dnd
+        self.apphome = apphome
         # preference settings
         # [dictionary key, file in preferences directory where info is stored]
         description = [ ['pids'   , 'pidlist.txt'   ], 
@@ -312,6 +313,7 @@ class ConvDialog(Toplevel):
         self.protocol("WM_DELETE_WINDOW", self.withdraw)
         self.title("DeDRM Processing")
         self.master = master
+        self.apphome = self.master.apphome
         self.prefs_array = prefs_array
         self.filenames = filenames
         self.interval = 50
@@ -328,11 +330,11 @@ class ConvDialog(Toplevel):
         body.grid_columnconfigure(1, weight=2)
 
         Tkinter.Label(body, text='Activity Bar').grid(row=0, sticky=Tkconstants.E)
-        self.bar = ActivityBar(body, length=50, height=15, barwidth=5)
+        self.bar = ActivityBar(body, length=80, height=15, barwidth=5)
         self.bar.grid(row=0, column=1, sticky=sticky)
 
         msg1 = ''
-        self.stext = ScrolledText(body, bd=5, relief=Tkconstants.RIDGE, height=4, width=50, wrap=Tkconstants.WORD)
+        self.stext = ScrolledText(body, bd=5, relief=Tkconstants.RIDGE, height=4, width=80, wrap=Tkconstants.WORD)
         self.stext.grid(row=2, column=0, columnspan=2,sticky=sticky)
         self.stext.insert(Tkconstants.END,msg1)
 
@@ -435,7 +437,6 @@ class ConvDialog(Toplevel):
             if poll != 0:
                 msg = 'Failed\n'
                 text = self.p2.read()
-                text = self.p2.read()
                 text += self.p2.readerr()
                 msg += text
                 msg += '\n'
@@ -451,42 +452,43 @@ class ConvDialog(Toplevel):
         return
 
     def decrypt_ebook(self, infile, outdir, rscpath):
+        apphome = self.apphome
         rv = 1
         name, ext = os.path.splitext(os.path.basename(infile))
         ext = ext.lower()
         if ext == '.epub':
             outfile = os.path.join(outdir, name + '_nodrm.epub')
-            self.p2 = processEPUB(infile, outfile, rscpath)
+            self.p2 = processEPUB(apphome, infile, outfile, rscpath)
             return 0
         if ext == '.pdb':
-            self.p2 = processPDB(infile, outdir, rscpath)
+            self.p2 = processPDB(apphome, infile, outdir, rscpath)
             return 0
         if ext in ['.azw', '.azw1', '.prc', '.mobi', '.tpz']:
-            self.p2 = processK4MOBI(infile, outdir, rscpath)
+            self.p2 = processK4MOBI(apphome, infile, outdir, rscpath)
             return 0
         if ext == '.pdf':
             outfile = os.path.join(outdir, name + '_nodrm.pdf')
-            self.p2 = processPDF(infile, outfile, rscpath)
+            self.p2 = processPDF(apphome, infile, outfile, rscpath)
             return 0
         return rv
 
 
 # run as a subprocess via pipes and collect stdout, stderr, and return value
-def runit(ncmd, nparms):
-    cmdline = 'python ' + ncmd
+def runit(apphome, ncmd, nparms):
+    cmdline = 'python ' + '"' + os.path.join(apphome, ncmd) + '" '
     if sys.platform.startswith('win'):
         search_path = os.environ['PATH']
         search_path = search_path.lower()
         if search_path.find('python') < 0: 
             # if no python hope that win registry finds what is associated with py extension
-            cmdline = ncmd
+            cmdline = '"' + os.path.join(apphome, ncmd) + '" '
     cmdline += nparms
     cmdline = cmdline.encode(sys.getfilesystemencoding())
     p2 = subasyncio.Process(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
     return p2
 
-def processK4MOBI(infile, outdir, rscpath):
-    cmd = '"' + os.path.join('lib','k4mobidedrm.py') +  '" '
+def processK4MOBI(apphome, infile, outdir, rscpath):
+    cmd = os.path.join('lib','k4mobidedrm.py')
     parms = ''
     pidnums = ''
     pidspath = os.path.join(rscpath,'pidlist.txt')
@@ -511,30 +513,33 @@ def processK4MOBI(infile, outdir, rscpath):
             dpath = os.path.join(rscpath,filename)
             parms += '-k "' + dpath + '" '
     parms += '"' + infile +'" "' + outdir + '"'
-    p2 = runit(cmd, parms)
+    p2 = runit(apphome, cmd, parms)
     return p2
 
-def processPDF(infile, outfile, rscpath):
-    cmd = '"' + os.path.join('lib','decryptpdf.py') + '" '
+def processPDF(apphome, infile, outfile, rscpath):
+    cmd = os.path.join('lib','decryptpdf.py')
     parms =  '"' + infile + '" "' + outfile + '" "' + rscpath + '"'
-    p2 = runit(cmd, parms)
+    p2 = runit(apphome, cmd, parms)
     return p2
 
-def processEPUB(infile, outfile, rscpath):
+def processEPUB(apphome, infile, outfile, rscpath):
     # invoke routine to check both Adept and Barnes and Noble
-    cmd = '"' + os.path.join('lib','decryptepub.py') + '" '
+    cmd = os.path.join('lib','decryptepub.py')
     parms = '"' + infile + '" "' + outfile + '" "' + rscpath + '"'
-    p2 = runit(cmd, parms)
+    p2 = runit(apphome, cmd, parms)
     return p2
 
-def processPDB(infile, outdir, rscpath):
-    cmd = '"' + os.path.join('lib','decryptpdb.py') + '" '
+def processPDB(apphome, infile, outdir, rscpath):
+    cmd = os.path.join('lib','decryptpdb.py')
     parms = '"' + infile + '" "' + outdir + '" "' + rscpath + '"'
-    p2 = runit(cmd, parms)
+    p2 = runit(apphome, cmd, parms)
     return p2
 
 
 def main(argv=sys.argv):
+    apphome = os.path.dirname(sys.argv[0])
+    apphome = os.path.abspath(apphome)
+
     # windows may pass a spurious quoted null string as argv[1] from bat file
     # simply work around this until we can figure out a better way to handle things
     if len(argv) == 2:
@@ -571,7 +576,7 @@ def main(argv=sys.argv):
                         filenames.append(infile)
 
     # start up gui app
-    app = MainApp(dnd, filenames)
+    app = MainApp(apphome, dnd, filenames)
     app.mainloop()
     return 0
 
index 81d93bc89fb3a90d53ea651fee7ef985cf0f03d5..ae2c8dd8021def8f78baf35eb75e960482b4d1e7 100644 (file)
@@ -68,7 +68,7 @@ class DocParser(object):
         ys = []
         gdefs = []
 
-        # get path defintions, positions, dimensions for ecah glyph 
+        # get path defintions, positions, dimensions for each glyph 
         # that makes up the image, and find min x and min y to reposition origin
         minx = -1
         miny = -1
@@ -305,6 +305,15 @@ class DocParser(object):
                 lastGlyph = firstglyphList[last]
             else :
                 lastGlyph = len(gidList)
+
+            # handle case of white sapce paragraphs with no actual glyphs in them
+            # by reverting to text based paragraph
+            if firstGlyph >= lastGlyph:
+                # revert to standard text based paragraph
+                for wordnum in xrange(first, last):
+                    result.append(('ocr', wordnum))
+                return pclass, result
+
             for glyphnum in xrange(firstGlyph, lastGlyph):
                 glyphList.append(glyphnum)
             # include any extratokens if they exist
index 880690f2f64fc66e49fb02f96913f6f38a49463b..776ca6e2f0636fc6bf2e1d2e9fe92daea91bc156 100644 (file)
@@ -29,7 +29,7 @@ from __future__ import with_statement
 # and import that ZIP into Calibre using its plugin configuration GUI.
 
 
-__version__ = '2.1'
+__version__ = '2.2'
 
 class Unbuffered:
     def __init__(self, stream):
@@ -75,6 +75,7 @@ def zipUpDir(myzip, tempdir,localname):
 # borrowed from calibre from calibre/src/calibre/__init__.py
 # added in removal of non-printing chars
 # and removal of . at start
+# convert spaces to underscores
 def cleanup_name(name):
     _filename_sanitize = re.compile(r'[\xae\0\\|\?\*<":>\+/]')
     substitute='_'
@@ -89,6 +90,7 @@ def cleanup_name(name):
     # Mac and Unix don't like file names that begin with a full stop
     if len(one) > 0 and one[0] == '.':
         one = substitute+one[1:]
+    one = one.replace(' ','_')
     return one
 
 def decryptBook(infile, outdir, k4, kInfoFiles, serials, pids):
@@ -248,7 +250,7 @@ if not __name__ == "__main__" and inCalibre:
                                 Provided by the work of many including DiapDealer, SomeUpdates, IHeartCabbages, CMBDTC, Skindle, DarkReverser, ApprenticeAlf, etc.'
         supported_platforms = ['osx', 'windows', 'linux'] # Platforms this plugin will run on
         author              = 'DiapDealer, SomeUpdates' # The author of this plugin
-        version             = (0, 2, 1)   # The version number of this plugin
+        version             = (0, 2, 2)   # The version number of this plugin
         file_types          = set(['prc','mobi','azw','azw1','tpz']) # The file types that this plugin will be applied to
         on_import           = True # Run this plugin during the import
         priority            = 210  # run this plugin before mobidedrm, k4pcdedrm, k4dedrm
index 1b501ba41a39a1691d1e347ec79e25afca30c85b..5e57701cd37ec0bfa4a0fab0b647ff1a9dcab1cc 100644 (file)
@@ -189,6 +189,6 @@ def openKindleInfo(kInfoFile=None):
            raise DrmException('Error: .kindle-info file can not be found')
        return open(kinfopath,'r')
     else:
-       if not os.path.isfile(kinfoFile):
+       if not os.path.isfile(kInfoFile):
            raise DrmException('Error: kindle-info file can not be found')
         return open(kInfoFile, 'r')
index 8e1cfea5b321dc5a3782e88a0a953e1bd93c1a43..73c13b0fed724566432c944a92cde99ad35d6459 100644 (file)
@@ -1,5 +1,5 @@
-ReadMe_DeDRM_WinApp_v1.2
------------------------
+ReadMe_DeDRM_WinApp_v1.3
+------------------------
 
 DeDRM_WinApp is a pure python drag and drop application that allows users to drag and drop ebooks or folders of ebooks onto theDeDRM_Drop_Target to have the DRM removed.  It repackages the"tools" python software in one easy to use program.
 
index d4f37fb41640a467c25e2347d036825f5246e3e1..63ef77d7651c8233b160f00a64a4527cdf54d408 100644 (file)
@@ -207,11 +207,11 @@ class MainDialog(Tkinter.Frame):
 
         tpz = False
         # Identify any Topaz Files
-        with open(mobipath, 'rb') as f:
-            raw = f.read(3)
-            if raw.startswith('TPZ'):
-                tpz = True
-            f.close()
+        f = file(mobipath, 'rb')
+        raw = f.read(3)
+        if raw.startswith('TPZ'):
+            tpz = True
+        f.close()
         if not outpath:
             self.status['text'] = 'No output directory specified'
             self.sbotton.configure(state='normal')
index 81d93bc89fb3a90d53ea651fee7ef985cf0f03d5..ae2c8dd8021def8f78baf35eb75e960482b4d1e7 100644 (file)
@@ -68,7 +68,7 @@ class DocParser(object):
         ys = []
         gdefs = []
 
-        # get path defintions, positions, dimensions for ecah glyph 
+        # get path defintions, positions, dimensions for each glyph 
         # that makes up the image, and find min x and min y to reposition origin
         minx = -1
         miny = -1
@@ -305,6 +305,15 @@ class DocParser(object):
                 lastGlyph = firstglyphList[last]
             else :
                 lastGlyph = len(gidList)
+
+            # handle case of white sapce paragraphs with no actual glyphs in them
+            # by reverting to text based paragraph
+            if firstGlyph >= lastGlyph:
+                # revert to standard text based paragraph
+                for wordnum in xrange(first, last):
+                    result.append(('ocr', wordnum))
+                return pclass, result
+
             for glyphnum in xrange(firstGlyph, lastGlyph):
                 glyphList.append(glyphnum)
             # include any extratokens if they exist
index 880690f2f64fc66e49fb02f96913f6f38a49463b..776ca6e2f0636fc6bf2e1d2e9fe92daea91bc156 100644 (file)
@@ -29,7 +29,7 @@ from __future__ import with_statement
 # and import that ZIP into Calibre using its plugin configuration GUI.
 
 
-__version__ = '2.1'
+__version__ = '2.2'
 
 class Unbuffered:
     def __init__(self, stream):
@@ -75,6 +75,7 @@ def zipUpDir(myzip, tempdir,localname):
 # borrowed from calibre from calibre/src/calibre/__init__.py
 # added in removal of non-printing chars
 # and removal of . at start
+# convert spaces to underscores
 def cleanup_name(name):
     _filename_sanitize = re.compile(r'[\xae\0\\|\?\*<":>\+/]')
     substitute='_'
@@ -89,6 +90,7 @@ def cleanup_name(name):
     # Mac and Unix don't like file names that begin with a full stop
     if len(one) > 0 and one[0] == '.':
         one = substitute+one[1:]
+    one = one.replace(' ','_')
     return one
 
 def decryptBook(infile, outdir, k4, kInfoFiles, serials, pids):
@@ -248,7 +250,7 @@ if not __name__ == "__main__" and inCalibre:
                                 Provided by the work of many including DiapDealer, SomeUpdates, IHeartCabbages, CMBDTC, Skindle, DarkReverser, ApprenticeAlf, etc.'
         supported_platforms = ['osx', 'windows', 'linux'] # Platforms this plugin will run on
         author              = 'DiapDealer, SomeUpdates' # The author of this plugin
-        version             = (0, 2, 1)   # The version number of this plugin
+        version             = (0, 2, 2)   # The version number of this plugin
         file_types          = set(['prc','mobi','azw','azw1','tpz']) # The file types that this plugin will be applied to
         on_import           = True # Run this plugin during the import
         priority            = 210  # run this plugin before mobidedrm, k4pcdedrm, k4dedrm
index 1b501ba41a39a1691d1e347ec79e25afca30c85b..5e57701cd37ec0bfa4a0fab0b647ff1a9dcab1cc 100644 (file)
@@ -189,6 +189,6 @@ def openKindleInfo(kInfoFile=None):
            raise DrmException('Error: .kindle-info file can not be found')
        return open(kinfopath,'r')
     else:
-       if not os.path.isfile(kinfoFile):
+       if not os.path.isfile(kInfoFile):
            raise DrmException('Error: kindle-info file can not be found')
         return open(kInfoFile, 'r')
index b864d0749fa0816fa712ef12cf9be24560d470ef..fb71e9da8dfd90241033b8b22ef782cdfde8e1b0 100644 (file)
@@ -1,8 +1,8 @@
 ePub_Fixer
 
-ePubs are specially crafted zip archives.  Unfortunately, many of the DRM encoded Adobe Adept and Barnes & Noble ePubs are not "proper" zip archives in that the names of some files in the zip central directory do NOT match the local name given in archive itself.  This type of zip archive is technically incorrect/corrupted and can not be read by many other programs.
+ePubs are specially crafted zip archives whose first file is an uncompresssed "mimetype" file.  Unfortunately, many of the DRM encoded Adobe Adept and Barnes & Noble ePubs are not "proper" zip archives in that the names of some files in the zip central directory do NOT match the local name given in archive itself, or they do not have an uncompressed mimetype file as the first file in the archive.  These types of epubs are technically incorrect/corrupted and can not be read by many other programs.
 
-ePub_Fixer was designed to fix improperly created zip archives of this type.
+ePub_Fixer was designed to fix improperly created zip archives of these types.
 
 1. Simply double-click to launch ePub_Fixer.pyw.
 
index ad172a32dc93deef04aa12e9d6ee0479b46451cd..5585cf5d5224b22b913df86bda5effee6beda4f2 100644 (file)
@@ -42,7 +42,7 @@ class eRdrDeDRM(FileTypePlugin):
                             Credit given to The Dark Reverser for the original standalone script.'
     supported_platforms = ['linux', 'osx', 'windows'] # Platforms this plugin will run on
     author              = 'DiapDealer' # The author of this plugin
-    version             = (0, 0, 3)   # The version number of this plugin
+    version             = (0, 0, 4)   # The version number of this plugin
     file_types          = set(['pdb']) # The file types that this plugin will be applied to
     on_import           = True # Run this plugin during the import