Jump to Content
Jump to Navigation

The Best Way for Senators to Celebrate Mothers Day

May 7th, 2010

Dear Senators Warner and Webb,

As you know, this Sunday is Mothers Day here in the US. Please celebrate it with your fellow Senators by ratifying the Women’s Treaty, known as CEDAW (the Convention on the Elimination of All Forms of Discrimination Against Women).

It means a lot to a lot of people in Charlottesville, Virginia, the United States and the World.  If nothing else, it’d be a chance to distinguish ourselves from Iran, one of the only other countries not to have signed on.

Regards,

Jeff Lavezzo
Charlottesville


Facebook privacy tool

May 5th, 2010

I spent last Saturday at a local tech conference, BeCamp 2010, it was a great success.  The topics were excellent, the participants were the best of central Virginia’s tech community and the sponsors provided excellent food.

The most useful session I attended was John Feminella‘s presentation on Internet Privacy. It was a great example of the kind of nuance that I see missing from general public discourse on any topic. The first step in addressing any problem is understanding the problem. And when the problem is privacy on the Internet, we have to understand what we mean by privacy.  John’s main point was

privacy != secrecy

that is, our privacy is not achieved through secrecy.  Instead what we really want is control over our information.  When Facebook changes their settings or when we find out about Spokeo’s listing on us it’s the lack of control that causes our anxiety, not the lack of secrecy. We don’t put secrets on Facebook for our friends to read and Spokeo’s data is collected from public records like the Charlottesville City Assessor’s Office. The problem starts when we feel that we don’t have control over how the information is distributed.

Facebook’s big change this year was their new “API” or interface (called Facebook Open Graph) for other websites and applications to read data out of their site.  And by data I mean what you and I have put on Facebook. They reorganized their privacy settings to align with this new API and to align with their business goals of making money off our information.  The two big problems with the new privacy settings are that many of them defaulted to be more sharing than most people like and that it’s very hard to tell when you’ve locked them down enough to suit you.   That’s where the tool John Feminella showed comes in handy.  Not sure what the Internet can see of your Facebook profile? Go to http://zesty.ca/facebook/ and put in your Facebook ID.  Click on the links in the list it generates to see what anyone else can see about you.  Because the tool’s navigation is not the best, I recommend ‘center-clicking’ to open the links in a new tab or ‘shift-clicking’ to open in a new window. Review each category of information, then go back into Facebook and change the settings.  Because of the loose structure of Facebook’s database, there may be a time delay between changing the settings and seeing the changes on Zesty’s tool.

I locked my profile down a few days ago and now the only thing it shows is a list of “likes” I belong to.

Hope this helps you feel okay about staying on Facebook.


Groovy: Simple file download from URL – Fixed

April 26th, 2010

The Grails app I’m working on right now has some cookbook code that takes a list of URLs and downloads the file each URL points to into a staging directory for other code to work on them. There are a couple dozen similar examples on groovy/grails blogs on the net:

def downloadFiles = { sourceUrls->
 def stagingDir = "/tmp/stagingdir"
 new File(stagingDir).mkdirs()
 sourceUrls.each { sourceUrl ->
   def filename = sourceUrl.tokenize('/')[-1]
   def file = new FileOutputStream("$stagingDir/$filename")
   def out = new BufferedOutputStream(file)
   out << new URL(sourceUrl).openStream()
   out.close()
 }
}

downloadFiles(
 ["http://lavezzo.com/saic/mvnBuildLifecycle.png",
 "http://lavezzo.com/saic/settings.xml"
 ])

Looks reasonable, right?

What happens if we call it like this?

downloadFiles(
 ["http://lavezzo.com/saic/mvnBuildLifecycle.png",
 "http://lavezzo.com/saic/I have a space.png"
 ])

Disaster!  java.net.URL can’t handle spaces? Now normally, if I were writing the URLs I’d just add in my own %20s and call it a day. But in this case that array of URL strings is the output of an XmlSlurper pointed at an html file. I have no control over the spaces in that file. java.net.URLEncoder seems like a good place to look, but it turns out that class is intended for use when composing links for html files. It substitutes a + for spaces, which don’t work in java.net.URL. java.net.URI‘s documentation mentions that it encodes non-US-ASCII characters but not with the URI(String str) constructor. Again, this class seems to assume that you are making this URL yourself and can enter the protocol, port, hostname, etc each in its own constructor argument.

Well it was hard for me to believe but the answer was to separate out JUST the http portion of the URL string I collected from the web page and pass those into the URI(String scheme, String ssp, String fragment) constructor and then call URI’s toURL() method.  Some Groovy array manipulation convienences made it a little easier:

def downloadFiles = { sourceUrls->
 def stagingDir = "/tmp/stagingdir"
 new File(stagingDir).mkdirs()
 sourceUrls.each { sourceUrl ->
   def filename = sourceUrl.tokenize('/')[-1]
   def file = new FileOutputStream("$stagingDir/$filename")
   def protocolUrlTokens = sourceUrl.tokenize(':')
   def sourceUrlAsURI = new URI(protocolUrlTokens[0],
       protocolUrlTokens[1..(protocolUrlTokens.size-1)].join(":"), "")
   def out = new BufferedOutputStream(file)
   out << sourceUrlAsURI.toURL().openStream()
   out.close()
 }
}

downloadFiles(
 ["http://lavezzo.com/saic/mvnBuildLifecycle.png",
 "http://lavezzo.com/saic/I have a space.png"
 ])

It looks silly to be splitting out the http just to put it back together in the constructor.  Seems like a simple point of improvement in the one argument constructor to URI to parse the String for protocol and then use the three argument constructor internally.

In Charlottesville, Virginia
Jeff

[Ed: Now with SyntaxHighlighter goodness]