1) One just booted the system. Hence, the app should start Safari, open Gmail login page and then login with credentials stored in a keychain.
2) One has already logged into his gmail account. But, the page has been closed but account hasn't been logged out. In this scenario, app should not enter the username and password as when it tries to open the Gmail login page your Gmail opens up with your inbox with emails since you already logged in before closing the page.
3) You logged out but didn't close the page. Then, after a while you want to log back in. In this case it should not reopen the login page but find the already logged out page that's open and put the credentials.
4) The account is already opened and active in a tab that is not in focus right now. In this situation, app should simply bring this tab to the front.
5) The other case is where Safari is minimized with account is already open but page is closed, is logged out but page is open, etc.
6) Most important thing is to make sure Gmail login page loads before it starts entering username and password.
7) At the same time accessing username and password has to be secure.
8) Multiple windows and tabs are open and the app should cycle through them to find some of the above mentioned cases.
This code covers all these cases. I'm sure there are many more one might come across. For now this is working great for me on my 3 different macs (office iMac, home iMac and Macbook Pro). All these 3 have mountain lion operating system with Safari 6.0.3.
This code uses apple security tool to access the username and password I have stored in a keychain. This makes it very secure unlike storing the password in the script it self (check for one of my previous scripts).
The one important thing one needs to remember is to change the keychain location in the script based on their username. For example, on all my macs my username is manchu and I store the keychain in the default location of /Users/manchu/Library/Keychain. So, if you save it in the default location then you should just change manchu in the above path with your home directory name (the one that has home/house symbol in the finder window on the left pane).
This code ensures that page has successfully loaded by checking whether File --> Save as becomes active in the Safari menu. I'm not sure whether this is the right way but some how it appears to be working ok. I have given 10 seconds for the page to load. If it doesn't happen before that it will let you know that page has failed to load through announcement as well as display dialog. If you don't want your Mac to announce it then hash the lines with "say".
If you'd like to use this script, then make sure you create a keychain with your Gmail login credentials in it and change the path to it in the script below. You can see my post before this one to know how to create a keychain.
Here is the code:
# Applescript to open Gmail account in Safari. # Written by Sreedhar Manchu. # Password retrieval from keychain access has been accomplished with the code # found on www.vickash.com. The page is titled "More Secure Passwords In Applescript" set IsDefined to true set theCredentials to getCredentials of ¬ "GMailPersonal" from "/Users/manchu/Library/Keychains/WebLogins.keychain" set userName to account of theCredentials set thePW to password of theCredentials set theTitle to "" & userName & "@gmail.com - Gmail" as string if appIsRunning("Safari") then tell application "Safari" activate if windows is not {} then activate repeat with j from (count of windows) to 1 by -1 repeat with i from (count of tabs of window j) to 1 by -1 set thisTab to tab i of window j set thePageName to name of thisTab #display dialog thePageName if thePageName contains theTitle then set current tab of window j to thisTab set windowNum to j set alreadyLogged to true end if end repeat end repeat end if end tell end if try get alreadyLogged on error set IsDefined to false end try if IsDefined then tell application "Safari" activate set index of window windowNum to 1 end tell else set IsDefined to true set theTitle to "Gmail: Email from Google" as string tell application "Safari" activate if windows is not {} then activate repeat with j from (count of windows) to 1 by -1 repeat with i from (count of tabs of window j) to 1 by -1 set thisTab to tab i of window j set thePageName to name of thisTab if thePageName is equal to theTitle then #set tabNum to i set theWindows to windows set winOne to item j of theWindows if (miniaturized of winOne) then #set miniaturized of winOne to false activate #delay 0.5 end if #set currentTab to item i of tabs of window j set currentTab to item i of tabs of winOne #set winOne to item j of windows set alreadyOpen to true end if end repeat end repeat end if end tell try get alreadyOpen on error set IsDefined to false end try if IsDefined then tell application "Safari" activate tell winOne set index to 1 set visible to false set visible to true end tell #set thisTab to tab tabNum of window 1 #set current tab of window 1 to thisTab set current tab of window 1 to currentTab tell application "System Events" keystroke userName keystroke tab keystroke thePW keystroke return end tell end tell else tell application "Safari" activate if windows is not {} then tell window 1 if (miniaturized) then set miniaturized to false end if set current tab to (make new tab with properties {URL:"https://mail.google.com"}) #set current tab to (make new tab with properties {URL:"http://www.bsnl.co.in"}) end tell else tell application "Safari" activate make new document with properties {URL:"https://mail.google.com"} end tell end if end tell if page_loaded(10) then set IsDefined to false tell application "Safari" activate #set theURL to URL of current tab of front window as text #set thePageName to name of current tab of front window as string set thePageName to name of current tab of window 1 as string if thePageName as string is equal to "" or thePageName as string is equal to null or thePageName is equal to missing value then set pageIsNotLoading to true end if end tell try get pageIsNotLoading on error set IsDefined to true end try if IsDefined then #display dialog thePageName set theTitle to "" & userName & "@gmail.com - Gmail" as string if thePageName does not contain theTitle then tell application "Safari" activate tell application "System Events" keystroke userName keystroke tab keystroke thePW keystroke return say "Gmail login has been successful" end tell end tell end if else say "Either page has failed to load or Gmail is taking time" display dialog "Either page has failed to load or Gmail is taking time!" end if end if end if end if on page_loaded(timeout_value) -- in seconds tell application "System Events" tell process "Safari" tell menu 1 of menu bar item "File" of menu bar 1 repeat with i from 1 to timeout_value if enabled of menu item "Save as..." is false then delay 0.5 else return true end if if i is timeout_value then #set timeoutValue to timeout_value * 0.5 beep display dialog "" & timeout_value * 0.5 & " seconds have elapsed; Either page has failed to load or Gmail is taking time!" return false end if end repeat end tell end tell end tell end page_loaded on extractData(theText, theFieldName, theEndDelimiter, spaces) set theDataStart to the offset of theFieldName in theText if theDataStart = 0 then return "" else set theDataStart to theDataStart + (length of theFieldName) + spaces set theData to text theDataStart through end of theText set theDataEnd to ((offset of theEndDelimiter in theData) - 1) set theData to text 1 through theDataEnd of theData end if end extractData on getCredentials of theKeychainItem from theKeychain set theKeychainPath to (POSIX path of theKeychain) as text try set theKeychainAlias to (POSIX file theKeychainPath) as alias set theKeychainPath to (POSIX path of theKeychainAlias) on error return "Keychain file not found at specified location: " & ¬ theKeychain as text end try try set theResult to do shell script ¬ "security 2>&1 find-generic-password -gs " & ¬ theKeychainItem & " " & ¬ quoted form of theKeychainPath set theAccount to extractData(theResult, "\"acct\"<blob>=\"", "\"", 0) set thePassword to extractData(theResult, "password: \"", "\"", 0) return {account:theAccount, password:thePassword} on error return "Generic password item specifeid does not exist in keychain: " & ¬ theKeychainItem end try end getCredentials on appIsRunning(appName) tell application "System Events" to (name of processes) contains appName end appIsRunning
No comments:
Post a Comment