January 9th, 2014 at 12:35 am by Dr. Drang
When Version 1.4 of Pythonista was released at the end of November, I immediately1 looked through the documentation for the new
location module and wrote a little script to see how it worked. This, I thought, could be really useful if it was cleaned up a bit. Then I promptly forgot about it until this morning, when I did the necessary cleaning and ended up with a script that I find absolutely delightful. It wasn’t hard to write, and it may not be especially useful in the long run, but I’ve been thinking about it all day.
Location.py, and it’s a simple little thing that’s meant to be called from Drafts. It appends the location—both the latitude/longitude coordinates and the address—to the current draft. Here’s the code:
python: 1: import sys 2: import location, time 3: import urllib, webbrowser 4: 5: # Handle argument, if present. 6: try: 7: a = sys.argv 8: except IndexError: 9: a = '' 10: 11: # Get the GPS info. 12: location.start_updates() 13: time.sleep(5) 14: loc = location.get_location() 15: addr = location.reverse_geocode(loc) 16: location.stop_updates() 17: 18: # Assemble the output. 19: spot = '''%s%s 20: %s, %s %s 21: %.4f, %.4f''' % \ 22: (a, addr['Street'], 23: addr['City'], addr['State'], addr['ZIP'], 24: loc['latitude'], loc['longitude']) 25: 26: # Send output to Drafts. 27: webbrowser.open("drafts://x-callback-url/create?text=" + urllib.quote(spot.encode('utf-8')))
It can be run directly from within Pythonista, or, more usefully, it can be run from Drafts through this URL Action:
The comments separate the four parts of the script:
- Lines 6–9 deal with the two ways to call the script. If it’s called from Drafts, the variable
agets the contents of the current draft. If it’s called from Pythonista,
ais set to the empty string. This will affect what’s sent back to Drafts at the end of the script.
- Lines 12–16 are the meat of the script. They activate the GPS, get the current location, look up the address, and then deactivate the GPS. The five-second delay in Line 13 is there to give the GPS a chance to figure out where it is. I doubt that’s the optimum delay, but it’s worked so far and it’ll be easy to change if I learn later that it needs more time.
- Lines 19–24 format the location and put it after
- Line 27 sends everything back to Drafts to create a new draft.2
My intent is to use this in conjunction with my Work Diary action, which I use to track the time I spend on projects at work. When I’m out of the office, I can quickly add an entry that includes where I am by starting a draft with a brief description
Arrived at inspection site
then invoking the Location action to extend it to include the location
Arrived at inspection site 526 S State St Chicago, IL 60605 41.8762, -87.6278
before finally calling the Work Diary action to add this, preceded by a time stamp, to a daily diary file in Dropbox. This is the sort of thing that can save time later when I want to look up where I was on a map. Originally, I had the coordinates formatted with directional indicators, like
41.8762 N, 87.6278 W; but I soon learned that Apple’s Maps app prefers the purely numeric coordinates, which can be copied directly into the search field on both the OS X and iOS versions of Maps. You can do the same with Google Maps if that’s what you prefer.
Why am I so taken with this simple little script? I think it’s because of all the infrastructure it’s using behind the scenes. Most of my scripts run on the processor of my local machine. Some of them trigger an action by another computer across a network. This script, though, trivial as it is, is reading signals sent from satellites orbiting the Earth. I just cannot be blasé about that.
You may remember the idiotic fuss made over “You didn’t build that” during the last election campaign. This is the sort of thing President Obama was talking about. I’ve written a 27-line program that allows me to automatically add my location to a diary file. It’s a cute program, but it relies on so much behind the scenes:
- First, there’s Ole Zorn, who made both Pythonista and the
- A layer out from there is Apple, who wrote the Location Services code and made it accessible to developers like Ole.
- Then there’s the GPS hardware and firmware layer, made by I-don’t-know-who and incorporated by Apple into the phone.
- Finally, there’s the GPS infrastructure, designed, built, and maintained by the U.S. government over a period of decades.
All of this at my command with the call to
location.get_location() in Line 14. Amazing.
Honestly, I think I’m losing my mind. Less than a week ago, @hiilppp tweeted a link to his script that does essentially the same thing. I may have even retweeted it. I don’t know why I didn’t remember that as I was writing this, but I find it acutely embarrassing. I didn’t copy any of his code—as I said in the post, I wrote the essential parts back in November—but that’s not the point. Attribution is everything, especially when you’re giving your ideas away, and I failed here. Deepest apologies.
(Is it especially ironic that I failed to link to another’s work in a post where I’m trying to make a point about how we all build on what others have built before us? Yes.)
In addition to apologizing, I should mention that following @hiilppp is a good idea, especially if you’re interested in Drafts. He and Greg Pierce have long Twitter conversations about bugs and edge cases that may help your use of the program.
You know how I said the location was appended to the current draft? Strictly speaking, that’s a lie. What really happens is that the original draft is deleted and a new one is made with a copy of the original contents followed by the location. The effect is the same as appending. ↩