![]() |
AppleScript: Need help modifying script..
Greetings again true believers.. once again, I need to try and rely on AppleScript to get something accomplished. And once again, I must state that I know nothing about AppleScript and unfortunately, I'm under a huge time constraint. That means I won't have time to RTFM and learn it to get when I need done. That being said, I hope I can rely on someone else who has already forgotten more about it then I will be able to learn.
What am I doing? Using the "Go To Server" facility to mount a set of SMB shares can be a bit cumbersome, and also I have some users who are.. shall we say.. not terribly computer literate? I want to create a double-clickable AppleScript.app that will mount the remote share and then open the requisite user folder. So far I've got this part working: Code:
tell application "Finder"Thanks for all your help! |
One thing I discovered while palying with it that I can strip out the line "make new Finder window to disk "GROUP_HOME"", since I don't need that open, just the user's home folder.
Code:
tell application "Finder" |
Quote:
Code:
tell application "Finder" |
This is all well fine and good AS practice, but why not just make an alias to the volume once mounted and then put it where they can double-click it?
|
FWIW, you could shorten it:
Code:
tell application "Finder" |
Quote:
Code:
repeat until (list disks) contains "GROUP_HOME" |
Quote:
I want to make an "idiot-proof" way of doing it. Hence, the need for an AppleScript. |
OK, thanks guardian34 and NovaScotian, I will shorten it and bomb-proof it and see how that fares!
|
Quote:
EDIT: it seems to work out of the box. thanks for the suggestion! :) |
Quote:
|
Keywords: applescript mount smb
OK, thanks again! Naturally the following is 'anonymoized' somewhat.
1) This one is for the user's networked home directory.. Code:
tell application "Finder"Code:
tell application "Finder"EDIT: Incorporated guardian34's suggestion on script repetitiveness.. |
list disks is an actual AppleScript Command - part of the Scripting Addition commands; so doesn't need a tell.
If you're not sure that the server is online, you can ping it first: set myPing to do shell script "ping -c 2 192.169.1.109" -- or whatever if the ping is successful myPing will be this string: Code:
"PING 192.168.1.101 (192.168.1.101): 56 data bytesCode:
"PING 192.168.1.109 (192.168.1.109): 56 data bytescount of paragraphs of (do shell script "ping -c 2 192.168.1.101). This pings the server twice, and if the server answers the result is 7, if not, the result is 4. |
Well, let me modify it a bit further...
How can I add an "if/then" statement to these scripts as I have them above? Basically (crudely) I want to have it be: if volume "GROUP_HOME" isn't mounted, then do the mount part, elseif just open the folders. But I think my map above is flawed, because I want to ensure that the folders get opened if the volume "GROUP_HOME" isn't mounted. I guess I'd put the "open the folders" part as part of the "then" statement as well? Is that possible? EDIT: I ask this because I want to put these scripts in the Dock so 1d10t-user-A can just click on the icon in the Dock and open their folders when they loose track of them. As it is, when the drives are mounted, if I click the icon again, it wants me to authenticate again. |
I'm not sure I understand your logic, but to the generic question, the structure you want is:
if BooleanExpression then -- do your stuff for true here else -- do your stuff for false here end if You can nest these, i.e. else if BooleanExpression then, but I always end up struggling to recall when I need extra end ifs, and when not. |
I guess the problem is, I don't know what the commands that AppleScript aknowledges are, and I'm having a bit of a time googling for them as a complete list. Anyway, what I'm trying to accomplish is akin to this (text in red is completle made up but illustrates my "logic" :) ):
Code:
if volume "group_home" is not mounted thenI found this POST that details how to check for a volume, but frankly, I don't fully understand it, but I'm going to try it. |
I can not test this as i do not have the smb's
but this may work. Code:
tell application "Finder" |
Hmm so close!! That doesn't quite work.. it won't open the folder anew if it's been closed, by at least it's not asking for smb authentication again! Thanks for helping me get even closer to the perfect solution.
|
Quote:
|
I actually figured it out.. trial and error style:
Code:
tell application "Finder"Now I need to figure out some error checking. I noticed that if I clicked on the "Cancel" button in the SMB share authentication window, the AppleScript would keep bringing it up forever until someone authenticated. I need to make sure that if someone clicks cancel, that it goes away. Thanks for everyone's help so far!! |
The saga continues..
Quote:
Code:
tell application "Finder" |
Quote:
I.e. after the dialog is dismissed, control gets back to the next line. That is where you want to tell AppleScript to go home - it's all over. |
I'm not sure what the proper terms for an AS 'return' would be. I imagine a conditional 'end tell', but I got compilation errors when I tried that. But I know what you mean from what little C I've learned.
I removed the "OK" button from the dialog and that worked. Code:
tell application "Finder" |
Don't know how to trap the "Cancel" problem - the AppleScript isn't doing it and don't have my own PC server running.
You might think about some means of escaping from the "repeat until .." loop too; suppose the damned server won't mount for some reason - the test will never be satisfied. The "with timeout" structure doesn't work within the AS itself - it applies when you are concerned that a "tell" segment will fail when the "told app" fails to respond. AppleScript and its Additions are not very good at timing in ticks or finer scales and I don't know what OSAXen you have. Another way is to increment an integer and stop it when it reaches some large number, i.e. limit the number of loops allowed. An Afterthought Since Applescript isn't good at timing, you might just put a delay of 2 seconds in the repeat until loop so it will only execute every 2. Otherwise the loop will run as fast as it can and eat CPU time. |
Quote:
return will return to the caller of a function. I believe that a simple 'return' at the top level in a script will exit the script. O'Reilly book sample chapter on AppleScript control-flow keywords: http://www.oreilly.com/catalog/aplsc...pter/ch07.html |
Sweet! Thanks! Trying my hand at XCode now to build a cocoa app to do this (yeah right, good luck yellow! :))!
|
Does this work any better?
Code:
property user : "bruce"The last line is an example of how to size a Finder window. If you're trying to determine a good size, move the window yourself, then run this statement in a new Script Editor window: Code:
tell application "Finder" to return bounds of front Finder window |
There are a couple of scripts here that give the full works with regard to window sizes etc. They are compiled ones for some reason. The scripts are called 'Tile Front Windows' and 'Open Tandem Browser Windows'
If the only reason for wanting to use AS Studio is to allow the user to enter their user name/passwords, bear in mind that 'normal' AS will allow you to enter stuff into the script with 'display dialog' Code:
set response to display dialog "What is the unladen weight of a sparrow?" default answer "African or European"On the other hand, if yellow just wants to use AS studio because he can ...... go for it! |
Thanks, I'll look into both of those last 2 posts when I hit work today.
I actually bit the bullet and picked up an AppleScript book last night at my local book gigantomart. I figured I better start somewhere, I can always be begging others to do my work for me. I think that I want to use ASS (heehee!) mainly because it'll give me a nice polished looking app that I can use to gather username, domain, the user's view preferences, and save all that in a .plist file. Then give them 3 1d10t buttons at the bottom of the app window that allows them to mount/open their Home, Public Shared, and Private Shared. One polished app, incorporating all that they need. I'm also hoping that I can figure out how to get this to log to /var/log/system.log. Definitely not necessary, but something I'd like to learn. |
yellow, would you be using OS X 10.3?
|
Yes.. all the Macs this is destined to end up on will be running Panther (10.3.8).
|
Normally those commands should work on other versions too though... Its all pretty much standard OS X applescript stuff.
|
Quote:
|
Quote:
|
Cool, thanks! I'll definitely look into it.
|
Is there an example anywhere of Cocoa Bindings in use in an AppleScript App?
|
Quote:
Frist, in Xcode's main menu, goto Project > Edit Active Target 'name', then, in the resulting window, choose Info.plist Entries > Simple View > Basic Information. Fill in the Identifier box. This will be used by the user defaults system. Apple's programs typically use com.apple.name. You might enter something like "yellow.OpenFolders" (sans quotes). Now, move over to Interface Builder. Let's say you have a text box where the user enters the domain. With said text box selected, open the Info panel and choose Bindings from the menu. You can bind any of the listed properties. For now, click on "value". Enter a name in the "Model Key Path" box, and press enter. (The "Bind" checkbox will automatically be checked.) This is the key that will be stored in the preference list (e.g. yellow.OpenFolders.plist). Of course, you will also use this name to get the key's value out of the preference list. We'll assume you entered "Domain". While we're in Interface Builder, you need to set "File's Owner" to trigger the "will finish launching" event handler. To do this, select "File's Owner" from the instances tab, open the Info window, and choose AppleScript from the menu. Expand the Application list, and check "will finish launching". Assign this event to a script in the box below. [Still with me? :)] Move back over to Xcode. Open the script that will handle the "will finish launching" event. Assuming you have nothing else in this handler, it needs to look like this: Code:
on will finish launching theObjectLet's see how things work so far. Build and run your application. The domain text box should contain the default value you entered in the "will finish launching" handler. Change the value of the text box, then quit and relaunch the application. The text box should contain the new value you entered. Well, that should be enough for now. Thanks for reading! |
Quote:
|
Just an update..
As I read through the AppleScript book, I've learned a little bit and added some stuff and cleaned up some stuff. Just though I'd update with where I'm at currently (if you care :)):
Code:
tell application "Finder" |
Looking rather pro, yellow, for a guy who just picked up AS the other day for the first time.
And Guardian34 - thanks for the very cogent explanation. Now it's clear to me what "binding" is. In languages like SuperCard, handlers are part of GUI objects themselves. From your explanation and Apple's, Cocoa Binding is the means of linking the pieces of the GUI to the handlers that deal with them, i.e., creating the event loop linkages for you in essence. Have I got the general picture? Having saved your explanation, I'll try it (and I'll bet yellow will too). Thanks. |
Quote:
Quote:
|
Quote:
|
Quote:
|
Looks fine, yellow.
Some changes you could make. If you check to see if the network share doesn't exist - and do that first, you can eliminate the code duplication. Also assigning a pointer to the new Finder window makes it clear which window will change. Users may already have a 'Finder window 1' open. Code:
tell application "Finder" |
In general in programming it is a bad idea to loop while doing nothing unless you are deliberately trying to consume CPU power.
Thus I would prefer to see some sort of 'delay' inside the repeat loop that waits for the disk to mount. Something like this: Code:
repeat until (list disks) contains "GROUP_HOME"It would be better to have it exit the loop after a while - e.g. after a fixed (large) number of iterations. Something like: Code:
set timeWaited to 0 |
Thanks for the continued input, I really appreciate it!
I took (parts) of the your suggestions and put them in the code. I think the removal of the code redundancy will wait until v2 (Cocoa version?), as the script/app is very small, it doesn't really bother me at the moment.. even though it's probably "good form" programatically. I just need to get something workable 'out-the-door' (so to speak) and then I can concentrate on cleaning it up and stuff like asking for/using values like 'username', so I don't have to recreate the wheel for each user. You're quite right about the 'Finder window 1' (I actually took that from recording some actions in the Finder to see what the associated AppleScript would be), so I've implemented your use of the mountFoo variables. And the addition of the delay and associated sane exiting on failure is also a great help and has made it's way into the script. Thanks again! EDIT: I'm experimenting with: set _username_ to "yellow" as string With hopes that this will populate _username_ throught the script. I'm just not sure how it will be handled in the "mount volume" line. RE-EDIT: I used guardian's "&_username_&" suggestion and it worked! |
Quote:
The previous 'on error' statement should catch any mounting issues. Yellow, you can get error codes sent to the 'on error' handler so that you can handle different errors in the same handler. Bet it's in your book. I'd replace the loop with a single delay statement. The second error handler would deal with any problems associated with being unable to get the correct full path to the SMB share. |
Quote:
I find the evolution of the script quite interesting and wonder what the final will look like once I reach the end of the book and you all get tired of helping me. :) |
try using
Code:
tell application "System Events"this gets the OSX user name. Not sure if you are using the same user name on the smb |
Quote:
|
Quote:
Quote:
Code:
repeat until (list disks) contains "GROUP_HOME"Quote:
Quote:
|
Quote:
Does this script take much CPU on your system? Code:
tell application "Finder" |
Quote:
|
Quote:
|
Quote:
Script Editor isn't a good test environment for determining deployment considerations. When I run the above script from Script Editor on my iBook, it also shows CPU usage approaching 100%. But if I save it as a compiled Application, and run that, the CPU usage averages less than 1 %. |
Same here, saved as an app, it maxed out at 1%. Larger RAM usage then with Script Ed, though.. about 50% larger.
|
I don't save everything as a compiled application though.
|
Most of my AppleScripts are inserted as scripts into QuicKeys X3 so I can run them with a hotkey or easily call them from another QK sequence. Run in that way, a delay is not the CPU eater I thought it was; QK uses less than 4% of CPU time, declining to 1 at the point that the delay times out. Perhaps an AS delay is now using the sleep shell function.
|
| All times are GMT -5. The time now is 06:03 AM. |
Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.