mirror of
				https://github.com/noDRM/DeDRM_tools.git
				synced 2025-10-23 23:07:47 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			216 lines
		
	
	
		
			No EOL
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			216 lines
		
	
	
		
			No EOL
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/env python
 | |
| 
 | |
| # This is a simple tool to identify all Amazon Topaz ebooks in a specific directory.
 | |
| # There always seems to be confusion since Topaz books downloaded to K4PC/Mac can have
 | |
| # almost any extension (.azw, .azw1, .prc, tpz). While the .azw1 and .tpz extensions
 | |
| # are fairly easy to indentify, the others are not (without opening the files in an editor).
 | |
| 
 | |
| # To run the tool with the GUI frontend, just double-click on the 'FindTopazFiles.pyw' file
 | |
| # and select the folder where all of the ebooks in question are located. Then click 'Search'.
 | |
| # The program will list the file names of the ebooks that are indentified as being Topaz.
 | |
| # You can then isolate those books and use the Topaz tools to decrypt and convert them.
 | |
| 
 | |
| # You can also run the script from a command line... supplying the folder to search
 | |
| # as a parameter: python FindTopazEbooks.pyw "C:\My Folder" (change appropriately for
 | |
| # your particular O.S.)
 | |
| 
 | |
| # ** NOTE: This program does NOT decrypt or modify Topaz files in any way. It simply identifies them.
 | |
| 
 | |
| # PLEASE DO NOT PIRATE EBOOKS! 
 | |
| 
 | |
| # We want all authors and publishers, and eBook stores to live
 | |
| # long and prosperous lives but at the same time  we just want to 
 | |
| # be able to read OUR books on whatever device we want and to keep 
 | |
| # readable for a long, long time
 | |
| 
 | |
| #  This borrows very heavily from works by CMBDTC, IHeartCabbages, skindle, 
 | |
| #    unswindle, DarkReverser, ApprenticeAlf, DiapDealer, some_updates 
 | |
| #    and many many others
 | |
| 
 | |
| # Revision history:
 | |
| #   1 - Initial release.
 | |
| 
 | |
| from __future__ import with_statement
 | |
| 
 | |
| __license__ = 'GPL v3'
 | |
| 
 | |
| import sys
 | |
| import os
 | |
| import re
 | |
| import shutil
 | |
| import Tkinter
 | |
| import Tkconstants
 | |
| import tkFileDialog
 | |
| import tkMessageBox
 | |
| 
 | |
| 
 | |
| class ScrolledText(Tkinter.Text):
 | |
|     def __init__(self, master=None, **kw):
 | |
|         self.frame = Tkinter.Frame(master)
 | |
|         self.vbar = Tkinter.Scrollbar(self.frame)
 | |
|         self.vbar.pack(side=Tkconstants.RIGHT, fill=Tkconstants.Y)
 | |
|         kw.update({'yscrollcommand': self.vbar.set})
 | |
|         Tkinter.Text.__init__(self, self.frame, **kw)
 | |
|         self.pack(side=Tkconstants.LEFT, fill=Tkconstants.BOTH, expand=True)
 | |
|         self.vbar['command'] = self.yview
 | |
|         # Copy geometry methods of self.frame without overriding Text
 | |
|         # methods = hack!
 | |
|         text_meths = vars(Tkinter.Text).keys()
 | |
|         methods = vars(Tkinter.Pack).keys() + vars(Tkinter.Grid).keys() + vars(Tkinter.Place).keys()
 | |
|         methods = set(methods).difference(text_meths)
 | |
|         for m in methods:
 | |
|             if m[0] != '_' and m != 'config' and m != 'configure':
 | |
|                 setattr(self, m, getattr(self.frame, m))
 | |
| 
 | |
|     def __str__(self):
 | |
|         return str(self.frame)
 | |
| 
 | |
| 
 | |
| def cli_main(argv=sys.argv, obj=None):
 | |
|     progname = os.path.basename(argv[0])
 | |
|     if len(argv) != 2:
 | |
|         print "usage: %s DIRECTORY" % (progname,)
 | |
|         return 1
 | |
|     
 | |
|     if obj == None:
 | |
|         print "\nTopaz search results:\n"
 | |
|     else:
 | |
|         obj.stext.insert(Tkconstants.END,"Topaz search results:\n\n")
 | |
|         
 | |
|     inpath = argv[1]
 | |
|     files = os.listdir(inpath)
 | |
|     filefilter = re.compile("(\.azw$)|(\.azw1$)|(\.prc$)|(\.tpz$)", re.IGNORECASE)
 | |
|     files = filter(filefilter.search, files)
 | |
|     
 | |
|     if files:
 | |
|         topazcount = 0
 | |
|         totalcount = 0
 | |
|         for filename in files:
 | |
|             with open(os.path.join(inpath, filename), 'rb') as f:
 | |
|                 try:
 | |
|                     if f.read().startswith('TPZ'):
 | |
|                         f.close()
 | |
|                         basename, extension = os.path.splitext(filename)
 | |
|                         if obj == None:
 | |
|                             print "   %s is a Topaz formatted ebook." % filename
 | |
|                             """
 | |
|                             if extension == '.azw' or extension == '.prc':
 | |
|                                 print "   renaming to %s" % (basename + '.tpz')
 | |
|                                 shutil.move(os.path.join(inpath, filename),
 | |
|                                             os.path.join(inpath, basename + '.tpz'))
 | |
|                             """
 | |
|                         else:
 | |
|                             msg1 = "   %s is a Topaz formatted ebook.\n" % filename
 | |
|                             obj.stext.insert(Tkconstants.END,msg1)
 | |
|                             """
 | |
|                             if extension == '.azw' or extension == '.prc':
 | |
|                                 msg2 = "   renaming to %s\n" % (basename + '.tpz')
 | |
|                                 obj.stext.insert(Tkconstants.END,msg2)
 | |
|                                 shutil.move(os.path.join(inpath, filename),
 | |
|                                             os.path.join(inpath, basename + '.tpz'))
 | |
|                             """
 | |
|                         topazcount += 1
 | |
|                 except:
 | |
|                     if obj == None:
 | |
|                         print "   Error reading %s." % filename
 | |
|                     else:
 | |
|                         msg = "   Error reading or %s.\n" % filename
 | |
|                         obj.stext.insert(Tkconstants.END,msg)
 | |
|                     pass
 | |
|             totalcount += 1
 | |
|         if topazcount == 0:
 | |
|             if obj == None:
 | |
|                 print "\nNo Topaz books found in %s." % inpath
 | |
|             else:
 | |
|                 msg = "\nNo Topaz books found in %s.\n\n" % inpath
 | |
|                 obj.stext.insert(Tkconstants.END,msg)
 | |
|         else:
 | |
|             if obj == None:
 | |
|                 print "\n%i Topaz books found in %s\n%i total books checked.\n" % (topazcount, inpath, totalcount)
 | |
|             else:
 | |
|                 msg = "\n%i Topaz books found in %s\n%i total books checked.\n\n" %(topazcount, inpath, totalcount)
 | |
|                 obj.stext.insert(Tkconstants.END,msg)
 | |
|     else:
 | |
|         if obj == None:
 | |
|             print "No typical Topaz file extensions found in %s.\n" % inpath
 | |
|         else:
 | |
|             msg = "No typical Topaz file extensions found in %s.\n\n" % inpath
 | |
|             obj.stext.insert(Tkconstants.END,msg)
 | |
|     
 | |
|     return 0
 | |
| 
 | |
| 
 | |
| class DecryptionDialog(Tkinter.Frame):
 | |
|     def __init__(self, root):
 | |
|         Tkinter.Frame.__init__(self, root, border=5)
 | |
|         ltext='Search a directory for Topaz eBooks\n'        
 | |
|         self.status = Tkinter.Label(self, text=ltext)
 | |
|         self.status.pack(fill=Tkconstants.X, expand=1)
 | |
|         body = Tkinter.Frame(self)
 | |
|         body.pack(fill=Tkconstants.X, expand=1)
 | |
|         sticky = Tkconstants.E + Tkconstants.W
 | |
|         body.grid_columnconfigure(1, weight=2)
 | |
|         Tkinter.Label(body, text='Directory to Search').grid(row=1)
 | |
|         self.inpath = Tkinter.Entry(body, width=30)
 | |
|         self.inpath.grid(row=1, column=1, sticky=sticky)
 | |
|         button = Tkinter.Button(body, text="...", command=self.get_inpath)
 | |
|         button.grid(row=1, column=2)
 | |
|         msg1 = 'Topaz search results \n\n'
 | |
|         self.stext = ScrolledText(body, bd=5, relief=Tkconstants.RIDGE,
 | |
|                                   height=15, width=60, wrap=Tkconstants.WORD)
 | |
|         self.stext.grid(row=4, column=0, columnspan=2,sticky=sticky)
 | |
|         #self.stext.insert(Tkconstants.END,msg1)
 | |
|         buttons = Tkinter.Frame(self)
 | |
|         buttons.pack()
 | |
|   
 | |
| 
 | |
|         self.botton = Tkinter.Button(
 | |
|             buttons, text="Search", width=10, command=self.search)
 | |
|         self.botton.pack(side=Tkconstants.LEFT)
 | |
|         Tkinter.Frame(buttons, width=10).pack(side=Tkconstants.LEFT)
 | |
|         self.button = Tkinter.Button(
 | |
|             buttons, text="Quit", width=10, command=self.quit)
 | |
|         self.button.pack(side=Tkconstants.RIGHT)
 | |
|         
 | |
|     def get_inpath(self):
 | |
|         cwd = os.getcwdu()
 | |
|         cwd = cwd.encode('utf-8')
 | |
|         inpath = tkFileDialog.askdirectory(
 | |
|             parent=None, title='Directory to search',
 | |
|             initialdir=cwd, initialfile=None)
 | |
|         if inpath:
 | |
|             inpath = os.path.normpath(inpath)
 | |
|             self.inpath.delete(0, Tkconstants.END)
 | |
|             self.inpath.insert(0, inpath)
 | |
|         return
 | |
|         
 | |
|     
 | |
|     def search(self):
 | |
|         inpath = self.inpath.get()
 | |
|         if not inpath or not os.path.exists(inpath):
 | |
|             self.status['text'] = 'Specified directory does not exist'
 | |
|             return
 | |
|         argv = [sys.argv[0], inpath]
 | |
|         self.status['text'] = 'Searching...'
 | |
|         self.botton.configure(state='disabled')
 | |
|         cli_main(argv, self)
 | |
|         self.status['text'] = 'Search a directory for Topaz files'
 | |
|         self.botton.configure(state='normal')
 | |
| 
 | |
|         return
 | |
| 
 | |
| 
 | |
| def gui_main():
 | |
|     root = Tkinter.Tk()
 | |
|     root.title('Topaz eBook Finder')
 | |
|     root.resizable(True, False)
 | |
|     root.minsize(370, 0)
 | |
|     DecryptionDialog(root).pack(fill=Tkconstants.X, expand=1)
 | |
|     root.mainloop()
 | |
|     return 0
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     if len(sys.argv) > 1:
 | |
|         sys.exit(cli_main())
 | |
|     sys.exit(gui_main()) | 
