mirror of
https://github.com/noDRM/DeDRM_tools.git
synced 2024-11-05 13:36:10 +06:00
1762 lines
129 KiB
Plaintext
1762 lines
129 KiB
Plaintext
property prefsFileName : "com.apprenticealf.dedrm.plist"
|
||
property tempFileName : "DeDRM_temp.log"
|
||
property prefsFolderName : "com.apprenticealf.dedrm"
|
||
property handledExtensions : {"epub", "pdf", "prc", "azw", "azw1", "tpz", "azw3", "azw4", "mobi", "pdb"}
|
||
|
||
global python
|
||
global oldAppleScript
|
||
|
||
global eReaderTool
|
||
global MobipocketTool
|
||
global KindlePIDTool
|
||
global BNKeyGenTool
|
||
global BNePubTool
|
||
global KindleKeyTool
|
||
global AdobeKeyGenTool
|
||
global AdobeePubTool
|
||
global ePubTestTool
|
||
global AdobePDFTool
|
||
global ZipFixTool
|
||
global ProgressApp
|
||
|
||
global PIDs
|
||
global UDIDs
|
||
global bnKeys
|
||
global KindleSerialList
|
||
global KindleKeyList
|
||
global AdeptKeyList
|
||
|
||
global ErrorList
|
||
global WarningList
|
||
global CompletedList
|
||
global ErrorCount
|
||
global WarningCount
|
||
global CompletedCount
|
||
global totalebooks
|
||
global completedebooks
|
||
global outputFolder
|
||
global logFilePath
|
||
global tempfilepath
|
||
|
||
global paraend
|
||
|
||
on writetolog(logstring)
|
||
try
|
||
set fileRef to open for access logFilePath with write permission
|
||
write logstring & "
|
||
" to fileRef starting at eof as «class utf8»
|
||
close access fileRef
|
||
end try
|
||
end writetolog
|
||
|
||
on clearlog()
|
||
try
|
||
set fileRef to open for access logFilePath with write permission
|
||
set eof fileRef to 0
|
||
close access fileRef
|
||
end try
|
||
end clearlog
|
||
|
||
on cleartemp()
|
||
try
|
||
set fileRef to open for access tempfilepath with write permission
|
||
set eof fileRef to 0
|
||
close access fileRef
|
||
end try
|
||
end cleartemp
|
||
|
||
on readtemp()
|
||
set tempContents to ""
|
||
try
|
||
set fileRef to open for access tempfilepath
|
||
if (get eof fileRef) > 0 then
|
||
set tempContents to read fileRef from 1 as «class utf8»
|
||
end if
|
||
close access fileRef
|
||
end try
|
||
return tempContents
|
||
end readtemp
|
||
|
||
on quotedtemppath()
|
||
set tempFile to POSIX path of file tempfilepath
|
||
return quoted form of tempFile
|
||
end quotedtemppath
|
||
|
||
on folderexists(inputFolder)
|
||
try
|
||
--display dialog "test -d " & quoted form of (POSIX path of inputFolder)
|
||
do shell script "test -d " & quoted form of (POSIX path of inputFolder)
|
||
return true
|
||
end try
|
||
|
||
return false
|
||
end folderexists
|
||
|
||
on fileexists(inputFile)
|
||
try
|
||
do shell script "test -f " & quoted form of (POSIX path of inputFile)
|
||
return true
|
||
end try
|
||
|
||
return false
|
||
end fileexists
|
||
|
||
on GetFileExtension(fileName)
|
||
set fileExtension to ""
|
||
if fileName contains "." then
|
||
set oldTIDs to AppleScript's text item delimiters
|
||
set AppleScript's text item delimiters to "."
|
||
set fileExtension to the last text item of fileName
|
||
set AppleScript's text item delimiters to oldTIDs
|
||
end if
|
||
return fileExtension
|
||
end GetFileExtension
|
||
|
||
on GetFileNameOnly(fileName)
|
||
set fileNameOnly to fileName
|
||
if fileName contains "." then
|
||
set oldTIDs to AppleScript's text item delimiters
|
||
set AppleScript's text item delimiters to "."
|
||
set fileNameOnly to (text items 1 through -2 of fileName) as string
|
||
set AppleScript's text item delimiters to oldTIDs
|
||
end if
|
||
return fileNameOnly
|
||
end GetFileNameOnly
|
||
|
||
on GetTools()
|
||
set paraend to "
|
||
"
|
||
set ASnumber to (text 1 thru 3 of (AppleScript's version as text) as real)
|
||
set oldAppleScript to (ASnumber < 2.0)
|
||
set python to "/usr/local/bin/python"
|
||
if not fileexists(python) then
|
||
set python to "/usr/bin/python"
|
||
end if
|
||
set pythonversion to "2.3"
|
||
try
|
||
set pythonversion to do shell script python & " -c \"from sys import version; print version[:3]\""
|
||
end try
|
||
-- display dialog pythonversion
|
||
if (pythonversion is not "2.5") and (pythonversion is not "2.6") and (pythonversion is not "2.7") then
|
||
set dialogresult to (display dialog "This AppleScript requires Python 2.7x.
|
||
|
||
Please install python 2.7x and try again." buttons {"Quit"} default button 1 with title "DeDRM" with icon stop)
|
||
return false
|
||
end if
|
||
-- we always want a space after the command
|
||
set python to python & " "
|
||
|
||
set eReaderTool to POSIX path of (path to resource "erdr2pml.py")
|
||
set MobipocketTool to POSIX path of (path to resource "k4mobidedrm.py")
|
||
set KindlePIDTool to POSIX path of (path to resource "kindlepid.py")
|
||
set BNKeyGenTool to POSIX path of (path to resource "ignoblekeygen.py")
|
||
set BNePubTool to POSIX path of (path to resource "ignobleepub.py")
|
||
set KindleKeyTool to POSIX path of (path to resource "kindlekey.py")
|
||
set AdobeKeyGenTool to POSIX path of (path to resource "adobekey.py")
|
||
set AdobeePubTool to POSIX path of (path to resource "ineptepub.py")
|
||
set ePubTestTool to POSIX path of (path to resource "epubtest.py")
|
||
set AdobePDFTool to POSIX path of (path to resource "ineptpdf.py")
|
||
set ZipFixTool to POSIX path of (path to resource "zipfix.py")
|
||
set ProgressApp to POSIX path of (path to resource "DeDRM Progress.app")
|
||
if not fileexists(eReaderTool) then
|
||
set dialogresult to (display dialog "The eReader script (erdr2pml.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
|
||
if button returned of dialogresult is "Quit" then
|
||
return false
|
||
end if
|
||
end if
|
||
if not fileexists(MobipocketTool) then
|
||
--display dialog MobipocketTool
|
||
set dialogresult to (display dialog "The Mobipocket script (k4mobidedrm.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
|
||
if button returned of dialogresult is "Quit" then
|
||
return false
|
||
end if
|
||
end if
|
||
if not fileexists(KindlePIDTool) then
|
||
--display dialog KindlePIDTool
|
||
set dialogresult to (display dialog "The KindlePID script (kindlepid.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
|
||
if button returned of dialogresult is "Quit" then
|
||
return false
|
||
end if
|
||
end if
|
||
if not fileexists(BNKeyGenTool) then
|
||
set dialogresult to (display dialog "The B&N Key Generation script (ignoblekeygen.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
|
||
if button returned of dialogresult is "Quit" then
|
||
return false
|
||
end if
|
||
end if
|
||
if not fileexists(BNePubTool) then
|
||
set dialogresult to (display dialog "The B&N script (ignobleepub.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
|
||
if button returned of dialogresult is "Quit" then
|
||
return false
|
||
end if
|
||
end if
|
||
if not fileexists(KindleKeyTool) then
|
||
set dialogresult to (display dialog "The Kindle Key Generation script (kindlekey.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
|
||
if button returned of dialogresult is "Quit" then
|
||
return false
|
||
end if
|
||
end if
|
||
if not fileexists(AdobeKeyGenTool) then
|
||
set dialogresult to (display dialog "The Adobe Key Generation script (adobekey.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
|
||
if button returned of dialogresult is "Quit" then
|
||
return false
|
||
end if
|
||
end if
|
||
if not fileexists(AdobePDFTool) then
|
||
set dialogresult to (display dialog "The Adobe PDF script (ineptpdf.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
|
||
if button returned of dialogresult is "Quit" then
|
||
return false
|
||
end if
|
||
end if
|
||
if not fileexists(AdobeePubTool) then
|
||
set dialogresult to (display dialog "The Adobe ePub script (ineptepub.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
|
||
if button returned of dialogresult is "Quit" then
|
||
return false
|
||
end if
|
||
end if
|
||
if not fileexists(ePubTestTool) then
|
||
set dialogresult to (display dialog "The ePub encryption test script (epubtesttool.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
|
||
if button returned of dialogresult is "Quit" then
|
||
return false
|
||
end if
|
||
end if
|
||
if not folderexists(ProgressApp) then
|
||
set dialogresult to (display dialog "The Progress dialog application (DeDRM Progress.app) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
|
||
if button returned of dialogresult is "Quit" then
|
||
return false
|
||
end if
|
||
end if
|
||
return true
|
||
end GetTools
|
||
|
||
on unlockmobifile(encryptedFile)
|
||
--check it's a mobi file.
|
||
set BOOKMOBI to "NOTAMOBI"
|
||
try
|
||
set BOOKMOBI to read file encryptedFile from 61 for 8
|
||
end try
|
||
if BOOKMOBI is not "BOOKMOBI" and BOOKMOBI is not "TEXtREAd" then
|
||
set TOPAZ to "NOT"
|
||
try
|
||
set TOPAZ to read file encryptedFile from 1 for 4
|
||
end try
|
||
if TOPAZ is not "TPZ0" then
|
||
set ErrorCount to ErrorCount + 1
|
||
set ErrorList to ErrorList & encryptedFile & " is neither a Kindle not a Mobipocket file.
|
||
"
|
||
return
|
||
end if
|
||
end if
|
||
set encryptedFilePath to POSIX path of file encryptedFile
|
||
tell application "Finder"
|
||
set parent_folder to (container of file encryptedFile) as text
|
||
set fileName to (name of file encryptedFile) as text
|
||
end tell
|
||
set fileExtension to "." & GetFileExtension(fileName)
|
||
set fileName to GetFileNameOnly(fileName)
|
||
if outputFolder is "" or not folderexists(outputFolder) then
|
||
set dedrmFolder to POSIX path of file parent_folder
|
||
else
|
||
set dedrmFolder to POSIX path of file outputFolder
|
||
end if
|
||
set shellcommand to python & (quoted form of MobipocketTool)
|
||
repeat with KindleKeyPath in KindleKeyList
|
||
set shellcommand to shellcommand & " -k " & quoted form of KindleKeyPath
|
||
end repeat
|
||
set Serialstring to GetSerialstring()
|
||
if Serialstring is not "" then set shellcommand to shellcommand & " -s " & quoted form of Serialstring
|
||
set PIDstring to GetPIDstring()
|
||
if PIDstring is "" then
|
||
set PIDstring to GetUDIDPIDs()
|
||
else
|
||
set PIDstring to PIDstring & "," & GetUDIDPIDs()
|
||
end if
|
||
|
||
if PIDstring is not "" then set shellcommand to shellcommand & " -p " & quoted form of PIDstring
|
||
set shellcommand to shellcommand & " " & (quoted form of encryptedFilePath) & " " & (quoted form of dedrmFolder)
|
||
set shellcommand to shellcommand & " > " & quotedtemppath()
|
||
--display dialog "shellcommand: " default answer shellcommand buttons {"OK"} default button 1 giving up after 10
|
||
writetolog("shellcommand: " & shellcommand)
|
||
cleartemp()
|
||
set DecodingError to false
|
||
set shellresult to ""
|
||
set ErrorText to ""
|
||
try
|
||
do shell script shellcommand
|
||
on error ErrorText number errnum
|
||
set DecodingError to true
|
||
end try
|
||
set shellresult to readtemp()
|
||
writetolog("shellresult: " & shellresult & " " & ErrorText)
|
||
try
|
||
repeat
|
||
if (totalebooks > 1) or (offset of "No key found" in shellresult) is 0 then
|
||
--display dialog (totalebooks as text) & shellresult
|
||
exit repeat
|
||
end if
|
||
-- ask for another PID as we're only doing one ebook
|
||
set newPID to "None"
|
||
set DialogPrompt to "Couldn't decode " & fileName & ". Do you have another PID to try?"
|
||
try
|
||
set dialogresult to (display dialog DialogPrompt default answer "" buttons {"Try This One", "No Extra PID"} with title "DeDRM" default button 2)
|
||
if button returned of dialogresult is "Try This One" then
|
||
set newPID to text returned of dialogresult
|
||
end if
|
||
end try
|
||
if newPID is "None" or (length of newPID is not 10 and length of newPID is not 8) then
|
||
exit repeat
|
||
end if
|
||
set shellcommand to python & (quoted form of MobipocketTool) & " -p " & quoted form of newPID & " " & (quoted form of encryptedFilePath) & " " & (quoted form of dedrmFolder)
|
||
set shellcommand to shellcommand & " > " & quotedtemppath()
|
||
--display dialog "shellcommand: " default answer shellcommand buttons {"OK"} default button 1 giving up after 10
|
||
writetolog("shellcommand: " & shellcommand)
|
||
set DecodingError to false
|
||
set shellresult to ""
|
||
set ErrorText to ""
|
||
try
|
||
do shell script shellcommand
|
||
on error ErrorText
|
||
set DecodingError to true
|
||
end try
|
||
set shellresult to readtemp()
|
||
writetolog("shellresult: " & shellresult & " " & ErrorText)
|
||
--display dialog shellresult
|
||
end repeat
|
||
if DecodingError then
|
||
set ErrorCount to ErrorCount + 1
|
||
set ErrorList to ErrorList & fileName & fileExtension & " couldn't be decrypted.
|
||
"
|
||
else if (offset of "not encrypted" in shellresult) > 0 then
|
||
set WarningCount to WarningCount + 1
|
||
set WarningList to WarningList & fileName & fileExtension & " is not encrypted.
|
||
"
|
||
else
|
||
set CompletedCount to CompletedCount + 1
|
||
set CompletedList to CompletedList & fileName & fileExtension & paraend
|
||
end if
|
||
end try
|
||
end unlockmobifile
|
||
|
||
on unlockpdbfile(encryptedFile)
|
||
--check it's an eReader file.
|
||
set PNRdPPrs to "NOT_eREADER"
|
||
try
|
||
set PNRdPPrs to read file encryptedFile from 61 for 8
|
||
end try
|
||
if PNRdPPrs is not "PNRdPPrs" then
|
||
set ErrorCount to ErrorCount + 1
|
||
set ErrorList to ErrorList & encryptedFile & " is not an eReader file.
|
||
"
|
||
return
|
||
end if
|
||
set encryptedFilePath to POSIX path of file encryptedFile
|
||
tell application "Finder"
|
||
set parent_folder to (container of file encryptedFile) as text
|
||
set fileName to (name of file encryptedFile) as text
|
||
end tell
|
||
set fileExtension to "." & GetFileExtension(fileName)
|
||
set fileName to GetFileNameOnly(fileName)
|
||
if outputFolder is "" or not folderexists(outputFolder) then
|
||
set dedrmFolder to parent_folder
|
||
else
|
||
set dedrmFolder to outputFolder
|
||
end if
|
||
set pmlFile to dedrmFolder & fileName & "_Source:" & fileName & ".pml"
|
||
set clearFile to dedrmFolder & fileName & "_Source:" & fileName & ".pdb"
|
||
set clearFileNew to dedrmFolder & fileName & "_Source:" & fileName & "_nodrm.pdb"
|
||
set clearFileNewName to fileName & "_nodrm.pdb"
|
||
set sourcePath to POSIX path of file dedrmFolder & fileName & "_Source/"
|
||
set pmlzFilePath to POSIX path of file dedrmFolder & fileName & "_nodrm.pmlz"
|
||
if length of bnKeys is 0 then
|
||
GetKeys(false, "DeDRM")
|
||
end if
|
||
set shellresult to "Error: No eReader/Barnes & Noble Name:Number keys supplied. Can't decrypt."
|
||
repeat with BNKey in bnKeys
|
||
set encryptionName to first item of BNKey
|
||
set encryptionNumber to second item of BNKey
|
||
if length of encryptionName > 0 and length of encryptionNumber > 0 then
|
||
set shellcommand to python & (quoted form of eReaderTool) & " " & (quoted form of encryptedFilePath) & " " & (quoted form of sourcePath) & " " & (quoted form of encryptionName) & " " & (quoted form of encryptionNumber)
|
||
set shellcommand to shellcommand & " > " & quotedtemppath()
|
||
--display dialog "shellcommand: " & shellcommand buttons {"OK"} default button 1 giving up after 10
|
||
writetolog("shellcommand: " & shellcommand)
|
||
set shellresult to "no result"
|
||
cleartemp()
|
||
set DecodingError to false
|
||
set ErrorText to ""
|
||
try
|
||
do shell script shellcommand
|
||
on error ErrorText
|
||
set DecodingError to true
|
||
end try
|
||
set shellresult to readtemp()
|
||
writetolog("shellresult: " & shellresult & " " & ErrorText)
|
||
--display dialog shellresult
|
||
if not DecodingError then
|
||
-- try to run dropbook and move compiled book to same folder as encrypted book
|
||
try
|
||
try
|
||
tell application "Finder" to set DropBook to (application file id "PPDr") as string
|
||
on error
|
||
error "Couldn't find DropBook application"
|
||
end try
|
||
-- now also compile back up into pdb file using DropBook if it's on this system
|
||
tell application DropBook to open file pmlFile
|
||
delay 1 -- probably don't need this, but just in case.
|
||
tell application DropBook to quit -- DropBook will quit only after the compilation has happened
|
||
try
|
||
tell application "Finder"
|
||
set name of file clearFile to clearFileNewName
|
||
move clearFileNew to dedrmFolder
|
||
end tell
|
||
on error errmsg
|
||
error "DropBook failed to compile the source folder into a pdb file."
|
||
end try
|
||
on error errmsg
|
||
set WarningCount to WarningCount + 1
|
||
set WarningList to (WarningList & fileName & fileExtension & " couldn't be compiled back to pdb:
|
||
" & errmsg as text) & "
|
||
"
|
||
end try
|
||
-- try to compress source folder contensts to a pmlz file for easy import into Calibre
|
||
try
|
||
set shellcommand to "cd " & quoted form of sourcePath & "; zip -r " & quoted form of pmlzFilePath & " *"
|
||
--display dialog shellcommand
|
||
writetolog("shellcommand: " & shellcommand)
|
||
set zipshellresult to ""
|
||
set zipshellresult to do shell script shellcommand
|
||
writetolog("shellresult: " & zipshellresult)
|
||
--display dialog zipshellresult
|
||
tell application "Finder"
|
||
-- move source folder to the trash
|
||
move dedrmFolder & fileName & "_Source" to trash
|
||
end tell
|
||
on error errmsg
|
||
set WarningCount to WarningCount + 1
|
||
set WarningList to (WarningList & fileName & fileExtension & "source folder couldn't be compressed to pmlz:
|
||
" & errmsg as text) & "
|
||
|
||
"
|
||
end try
|
||
-- we've done the decrypting so exit the loop.
|
||
exit repeat
|
||
end if
|
||
end if
|
||
end repeat
|
||
try
|
||
if (offset of "incorrect eReader version 10" in shellresult) > 0 then
|
||
set WarningCount to WarningCount + 1
|
||
set WarningList to WarningList & fileName & fileExtension & " is not encrypted.
|
||
"
|
||
else if DecodingError then
|
||
set ErrorCount to ErrorCount + 1
|
||
set ErrorList to (ErrorList & fileName & fileExtension & " couldn't be decoded:
|
||
" & ErrorText as text) & "
|
||
"
|
||
else
|
||
set CompletedCount to CompletedCount + 1
|
||
set CompletedList to CompletedList & fileName & fileExtension & paraend
|
||
end if
|
||
end try
|
||
end unlockpdbfile
|
||
|
||
on unlockepubfile(encryptedFile)
|
||
set encryptedFilePath to POSIX path of file encryptedFile
|
||
tell application "Finder"
|
||
set parent_folder to (container of file encryptedFile) as text
|
||
set fileName to (name of file encryptedFile) as text
|
||
end tell
|
||
set fileExtension to "." & GetFileExtension(fileName)
|
||
set fileName to GetFileNameOnly(fileName)
|
||
|
||
set decoded to "NO"
|
||
-- first we must fix any possible zip problems with the epub
|
||
if outputFolder is "" or not folderexists(outputFolder) then
|
||
set fixedFilePath to POSIX path of file (parent_folder & fileName & "_fixed" & fileExtension)
|
||
else
|
||
set fixedFilePath to POSIX path of file (outputFolder & fileName & "_fixed" & fileExtension)
|
||
end if
|
||
set shellcommand to python & (quoted form of ZipFixTool) & " " & (quoted form of encryptedFilePath) & " " & (quoted form of fixedFilePath)
|
||
set shellcommand to shellcommand & " > " & quotedtemppath()
|
||
writetolog("shellcommand: " & shellcommand)
|
||
cleartemp()
|
||
set ZipErrorText to ""
|
||
set ZipFixError to false
|
||
try
|
||
--display dialog "shellcommand: " default answer shellcommand buttons {"OK"} default button 1 giving up after 10
|
||
do shell script shellcommand
|
||
on error errmsg
|
||
set ZipErrorText to errmsg
|
||
set ZipFixError to true
|
||
end try
|
||
set shellresult to readtemp()
|
||
writetolog("shellresult: " & shellresult & " " & ZipErrorText)
|
||
--display dialog shellresult
|
||
|
||
if ZipFixError then
|
||
set ErrorCount to ErrorCount + 1
|
||
set ErrorList to ((ErrorList & fileName & fileExtension & " had a problem with ZipFix:
|
||
" & ZipErrorText as text) & "
|
||
")
|
||
return
|
||
end if
|
||
|
||
--check it's an ePub file.
|
||
set ePubSig to "NOT_ePub"
|
||
try
|
||
set ePubSig to read POSIX file fixedFilePath from 31 for 28
|
||
end try
|
||
--display dialog ePubSig
|
||
if ePubSig is not "mimetypeapplication/epub+zip" then
|
||
set ErrorCount to ErrorCount + 1
|
||
set ErrorList to ErrorList & encryptedFile & " is not an ePub file.
|
||
"
|
||
tell application "Finder"
|
||
move alias ((POSIX file fixedFilePath) as text) to trash
|
||
end tell
|
||
return
|
||
end if
|
||
|
||
if outputFolder is "" or not folderexists(outputFolder) then
|
||
set unlockedFilePath to POSIX path of file (parent_folder & fileName & "_nodrm" & fileExtension)
|
||
else
|
||
set unlockedFilePath to POSIX path of file (outputFolder & fileName & "_nodrm" & fileExtension)
|
||
end if
|
||
set shellresult to "no keys"
|
||
set ErrorText to ""
|
||
|
||
-- get encryption type
|
||
set TryBandNePub to true
|
||
set TryAdobeePub to true
|
||
set shellcommand to python & (quoted form of ePubTestTool) & " " & (quoted form of fixedFilePath)
|
||
set shellcommand to shellcommand & " > " & quotedtemppath()
|
||
--display dialog "shellcommand: " & shellcommand buttons {"OK"} default button 1 giving up after 10
|
||
writetolog("shellcommand: " & shellcommand)
|
||
cleartemp()
|
||
set TestError to false
|
||
set ErrorText to ""
|
||
try
|
||
do shell script shellcommand
|
||
on error ErrorText
|
||
set TestError to true
|
||
end try
|
||
set shellresult to readtemp()
|
||
writetolog("shellresult: " & shellresult & " " & ErrorText)
|
||
--display dialog shellresult
|
||
if not TestError then
|
||
if (offset of "B&N" in shellresult) > 0 then
|
||
set TryAdobeePub to false
|
||
else if (offset of "Adobe" in shellresult) > 0 then
|
||
set TryBandNePub to false
|
||
else if (offset of "Unencrypted" in shellresult) > 0 then
|
||
set TryAdobeePub to false
|
||
set TryBandNePub to false
|
||
end if
|
||
end if
|
||
|
||
|
||
-- first we'll try the Barnes & Noble keys
|
||
if TryBandNePub then
|
||
repeat with BNKey in bnKeys
|
||
|
||
set keyfilepath to third item of BNKey
|
||
if length of keyfilepath > 0 then
|
||
set shellcommand to python & (quoted form of BNePubTool) & " " & (quoted form of keyfilepath) & " " & (quoted form of fixedFilePath) & " " & (quoted form of unlockedFilePath)
|
||
set shellcommand to shellcommand & " > " & quotedtemppath()
|
||
--display dialog "shellcommand: " & shellcommand buttons {"OK"} default button 1 giving up after 10
|
||
writetolog("shellcommand: " & shellcommand)
|
||
cleartemp()
|
||
set DecodingError to false
|
||
set ErrorText to ""
|
||
try
|
||
do shell script shellcommand
|
||
on error ErrorText
|
||
set DecodingError to true
|
||
end try
|
||
set shellresult to readtemp()
|
||
writetolog("shellresult: " & shellresult & " " & ErrorText)
|
||
--display dialog shellresult
|
||
if not DecodingError then
|
||
set decoded to "YES"
|
||
exit repeat
|
||
end if
|
||
end if
|
||
end repeat
|
||
end if
|
||
|
||
if decoded is "NO" and TryAdobeePub then
|
||
-- now try Adobe ePub
|
||
repeat with AdeptKey in AdeptKeyList
|
||
set shellcommand to python & (quoted form of AdobeePubTool) & " " & (quoted form of AdeptKey) & " " & (quoted form of fixedFilePath) & " " & (quoted form of unlockedFilePath)
|
||
set shellcommand to shellcommand & " > " & quotedtemppath()
|
||
--display dialog "shellcommand: " default answer shellcommand buttons {"OK"} default button 1 giving up after 10
|
||
writetolog("shellcommand: " & shellcommand)
|
||
cleartemp()
|
||
set DecodingError to false
|
||
set ErrorText to ""
|
||
try
|
||
do shell script shellcommand
|
||
on error ErrorText
|
||
set DecodingError to true
|
||
end try
|
||
set shellresult to readtemp() as text
|
||
writetolog("shellresult: " & shellresult & " " & ErrorText)
|
||
--display dialog shellresult
|
||
if not DecodingError then
|
||
set decoded to "YES"
|
||
exit repeat
|
||
end if
|
||
end repeat
|
||
end if
|
||
|
||
if decoded is "YES" then
|
||
set CompletedCount to CompletedCount + 1
|
||
set CompletedList to CompletedList & fileName & fileExtension & paraend
|
||
else if not TryAdobeePub and not TryBandNePub then
|
||
set WarningCount to WarningCount + 1
|
||
set WarningList to (WarningList & fileName & " doesn't seem to be encrypted.
|
||
")
|
||
else if shellresult is "no keys" then
|
||
set ErrorCount to ErrorCount + 1
|
||
set ErrorList to (ErrorList & fileName & fileExtension & " couldn't be decoded: no keys.
|
||
")
|
||
else
|
||
set ErrorCount to ErrorCount + 1
|
||
set ErrorList to ((ErrorList & fileName & fileExtension & " couldn't be decoded:
|
||
" & ErrorText as text) & "
|
||
")
|
||
end if
|
||
|
||
tell application "Finder"
|
||
move alias ((POSIX file fixedFilePath) as text) to trash
|
||
end tell
|
||
end unlockepubfile
|
||
|
||
on unlockpdffile(encryptedFile)
|
||
--check it's an ePub file.
|
||
set PDFSig to "NOT_PDF"
|
||
try
|
||
set PDFSig to read file encryptedFile from 1 for 4
|
||
end try
|
||
--display dialog PDFSig
|
||
if PDFSig is not "%PDF" then
|
||
set ErrorCount to ErrorCount + 1
|
||
set ErrorList to ErrorList & encryptedFile & " is not a PDF file.
|
||
"
|
||
return
|
||
end if
|
||
set encryptedFilePath to POSIX path of file encryptedFile
|
||
tell application "Finder"
|
||
set parent_folder to (container of file encryptedFile) as text
|
||
set fileName to (name of file encryptedFile) as text
|
||
end tell
|
||
set fileExtension to "." & GetFileExtension(fileName)
|
||
set fileName to GetFileNameOnly(fileName)
|
||
|
||
set decoded to "NO"
|
||
-- first we must check we have a PDF script
|
||
if not fileexists(AdobePDFTool) then
|
||
set ErrorCount to ErrorCount + 1
|
||
set ErrorList to ErrorList & encryptedFile & " is a PDF file and no ineptpdf script found.
|
||
"
|
||
return
|
||
end if
|
||
|
||
if outputFolder is "" or not folderexists(outputFolder) then
|
||
set unlockedFilePath to POSIX path of file (parent_folder & fileName & "_nodrm" & fileExtension)
|
||
else
|
||
set unlockedFilePath to POSIX path of file (outputFolder & fileName & "_nodrm" & fileExtension)
|
||
end if
|
||
set decoded to false
|
||
set shellresult to "no keys"
|
||
set ErrorText to ""
|
||
|
||
repeat with AdeptKey in AdeptKeyList
|
||
set shellcommand to python & (quoted form of AdobePDFTool) & " " & (quoted form of AdeptKey) & " " & (quoted form of encryptedFilePath) & " " & (quoted form of unlockedFilePath)
|
||
set shellcommand to shellcommand & " > " & quotedtemppath()
|
||
--display dialog "shellcommand: " default answer shellcommand buttons {"OK"} default button 1 giving up after 10
|
||
writetolog("shellcommand: " & shellcommand)
|
||
cleartemp()
|
||
set DecodingError to false
|
||
set ErrorText to ""
|
||
try
|
||
do shell script shellcommand
|
||
on error ErrorText
|
||
set DecodingError to true
|
||
end try
|
||
set shellresult to readtemp()
|
||
writetolog("shellresult: " & shellresult & " " & ErrorText)
|
||
--display dialog shellresult
|
||
if not DecodingError then
|
||
set decoded to true
|
||
exit repeat
|
||
end if
|
||
end repeat
|
||
|
||
if decoded then
|
||
set CompletedCount to CompletedCount + 1
|
||
set CompletedList to CompletedList & fileName & fileExtension & paraend
|
||
else if shellresult is "no keys" then
|
||
set ErrorCount to ErrorCount + 1
|
||
set ErrorList to (ErrorList & fileName & fileExtension & " couldn't be decoded: no keys.
|
||
")
|
||
else
|
||
set ErrorCount to ErrorCount + 1
|
||
set ErrorList to ((ErrorList & fileName & fileExtension & " couldn't be decoded:
|
||
" & ErrorText as text) & "
|
||
")
|
||
end if
|
||
end unlockpdffile
|
||
|
||
on handlefile(droppedFile)
|
||
tell application "Finder"
|
||
set fileName to (name of file droppedFile) as text
|
||
end tell
|
||
writetolog("Processing file: " & fileName)
|
||
set fileExtension to GetFileExtension(fileName)
|
||
set fileName to GetFileNameOnly(fileName)
|
||
if fileExtension is "prc" or fileExtension is "mobi" or fileExtension is "azw" or fileExtension is "azw1" or fileExtension is "tpz" or fileExtension is "azw3" or fileExtension is "azw4" then
|
||
set completedebooks to completedebooks + 1
|
||
IncProgress(fileName, completedebooks)
|
||
unlockmobifile(droppedFile as text)
|
||
else if fileExtension is "pdb" then
|
||
set completedebooks to completedebooks + 1
|
||
IncProgress(fileName, completedebooks)
|
||
unlockpdbfile(droppedFile as text)
|
||
else if fileExtension is "epub" then
|
||
set completedebooks to completedebooks + 1
|
||
IncProgress(fileName, completedebooks)
|
||
unlockepubfile(droppedFile as text)
|
||
else if fileExtension is "pdf" then
|
||
set completedebooks to completedebooks + 1
|
||
IncProgress(fileName, completedebooks)
|
||
unlockpdffile(droppedFile as text)
|
||
end if
|
||
end handlefile
|
||
|
||
on handlefolder(droppedFolder)
|
||
tell application "Finder" to set fileList to (every file in folder droppedFolder)
|
||
tell application "Finder" to set folderList to (every folder in folder droppedFolder)
|
||
repeat with this_item in fileList
|
||
if not ProgressActive() then
|
||
exit repeat
|
||
end if
|
||
handlefile(this_item as text)
|
||
end repeat
|
||
repeat with this_item in folderList
|
||
if not ProgressActive() then
|
||
exit repeat
|
||
end if
|
||
handlefolder(this_item as text)
|
||
end repeat
|
||
end handlefolder
|
||
|
||
on countfile(droppedFile)
|
||
tell application "Finder"
|
||
set fileName to (name of file droppedFile) as text
|
||
end tell
|
||
set fileExtension to GetFileExtension(fileName)
|
||
set fileName to GetFileNameOnly(fileName)
|
||
--display dialog "fileName: " & fileName & "
|
||
--extension: " & fileExtension
|
||
if fileExtension is in handledExtensions then
|
||
set totalebooks to totalebooks + 1
|
||
end if
|
||
end countfile
|
||
|
||
on GetSerialstring()
|
||
set Serialstring to ""
|
||
repeat with Serial in KindleSerialList
|
||
if Serialstring is "" then
|
||
set Serialstring to Serial
|
||
else
|
||
set Serialstring to Serialstring & "," & Serial
|
||
end if
|
||
end repeat
|
||
return Serialstring
|
||
end GetSerialstring
|
||
|
||
on GetPIDstring()
|
||
set PIDstring to ""
|
||
repeat with PID in PIDs
|
||
if PIDstring is "" then
|
||
set PIDstring to PID
|
||
else
|
||
set PIDstring to PIDstring & "," & PID
|
||
end if
|
||
end repeat
|
||
return PIDstring
|
||
end GetPIDstring
|
||
|
||
on GetUDIDstring()
|
||
set UDIDstring to ""
|
||
repeat with UDIDPair in UDIDs
|
||
if UDIDstring is "" then
|
||
set UDIDstring to first item of UDIDPair
|
||
else
|
||
set UDIDstring to UDIDstring & "," & first item of UDIDPair
|
||
end if
|
||
end repeat
|
||
return UDIDstring
|
||
end GetUDIDstring
|
||
|
||
on GetUDIDPIDs()
|
||
set UDIDPIDs to ""
|
||
repeat with UDIDPair in UDIDs
|
||
if UDIDPIDs is "" then
|
||
set UDIDPIDs to second item of UDIDPair
|
||
else
|
||
set UDIDPIDs to UDIDPIDs & "," & second item of UDIDPair
|
||
end if
|
||
end repeat
|
||
return UDIDPIDs
|
||
end GetUDIDPIDs
|
||
|
||
on GetAdeptstring()
|
||
set Adeptstring to ""
|
||
repeat with AdeptKeyFile in AdeptKeyList
|
||
set AppleTypeFile to POSIX file (AdeptKeyFile as text)
|
||
tell application "Finder"
|
||
set fileName to name of file (AppleTypeFile as text)
|
||
end tell
|
||
|
||
if Adeptstring is "" then
|
||
set Adeptstring to fileName
|
||
else
|
||
set Adeptstring to Adeptstring & "
|
||
" & fileName
|
||
end if
|
||
end repeat
|
||
return Adeptstring
|
||
end GetAdeptstring
|
||
|
||
on GetKindlestring()
|
||
set Kindlestring to ""
|
||
repeat with KindleKeyFile in KindleKeyList
|
||
set AppleTypeFile to POSIX file (KindleKeyFile as text)
|
||
tell application "Finder"
|
||
set fileName to name of file (AppleTypeFile as text)
|
||
end tell
|
||
|
||
if Kindlestring is "" then
|
||
set Kindlestring to fileName
|
||
else
|
||
set Kindlestring to Kindlestring & "
|
||
" & fileName
|
||
end if
|
||
end repeat
|
||
return Kindlestring
|
||
end GetKindlestring
|
||
|
||
on GetBNKeystring()
|
||
set BNKeystring to ""
|
||
repeat with BNKey in bnKeys
|
||
if BNKeystring is "" then
|
||
set BNKeystring to first item of BNKey & ":" & second item of BNKey
|
||
else
|
||
set BNKeystring to BNKeystring & "
|
||
" & first item of BNKey & ":" & second item of BNKey
|
||
end if
|
||
if length of third item of BNKey > 0 then
|
||
set BNKeystring to BNKeystring & "*"
|
||
end if
|
||
if length of second item of BNKey > 0 then
|
||
set BNKeystring to BNKeystring & "†"
|
||
end if
|
||
end repeat
|
||
return BNKeystring
|
||
end GetBNKeystring
|
||
|
||
|
||
on GetUDIDs(DialogTitle)
|
||
set UDID to ""
|
||
repeat
|
||
set UDIDstring to GetUDIDstring()
|
||
if UDIDstring is "" then
|
||
set DialogPrompt to "Enter any iPod/iPhone/iPad UDIDs (40 characters) one at a time. Note: This only works for older versions of Kindle for iOS."
|
||
set FinishedButton to "Close"
|
||
else
|
||
set DialogPrompt to "Current UDIDs: " & UDIDstring & ".
|
||
|
||
Enter any additional iPod/iPhone/iPad UDIDs (40 characters) one at a time:"
|
||
set FinishedButton to "Close"
|
||
end if
|
||
set dialogresult to (display dialog DialogPrompt default answer UDID buttons {"Delete All", "Add", FinishedButton} with title DialogTitle default button 2)
|
||
if button returned of dialogresult is "Add" then
|
||
set UDID to text returned of dialogresult
|
||
set UDIDlength to length of UDID
|
||
if UDIDlength is 40 then
|
||
set shellresult to ""
|
||
set scriptError to ""
|
||
set shellcommand to python & (quoted form of KindlePIDTool) & " " & (quoted form of UDID)
|
||
writetolog("shellcommand: " & shellcommand)
|
||
try
|
||
set shellresult to do shell script shellcommand
|
||
on error errmsg
|
||
set shellresult to ""
|
||
set scriptError to "KindlePID Script failed:" & " " & errmsg
|
||
end try
|
||
writetolog("shellresult: " & scriptError & " " & shellresult)
|
||
--display dialog shellresult
|
||
|
||
if shellresult is not "" then
|
||
set PID to (text -10 thru -1 of shellresult)
|
||
if UDIDs contains {{UDID, PID}} then
|
||
display dialog "UDID " & UDID & " is already in your list of UDIDs." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
else
|
||
display dialog "The equivalent UDID for UDID " & UDID & " is " & PID & ". Adding to list." buttons {"OK"} default button 1 with title "DeDRM" with icon note
|
||
set UDIDs to UDIDs & {{UDID, PID}}
|
||
set UDID to ""
|
||
end if
|
||
else
|
||
writetolog(scriptError)
|
||
display dialog "Error generating PID from this UDID, error message was: " & scriptError buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
end if
|
||
else
|
||
display dialog "UDIDs must be 40 characters." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
end if
|
||
else if button returned of dialogresult is "Delete All" then
|
||
if UDIDstring is not "" then
|
||
try
|
||
set dialogresult to (display dialog "Are you sure you want to delete all stored UDIDs?" buttons {"Cancel", "Delete"} default button 1 with title "DeDRM")
|
||
end try
|
||
if button returned of dialogresult is "Delete" then
|
||
set UDIDs to {}
|
||
end if
|
||
end if
|
||
else
|
||
set UDID to text returned of dialogresult
|
||
if UDID is not "" then
|
||
try
|
||
set dialogresult to (display dialog "You entered some text, but didn't click Add. Are you sure you want to more on to the next dialog?" buttons {"Whoops", "Yes, Move on"} default button 1 with title "DeDRM")
|
||
end try
|
||
if button returned of dialogresult is "Yes, Move on" then
|
||
exit repeat
|
||
end if
|
||
else
|
||
exit repeat
|
||
end if
|
||
end if
|
||
end repeat
|
||
end GetUDIDs
|
||
|
||
on GetPIDs(DialogTitle)
|
||
set PID to ""
|
||
repeat
|
||
set PIDstring to GetPIDstring()
|
||
if PIDstring is "" then
|
||
set DialogPrompt to "Enter any Mobipocket PIDs one at a time:"
|
||
set FinishedButton to "Close"
|
||
else
|
||
set DialogPrompt to "Current PIDs: " & PIDstring & ".
|
||
|
||
Enter any additional Mobipocket PIDs one at a time:"
|
||
set FinishedButton to "Close"
|
||
end if
|
||
set dialogresult to (display dialog DialogPrompt default answer PID buttons {"Delete All", "Add", FinishedButton} with title DialogTitle default button 2)
|
||
if button returned of dialogresult is "Add" then
|
||
set PID to text returned of dialogresult
|
||
set PIDlength to length of PID
|
||
if PIDlength is 8 or PIDlength is 10 then
|
||
if PIDs contains PID then
|
||
display dialog "PID" & PID & " is already in your list of PIDs." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
else
|
||
set PIDs to PIDs & PID
|
||
set PID to ""
|
||
end if
|
||
else
|
||
display dialog "PIDs must be 8 or 10 characters long, and UDIDs must be 40 characters." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
end if
|
||
else if button returned of dialogresult is "Delete All" then
|
||
if PIDstring is not "" then
|
||
try
|
||
set dialogresult to (display dialog "Are you sure you want to delete all stored PIDs?" buttons {"Cancel", "Delete"} default button 1 with title "DeDRM")
|
||
end try
|
||
if button returned of dialogresult is "Delete" then
|
||
set PIDs to {}
|
||
end if
|
||
end if
|
||
else
|
||
set PID to text returned of dialogresult
|
||
if PID is not "" then
|
||
try
|
||
set dialogresult to (display dialog "You entered some text, but didn't click Add. Are you sure you want to more on to the next dialog?" buttons {"Whoops", "Yes, Move on"} default button 1 with title "DeDRM")
|
||
end try
|
||
if button returned of dialogresult is "Yes, Move on" then
|
||
exit repeat
|
||
end if
|
||
else
|
||
exit repeat
|
||
end if
|
||
end if
|
||
end repeat
|
||
end GetPIDs
|
||
|
||
on GetSerials(DialogTitle)
|
||
set Serial to ""
|
||
repeat
|
||
set Serialstring to GetSerialstring()
|
||
if Serialstring is "" then
|
||
set DialogPrompt to "Enter any Kindle (not Kindle Fire) Serial Numbers, or Apple iPod/iPhone/iPad UDIDs one at a time:"
|
||
set FinishedButton to "Close"
|
||
else
|
||
set DialogPrompt to "Current Kindle Serial Numbers: " & Serialstring & ".
|
||
|
||
Enter any additional Kindle Serial Numbers one at a time:"
|
||
set FinishedButton to "Close"
|
||
end if
|
||
set dialogresult to (display dialog DialogPrompt default answer Serial buttons {"Delete All", "Add", FinishedButton} with title DialogTitle default button 2)
|
||
if button returned of dialogresult is "Add" then
|
||
set Serial to text returned of dialogresult
|
||
set Seriallength to length of Serial
|
||
if Seriallength is 16 and ((first character of Serial) is "B" or (first character of Serial) is "9") then
|
||
set KindleSerialList to KindleSerialList & Serial
|
||
set Serial to ""
|
||
else
|
||
display dialog "Kindle Serial Numbers are 16 characters long and start with B." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
end if
|
||
else if button returned of dialogresult is "Delete All" then
|
||
if Serialstring is not "" then
|
||
try
|
||
set dialogresult to (display dialog "Are you sure you want to delete all stored Kindle Serial Numbers?" buttons {"Cancel", "Delete"} default button 1 with title "DeDRM")
|
||
end try
|
||
if button returned of dialogresult is "Delete" then
|
||
set KindleSerialList to {}
|
||
end if
|
||
end if
|
||
else
|
||
set Serial to text returned of dialogresult
|
||
if Serial is not "" then
|
||
try
|
||
set dialogresult to (display dialog "You entered some text, but didn't click Add. Are you sure you want to more on to the next dialog?" buttons {"Whoops", "Yes, Move on"} default button 1 with title "DeDRM")
|
||
end try
|
||
if button returned of dialogresult is "Yes, Move on" then
|
||
exit repeat
|
||
end if
|
||
else
|
||
exit repeat
|
||
end if
|
||
end if
|
||
end repeat
|
||
end GetSerials
|
||
|
||
on GetOutputFolder(DialogTitle)
|
||
set newFolder to ""
|
||
try
|
||
tell me to activate
|
||
repeat
|
||
|
||
if folderexists(outputFolder) then
|
||
set DialogPrompt to "The deDRMed ebooks will be saved to the following folder:
|
||
" & (outputFolder) & "
|
||
|
||
"
|
||
else
|
||
set outputFolder to ""
|
||
set DialogPrompt to "The deDRMed ebooks will be saved in the same folder as the original DRMed ebooks.
|
||
|
||
"
|
||
end if
|
||
set DialogPrompt to DialogPrompt & "To keep this choice, click 'Close', otherwise select the option you want by clicking on one of the other buttons."
|
||
set dialogresult to (display dialog DialogPrompt buttons {"Use Same Folder as DRMed Ebooks", "Choose Output Folder…", "Close"} with title DialogTitle default button 3)
|
||
if button returned of dialogresult is "Choose Output Folder…" then
|
||
try
|
||
if outputFolder is "" then
|
||
set outputFolder to ((choose folder with prompt "DRM Application
|
||
Please choose the Output Folder for DeDRMed ebooks.") as text)
|
||
else
|
||
set outputFolder to ((choose folder with prompt "DRM Application
|
||
Please choose the Output Folder for DeDRMed ebooks." default location alias outputFolder) as text)
|
||
end if
|
||
end try
|
||
else if button returned of dialogresult is "Use Same Folder as DRMed Ebooks" then
|
||
set outputFolder to ""
|
||
else
|
||
exit repeat
|
||
end if
|
||
--on error errormessage
|
||
-- display dialog errormessage
|
||
end repeat
|
||
end try
|
||
WritePrefs()
|
||
end GetOutputFolder
|
||
|
||
on GetKeys(running, DialogTitle)
|
||
set bnKeyText to ""
|
||
repeat
|
||
set BNKeystring to GetBNKeystring()
|
||
if BNKeystring is "" then
|
||
set DialogPrompt to "Please enter any "
|
||
set FinishedButton to "Close"
|
||
else
|
||
set DialogPrompt to "Current B&N keys*, eReader keys†:
|
||
" & BNKeystring & "
|
||
|
||
|
||
Please enter any additional "
|
||
set FinishedButton to "Close"
|
||
end if
|
||
set DialogPrompt to DialogPrompt & "eReader/Barnes & Noble Name,Number key pairs one at a time. The name is usually your name as on your credit card, but might be your Barnes & Noble user name. If you're only decoding eReader files, the last 8 digits of the Number will do. The full 15 or 16 are only needed for Barnes & Noble ePubs. Only the last eight will be stored or displayed. Please separate the name and number with a comma and click \"Add\". Or to add a an already generated .b64 file, just click \"Add\" with nothing in the text field."
|
||
set dialogresult to (display dialog DialogPrompt default answer bnKeyText with title DialogTitle buttons {"Delete All", "Add", FinishedButton} default button 2)
|
||
if button returned of dialogresult is "Add" then
|
||
set bnKeyText to text returned of dialogresult
|
||
if bnKeyText is "" then
|
||
try
|
||
set newFile to (choose file with prompt "Please select a Barnes & Noble (.b64) key file") as text
|
||
-- copy to prefs
|
||
AddbnKey(newFile)
|
||
on error message
|
||
if message does not contain "cancel" then
|
||
display dialog message
|
||
end if
|
||
end try
|
||
else if not (bnKeyText contains ",") then
|
||
display dialog "Name and Number must be separated by a comma (,)." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
else
|
||
set oldTIDs to AppleScript's text item delimiters
|
||
set AppleScript's text item delimiters to ","
|
||
set keyNumber to the last text item of bnKeyText
|
||
set keyName to (text items 1 through -2 of bnKeyText) as string
|
||
set AppleScript's text item delimiters to oldTIDs
|
||
|
||
if ((length of keyNumber) = 16 or (length of keyNumber) = 15 or (length of keyNumber) = 8) and (length of keyName) > 0 then
|
||
set shellresult to ""
|
||
set keyfilepath to ""
|
||
if (length of keyNumber) = 16 or (length of keyNumber) = 15 then
|
||
-- get the B&N key from this pair
|
||
set shellresult to ""
|
||
set scriptError to ""
|
||
set success to true
|
||
set prefsFolder to (path to preferences from user domain as string) & prefsFolderName & ":"
|
||
set keyfileName to GetUniqueName(prefsFolder, keyName & (text -8 thru -1 of keyNumber) & ".b64")
|
||
set keyfilepath to POSIX path of (prefsFolder & keyfileName)
|
||
set shellcommand to python & (quoted form of BNKeyGenTool) & " " & (quoted form of keyName) & " " & (quoted form of keyNumber) & " " & quoted form of keyfilepath
|
||
set shellcommand to shellcommand & " > " & quotedtemppath()
|
||
|
||
writetolog("shellcommand: " & shellcommand)
|
||
cleartemp()
|
||
try
|
||
do shell script shellcommand
|
||
on error scriptError
|
||
set success to false
|
||
end try
|
||
set shellresult to readtemp()
|
||
writetolog("shellresult: " & scriptError & " " & shellresult)
|
||
--display dialog shellresult
|
||
end if
|
||
if success then
|
||
set bnKeys to bnKeys & {{keyName, (text -8 thru -1 of keyNumber), keyfilepath}}
|
||
set bnKeyText to ""
|
||
else
|
||
display dialog "Error generating key from this info, error message was: " & scriptError buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
end if
|
||
else
|
||
display dialog "Key numbers must be 8 or 15 or 16 characters long (no spaces) and the key name must not be absent." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
end if
|
||
end if
|
||
else if button returned of dialogresult is "Delete All" then
|
||
if BNKeystring is not "" then
|
||
try
|
||
set dialogresult to (display dialog "Are you sure you want to delete all stored Name:Number key pairs?" buttons {"Cancel", "Delete"} default button 1 with title "DeDRM")
|
||
end try
|
||
if button returned of dialogresult is "Delete" then
|
||
set bnKeys to {}
|
||
end if
|
||
end if
|
||
set bnKeyText to ""
|
||
else
|
||
set bnKeyText to text returned of dialogresult
|
||
if bnKeyText is not "" then
|
||
try
|
||
set dialogresult to (display dialog "You entered some text, but didn't click Add. Are you sure you want to more on to the next dialog?" buttons {"Whoops", "Yes, Move on"} default button 1 with title "DeDRM")
|
||
end try
|
||
if button returned of dialogresult is "Yes, Move on" then
|
||
exit repeat
|
||
end if
|
||
else
|
||
exit repeat
|
||
end if
|
||
end if
|
||
end repeat
|
||
end GetKeys
|
||
|
||
on GetAdeptKeyFiles(DialogTitle)
|
||
repeat
|
||
set Adeptstring to GetAdeptstring()
|
||
if Adeptstring is "" then
|
||
set DialogPrompt to "To add Adobe Digital Editions (Adept) key files, click the Add… button. "
|
||
set FinishedButton to "Close"
|
||
else
|
||
set DialogPrompt to "Current Adobe Digital Editions (Adept) key files:
|
||
" & Adeptstring & "
|
||
|
||
To add extra key files (.der), click the Add… button."
|
||
set FinishedButton to "Close"
|
||
end if
|
||
set dialogresult to (display dialog DialogPrompt buttons {"Forget All", "Add…", FinishedButton} with title DialogTitle default button 2)
|
||
if button returned of dialogresult is "Add…" then
|
||
try
|
||
set newFile to (choose file with prompt "Please select an Adobe Digital Editions (.der) key file") as text
|
||
-- copy to prefs
|
||
AddAdeptKey(newFile)
|
||
on error message
|
||
if message does not contain "cancel" then
|
||
display dialog message
|
||
end if
|
||
end try
|
||
|
||
else if button returned of dialogresult is "Forget All" then
|
||
if Adeptstring is not "" then
|
||
try
|
||
set dialogresult to (display dialog "Are you sure you want to forget all extra Adobe Digital Editions Adept key files?" buttons {"Cancel", "Forget"} default button 1 with title "DeDRM")
|
||
end try
|
||
if button returned of dialogresult is "Forget" then
|
||
set AdeptKeyList to {}
|
||
GetAdeptKey(false)
|
||
end if
|
||
end if
|
||
else
|
||
exit repeat
|
||
end if
|
||
end repeat
|
||
end GetAdeptKeyFiles
|
||
|
||
on GetKindleKeyFiles(DialogTitle)
|
||
repeat
|
||
set Kindlestring to GetKindlestring()
|
||
if Kindlestring is "" then
|
||
set DialogPrompt to "To add Kindle for Mac key files (.k4i), click the Add… button. "
|
||
set FinishedButton to "Close"
|
||
else
|
||
set DialogPrompt to "Current Kindle for Mac key files:
|
||
" & Kindlestring & "
|
||
|
||
To add extra key files (.k4i), click the Add… button."
|
||
set FinishedButton to "Close"
|
||
end if
|
||
set dialogresult to (display dialog DialogPrompt buttons {"Forget All", "Add…", FinishedButton} with title DialogTitle default button 2)
|
||
if button returned of dialogresult is "Add…" then
|
||
try
|
||
set newFile to (choose file with prompt "Please select a Kindle for Mac/PC (.k4i) key file") as text
|
||
-- copy to prefs
|
||
AddKindleKey(newFile)
|
||
on error message
|
||
if message does not contain "cancel" then
|
||
display dialog message
|
||
end if
|
||
end try
|
||
|
||
else if button returned of dialogresult is "Forget All" then
|
||
if Kindlestring is not "" then
|
||
try
|
||
set dialogresult to (display dialog "Are you sure you want to forget all extra Kindle for Mac key files?" buttons {"Cancel", "Forget"} default button 1 with title "DeDRM")
|
||
end try
|
||
if button returned of dialogresult is "Forget" then
|
||
set KindleKeyList to {}
|
||
GetKindleKey(false)
|
||
end if
|
||
end if
|
||
else
|
||
exit repeat
|
||
end if
|
||
end repeat
|
||
end GetKindleKeyFiles
|
||
|
||
on GetAdeptKey(always)
|
||
--display dialog (AdeptKeyList as text)
|
||
if ((count of AdeptKeyList) is 0) or always then
|
||
set userPrefsPath to path to preferences from user domain as string
|
||
set preferencesFolderPath to userPrefsPath & prefsFolderName & ":"
|
||
if not folderexists(preferencesFolderPath) then
|
||
tell application "Finder"
|
||
set preferencesFolder to make new folder at userPrefsPath with properties {name:prefsFolderName}
|
||
end tell
|
||
end if
|
||
set userAdeptKeyPath to POSIX path of (preferencesFolderPath & "Local Adept Key.der")
|
||
set scriptError to ""
|
||
set shellresult to ""
|
||
set success to true
|
||
set shellcommand to python & (quoted form of AdobeKeyGenTool) & " " & quoted form of userAdeptKeyPath
|
||
set shellcommand to shellcommand & " > " & quotedtemppath()
|
||
writetolog("shellcommand: " & shellcommand)
|
||
cleartemp()
|
||
try
|
||
do shell script shellcommand
|
||
on error scriptError
|
||
set success to false
|
||
end try
|
||
set shellresult to readtemp()
|
||
writetolog("shellresult: " & shellresult & " " & scriptError)
|
||
--display dialog shellresult
|
||
if success then
|
||
if not (AdeptKeyList contains userAdeptKeyPath) then
|
||
set AdeptKeyList to AdeptKeyList & userAdeptKeyPath
|
||
end if
|
||
else
|
||
if (always) then
|
||
display dialog "Error generating key for Adobe Editions: " & scriptError & "
|
||
|
||
You must have Adobe Digital Editions installed for this script to work with Adobe ePubs, or add a key file manually. " buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
end if
|
||
end if
|
||
end if
|
||
end GetAdeptKey
|
||
|
||
on GetKindleKey(always)
|
||
--display dialog (KindleKeyList as text)
|
||
if ((count of KindleKeyList) is 0) or always then
|
||
set userPrefsPath to path to preferences from user domain as string
|
||
set preferencesFolderPath to userPrefsPath & prefsFolderName & ":"
|
||
if not folderexists(preferencesFolderPath) then
|
||
tell application "Finder"
|
||
set preferencesFolder to make new folder at userPrefsPath with properties {name:prefsFolderName}
|
||
end tell
|
||
end if
|
||
set userKindleKeyPath to POSIX path of (preferencesFolderPath & "Local Kindle Key.k4i")
|
||
set scriptError to ""
|
||
set shellresult to ""
|
||
set success to true
|
||
set shellcommand to python & (quoted form of KindleKeyTool) & " " & quoted form of userKindleKeyPath
|
||
set shellcommand to shellcommand & " > " & quotedtemppath()
|
||
writetolog("shellcommand: " & shellcommand)
|
||
cleartemp()
|
||
try
|
||
do shell script shellcommand
|
||
on error scriptError
|
||
set success to false
|
||
end try
|
||
set shellresult to readtemp()
|
||
writetolog("shellresult: " & shellresult & " " & scriptError)
|
||
--display dialog shellresult
|
||
if success then
|
||
if not (KindleKeyList contains userKindleKeyPath) then
|
||
set KindleKeyList to KindleKeyList & userKindleKeyPath
|
||
end if
|
||
else
|
||
if (always) then
|
||
display dialog "Error generating key for Kindle for Mac: " & scriptError & "
|
||
|
||
You must have Kindle for Mac installed for this application to work with Kindle ebooks from Kindle for Mac. " buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
end if
|
||
end if
|
||
end if
|
||
end GetKindleKey
|
||
|
||
on encodeAsBase64(theFilePath)
|
||
set posixfilepath to POSIX path of file theFilePath
|
||
set base64path to POSIX path of file ((path to me as text) & "Contents:Resources:encodebase64.py")
|
||
return do shell script python & quoted form of base64path & " " & quoted form of posixfilepath
|
||
end encodeAsBase64
|
||
|
||
on AddAdeptKey(keyfile)
|
||
set fileExtension to GetFileExtension(keyfile)
|
||
if fileExtension is "der" then
|
||
set newPrefsFile to CopyToPrefs(keyfile)
|
||
set AdeptKeyList to AdeptKeyList & POSIX path of newPrefsFile
|
||
else
|
||
display dialog "Adobe Adept key files generated by adeptkey.py must have a .der extension." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
end if
|
||
end AddAdeptKey
|
||
|
||
on AddKindleKey(keyfile)
|
||
set fileExtension to GetFileExtension(keyfile)
|
||
if fileExtension is "k4i" then
|
||
set newPrefsFile to CopyToPrefs(keyfile)
|
||
set KindleKeyList to KindleKeyList & POSIX path of newPrefsFile
|
||
else
|
||
display dialog "Kindle key files generated by kindlekey.py must have a .k4i extension." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
end if
|
||
end AddKindleKey
|
||
|
||
on AddbnKey(keyfile)
|
||
set fileExtension to GetFileExtension(keyfile)
|
||
if fileExtension is "b64" then
|
||
set newPrefsFile to CopyToPrefs(keyfile)
|
||
tell application "Finder"
|
||
set keyfileName to (name of file newPrefsFile) as text
|
||
end tell
|
||
set fileName to GetFileNameOnly(keyfileName)
|
||
set bnKeys to bnKeys & {{fileName, "", POSIX path of newPrefsFile}}
|
||
else
|
||
display dialog "Barnes & Noble key files generated by ignoblekeygen.py must have a .b64 extension." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
|
||
end if
|
||
end AddbnKey
|
||
|
||
on GetUniqueName(folderPath, fileName)
|
||
set newFileName to fileName
|
||
if fileexists(folderPath & fileName) then
|
||
-- first find new name that's unique to folder
|
||
set namecount to 2
|
||
set fileExtension to GetFileExtension(fileName)
|
||
set fileNameOnly to GetFileNameOnly(fileName)
|
||
repeat
|
||
set newFileName to fileNameOnly & " " & (namecount as text) & "." & fileExtension
|
||
if not fileexists(folderPath & newFileName) then
|
||
exit repeat
|
||
end if
|
||
set namecount to namecount + 1
|
||
end repeat
|
||
end if
|
||
return newFileName
|
||
end GetUniqueName
|
||
|
||
on CopyToPrefs(keyfilepath)
|
||
tell application "Finder"
|
||
set keyfileName to (name of file keyfilepath) as text
|
||
end tell
|
||
set keyfileApplepath to POSIX file (POSIX path of keyfilepath)
|
||
set userPrefsPath to path to preferences from user domain as string
|
||
set userTempPath to path to temporary items from user domain as string
|
||
set preferencesFolderPath to userPrefsPath & prefsFolderName & ":"
|
||
if not folderexists(preferencesFolderPath) then
|
||
tell application "Finder"
|
||
set preferencesFolder to make new folder at userPrefsPath with properties {name:prefsFolderName}
|
||
end tell
|
||
end if
|
||
if fileexists(preferencesFolderPath & keyfileName) then
|
||
-- copy to temporary items folder, rename, and then we can copy from there to the preferences folder
|
||
-- first find new name
|
||
set namecount to 2
|
||
set fileExtension to GetFileExtension(keyfileName)
|
||
set keyfileNameOnly to GetFileNameOnly(keyfileName)
|
||
repeat
|
||
set newkeyfileName to keyfileNameOnly & " " & (namecount as text) & "." & fileExtension
|
||
if not fileexists(preferencesFolderPath & newkeyfileName) and not fileexists(userTempPath & newkeyfileName) then
|
||
exit repeat
|
||
end if
|
||
set namecount to namecount + 1
|
||
end repeat
|
||
-- rename to new name
|
||
set newkeyfilepath to userTempPath & newkeyfileName
|
||
tell application "Finder"
|
||
set tempfilepath to duplicate file keyfileApplepath to folder userTempPath with replacing
|
||
set name of tempfilepath to newkeyfileName
|
||
move file newkeyfilepath to preferencesFolderPath
|
||
end tell
|
||
set newFile to preferencesFolderPath & newkeyfileName
|
||
else
|
||
tell application "Finder"
|
||
set newFile to duplicate file keyfileApplepath to folder preferencesFolderPath with replacing
|
||
end tell
|
||
end if
|
||
|
||
return newFile as text
|
||
end CopyToPrefs
|
||
|
||
on ReadPrefs()
|
||
-- read any existing keys from the preferences
|
||
set preferencesFilePath to (path to preferences from user domain as string) & prefsFileName
|
||
set PIDs to {}
|
||
set UDIDs to {}
|
||
set bnKeys to {}
|
||
set KindleKeyList to {}
|
||
set KindleSerialList to {}
|
||
set AdeptKeyList to {}
|
||
set outputFolder to (path to desktop as string)
|
||
set logFilePath to (path to desktop as string) & "DeDRM.log"
|
||
set tempfilepath to (path to preferences from user domain as string) & prefsFolderName & ":" & tempFileName
|
||
--set tempfilepath to (path to temporary items as string)& "DeDRM_temp.log"
|
||
|
||
if fileexists(POSIX path of file preferencesFilePath) then
|
||
tell application "System Events"
|
||
try
|
||
set PIDs to value of property list item "PIDs" of property list file preferencesFilePath
|
||
end try
|
||
try
|
||
set UDIDs to value of property list item "UDIDs" of property list file preferencesFilePath
|
||
end try
|
||
try
|
||
set KindleSerialList to value of property list item "KindleSerials" of property list file preferencesFilePath
|
||
end try
|
||
try
|
||
set KindleKeyList to value of property list item "KindleKeyList" of property list file preferencesFilePath
|
||
end try
|
||
try
|
||
set bnKeys to value of property list item "bnKeys" of property list file preferencesFilePath
|
||
end try
|
||
try
|
||
set AdeptKeyList to value of property list item "AdeptKeys" of property list file preferencesFilePath
|
||
end try
|
||
try
|
||
set KindleKeyList to value of property list item "KindleKeys" of property list file preferencesFilePath
|
||
end try
|
||
try
|
||
set outputFolder to value of property list item "OutputFolder" of property list file preferencesFilePath
|
||
end try
|
||
end tell
|
||
end if
|
||
|
||
|
||
set newList to {}
|
||
repeat with i from 1 to count AdeptKeyList
|
||
if fileexists(AdeptKeyList's item i) then set newList's end to AdeptKeyList's item i
|
||
end repeat
|
||
set AdeptKeyList to newList
|
||
|
||
set newList to {}
|
||
repeat with i from 1 to count KindleKeyList
|
||
if fileexists(KindleKeyList's item i) then set newList's end to KindleKeyList's item i
|
||
end repeat
|
||
set KindleKeyList to newList
|
||
|
||
set newList to {}
|
||
repeat with i from 1 to count bnKeys
|
||
if (item 3 of bnKeys's item i) is "" or fileexists(item 3 of bnKeys's item i) then set newList's end to bnKeys's item i
|
||
end repeat
|
||
set bnKeys to newList
|
||
|
||
end ReadPrefs
|
||
|
||
on CreatePlist(filePath)
|
||
set theEmptyPListData to "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
||
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
|
||
<plist version=\"1.0\">
|
||
<dict/>
|
||
</plist>"
|
||
|
||
set thePListFile to open for access filePath with write permission
|
||
set eof of thePListFile to 0
|
||
write theEmptyPListData to thePListFile starting at eof
|
||
close access thePListFile
|
||
|
||
end CreatePlist
|
||
|
||
on WritePrefsOld()
|
||
-- write keys to the preferences from older AppleScript
|
||
set preferencesFilePath to (path to preferences from user domain as string) & prefsFileName
|
||
CreatePlist(preferencesFilePath)
|
||
tell application "System Events"
|
||
tell contents of property list file preferencesFilePath
|
||
set value to ({|PIDs|:PIDs} & {|UDIDs|:UDIDs} & {|KindleSerials|:KindleSerialList} & {|KindleKeys|:KindleKeyList} & {|bnKeys|:bnKeys} & {|AdeptKeys|:AdeptKeyList} & {|OutputFolder|:outputFolder})
|
||
|
||
end tell
|
||
end tell
|
||
end WritePrefsOld
|
||
|
||
on WritePrefs()
|
||
if oldAppleScript then
|
||
WritePrefsOld()
|
||
else
|
||
-- write keys to the preferences for AppleScript 2.0 and later
|
||
set preferencesFilePath to (path to preferences from user domain as string) & prefsFileName
|
||
tell application "System Events"
|
||
set the base_dict to make new property list item with properties {kind:record}
|
||
set myPrefs to make new property list file with properties {contents:base_dict, name:preferencesFilePath}
|
||
make new property list item at end of property list items of contents of myPrefs with properties {kind:list, name:"PIDs", value:PIDs}
|
||
make new property list item at end of property list items of contents of myPrefs with properties {kind:list, name:"UDIDs", value:UDIDs}
|
||
make new property list item at end of property list items of contents of myPrefs with properties {kind:list, name:"KindleSerials", value:KindleSerialList}
|
||
make new property list item at end of property list items of contents of myPrefs with properties {kind:list, name:"KindleKeys", value:KindleKeyList}
|
||
make new property list item at end of property list items of contents of myPrefs with properties {kind:list, name:"bnKeys", value:bnKeys}
|
||
make new property list item at end of property list items of contents of myPrefs with properties {kind:list, name:"AdeptKeys", value:AdeptKeyList}
|
||
make new property list item at end of property list items of contents of myPrefs with properties {kind:string, name:"OutputFolder", value:outputFolder}
|
||
end tell
|
||
end if
|
||
end WritePrefs
|
||
|
||
|
||
on InitProgress(maxcount)
|
||
try
|
||
if totalebooks > 1 then
|
||
launch application ((path to resource "DeDRM Progress.app") as string)
|
||
tell application ((path to resource "DeDRM Progress.app") as string)
|
||
activate
|
||
set contents of «class texF» "maintext" of window "main" to "Decrypting " & maxcount & " ebooks."
|
||
set contents of «class texF» "subtext" of window "main" to "Decrypting book 0: "
|
||
set «class maxV» of «class proI» "bar" of window "main" to maxcount
|
||
set «class conT» of «class proI» "bar" of window "main" to 0
|
||
end tell
|
||
end if
|
||
end try
|
||
|
||
end InitProgress
|
||
|
||
on ProcessItems(some_items)
|
||
try
|
||
set ErrorList to ""
|
||
set WarningList to ""
|
||
set CompletedList to ""
|
||
set ErrorCount to 0
|
||
set WarningCount to 0
|
||
set CompletedCount to 0
|
||
set totalebooks to 0
|
||
set completedebooks to 0
|
||
repeat with this_item in some_items
|
||
if (folder of (info for this_item) is true) then
|
||
tell application "Finder" to set totalebooks to totalebooks + (count of (every file in entire contents of folder this_item whose name extension is in handledExtensions))
|
||
else
|
||
countfile(this_item as text)
|
||
end if
|
||
end repeat
|
||
if totalebooks is 1 then
|
||
set TotalText to "There is 1 ebook to be decrypted."
|
||
else
|
||
set TotalText to "There are " & totalebooks & " ebooks to be decrypted."
|
||
end if
|
||
writetolog(TotalText)
|
||
InitProgress(totalebooks)
|
||
repeat with this_item in some_items
|
||
if totalebooks > 1 and not ProgressActive() then
|
||
exit repeat
|
||
end if
|
||
if (folder of (info for this_item) is true) then
|
||
handlefolder(this_item as text)
|
||
else
|
||
handlefile(this_item as text)
|
||
end if
|
||
end repeat
|
||
endProgress()
|
||
on error errmsg number errnum
|
||
set errorReport to "An unexpected error occurred. Please report on Apprentice Alf's blog.
|
||
|
||
Error Message: " & errmsg & "
|
||
Error Number: " & errnum
|
||
writetolog(errorReport)
|
||
display dialog errorReport with title "DeDRM" buttons {"Bother"} default button 1 with icon stop
|
||
end try
|
||
if WarningList is not "" then
|
||
set WarningText to ""
|
||
if WarningCount is 1 then
|
||
set WarningText to "There was a warning with 1 ebook:"
|
||
else
|
||
set WarningText to "There were warnings with " & WarningCount & " ebooks:"
|
||
end if
|
||
writetolog(WarningText)
|
||
writetolog(WarningList)
|
||
set dialogresult to display dialog WarningText & "
|
||
|
||
" & WarningList buttons {"OK"} with title "DeDRM" default button 1
|
||
end if
|
||
if ErrorList is not "" then
|
||
set ErrorText to ""
|
||
if ErrorCount is 1 then
|
||
set ErrorText to "There was an error with 1 ebook:"
|
||
else
|
||
set ErrorText to "There were errors with " & ErrorCount & " ebooks:"
|
||
end if
|
||
writetolog(ErrorText)
|
||
writetolog(ErrorList)
|
||
set dialogresult to display dialog ErrorText & "
|
||
|
||
" & ErrorList buttons {"Bother"} with title "DeDRM" default button 1
|
||
end if
|
||
if CompletedCount > 0 then
|
||
set CompletedText to ""
|
||
if CompletedCount is 1 then
|
||
set CompletedText to "Successfully de-drmed 1 ebook:"
|
||
else
|
||
set CompletedText to "Successfully de-drmed " & CompletedCount & " ebooks:"
|
||
end if
|
||
writetolog(CompletedText)
|
||
writetolog(CompletedList)
|
||
set dialogresult to display dialog CompletedText & "
|
||
|
||
" & CompletedList buttons {"Thanks"} with title "DeDRM" default button 1
|
||
end if
|
||
return CompletedCount + WarningCount + ErrorCount
|
||
end ProcessItems
|
||
|
||
on ProgressActive()
|
||
tell application "System Events" to set progactive to count (every process whose name is "DeDRM Progress")
|
||
if progactive > 0 then return true
|
||
return false
|
||
end ProgressActive
|
||
|
||
on IncProgress(booktitle, doingcount)
|
||
try
|
||
if ProgressActive() then
|
||
tell application ((path to resource "DeDRM Progress.app") as string)
|
||
set contents of «class texF» "subtext" of window "main" to "Decrypting book " & doingcount & ": " & booktitle
|
||
set «class conT» of «class proI» "bar" of window "main" to doingcount
|
||
end tell
|
||
end if
|
||
end try
|
||
end IncProgress
|
||
|
||
on endProgress()
|
||
try
|
||
if ProgressActive() then tell application ((path to resource "DeDRM Progress.app") as string) to quit
|
||
end try
|
||
end endProgress
|
||
|
||
|
||
on run
|
||
if GetTools() then
|
||
ReadPrefs()
|
||
clearlog()
|
||
GetAdeptKey(false)
|
||
GetKindleKey(false)
|
||
repeat
|
||
set dialogresult to display dialog "To remove DRM from an ebook, click ‘Select Ebook…’
|
||
To configure this software, click ‘Configure…’
|
||
|
||
When the DeDRM application is not running, you can also remove DRM from ebooks by dropping them onto the DeDRM application icon in the Finder.
|
||
|
||
For details of the ebook formats which this application can handle, see the ReameMe file or visit http://apprenticealf.wordpress.com/
|
||
Please only use this application on your own books. Authors, publishers and ebook stores need to make money to produce more ebooks.
|
||
Don't cheat them.
|
||
|
||
This application is by Apprentice Alf and uses python scripts produced by Apprentice Alf, CMBDTC, The Dark Reverser, DiapDealer, i♥cabbages, some_updates, Paul Durrant and others.
|
||
The AppleScript part of this application is free software released into the public domain, see http://unlicense.org/
|
||
The application icon is adapted from the Authors Against DRM logo at
|
||
http://readersbillofrights.info/AAD and is under the Creative Commons Attribution-ShareAlike licence.
|
||
|
||
The included Python scripts are all free to use, but have a variety of licences. See the individual files for details.
|
||
" with title "DeDRM by Apprentice Alf" buttons {"Quit", "Select Ebook… ", "Configure… "} default button 1 with icon note
|
||
if button returned of dialogresult is "Quit" then exit repeat
|
||
if button returned of dialogresult is "Select Ebook… " then
|
||
set DRMebook to ""
|
||
try
|
||
set DRMebook to {choose file with prompt "Please select a DRMed ebook"}
|
||
end try
|
||
if DRMebook is not "" then
|
||
if ProcessItems(DRMebook) is 0 then
|
||
display dialog "That was a file that this script cannot process." with title "DeDRM" buttons {"OK"} default button 1 with icon note
|
||
end if
|
||
end if
|
||
else
|
||
set choice to true
|
||
repeat while choice is not false
|
||
set choice to choose from list {"eInk Kindle eBooks", "Barnes and Noble ebooks", "Mobipocket eBooks", "eReader ebooks", "Adobe Digital Editions ebooks", "Kindle for Mac ebooks", "Output Folder"} with prompt "Choose a Configuration Option:" with title "DeDRM Configuration" OK button name "Configure..." cancel button name "Finished"
|
||
if choice contains "Barnes and Noble ebooks" then
|
||
GetKeys(true, "DeDRM Configure for Barnes and Noble")
|
||
else if choice contains "eInk Kindle eBooks" then
|
||
GetSerials("DeDRM Configure for eInk Kindle")
|
||
else if choice contains "Mobipocket eBooks" then
|
||
GetPIDs("DeDRM Configure for Mobipocket")
|
||
else if choice contains "eReader ebooks" then
|
||
GetKeys(true, "DeDRM Configure for eReader")
|
||
else if choice contains "Kindle for Mac ebooks" then
|
||
GetKindleKeyFiles("DeDRM Configure Kindle for Mac")
|
||
else if choice contains "Adobe Digital Editions ebooks" then
|
||
GetAdeptKeyFiles("DeDRM Configure Adobe Digital Editions")
|
||
else if choice contains "Output Folder" then
|
||
GetOutputFolder("DeDRM Configure Output Folder")
|
||
end if
|
||
--GetSerials("DeDRM Configuration 1/6")
|
||
--GetPIDs("DeDRM Configuration 2/6")
|
||
--GetUDIDs("DeDRM Configuration 3/6")
|
||
--GetKeys(true, "DeDRM Configuration 4/6")
|
||
--GetAdeptKeyFiles("DeDRM Configuration 5/6")
|
||
--GetOutputFolder("DeDRM Configuration 6/6")
|
||
end repeat
|
||
WritePrefs()
|
||
end if
|
||
end repeat
|
||
end if
|
||
end run
|
||
|
||
on open some_items
|
||
--display dialog (some_items as text)
|
||
if GetTools() then
|
||
ReadPrefs()
|
||
clearlog()
|
||
GetAdeptKey(false)
|
||
GetKindleKey(false)
|
||
|
||
if ProcessItems(some_items) is 0 then
|
||
display dialog "No ebooks found in the dropped items. DeDRM can handle Mobipocket, Kindle, eReader, Adobe ePub, Barnes & Noble ePub and Adobe PDF. Please try again." buttons {"OK"} with title "DeDRM" default button 1 with icon note
|
||
end if
|
||
WritePrefs()
|
||
end if
|
||
end open
|
||
|