Sunday, June 19, 2016

We will miss you Srinivas

We all live on this earth as though we will be here forever. I guess that's the way we're disposed to think. Otherwise, I guess all of us will simply prematurely end our lives.

To come to the point, one of my engineering friends has recently passed away. Even though I know that one day it'll be my time to go off the face of this planet, it made me very sad to know that he passed away not fully living his time. I just feel like I wanted to share or express my homage to him by writing it on my blog here.

It was 1998 fall and we just joined Engineering college, JNTU in Hyderabad. Just like my self being from rural background, Srinivas or fondly called YSR, Yampati Srinivasa Reddy being his full name, is also from a small village in current Telangana. We used to live in a hostel along with many other friends. One thing I always did was to play cricket, literally all day. I didn't know much about Srinivas except that he was the best EAMCET ranker in our mechanical engineering class. I think it was around 600 which I'd say is exceptional.

Like I said I used to play cricket all the time and if I remember right only thing I observed of Srinivas was that he used to sit in his room in front of books. I used to think of him as a just another bookish guy. Honestly speaking, I didn't care to think more than that. Then it all changed just in one moment.

One evening like it always was the case I was playing cricket with my friends and some one played a lofted drive and the ball ended up hitting Srinivas' room window and breaking it. I went into his room to get the ball and just like expected he wasn't happy. In fact he was upset and angry. Immediately I said sorry and started looking for a ball. That moment Srinivas said something around these words in thick Telangana accent "Emiraa mee amma naayana kastapadi mimmalni ikkadki pampisthe meeku kovvekki eppudu aatalentra". Actually it was very intense. I still remember I was so shocked I was taken aback and didn't know what to say.

I myself is not a guy to take things lightly when someone says things to my face. To my astonishment, I didn't get angry at all. In fact, he made a great impression on me. So, I said to him sorry again and asked him why couldn't he ease a bit and join us to play cricket. This guy truly had a great heart. He started smiling and refused the offer and said he needed to study. Immediately, I told him we were just beginning the semester and there was no need to sit 24 hours in front of books. Then he said he wasn't worried about our first year but he was preparing for IIT. I was like "wow, this guy is amazing". Then we ended up talking few things and then I asked him what book he was going through at that moment. To his surprise I ended up helping him solve few physics problems.

Another great aspect of this guy was he would tell you on your face whatever he thought or would think. That moment he told me "I really thought all you guys are brainless". I started laughing and then he said why I was wasting time and why couldn't I join him for IIT preparation. I laughed it off and wished him good luck. He was not only hardworking and truly apply himself there working towards a goal. I mean we were young and always wanted to have fun whether it be playing cricket, watching movies or talking about girls. That's the age, right? But this guy was special. He had discipline and he always knew what he wanted. How many of us had those qualities? If he had bit of luck I am sure he would have been here with us doing great things.

So our friendship continued. Like I said he always thought hostel environment wasn't helping him at all in reaching his goals. So, he left hostel pretty soon and took a room outside. One day I went with him to his room. I still remember it was raining pretty hard and I was shocked to see how small the room was. He asked me to sit there and started making food. You'd think no big deal, right? He had to cook under a tarp that had holes all the over place. Nothing bothered him. He quickly made something and offered me. To think back of that moment it makes me tearful. Great thing was he never complained.

One thing we both had in common was both of our families were dependent on farming. We used to talk how difficult it was for our families given that how difficult farming was. The more I know about him and his family the more I liked him.

At some point in third or fourth year he suddenly out of no where wanted to watch movies and have some fun. It was great to see him wanting to do other stuff as well. I think he must have felt the urgency to feel the fun as we were closing on finishing up our engineering. When our entire class went to Nagarjuna Sagar he was there next to me. We took one picture together and that's the only picture I have with him.

After engineering we all went separate routes and I ended up in Sweden doing masters. One day I got a very angry email from Srinivas asking whether I was alive or dead. I got so upset I wrote him back very angry response. Then he wrote me back apologizing. Of course I called him and we ended up talking for more than half an hour or so. It was heartbreaking to hear he went through real hard time after engineering. He stuck to mechanical engineering and it didn't do him any favours. After going through lot of difficulties he realized it was time to quit and go for software. As he was a sharp guy, he learned few things quickly and got a job in Infosys which I'd say amazing.

After that life was good to him. I talked to him few times and he was truly happy. He helped his family out as a dutiful first son in taking care of them as well as getting his sister married. He was always there as a son and brother. He said he was happy when he talked about his daughter.

For whatever reasons except for an odd email here and there we were not in touch that well for a while, I'd say at least in the last 2 years. Then suddenly he wrote me an email last December I think. I felt really happy that he cared enough to write an email after such a long time. Truly good friend. Then I wrote him back and eventually I called him. He was with his friends and we talked for 10 minutes. I said I'd call him soon again and told ourselves that we should do video chat and catch up on how our lives went, etc.

So, I was thinking of calling him sometime and then one day out of no where my friend Kishan mentioned to me what happened. It was biggest shock of my life. I was there next to my grandfather when he passed away. I cried a lot back then. But it was bound to happen with anyone when they get old and fragile. It's part of life. But it's not the case with Srinivas. He is in his thirties and having a life and working hard to take care of his family. Like any father he wanted to be there to take care of and guide and prepare his daughter towards her future. Then in one moment his life was ended.

Now I am asking myself again and again "why in the world this should happen to him?". I don't know the answer but one thing I know for sure is life is not fair. It's not fair at all. He should be here along with us doing great.

We will truly miss you Srinivas. If not for unfairness in life you would be here with your family. I know that no one can replace you for your family. As a friend I promise you we will try our best to help your family.

Bye for now Srinivas. Sreedhar.

Sunday, August 17, 2014

Applescript to delete multiple Google Voice Messages

I use Android phone in my work as well in personal life. When we are paying so much for data on our phones why the heck should we pay for text bundles. So, out of million options I chose google voice as my text messaging application. Advantage with this one is that I could do pretty much everything from gmail/voice web interface.

My experience with google voice has been great except for one annoyance. On android phone it wouldn't delete me multiple messages at a time. I need to long press each message and then select delete from it. Over the time these tend to be hundreds. This means long pressing all these is not an option. So, you'd think we should be able to select all the read/unread/all messages from the google voice web interface like we can do for the emails on the gmail web interface (by clicking on select all on the inbox after selecting all messages in on the first page) and then be able to delete, etc. Nope, we can't do this on google voice web page. Sucks big time. This means we need to select all the messages on the page we're seeing and then select delete to delete them. Given that there might be hundreds of these messages we might have to select and click delete hundreds of times. Not a viable option for me.

Best option would be to write python code which does an excellent and foolproof job. But, again who has time. I definitely don't. So, I went for not so foolproof solution: applescript. You can make a nice application with applescript that would ask for details like "your username, password" and then store them in the keychain securely and also ask you "yes or no" questions to make sure you know what you're doing, and also which messages like "all/read/unread", etc.

I wanted to make this application but not sure whether it was worth it. In the mean time I put this code in few minutes and ran and my inbox was nice and empty on both web interface as well as on my android google voice app.
This is what I did. First, I logged in onto my gmail web interface from Safari. I saw that there were 253 total messages in my inbox (you can see that on the top right corner). I think each page shows 10 messages. So, I will have to make applescript go through 26 pages. You can program it as (numberOfMessages div 10).

Then I ran this script from applescript editor and in few minutes my inbox was empty. That's it. When I tried to run the same script on my home mac I had few problems. The reason was that on my home mac pressing tab two times was enough to reach select checkbox on the page where as I needed to press tab three time on my office mac.

Anyway, it'd be simple to change these to make it work. As you notice, I'm making applescript open google voice page. It opens it without asking for password as you've already opened your gmail account. Now, it'd wait for 3 seconds. This is to make sure page opened in time before applescript goes onto pressing keys. Increase it in case you've slower internet (I doubt it these days). Ascii character 31 is lower arrow key. Everything is self explanatory.

There is no need for closing the page each and every cycle. The reason I did that was I was already using another applescript script to do some tasks on our dns manager. I simply copied that and modified. Anyway play with it. The other reason is, occasionally it doesn't do what it is supposed to do and so closing and opening the page makes it like starting afresh.

tell application "Safari"
 activate
 tell window 1
  set current tab to (make new tab with properties {URL:"https://www.google.com/voice"})
  delay 3
  repeat with n from 0 to 25
   tell application "System Events"
    keystroke tab
    keystroke tab
    keystroke tab
    keystroke space
    keystroke (ASCII character 31)
    keystroke return
    keystroke tab
    keystroke tab
    keystroke tab
    keystroke tab
    keystroke return
   end tell
   delay 3
  end repeat
  tell application "System Events"
   keystroke "w" using command down
  end tell
 end tell
end tell

Monday, March 25, 2013

Giving an icon to an applescript application

I showed how to save an applescript code as an application in my previous post. In this post I will show how to give a different image to an applescript application to replace the customary apple applet icon. I've already saved one of my codes that opens my gmail web account in safari (check my previous posts) as an app "GMail" on my Desktop.

First thing I did was to choose an icon from google images. Just search for whatever image you'd like to give it to your app. I chose some GMail image that came up in the images search. Then, open the image with preview.

Select the image and copy it to clipboard.




Then, right click on the app you saved and select "Get Info".


Click on the applet icon in the left most corner of the info window that has opened up. You can blue shade around the icon highlighting the fact it has been selected.



After that, just paste the image we've copied onto clipboard from preview by doing command + v. Now, you can see that icon has been changed.


This is what I've got on my Desktop. As you can see the icon of the app has been changed. This looks much better. Right?


Now, you can simply drag this app onto your dock and with one click you have your application running.



Making an app from applescript

This post shows how to make an app from applescript code on your mac.

First, open applescript editor and write/put some applescript code. Press Command + Space bar and type apple and you should applescript editor like shown below.


Save the code in scpt (script) format just in case you'd like to make changes at some point in the future.


Once you're done saving it scpt format, try to save it again by selecting duplicate and then rename it from the arrow mark next to title of the document it self.


Now you should see the app "display" where ever you saved it. I saved it on the Desktop and this is how it looks.


Double clicking on it would make it run like any other application on your Desktop. Since I put the code 'display dialog "Hello! How are you?", running it would show a display dialog with this content like shown below.



App on Mac through applescript to open GMail web account in Safari

Recently, out of curiosity I started writing an applescript code to make an app to login onto my gmail web account. Once I started it I realized there are many things I needed to consider. Here are the different scenarios:

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

Creating a new keychain on Mac

Recently, I wanted to make an app on my mac for logging onto my gmail account in Safari browser. Once I started looking into applescript I realized best way to use an login credentials is through mac native keychain access. For my GMail applescript I had to make a keychain and this is how I did it. First, open keychain access from applications. Goto File --> New Keychain or selecting New Keychain from the popup that comes up when you right click on the left pane as shown below:

 

I gave a name 'WebLogins' and created in a default location "/Users/manchu/Library/Keychains/"

 

Enter a password for the newly created keychain. This keeps all your username and password combinations we're going to keep in this keychain secure just in case some one got hold of your system.



Now click on WebLogins in the left pane and then click on "+" all the way below immediately next to the left pane. This would ask you to give a name to the item you're going to create. I gave it GMailPersonal as I'm going to use this item for logging onto my GMail web account. For account name I use my GMail username and for Password I use my GMail account password. Save it by clicking "Add".

 

Next step is to change the settings for this Keychain. Right click on "WebLogins" and select 'Change Settings for Keychain "WebLogins"...' as shown below:

 

Since I need my app to access these credentials randomly I uncheck the first item as I don't want to enter the keychain password every time it accesses the keychain. Since I use this to see my gmail it doesn't make sense to uncheck "Lock when sleeping" as I don't need to activate my app either remotely or make it run at certain time in a day (let's say cron job) in my absence.

 

In my applescript I use the tool security to access the username and password from the WebLogins keychain. You'd be asked to either always allow or deny or just one-time allow the security to access the username and password. I go for always allow as I don't want to enter keychain password through out the day.

 

Whenever you logout of or restart the system you will be asked to enter the keychain password as a security feature. As you see security tool is trying to use the password.

 

Saturday, March 23, 2013

Thunderbolt display problem

I have thunderbolt display that goes along with my iMac. Most of the time I don't use this display unless I'm working from home and I need to keep many terminal windows open. But when I don't need this display it looks like I can not turn it off. This means this display is turned on when ever I'm using iMac. I searched online and haven't found a native solution. There is an app SwitchResX that would do this, it seems. But it just doesn't make sense to not to be able to do it. So far, what I have been doing to solve this problem is to plug the thunderbolt cable off the iMac and this would turn the display off. But it's frustrating to do this when you need to do this many times as you need to reach for the cable at the back of the iMac. So, I looked at the SwitchResX and it looks like a great tool if you really need all the functionality it provides. This is not the case for me and so what I'm doing these days is to simply make the display brightness to zero. Just to let you know, when you press brightness key on your keyboard it acts only on your iMac display. In order to reduce or increase the thunderbolt display brightness just press brightness key while holding control key. This would do the trick. In any case, I'd be great if someone could post any other solution that's working out well.

PBS Script Generator: Interdependent dropdown/select menus in Javascript

PBS SCRIPT GENERATOR
SH/BASH TCSH/CSH
Begin End Abort

About Me

LA, CA, United States
Here I write about the battles that have been going on in my mind. It's pretty much a scribble.

Sreedhar Manchu

Sreedhar Manchu
Higher Education: Not a simple life anymore