AlexUndercover.com

…from my geeky side.

And All of a Sudden I’m an (Amateur) Photographer

I’ve always loved photography. I got some of that love from my father and sister who are both incredible photographers. Until just recently however 100% of what I’ve done has been simple point and shoot. I’ve been able to get some great quality pictures but really wanted to take it to the next level.

A couple of months ago Chase Jarvis, a professional photographer, came to Amazon to promote his latest book “The Best Camera is the One You Have With You”. He was clearly very passionate about his work and wanted to get everybody else in the room fired up about photography too. That’s really when I started to  give photography a bit more consideration.

I hatched a plan to save up for a new DSLR (a Nikon D90), signed up for a beginning photography class at the nearby community college (which I start Tuesday) and have started to make photography part of my everyday life.

More recently I started reading Digital Photography School and came across an article about the concept of Project 365. The idea is that you commit to taking and sharing one photograph a day for a year so you can see how you progress with your skill and also to integrate photography into your every day life. Since I’m starting to take the art more seriously I thought I’d give it a try and joined the Project 365! group on Flickr and took my first photo this morning:

Full moon at 5am

Since I’m only just getting into the details of photography I’m excited to see how quickly my skill and technique improve.

Leave a Comment

Rejoining The World Of Warcraft

I’ve been playing World of Warcraft off and on since before it’s initial release in 2004. I’ve never been a huge fan of MMORPG’s in the past either because they require far too much grinding or they place too much of a focus on the multiplayer aspect and essentially ignoring the solo player (because I have such a busy schedule I tend to be more of a solo player in general). When WoW came along I was intrigued by the small barrier to entry, it’s simple and effective questing system and it of course had the advantage of the Warcraft history built in.

Because of my lack of focus when it comes to games (I’m far too easily distracted by other things) I would generally play for a few months and then take several months off from WoW. My latest hiatus lasted about a year. It took a new expansion to get me back into the game.

I’ve been playing again now for about 4 months or so and am delighted to say that Im having a great time and not getting bored nearly as easily as I have in the past. Previously the highest level that I achieved for a character was 44. At that point I would either start a new character of a different class or just quit altogether. My current main character is a level 58 rogue. I’m glad I’ve really stuck with the game this time as I’m only now starting to discover the higher level content; content which I haven’t seen before.

Here’s why I think WoW is such a great game and why it always keeps me compng back for more….
• As mentioned before the barrier to entry is minimal. You can easily jump into a new character and figure out how to play it pretty quickly.
• The interface is customizable. There are some fantastic addons out there that make the game more fun and efficient to play all because Blizzard decided to make the interface scriptable.
• It’s feasible to solo. Although some classes are better than others for this purpose WoW is accessable for the solo player.
• The stories and history of Azeroth that ate presented to you throughout the game is nothing short of astounding. There are definitely some truly creative minds at Blizzard.
• There is a ton of content. The world is just huge. If you get bored questing in one area there are likely several others that will be suited for your character’s level.
• Multiplayer specific content is reasonably accessable. The UI makes it easy to find other people to group with for the games instances and the rewards are worth it. Also the 5 man instances can be run through in a few hours so it’s not abhoge time commitment.
• The new achievements system adds an interesting twist. If after all the main content you start to get bored they have some very interesting and sometimes strange things to do for accomplishment points ( and bragging rights of course).
• Leveling isn’t quite as difficult as it used to be. This is another aspect that makes soloing possible.
• Youre not pinosjed for not playing for a while. When logged out you actually become rested. When your character is rested you gain twice the experience when killing creatures for a while which can make up for some lost time.

Though I mainly solo I’ve started a small guild with a few friends and we run instances together occasionally. That only adds to the fun. Since I finally got a character past 55 I’ve been playing the new death knight class from the latest release and have also been able to visit Outland.

I’m still discovering new and cool things about the game. It’s east enough to suck you in and deep enough to keep you playing for a long time.

Geolocate this post.

Posted with LifeCast

Leave a Comment

Interplay relaunches site, rehires original Fallout dev

Say what now?

How cool is this?! I worked for both Babbages and Egghead Software during and after high school and played just about all of the games that Interplay published. It seems to have taken quite an effort on their part but hopefully this is just the beginning of the good news for this company.

The first project to be an MMOG based on the Fallout universe is very exciting. It certainly has a ton of potential. Hiring Chris Taylor was a great move also.

Leave a Comment

Backfilling Flickr Data in Aperture

This is a follow-up post to the Scripting OS X with Ruby post from the other day.

Step 1: Determine Flickr ID mappings

With the knowledge in from that post I started to write some code which would help me get my photos’ Flickr ids from my old data into my new data. I started by writing some Java code to export the photo name to Flickr id mappings using the Photoshop Elements library I wrote about. Because I had very rarely changed the titles of the photos it was easy to make the mapping from the base file name to Aperture version name (base file name: P1000243.JPG, Aperture version name: P1000243). The code I wrote simply output the expected version name and the Flickr id with a colon as the delimiter between them on each line of a file. Because of the work I had done previously it took about 10 minutes to write, debug and get my simple mapping file together.

Step 2: Backfill metadata from hacky app to Aperture

With the mapping file I was then able to write some Ruby code to go through each line of the file, getting the version name and Flickr ID and then applying that flickr id to the corresponding photo in Aperture using the following script:

#!/usr/bin/ruby

begin; require 'rubygems'; rescue LoadError; end

require 'appscript'include Appscriptaperture = app('Aperture')library = aperture.libraries.get[0]

failed_images = Array.new

file = File.new( 'flickr_image.export' )

file.each do |line|  (version_name, flickr_id) = line.split(/:/)  flickr_id.chomp

  begin    image = library.image_versions[version_name]    image.make(    :new => :custom_tag,    :with_properties => {      :name => 'Flickr ID',      :value => flickr_id    }    )    puts( "#{version_name} updated successfully.")  rescue    $stderr.puts( "Version name: #{version_name} doesn't exist." )    failed_images.push( version_name )  endend

images = failed_images.join("\n")$stderr.puts( "The following images failed:\n#{images}")

If the version name I was after didn’t exist in the Aperture library an exception would be thrown. This worked well for about 100 photos or so but I started to get the failed messages for just about every photo after that for some reason. Strangely enough the new meta data was applied successfully to all of the photos in the list regardless.

Step 3: Check my work

With all of the failed messages I saw above it was very important to check my work as the exceptions were unexpected.

In Aperture I did a search by looking for any photos in the library which didn’t contain the “Flickr ID” meta data.

  1. Click on the magnifying glass icon to the right of the top-level Library in the Projects Pain.
  2. On the right side of the HUD that pops up click the “+” drop-down and select “Other Metadata”.
  3. In the entry that appears at the bottom of the HUD select “Flickr ID” from the first drop-down and “is empty” from the second drop-down. If “Flickr ID” isn’t an option then you likely don’t have any photos with that metadata included.

The photos that show up are all of the photos in your library that don’t contain the “Flickr ID” data.

Most of what I found wasn’t surprising. Almost all of the photos that showed up were ones that I expected to not have a Flickr ID yet because I hadn’t uploaded them. There were about 200 or so that I had uploaded, however. All of our wedding photos, which I had uploaded using my hacky app mentioned in the previous post didn’t appear to have saved the Flickr mappings when running. In order to backfill that information I had to go back to some scripting.

Step 4: Backfill from Flickr to Aperture

Because all of the data I needed (again, version name and flickr id) were already contained in Flickr and the number of photos in the Flickr Set and the Album in Aperture were the same I decided to use Ruby to get the data and again add the metadata to the photos in Aperture.

By browsing to the set that contained all of our wedding photos and viewing the source I was able to get all the photos’ Flickr IDs involved. Just look for a section near the top of the page that looks like this:

global_sets['72157600654403170'] = new Object();global_sets['72157600654403170'].id = '72157600654403170';global_sets['72157600654403170'].title = 'Alex and Sari\'s Wedding';global_sets['72157600654403170'].description = '';global_sets['72157600654403170'].photo_idsA = [721448862,720575657,720577847,721459142,720587057,720592155,720596975,721480694,721487494,721494014,721499708,720626861,721510464,721516590,721522196,721528146,720654335,721537536,721543722,721549982,721555546,721561178,721568258,721574902,721581254,721588748,721593932,721598804,720726129,721609556,721614806,720742101,721625256,721630088,720760553,720768581,720776539,720784397,720791491,720798499,720806419,720813539,720822055,721707338,721715668,721726106,721734054,721743012,720874147,721758916,721771556,720907749,721792566,721801074,721809846,720944203,720956835,720966039,720974725,720984393,721871314,721881724,721018051,721907252,721043721,721928502,721938482,721071093,721079767,721095737,721116003,721125853,721139461,721164689,721175687,721186835,721196177,721203885,721214963,722097094,722112912,721250149,721261431,721282895,721298017,722188682,722208672,722218464,721352681,721360691,721375777,721406079,721419239,721429501,722315832,722322280,722332468,722343288,721477201,721484673,721493495,721503539,721516023,721524567,721533793,721982440,722274228,722263084,721322485,721271943,722106812,721150679,722421670,721556795,721568375,722454366,721590801,722479054,722490540,721624955,722512596,722525534,721662789,722549680,721685979,721697239,722585528,722597692,722611152,722625450,721760949,721771897,721781583,721791799,722675164,721809325,721818701,721828109,722712190,721847011,722729474,721865557,722748932,722756934,721893779,722776730,722784676,721919737,722800982,721935947,722815314,722820704,722827274,721960155,721968481,721977651,722861182,721998131,722880560,722019003,722027929,722036629,722045461,722926052,722935076,722070033,722082061,722088651,722973198,722981234,722115859,722998550,723011414,722144937,722156955,722166669,723051996,723063288,723073570,723086058,722221335,723103304,723110852,722247905,723130588,722267787,722277497,723158408,723172320,722307709,722317911,723201084,723213076,723222192,722359813,723242728,723252446,722394491,722409131,723294758,722443199,723323630,723332270,723343304,723353992,723364948,722503253,723384774,722522125,723403358,723412368,722548327,722556293,722434609];global_sets['72157600654403170'].primary_photo_id = [722434609];

var page_set = global_sets['72157600654403170'];

The line you want is the global_sets['????'].photo_idsA = line. The comma-delimited list on that line is all of the Flickr IDs involved.

By writing a Ruby script that would get the name of each of the photos corresponding to the Flickr ID I could then add the meta data to Aperture. I copied the list of IDs from above, replaced all of the commas with newline characters (one ID per line) and wrote the IDs to a file called flickr_ids.

I then wrote a script to read in each line of the file, get data on the Flickr photo and write the photo’s name along with the Flickr ID to a file to be read by the first script:

#!/usr/bin/ruby

begin; require 'rubygems'; rescue LoadError; endrequire 'flickr'

KEY = 'YOUR KEY HERE'

flickr = Flickr.new( KEY )

flickr_ids = File.new( 'flickr_ids' )flickr_ids_export = File.new( 'flickr_ids.export', 'w' )flickr_ids.each do |flickr_id|  flickr_id.chomp!  begin    photo = Flickr::Photo.new( flickr_id, KEY )    parts = photo.title.split(/\./)    version_name = parts[0]    flickr_ids_export.puts( "#{version_name}:#{flickr_id}" )  rescue    $stderr.puts( "Photo with id #{flickr_id} not found.")  endend

flickr_ids_export.close

After changing the name of the file imported I used the existing script to set the Flickr IDs and I was done. This assumes that the photos in question are public on Flickr.

I realize this is a problem very specific to my custom code and this specific problem but hopefully my experience will show how easy it is to do some pretty great things with Ruby.

Leave a Comment

Blogging On The Go

I’ve been wanting an app for my iPhone that will allow me to post to my Blogger blogs for some time. I tried Lifecast but it didn’t appear to actually send the posts to Blogger. It turns out it was something that I had setup incorrectly. Once that was fixed all the test Lifecast posts magically appeared.

I’m now a firm believer in the app. It’s simple, can post pictures and gets the job done.

Geolocate this post

Posted with LifeCast

Comments (1)

Scripting OS X Software with Ruby

Ever since I discovered Flickr a few years ago I've wanted to
developm an application to synchronize the data between it and
whatever desktop application I was using. At the time I was using
Photoshop Elements on Windows and was able to "decode" the data model
used in the Access database that stores all of it's data. Using that
knowledge I created a library in Java to read the data into Java
objects. On top of that I was able to throw together some simple code
to upload images and add metadata in Flickr using the Flickrj library.
It was inefficient but got the job done… eventually. Since it worked
well enough I pretty much abandoned further development in favor of
other projects.

Fast forward a year or two and I started to desire moving to the Mac
platform and iPhoto or Aperture. I wanted to be able to adapt my
existing code to export to one of the new apps and then export from
there to Flickr. Unfortunately the Java support on OS X does not
necessarily intend interaction with native applications which makes
this kind of process difficult. After asking how this process might be
accomplished on some Apple development forums I eventually gave up.
For the time being I settled for exporting meta data to the images,
adding them to Aperture, and painstakingly reorganizing them into
sets. Not a fun process. I then added the popular Flickr Export plugin
to send my photos to Flickr. Unfortunately Flickr Export is only
intended to export (no syncing) and if I update meta data in Aperture
it won't be updated in Flickr which is a bug as far as I'm concerned.
Because I am the way I am I've always felt uncomfortable with this
process. To top it all off the images that I've already stored don't
have the Flickr IDs stored in the images so all that information was
lost in Aperture (though I still had the mappings stores on my Windows
box).

It seems I've found a way to kill two birds with one stone. The first
issue I wanted to solve was to get Flickr information into Aperture so
Flickr Export wouldn't upload photos that were already there. I knew I
could do this pretty easily with AppleScript but as I don't know
AppleScript and the syntax, while intended to be more readable is
incredibly cryptic, I wanted to avoid it at all costs. Plus I didn't
feel like learning a whole new language to write what would
essentially be a use-once, throw away script. Ruby to the rescue!
There are two Ruby libraries which can interact with OS X applications
that I evaluated: Ruby OSA and appscript.

While Ruby OSA has a much nicer Ruby-like syntax and is able to
generate API documentation for OS X applications you're unable (as far
as I can tell) to access objects in collections by name. More
specifically I wanted to be able to get an image from my Aperture
library by name. I could write a quick method which would iterate the
whole set of images but with about 5000 images in my library it would
be terribly inefficient. I eventually settled on the appscript library
which can do this and do it efficiently. Armed with this knowledge I'm
now able to write code which will take the Flickr IDs associated with
my old photo library and add them to the images in Aperture.
Additionally using the code for these libraries as an example (or the
Objective C version of appscript) I should be able to do similar
operations using a combination of native code and JNI calls.

I'm really excited about these prospects and hope to apply them to
future development to make my Aperture to Flickr workflow more
efficient and reliable. I'll post more about this effort as I make
progress.

Comments (1)

iPhone Madness

Crazy, crazy, crazy!

I’ve been waiting to buy an iPhone for ages. The day finally arrived so I went down to U. Village around 7:30am, only 30 minutes before they opened, to stand in line with the other crazed Apple fans. It turns out that people started to wait in line the night before and had wrapped through U. Village all the way back to Office Depot. The Apple employees estimated that they would be able to get through 100 customers an hour. At that rate I would be out of the store by 11ish. Come 9:45a the line had hardly moved so I gave up for the time being.

After working from home for a while, stewing about the fact that I hadn’t gotten my hands on one of the shiny new phones I started forming a plan. Head down to the Apple store after work and dinner. Nothing too shocking but I was hoping that the lines would’ve died down a bit by then. Luckily Sari was very supportive of my adventure, especially since I was getting her one too (a belated birthday present), so she suggested that I head down as soon as she got home at 5pm. It’s a good thing she did too because the line was still long and the store was slowly running out of stock. Luckily the line only went through the undercover area in front of the store so it was about half the length but it still took a long time.

The fact that it wasn’t raining was a plus. Not to mention that the Apple employees were constantly passing out water, snacks and sunscreen to protect their customers the 5 hour (yes 5 hour) wait in line wasn’t too bad. The other “waiters” were also very friendly. There was sort of a passive aggressive, underlying bitchiness due to the long wait but we also shared a common hope in getting the iPhones we were after.

Near the front of the line the Apple employees would start coming out every so often and warn us that we might not be able to get a 16GB iPhone in black as they were going fast which added strain to the line. Luckily when I got to the front I got two of the last black 16GB iPhones available in the store. When I got back home with the new phones both Rob and Sari sat on the couch for a good half an hour just playing with them, googly eyed.

All in all the experience was very positive and despite standing in the same place for long periods of time wasn’t too exhausting. I certainly wouldn’t do it again any time soon. At least not until the next iPhone release. :)

Leave a Comment

Trouble with Maven

I’ve tried to use Maven during my Java development but have found it rather frustrating for a few reasons.

  • The documentation is a bit sparse – Most of what you need is represented but setting up your own settings, deploying artifacts a repository and other more advanced subjects are under represented.
  • Deploying artifacts is painful – This mostly goes along with the first point. The syntax, once figured out is far from obvious and much to verbose for my taste. That’s one of the drawbacks of extreme flexibility… extreme complexity.

Because I tend to be a perfectionist when it comes to code I write at home I had taken a break from coding Java for a while (except at work of course).

Recently I’ve had some really good ideas pop into my head as well as how to implement those ideas so I wanted to get started again with Maven. I was able to utilize the the Q4E project which is a Maven plugin for Eclipse which I’ve found more stable and consistent than the original M2Eclipse plugin (though I haven’t tried it in a while so it may have improved). This combined with my already POM-enabled projects in source control made for a pretty easy return to Java development. Unfortunately there was some frustration just around the corner.

When my new application was getting bulky enough to start needing some logging I decided to start using log4j which is commonly used in Java development. All I needed to do was add it to my project’s POM as a dependency and Maven should have taken care of downloading it and adding it to my CLASSPATH but unfortunately that wasn’t the case. Maven wasn’t able to figure out how to get 3 of log4j’s dependencies. Usually in a case like this it gives good suggestions on where to download them. Unfortunately the links that were given kept redirecting me somewhere on the Java site that wasn’t what I was after. After struggling with the issue for a few hours I gave up and started using the Java SDK’s (inferior, IMHO) logging mechanism but not being able to use log4j continued to nag at me.

This morning I decided to give it another try and this time the first thing I did was a google search which brought me to this blog entry. While installing a separate piece of software, Artifactory for a Maven Repository Proxy, this was something I had done using Proximity in the past so I was pretty familiar with what to expect. As I already had a server machine setup and ready to run Tomcat I was able to install Artifactory pretty quickly. Once installed I followed the instructions in the blog post and in the Artifactory documentation for setting up Maven to look at the repository proxy first and 2 of the 3 missing dependencies were downloaded no problem. I had to do an explicit search for jms-1.1.jar to get the last dependency but I followed similar instructions for installing it into my new repository.

Long story short I’m now able to use log4j in my Java coding. I can also easily deploy the artifacts I create to my own repository with ease.

Now I need to stop messing around with all this stuff and continue my coding.

Comments (1)

Google Reader for Your Wii

Now Wii users not only have the ability to browse the web but Google has released a Wii-specific version of Google-Reader (for RSS Aggregation) which takes advantage of the buttons on the Wii-Remote. I can’t wait to give this a try!



Google Reader for Your Wii



Powered by ScribeFire.

Leave a Comment

Better Builds with Maven

As a software developer I’m constantly looking for tools and techniques to make the development process easier. I used to use a strict command-line environment and XEmacs for my Java Development until I was introduced to Eclipse which is a very nice, extensible IDE for Java and other languages (though it does Java best). The fact that I can refactor code (rename a class for example), constantly build in the background to check for errors, handle version control and project dependencies all in one place was a God-send. There was still one glaring flaw, however. Ant builds, while flexible, can be a pain to setup, even with an IDE, and because there’s no standard for how to setup builds (because it’s so flexible) the setup process can tend to be a bit frustrating. This is where Maven comes in.

Maven is a Java tool who’s mission is to standardize building a project and managing its dependencies. When creating a new project you create a simple XML document called a POM (Project Object Model) which describes the project as well as what its dependencies are.

Maven defines a standard directory structure for creating projects. Because a standard is defined (though it can be overridden) there’s no reading through complicated build.xml files to figure out what’s going on or what targets you need to run in order to get the desired effect. This means that new developers to a project can get up to speed much faster. This also greatly simplifies the maintenance that needs to be done on the build setup of a project.

With Maven the days of storing a project’s dependencies in a child lib/ directory are over. When you build a project Maven will automatically download all the necessary dependencies and install them in your local repository. The local repository is for all Maven projects to use so, for example, if you use JUnit for testing purposes Maven would download the appropriate version (whichever you define), store it and make it available for use with all projects. This means you don’t have to store your binary dependencies in version control. Maven handles it all for you.

Maven doesn’t stop there though. It can also handle generating documentation, building a website for your project and deploying your project to a shared repository for others to use and more. If that’s not enough you can also integrate specialized Ant tasks into your Maven builds which will make the transition from Ant to Maven much more simple.

Having said all this wonderful stuff about Maven there is a reasonable learning curve, though it’s not nearly as bad as Ant’s. For assistance here are some helpful links to get started with:

Happy coding!

Leave a Comment