I’ve written a script to open PDFs in Acrobat, move and resave them (this typically reduces file size). The script works on a few files, and occasionally on more than a few, but definitely chokes on large batches of 100 files or so. I’ve tried to control this with timeout, but no luck. Ideally, I’d like to run this as a cron script but I can’t have it failing.
the code:
#!/usr/bin/osascript
set nofile to 0
set InFolder to "/Volumes/Users/SHARED/_ PDF Final Files (low res)/Electronic Marketing/ResaveIn"
set InFolderMac to ("Users:SHARED:_ PDF Final Files (low res):Electronic Marketing:ResaveIn" as alias)
set ProcFolder to "/Volumes/Users/SHARED/_ PDF Final Files (low res)/Electronic Marketing/ResaveProc"
set ProcFolderMac to ("Users:SHARED:_ PDF Final Files (low res):Electronic Marketing:ResaveProc" as alias)
try
do shell script "mv " & (quoted form of InFolder) & "/* " & (quoted form of ProcFolder)
set nofile to 1
end try
if nofile = 1 then
with timeout of 8947848 seconds
set thefiles to (list folder ProcFolderMac)
tell application "Finder"
--set thefiles to (files of entire contents of ProcFolderMac whose name extension is "pdf")
end tell
tell application "Adobe Acrobat Professional"
activate
repeat with eachfile in thefiles
if eachfile ends with "pdf" then
set procFile to (ProcFolderMac as text) & eachfile
--try
open procFile with invisible
--set docname to name of document 1
set newfile to "Volumes:Users:SHARED:_ PDF Final Files (low res):Electronic Marketing:ResaveOut:" & eachfile
save document 1 to file newfile with invisible
close document 1 with invisible
--end try
do shell script "rm " & (quoted form of ProcFolder) & "/" & eachfile
end if
end repeat
--quit
end tell
end timeout
end if
… and the error:
tell current application
do shell script "mv '/Volumes/Users/SHARED/_ PDF Final Files (low res)/Electronic Marketing/ResaveIn'/* '/Volumes/Users/SHARED/_ PDF Final Files (low res)/Electronic Marketing/ResaveProc'"
""
list folder alias "Users:SHARED:_ PDF Final Files (low res):Electronic Marketing:ResaveProc:"
{".DS_Store", "749457.PDF", "746118.PDF", "719977.PDF", "719974.PDF", "719971.PDF", "712165.PDF", "712162.PDF", "793827.PDF", "793049.PDF"}
end tell
tell application "Adobe Acrobat Professional"
activate
open "Users:SHARED:_ PDF Final Files (low res):Electronic Marketing:ResaveProc:749457.PDF" with invisible
«data aevt646C65320000000061657674000002BA00000000000000000000013C0000000400000003000000000000000000000000636F72657361766574B40680D3C1B1A1F04E1B0040183D16409133169001120050143A163016201570582117D3C1B1A140EE2A1590282415D0861900D3C1B1A1D3C1B1A1B0913E16D0DF1D0030441B00305D58A0E05E2A1560A12C17D3C1B1A16165767400010001637369676D61676E00000004000100007472616E6C6F6E6700000004000000006164647270736E200000000800000000002D42D47462736370736E20000000080000000000000000696E74656C6F6E670000000400000070726570716C6F6E6700000004000000007462736370736E2000000008000000000000000072656D6F6C6F6E67000000040000000066726F6D70736E200000000800000000000F40F4667265636C6F6E6700000004000000003B3B3B3B6B66696C6F626A20000000F40000000400000000666F726D656E756D000000046E616D6577616E74747970650000000466696C6573656C6475747874000000B40056006F006C0075006D00650073003A00550073006500720073003A005300480041005200450044003A005F0020005000440046002000460069006E0061006C002000460069006C0065007300200028006C006F007700200072006500730029003A0045006C0065006300740072006F006E006900630020004D00610072006B006500740069006E0067003A005200650073006100760065004F00750074003A003700340039003400350037002E00500044004666726F6D6E756C6C00000000757372666C6973740000002200000002000000005445585400000009696E76697369626C650074727565000000002D2D2D2D6F626A20000000440000000400000000666F726D656E756D00000004696E647877616E747479706500000004646F637573656C646C6F6E67000000040000000166726F6D6E756C6C00000000»
«data aevt646C65320000000061657674000001BA00000000000000000000013C0000000400000002000000000000000000000000636F7265636C6F7374B406842000760053003400E8287AA00100000002000000BC173D0108003000300030003000300030003000E8287AA00100000002000000C4173D0108003000350100000100000003000000E8287AA001000000020000006165767400010001637369676D61676E00000004000100007472616E6C6F6E6700000004000000006164647270736E200000000800000000002D42D47462736370736E20000000080000000000000000696E74656C6F6E670000000400000070726570716C6F6E6700000004000000007462736370736E2000000008000000000000000072656D6F6C6F6E67000000040000000066726F6D70736E200000000800000000000F40F4667265636C6F6E6700000004000000003B3B3B3B757372666C6973740000002200000002000000005445585400000009696E76697369626C650074727565000000002D2D2D2D6F626A20000000440000000400000000666F726D656E756D00000004696E647877616E747479706500000004646F637573656C646C6F6E67000000040000000166726F6D6E756C6C00000000»
do shell script "rm '/Volumes/Users/SHARED/_ PDF Final Files (low res)/Electronic Marketing/ResaveProc'/749457.PDF"
"Adobe Acrobat Professional got an error: rm: /Volumes/Users/SHARED/_ PDF Final Files (low res)/Electronic Marketing/ResaveProc/749457.PDF: Resource busy"
if anyone has insight into the source of failure, or a more elegant solution, I’d be very appreciative!
Ralph, sorry this is not an answer to your problem. However as your trying to reduce the size of PDF’s here is a possible GUI driven solution using Acrobat’s Optimizer. I was bored this morning and like playing with scripting the GUI. It works for me with some basic testing using saved presets. You or others may want to play with or expand on this:
tell application "Adobe Acrobat 7.0 Professional"
activate
tell active doc
tell application "System Events"
tell process "Acrobat"
tell menu bar 1
tell menu bar item "Advanced"
tell menu 1
-- Open PDF Optimizer window
click menu item "PDF Optimizer..."
end tell
end tell
end tell
tell window "PDF Optimizer"
tell group 1
click pop up button 1
-- This sticks at last used so use up arrow to top of list
keystroke (ASCII character 30) using command down
-- Use down arrow to navigate to list item
keystroke (ASCII character 31)
keystroke (ASCII character 31)
keystroke (ASCII character 31)
keystroke return
delay 1 -- Let the GUI catch up
-- Basic check for correct settings
set a to get value of pop up button 1
if a = "Marks Custom 1" then
set Optimized to true
click button "OK"
else
set Optimized to false
click button "Cancel"
-- Write a report file
end if
end tell
end tell
delay 1 -- Let the GUI catch up
if Optimized is true then
tell window "Save Optimized As"
click button "Save"
end tell
delay 1 -- Let the GUI catch up
tell window 1
click button "Replace"
end tell
end if
end tell
end tell
delay 6 -- Let Acrobat Optimize PDF
try
close saving no
end try
delay 1 -- Let the GUI catch up
tell application "System Events"
tell process "Acrobat"
if exists window "Conversion Warnings" then
tell window "Conversion Warnings"
tell group 1
click button "OK"
-- Write a report file
end tell
end tell
end if
end tell
end tell
end tell
end tell
that indeed got rid of the error. Now I’m getting a “resource busy” error, even when I throw in a generous 5 second delay and put the “rm” into a subroutine, er handler.
#!/usr/bin/osascript
global ProcFolder
global docname
set nofile to 0
set InFolder to "/Volumes/Users/SHARED/_ PDF Final Files (low res)/Electronic Marketing/ResaveIn"
set InFolderMac to ("Users:SHARED:_ PDF Final Files (low res):Electronic Marketing:ResaveIn" as alias)
set ProcFolder to "/Volumes/Users/SHARED/_ PDF Final Files (low res)/Electronic Marketing/ResaveProc"
set ProcFolderMac to ("Users:SHARED:_ PDF Final Files (low res):Electronic Marketing:ResaveProc" as alias)
try
do shell script "mv " & (quoted form of InFolder) & "/* " & (quoted form of ProcFolder)
set nofile to 1
end try
if nofile = 1 then
with timeout of 8947848 seconds
set thefiles to (list folder ProcFolderMac)
tell application "Finder"
--set thefiles to (files of entire contents of ProcFolderMac whose name extension is "pdf")
end tell
tell application "Adobe Acrobat Professional"
activate
repeat with eachfile in thefiles
if eachfile ends with "pdf" then
set procFile to (ProcFolderMac as text) & eachfile
open procFile with invisible
set docname to name of document 1
set newfile to "Volumes:Users:SHARED:_ PDF Final Files (low res):Electronic Marketing:ResaveOut:" & docname
save document 1 to file newfile
close document 1
delay 5
my rm()
end if
end repeat
--quit
end tell
end timeout
end if
to rm()
do shell script "rm " & (quoted form of ProcFolder) & "/" & docname
end rm
and the error:
tell current application
do shell script "mv '/Volumes/Users/SHARED/_ PDF Final Files (low res)/Electronic Marketing/ResaveIn'/* '/Volumes/Users/SHARED/_ PDF Final Files (low res)/Electronic Marketing/ResaveProc'"
""
list folder alias "Users:SHARED:_ PDF Final Files (low res):Electronic Marketing:ResaveProc:"
{".DS_Store", "749457.PDF", "746118.PDF", "719977.PDF", "719974.PDF", "719971.PDF", "793827.PDF", "793830.PDF", "793049.PDF"}
end tell
tell application "Adobe Acrobat Professional"
activate
open "Users:SHARED:_ PDF Final Files (low res):Electronic Marketing:ResaveProc:749457.PDF" with invisible
get name of document 1
"749457.PDF"
save document 1 to file "Volumes:Users:SHARED:_ PDF Final Files (low res):Electronic Marketing:ResaveOut:749457.PDF"
close document 1
end tell
tell current application
do shell script "rm '/Volumes/Users/SHARED/_ PDF Final Files (low res)/Electronic Marketing/ResaveProc'/749457.PDF"
"rm: /Volumes/Users/SHARED/_ PDF Final Files (low res)/Electronic Marketing/ResaveProc/749457
the delay didn’t fix the issue, but restarting the computer did. I think I had triggered too many overlapping cron scripts that somehow caused a problem. (I kept the delay in the script since it surely can’t hurt).
On a philosophical note, what’s the best way to structure one of these batch script- move one at a time, process, delete, or move them all, then process one at a time, delete one at a time, etc etc?
I was already informed that a Best Practice is to move incoming files into a processing folder, which I’ve implemented.
All these expressions have the same value as far as the shell is concerned:
“foo bar 'baz”
'foo bar ‘'‘baz’'
foo\ bar\ 'baz
foo’ ‘bar" "'baz
f’oo’" bar 'baz"
foo" "bar\ "'b"az
But you are right in thinking something is a bit off about it.
It came from this code:
do shell script "rm " & (quoted form of ProcFolder) & "/" & docname
which would be better as
do shell script "rm " & quoted form of (ProcFolder & "/" & docname)
That way the whole file path would be quoted, not just its directory.