Monday, October 28, 2013

Downloading Picasa Albums with Python...

Well, I'm ready to move my photos out of Picasa onto a new website (more on that later), so I wanted to download all my albums in their original resolution so I can edit and upload to the location. Well, after digging around out there I found that the Google api's will make this easy and there were even some Python bindings to make it easier. However, the api's are not exactly well documented (at least from what I could tell). I searched around for some open source or examples and there are a few out there, but the ones I tried either didn't work or they only downloaded low-resolution images. So it was time to try the DIY technique.

Starting with some of the sample code that comes with the api and using a lot of inspection of object methods and types I was able to put together a script that downloads all the albums. One of the trickiest parts was figuring out how to get the original resolution. At first all attempts seemed to always download 512 resolution samples. It turns out there's a magic option that you need to insert on one of the url's to get it to switch to the full-res download: "imgmax=d". The api doesn't seem to give any clue about this.

Anyway, without having to learn too much about the nitty gritty details of the api I was able to get what I needed. So, in case this helps someone else here it is:
import sys, os

pws =
pws.ClientLogin('', 'your password')

#Get all albums
albums = pws.GetUserFeed().entry
print dir(pws)

for album in albums:
    print "ALBUM: %30s [%3d]" % (, album.numphotos)
    uri = album.GetPhotosUri()
    uri += "&imgmax=d"

    photos = pws.GetFeed(uri).entry
    aname =
    aname = aname.replace(" ", "_");

    for photo in photos:
        pname = photo.title.text
        print "PHOTO:", photo.title.text, int(photo.width), int(photo.height)

        url = photo.GetMediaURL()
        media = pws.GetMedia(url)

        # print media.file_name, media.content_type, media.content_length
        data =

        filename = "%s/%s" % (aname, pname)
        print "Output: %s" % filename
        if not os.path.isdir(aname):

        out = open(filename, 'wb')

Sunday, January 13, 2013

Raspberry Pi - Adjusting the audio output volume

Ok, I have to admit that Linux can be quite obtuse and difficult to use for the non-technical user. Luckily I've had over 30 years of working with computer software to help me wade through the geek world that Linux basically is. One of the geek barriers to break through on the Raspberry Pi was figuring out how to change the audio output volume. This is done using the amixer command which has a really bizarre syntax and interface which I guess is complicated by the need to support a variety of output devices. Anyway, I won't claim to know all the details of using this command but I did figure out how to get it to change the volume on the Raspberry Pi. So I put together a script to make this a bit easier

Without arguments it tries to report the current volume settings. I'm just assuming that the two numbers are left and right volume. Can anyone confirm that? If you give it a number between 0 and 100 it will try to set the volume. Let me know if you have problems or suggestions. I'm only using the audio jack so I don't know if this works for hdmi audio.
import os, sys

def setVolume(id, percent):
   p = os.popen("amixer cset %s -- %d%%" % (id, percent))
   if p:
      gobble =

def getVolume(id):
   p = os.popen("amixer cget %s" % id)
   c = p.readlines()
   if len(c) > 2:
      range = c[1]
      value = c[2]

      r = range.split(',')
      min = int(r[3].split('=')[1])
      max = int(r[4].split('=')[1])

      v = value.split(',')
      left  = float(v[0].split('=')[1])
      right = float(v[1].strip())

      range = max - min
      volume = [left, right, range]
      volume = [-1, -1, 0]   # ??

   return volume

def showVolume(id):
   [left, right, range] = getVolume(id)
   print "Left: %d%% Right %d%%" % (int(left / range * 100.0 + 0.5), int(right / range * 100.0 + 0.5))

id = "numid=3"
p = os.popen("amixer controls | grep \"Master Playback Volume\"")
if p:
   c = p.readlines()
   if len(c) == 1:
      parms = c[0].split(',')
      id = parms[0]

argc = len( sys.argv )

if argc == 2:
   arg = int(sys.argv[1])
   percent = 0 if arg < 0 else 100 if arg > 100 else arg
   setVolume(id, arg)


Raspberry Pi - An amazing computer

Well, a couple of months ago I finally received my long awaited Raspberry Pi and I have to say this is an amazing little machine. Having been away from Unix for a long time I'm finding it great to get learning how to work with Linux and re-use a lot of my old Unix knowledge from many years ago. I'm hoping to start regularly blogging about using this little device for useful (and maybe not so useful) tasks. So watch for ongoing posts with RPi tips and tricks and other tidbits.


Garmin eTrex 30 review - Very disappointing.

Well, as promised a while ago, I'm finally getting around to putting together a summary of impressions on my hiking GPS the Garmin eTrex 30. I'll admit that I'm a GPS newbie/novice so I don't have any basis for comparison with other portable GPS devices. What I do have is over 30 years experience as a developer of interactive software. As you can tell from the title of this post, I'm not at all impressed with this device. I've been using it now for several months and overall I'm rather irritated by how difficult this unit is to use. I've been trying to come up with a list of positive aspects but I haven't been able to think of too many.

Positive points:

  • It seems to be very solid and well built. Although the little joy-stick thingy seems like the most exposed fragile part which contrasts with the rugged design of the rest of the unit.
  • Overall it does generally work, so, depending on your expectations, it's possible that this unit will fit your needs quite well.
  • It takes regular pen-light batteries which is good.
  • The battery life seems to be quite long. I haven't actually measured it but it hasn't been a serious problem thus far (as long as you remember to turn the unit off). See one of my comments below regarding power management problems for more details.
  • It's quite compact although I'm not keen on the form-factor (it's almost 3.5 cm thick, including the wasteful bulging hunk of plastic on the back of the battery cover). I would have much preferred a thinner unit with a larger screen. It's small size actually makes it somewhat difficult to manipulate when operating the buttons - it might be fine for someone with smaller hands.
 Well, it's not hard to find things about this device that leave a lot to be desired. Let's cover the most critical ones from my point of view:

Negative points:

  •  The user interface on this device is the biggest negative aspect of the entire experience. You would expect the main screen on a device light this to be the map view, but no, Garmin has decided that a huge menu of mostly useless choices is what you want to see the most. Counting them there are 27 options to choose from on the main screen. Do I have time to even figure out what all 27 of these are for? I'm sorry, life is too short. I think I use maybe 3 of the items on this list regularly. Now try to imagine how painful it is to find the 3 that you use the most each time you come to this list of 27. Sure, you learn where they are but how many button pushes does it take to get there. Let me tell you, it's really irritating. [Note, I've since discovered that you can remove and re-order this main list of options - so save yourself some pain right off the bat and go through the list and eliminate the 90% that you will likely never use. You can always add them back later once you learn how to use more features.]
  • Speaking of the map view, one would hope that some of the most common operations would be accessible from the map itself - but no, you can do almost nothing useful from the map view. The menu on the map screen has only 3 entries: setup map, measure distance, restore defaults. I've only ever used the setup - and in that choice only the select map option. I can't manage my tracks from here (my most common operation). I can't set waypoints from the map. No, to do these things you must go up to the main screen and search through the entries there to do what you want. 
  • As mentioned creating and managing tracks from my hiking is the main reason I purchased this product. On this aspect there also is a lot left to be desired. One really irritating issue with the track management is when you go to save your current track the software generates a track name for you using the current date. This is great and I use the default name all the time because typing in a new one every time would not be fun. However, the format they chose for the default track name is DD-MMM-YY HH:MM:SS. Can you guess what's wrong with this? Once you have tracks spread out over several months, the list of tracks ends up in order sorted by the day of the month. This makes it really painful to find the track you're looking for by date. The strange thing is that they use the correct year-month-day based naming for the auto-archive track feature. Go figure.
  • I forgot to mention that when you first buy this device it's almost useless until you go find some usable maps to install on it. There are free resources but I personally didn't have the time to research and try any of them out. I wish I had because I chose to purchase topo maps from Garmin and later discovered that I couldn't even get it to download maps of eastern Newfoundland. Their technical support for this problem turned out to be quite useless. Apparently there's a full topo map of Canada available online but it's quite large so you may have to purchase an expansion card and figure out how to download and install it.
  • I hinted above that there are some power management issues. On one of my trips I decided to use the GPS to create a track but when we got home I forgot to turn the GPS off. When I discovered this a day or two later the batteries were completely dead. By this point I wasn't really surprised that this device would disappoint yet one more time by not having an auto power off feature. It shouldn't really be too hard for it to know that it's not moving and not being used for some time period that could easily be configured by the user. To add insult to injury, the next time I used the unit after this power loss, I discovered that all the tracks that I had previously set to display on the map were no longer displayed. So it failed to retain some of my custom settings. This made it really difficult for me to get all my hiking trails displayed on the map again.
  • Another surprise aspect of this unit was the lack of precision. There are many cases where I go out on a hike and return by exactly the same trail and yet, when the track is offloaded, it shows that my return path can be as much as 20 to 30 meters away from my outgoing track. So if you need consistent accuracy don't rely on this unit.
  • I could go on about the many user interface issues that make the Base Camp software somewhat difficult to use. Once you figure out how to use it though it becomes an integral tool used along side the GPS unit.
So to make a long story longer, overall this unit has been very disappointing. The unit works, and along with the software can be used effectively, but the experience can be very frustrating. Your mileage may vary. In my opinion, Garmin needs to invest in some serious user interface testing and improvements in order to stay competitive.Soon many smart phones will likely be able to compete with these units (or already can?), so either the price will have to drop or the features improve to provide a customized and easy to use experience for outdoor trekking.

I'll add a plug here for a very handy website:  This site will take tracks exported from Base Camp and allow you to view them overlaid on Google maps or in Google Earth. Very cool and useful for sharing your hiking adventures with family and friends.

Cheers and happy hiking.