There’s a command line program called fs_usage that could help. It monitors all file system usage and prints out the results. It requires root privileges. It prints out a lot of information so we need to filter that info.
Here’s an example usage. Suppose I wanted to know when a particular file is opened, say a file on my desktop called “test.txt”. I can filter on an application name and a file path to eliminate almost all of the output from fs_usage. The application you filter on must be running, and thus I’ll choose to filter on the Finder because it’s always running.
So here’s how I would run the command:
sudo fs_usage -f filesys Finder | grep /Users/hmcshane/Desktop/test.txt
So try running that from the Terminal, and then launching your file. You’ll see you get output when you do. Now you just have to figure out how to use it from applescript.
I really have no idea whether kMDItemLastUsedDate is a reliable indicator for “Last Opened”. It appears to be, but I really don’t know.
Name of file: “No Subject Saturday, 19 June, 2010”
Location of file: “/Users/mikerickson/Documents/My Special Folder/No Subject Saturday, 19 June, 2010”
Substitute your applescript for the dialog.
on idle
set parentfolder to path to documents folder
set myfile to parentfolder & "My Special Folder" & ":" & "No Subject Saturday, 19 June, 2010" as string
set tPath to quoted form of (POSIX path of myfile)
set a to do shell script "mdls -name kMDItemLastUsedDate " & tPath
set b to text ((offset of "=" in a) + 2) thru end in a
tell (current date)
set its day to 1 -- Overflow precaution.
set its year to text 1 thru 4 of b -- Automatic .
set its month to text 6 thru 7 of b -- . text to integer .
set its day to text 9 thru 10 of b
set its hours to text 12 thru 13 of b -- . coercions.
set its minutes to text 15 thru 16 of b
set its seconds to text 18 thru 19 of b
set theDate to its date (date string) -- A date string in the user's preferred format.
end tell
if theDate > (current date) - 1 then
activate me
display dialog "Do whatever you like from now on"
end if
return 0.2
end idle
Save and run as a stay-open application.
So far, each time that I have opened the file the dialog appears. This could give some grounds for believing that your applescript could be triggered each time the file is opened.
Hello. @Val
Could you please put into code-exchange?
@Stefan
It’s kind of interesting, because no one of us but the OP knows what kind of file we are talking about.
If it is a small system file, then 5 times per second might be too slow!
On the other hand if there is a document type of file, then He could estimate the file to be open at least say 1 minute. then you could do the call every 50th second and be pretty sure the process will able to track when the file is open. 250 times cheaper than previous solution, but still nothing for a machine on batteries.
@AllOfYou
-Living in the belief that tripwire is able to track open files: (That may be wrong.)
We can install tripwire, so why shouldn’t one be able to do the same via a homemade kext (kernel extension).
-Thinking loudly, I think that the tripwire source, may provide a good solution should no other suffice.
@Val the code is still very interesting with its limitations.
Then we must go one level below into the i-node tables. And use unix-find or whatever.
They should be updated pretty timely.
Sorry to say but find doesn’t provide finer granularity than 1 second.
Most code stolen shamlessy from delpucci
on idle
set parentfolder to path to documents folder
set myfolder to parentfolder & "My Special Folder" & ":" as text
set ppath to quoted form of POSIX path of myfolder
if (do shell script "( find " & ppath & " -atime 1s -name " & (quoted form of "Saturday 19th of june 21Am ") & " | echo $? ) ") is 0 then
activate me
display dialog "Do whatever you like from now on"
end if
return 1
end idle
I’m not sure that it runs as it stands. Not tested.
Best Regards from beautiful Southern Norway on a Sunny Afternoon.
Since the question has been raised, the file would be an Excel workbook. The script would 1) assign buttons on the sheets to various scripts and/or 2) start a background script that mimics VBA’s Worksheet_Change event.
Its not a particular project that I have in mind, but a technique that could be applied to any workbook.
If I’m willing to have an “infinite” loop mimic the Change event, I should(?) be willing to use the resources for a “is it open yet” script.
On the other hand, opening the file via script rather than the Finder is a good option when I am the sole user. For other users, the background looping might be easiest. (Or…If I can cobble together the equivalent of a BeforeClose event, I could close the wb in such a way as to display an “Open Me With AppleScript” sheet to remind the users if they open it with Finder.)
You could make an applet, which you use as a default application for this particular workbook.
Then you could do all the stuff in the applets open handler. Including having excel opening
the workbook.
I’m not 100% sure that this will work, but 100% sure that something close will work (Eventually).
Came across a Ruby script (athttp://lists.apple.com/archives/applesc . 00280.html) that seems to overcome the issue of only activating when a file is double-clicked.
I do not know anything about Ruby nor have I any idea why or how it works.
The script below will activate the script if the file is double clicked to open OR if the file is opened via the File menu.
I have changed the file to an Excel Workbook (2008)
I have left the idle return at 1 second.
So far it activates the dialog every time the file is opened whether from the File menu or by double clicking.
File Name: My New Excel Workbook.xlsx
File Location: /Users/mikerickson/Documents/My Special Folder/My New Excel Workbook.xlsx
on idle
set tscript to "ruby -e 'puts File.stat(\"/Users/mikerickson/Documents/My Special Folder/My New Excel Workbook.xlsx\").atime'"
set RubyDate to do shell script tscript
set MO to {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
repeat with i from 1 to count of items in MO
if item i in MO = text 5 thru 7 of RubyDate then
set mn to i as number
end if
end repeat
tell (current date)
set its day to 1 -- Overflow precaution.
set its year to text -4 thru end of RubyDate
set its month to mn
set its day to text 9 thru 10 of RubyDate
set its hours to text 12 thru 13 of RubyDate -- . coercions.
set its minutes to text 15 thru 16 of RubyDate
set its seconds to text 18 thru 19 of RubyDate
set theDate to its date (date string) -- A date string in the user's preferred format.
end tell
if theDate > (current date) - 1 then
activate me
display dialog "Do whatever you like from now on"
end if
return 1
end idle
Val
Model: iMac8,1
AppleScript: Version 2.3 (118)
Browser: Safari 533.16
Operating System: Mac OS X (10.6)
I have a few files which I want to open in a defined way.
To achieve that, I use a script which grabs the list of files available in the folder containing them.
Then I select the file in a choose from list dialog.
So it’s easy to do the wanted tasks before opening the file (or after opening it).
set mon_dossier to "Western 2:Important:iWork:documents_Numbers:"
tell application "System Events"
set les_documents to get name of every file of folder mon_dossier
end tell
set mon_document to (choose from list les_documents)
if mon_document is false then error number -128
set mon_document to mon_dossier & item 1 of mon_document
(*
here code for tasks to achieve before opening the document
*)
tell application "System Events"
set nom_visible to displayed name of disk item mon_document
end tell
tell application "Numbers"
open mon_document
repeat until exists document nom_visible
delay 0.2
end repeat
end tell
(*
here code for tasks to achieve after opening the document
*)
Yvan KOENIG (VALLAURIS, France) lundi 21 juin 2010 22:38:18
I have even another solution that I haven’t implemented.
A folder action which opens the file Info window when the file (or an alias?) is dropped onto (added) to the folder.
You then choose which applet should open it, which provides the “on open” functionality you want eventually.
There could be said a lot about this approach as an opposite to Yvan’s method. Yvan’s is more well documented.
But If he had several solutions in one file, there could be more code to maintain. My solution is more easygoing.
As I don’t have to test for filetypes and such. On the other, If all these files were accessed through a folder then
it wouldn’t make such a mess. And if I provided a test in the “Associated” droplets for which path the files were opened from, I could even be informative about who really is opening the document if it was opened from it’s
original path, or bypass the extra functionality all together.
But I could always open the document directly,
Best Regards From a hot Summer Night in Southern Norway
Yvan’s solution at post 23 would appear to be the wisest so far on the thread as it is certain that it will work every time.
While I can confirm that, so far on my machine, the ruby script picks up the file opening every time, I would be more confident if I knew where it gets its information from.
There must be accessible depositories of system information that are very useful but that applescript or spotlight cannot use.
The more experienced scripters on the forum might enlighten us.
In the meantime I have tinkered with my script and replaced the repeat with an offset. It still works ----on my machine.
on idle
set tscript to "ruby -e 'puts File.stat(\"/Users/mikerickson/Documents/My Special Folder/My New Excel Workbook.xlsx\").atime'"
set RubyDate to do shell script tscript
set MO to "Jan01Feb02Mar03Apr04May05Jun06Jul07Aug08Sep09Oct10Nov11Dec12"
set a to offset of (text 5 thru 7 of RubyDate) in MO
set mn to text (a + 3) thru (a + 4) in MO
tell (current date)
set its day to 1 -- Overflow precaution.
set its year to text -4 thru end of RubyDate
set its month to mn
set its day to text 9 thru 10 of RubyDate
set its hours to text 12 thru 13 of RubyDate -- . coercions.
set its minutes to text 15 thru 16 of RubyDate
set its seconds to text 18 thru 19 of RubyDate
set theDate to its date (date string) -- A date string in the user's preferred format.
end tell
if theDate > (current date) - 1 then
activate me
display dialog "Do whatever you like from now on"
end if
return 1
end idle
This has been a good thread with lots of solutions.
@Val: Your ruby solution is almost the same as my find -name theName -mtime 1s
Both commands perform the stat system call, and checks the -accessed -date attribute of the inode for the file.
I am not after any “Best” solution really, it is however important to spot the differences among them. Your ruby solution may be faster than my find -atime solution, but then again my find solution takes care of all the current date stuff for me.
I agree with you. The only folder action I want is the one which associate a file in a folder for the purpose of some customized opening action with a droplet like yours.
All I want the folder action to do is to bring up alternatives of droplets with actions.
( Could be well organized by having those kinds of droplets in a special folder).
The droplet is more efficient than a folder action script for this task.
I use folder actions daily for several tasks which can’t be automated with droplets.
As I switch often between 10.4 and 10.5, I use one disk for each system and a third one to store datas.
I never took time to check if I may define target recipients on the third volume so,
(1) the downloaded items are received in a folder of the startup volume then a folder action script move them to the third volume
(2) the screenshot are sent in a folder of the startup volume then they are moved on the third volume.
I use other folder actions for these tasks:
(1) I grab from ebay photos of the potteries made in my workshop which appear in auctions.
I gather these photos in one folder per object then submit the folder to a folder action script which rename the embedded files with a fixed pattern.
(2) before embedding screenshots when I respond in Apple Discussions forums, I drop them in a folder to reduce their width to 640 pixels if needed.
but they will be replaced soon by droplets.
Each tool as pros and cons. The problem is that often I built a script in a hurry and discover later that I didn’t made the good choice.
Sometimes, representants aren’t re-elected,
sometimes couples divorce .
sometime French soccer money-minded are playing the fool.
It’s just life.
Yvan KOENIG (VALLAURIS, France) mardi 22 juin 2010 18:22:06
For completeness sake I revisited McUsr’s post 19 and came up with this (only slightly changed) version of the script of that post.
on idle
set parentfolder to path to documents folder
set myfile to parentfolder & "My Special Folder" & ":" & "My New Excel Workbook.xlsx" as text
set ppath to quoted form of POSIX path of myfile
if (do shell script " find " & ppath & " -atime -1s") is not "" then
activate me
display dialog "Do whatever you like from now on"
end if
return 1
end idle
It works, though Yvan’s appears a more certain way of controlling a whole process.
The greatness of AppleScript is being “glue” between applications, and like glue, you can bend it (“her”) to your will,
-switch freely between osascripts, applets (foreground and background), scripts, droplets, folder action scripts.
It is a rarity to end up with the best solution at the first time. At least if you are me. I often find that I want it different than what I perceived when I made it, and often the solution makes such a shift - to another kind of applescript. The folder action to droplet shift is something I have done a couple of time. Either because that in the end it was more practical than the folder action, or led to far less coding.
Apropos and most definitively out of the thread scope
I have recently (also) discovered the convert command. But I also have discovered the enscript command which means that I can bypass CUPS-PDF in many cases and get a real filename too.