New WordPress Sociable Plugin Has Unintuitive Setup

I got a notification this morning that the Sociable plugin for WordPress had a new version available, and did I want to install it. I try to keep my plugins updated, so I upgraded. Sociable now has two modes: Skyscraper and Classic. Classic is what you’re used to, with a row of icons under a post. Skyscraper is a tall and thin tower that lives in the left-hand margin of your site, scrolling along with the page. Skyscraper is the new default, but going back to Classic is what is unintuitive.

In your admin page, if you hover over the new menu “Select Sociable Plugin” you will see three options: Select Sociable Plugin, Sociable Options, and Skyscraper Options. Selecting the first one brings you to a page explaining the difference between the two modes, with ginormous buttons at the bottom to choose which version you want. Clicking the button for either mode takes you to the options for that mode, but doesn’t actually change which mode is selected.

At the bottom of each mode’s options page is a checkbox labeled, “Activate…” and the mode name. I assumed that checking the one for Classic mode was all I needed to do, but clearing my cache and viewing the page showed that not to be the case. You must also uncheck the “Activate…” checkbox on the Skyscraper options page to enable Classic mode. If you don’t uncheck it, then you will still get the Skyscraper showing up on your posts. If you decide to switch back from Classic to Skyscraper, you have to uncheck Classic, then go to the Skyscraper options page and check that one.

Since this is a binary choice, they need to have ONE place to enable one and disable the other, or at least explain to you that you have to take the extra step.

Once More, This Time With Clojure

If you happened to read my post from the other day entitled My New “Top Artists Last 7 Days” Widget, you know that I went through three iterations of getting it going. The final solution, written in Ruby worked well. Until bands like Motörhead, Mötley Crüe and Einstürzende Neubauten showed up in the list. At that point, the HTML parsing library I was using would barf, and processing would stop, leaving the list showing on the blog in an incomplete state. It wasn’t the library’s fault; apparently Ruby still has problems dealing with non-ASCII characters. I did everything I thought I needed to do to tell Ruby that it would be dealing with UTF-8 encoding, but it just kept right on barfing.

I was left with only two choices: stop listening to any band with an umlaut in the name (and God help me if any of my Scandinavian bands popped up, with the Ø or å characters), or rewrite the stupid program, again, in a language that I knew could easily deal with UTF-8.

Since I’ve been working in Clojure a lot lately, it seemed lika the logical choice. I spent about an hour working on it last night, and I ended up with a working program and a bit more Clojure experience. Here’s the program for your edification, with a description to follow:

(ns lastfmfetch.core
(:gen-class))

(require '[clj-http.client :as client])
(import '(java.io PrintStream)
'(org.htmlcleaner HtmlCleaner))

(defn get-artist-and-playcount [cell]
(let [title (.getAttributeByName cell "title")
[match artist playcount] (re-matches #"^(.+), played ([wd]+)s*S*$" title)
playcountStr (if (= playcount "once") "1" playcount)]
[artist playcountStr]))

(defn get-url [cell]
(let [links (.getElementsByName cell "a" true)
a (first links)
href (.getAttributeByName a "href")]
(str "http://last.fm" href)))

(defn fetch-data [filename]
(let [response (client/get "http://www.last.fm/user/joeyGibson/charts?rangetype=week&subtype=artists")
cleaner (HtmlCleaner.)]
(if (= (:status response) 200)
(with-open [out (PrintStream. filename "UTF-8")]
(.println out "<html><head><meta charset="UTF-8"/></head><body><ol>")
(doto (.getProperties cleaner)
(.setOmitComments true)
(.setPruneTags "script,style"))
(when-let [node (.clean cleaner (:body response))]
(let [subjectCells (take 5 (.getElementsByAttValue node "class" "subjectCell" true true))]
(doseq [cell subjectCells]
(let [[artist playcount] (get-artist-and-playcount cell)
url (get-url cell)]
(.println out (str "<li><a href='" url "'>" artist "</a>, Plays: " playcount "</li>"))))))
(.println out "</ol></body></html>")))))

;; Main
(defn -main [& args]
(if (< (count args) 1)
(println "Usage: lastfmfetch <output_file>")
(fetch-data (first args))))

I ended up using a library called clj-http to handle the fetching of the URL. It’s a Clojure wrapper for the Apache HTTP Commons library, and was really easy to use. I’m using Leningen, by the way, so including clj-http was just a matter of including a line in the project.clj file. I also used a Java library called HTMLCleaner, that fixes broken HTML and makes it available as a DOM. Since it is also in Maven Central, it was easy to include by adding another line to the project file.

(defproject lastfmfetch "1.0.0-SNAPSHOT"
:description "Fetch chart data from Last.fm"
:dependencies [[org.clojure/clojure "1.3.0"]
[net.sourceforge.htmlcleaner/htmlcleaner "2.2"]
[ clj-http "0.2.6"]]
:main lastfmfetch.core)

The -main function begins on line 38, but all it really does is check that there is a single command-line argument, and exits with a usage message if there is not. It then calls the fetch-data function, which begins on line 20.

On line 21, we declare two locals; one that will contain the results of fetching the web page, and one that is the HTML cleaner. If the fetch of the URL was successful, the status code will be the standard HTTP 200. If we got that, we then open a PrintStream on the filename given, specifying that it should be encoded with UTF-8. (I’ve been working with Java for a very long time, and I always assumed that since Java strings are Unicode, files created with Java would default to UTF-8. That is not the case. That’s why there’s a second argument when creating the PrintStream, and why I’m not using a PrintWriter.) We then print the first part of the output HTML file, set a couple of options to HTML Cleaner that cause it to strip comments, style and script sections from the HTML, and then start doing the real work.

On line 29, we declare a local called node that will contain the output of HTML Cleaner if it successfully parsed and cleaned the HTML. That’s what when-let does; it assigns the local as long as the function returns something truthy and then executes its body. If that function doesn’t return something truthy, the rest of the code is skipped. We then take the first five elements from the HTML that have an attribute called “class” with a value of “subjectCell”. These are table cells. We then loop over them, extracting the artist and playcount value, and the URL. We do these things in two separate functions.

The function called get-artist-and-playcount, starting on line 8, takes the table cell as input. It then gets the attribute called “title” and uses a regular expression to pull out the artist and playcount values. If the playcount is the word “once,” it converts it to a 1, so all the values are numeric. It then returns the two values as a vector.

The function called get-url, starting on line 14, also takes the table cell as input. It then gets all the “a” elements from the cell (there’s only one), and then gets the “href” attribute’s value, which is the URL.

Back at line 34, we take the three values we extracted with the two support functions and concatenates them together into HTML that will be a single line in an ordered list. We then output all the necessary closing tags to make the HTML well-formed, and we’re done.

While the Clojure code is a bit more dense than the Ruby code, it’s actually four lines shorter. And it handles Unicode characters, which makes me happy.

Fizzing and Buzzing With Clojure

I’ve known about the FizzBuzz problem for a few years. I’ve written solutions for it in a few languages, but never posted them. I’ve been working with Clojure lately, and after reading articles about how many job applicants can’t solve a simple problem like this here, here and here, I decided to do a Clojure version. (It baffles me that someone who claims to be a developer can’t come up with a solution for this, no matter how good or bad it might be.)

I ended up doing it three different ways. The first is a simple first-cut solution. The second is somewhat better, I think, and the third is a refinement of the second. In all three cases, they use a nested function to do the evaluation, and return a lazy, infinite sequence. Here’s the first

[clojure]
(defn fizzbuzz []
(map (fn [i] (cond
(and (= (rem i 3) 0)
(= (rem i 5) 0)) "FizzBuzz!"
(= (rem i 3) 0) "Fizz!"
(= (rem i 5) 0) "Buzz!"
:else i))
(iterate inc 1)))

(doseq [i (take 100 (fizzbuzz))]
(println i))
[/clojure]

This solution does work, but I have a problem with the fact that the division tests are done twice. I think doing those tests twice increases the chances of making a mistake. The second version does the tests one time, assigning the results to locals. It then checks them for nil, and concatenates them together, relying on the fact that a nil will not print.

[clojure]
(defn fb []
(let [fb1 (fn [n]
(let [fizz (if (= (rem n 3) 0) "Fizz")
buzz (if (= (rem n 5) 0) "Buzz")]
(if (or fizz buzz)
(str fizz buzz "!")
n)))]
(map fb1 (iterate inc 1))))

(doseq [i (take 100 (fb))]
(println i))
[/clojure]

In this version, instead of passing an anonymous function to map, I assigned it to a local in a let expression. You can see that I only do the math once, assigning locals with either the appropriate word, or nil. I then check that one or the other of the locals are non-nil, cat them together and return it. If both are nil, the number itself is returned.

The third version is almost identical to the second. The only difference is that the second one used a let expression, and the third one uses a letfn expression. It’s effectively the same thing, but the third one is ever-so-slightly shorter, and I think every-so-slightly easier to read.

[clojure]
(defn fb2 []
(letfn [(fb3 [n]
(let [fizz (if (= (rem n 3) 0) "Fizz")
buzz (if (= (rem n 5) 0) "Buzz")]
(if (or fizz buzz)
(str fizz buzz "!")
n)))]
(map fb3 (iterate inc 1))))

(doseq [i (take 100 (fb2))]
(println i))
[/clojure]

I don’t claim that these are particularly good solutions, though I do claim they work correctly. Any Clojure experts care to point out problems and/or offer suggestions?

JUnitLaunchFixer 1.0.4 Released

I’ve just released a new version of my Eclipse plugin called JUnitLaunchFixer. If you’ve never heard of it, it lets you set the default heap size for new debug launchers in Eclipse. You can read more about it in the original announcement. This new version fixes a bug that caused it not to accept new parameters in one case, and it also adds the ability to set a default for the maximum permgen size, which is something I’d been wanting to add for a while.

If you already have it installed, go to Help>Check for Updates in Eclipse, and you’ll see it. If you don’t have it installed, the update site is here:

http://junitlaunchfixer.googlecode.com/svn/trunk/JUnitLaunchFixer-update-site/

 

Two Features To Make Lion’s Launchpad Perfect

One of the features in Lion that I didn’t think I would like has become one of my favorites: Launchpad. This is essentially Springboard from iOS, but for the Mac. It’s a nice iOS-like view of your /Applications folder, that you can get to by pinching on your trackpad using your thumb and three fingers. Once it opens, you see all your installed applications, with multiple pages, just like in iOS. Swiping left and right with two fingers switches between pages. Single-clicking an app runs it. Holding down Option makes the icons “go wiggly,” so you can move them around, just like in iOS.

The main problem is that you have to move apps around just like on iOS: one at a time. It makes sense on a touchscreen to only let you move one thing at a time, but on a traditional computer, it’s a limitation. My first suggested feature, then, is Apple should add the ability to select groups of icons and move them between pages as a group. It might also be nice to have a “consolidate” option that would just squeeze the apps onto as few pages as possible.

Which brings me to the second feature I’d like to see: pre-defined sort options. I like to have icons show up in alphabetical order, so having a menu option to “Sort Ascending” or something like that would be nice. I can also see something like sorting by most-recently used, so the apps you have recently used show up first. Or maybe a most-used sort, so those apps you use the most are at the top of the first page. Of course, they need an “as arranged” option so they show up how you arrange them.

These should be easy additions, and Apple should have already thought of them. I hope they will be in an update soon.

My Lion “Clean Install” Saga

Updated! Scroll down for the latest.

I upgraded my 2011 Macbook Pro and my 2006 Mac Pro to Lion on Day 1. The MBP has had no problems at all. The Mac Pro, on the other hand, was acting a little squirrelly. For example, after installing Xcode 4.1, iTunes could no longer see my iPhone or iPad when I attached them. Looking in Console, I saw errors about trying to start usbmuxd, but not being able to find it. This is because /System/Library/PrivateFrameworks/MobileDevice.framework had been gutted. Only a few files were left, none of which were the files in question. I could tell when they went missing from looking at the Time Machine backups, and it was the Xcode 4.1 installer’s fault. Xcode 4.1 also crashed on startup, every time. I had also been having some strange goings-on between my AppleTV and iTunes. All in all, I figured maybe a clean install was warranted. After all, I have never done one. I bought this machine new in 2006, and it came with Tiger. I then upgraded to Leopard, Snow Leopard and now Lion.

So I made a bootable Lion disc this morning, booted from it, repartitioned my hard drive and then started the install. It took a while. Finally, it asked me if I wanted to transfer data from another machine or from a Time Machine backup. I selected Time Machine, picked the backup to restore from, and then unselected the stuff I didn’t want to come over. I noticed that ~/Library was not shown, so I assumed that meant it would not be restored. I was wrong. Once I got into the system, I could tell that ~/Library had been restored. That meant that a good deal of the cruft I was hoping to cleanse was now back. So I started the whole process over again.

This time, when it asked if I wanted to transfer/migrate/restore, I said “no.” I ended up at a clean desktop, with no customizations, just like you would expect. I started restoring things from Time Machine, starting with my iTunes library. I have over 230GB of stuff in iTunes, so when it was finished, and I tried to open iTunes, I was a bit shocked when it said it couldn’t open the iTunes folder because it was on a locked volume. Clearly it wasn’t, but something was up. I ended up finding a command that seemed to fix this, but I also noticed that the gid on some of the files was wrong. So I typed

sudo chown -R jgibson:staff .

and shortly thereafter, iTunes was happy. But then I tried to restore my Documents folder. It got through a few of them, and then died with a similar message. Upon closer inspection, I could see part of the problem: the group id (gid) of all of my files in the backup was 501, but my current gid was staff (20). The group 501 doesn’t exist on this system (that’s a relic of a previous OSX version), so I figured I could just chgrp the files and all would be fine.

Except it wasn’t. As root, I was able to change most of the files and directories to have the proper gid, but some just responded with “operation not permitted.” That’s it. No further explanation about why or what to do about it. This was probably the crux of my problem, but I couldn’t fix it, even as root. I scoured the web, looking for answers, and found several, like ensuring the uchg flag is not set. I did so, but the problem persisted.

Next I decided to create a group that had 501 as its gid and add myself to it. Once I did this, the files in the backup volume now showed the new group’s name instead of 501. I thought I was home free. I was wrong.

I tried to change the gid of the files, but couldn’t. I figured I would need to logout and back in, since group changes usually require that on a Unix-y system. I did so. And then I noticed something else. None of the changes I had made to preferences or the dock had persisted. I use a Microsoft keyboard, so I had swapped the values of the Command and Option keys; they had reverted. I had removed Photo Booth from the Dock; it was back. I had changed the settings for Terminal and chosen “use settings as defaults;” the defaults had defaulted to their defaults.  Something else was definitely going on. After spending a few hours trying to find anything that looked possible, I gave up. I decided to start yet another install, and pay close attention to see if there’s something I missed. Perhaps when I first tried to restore from Time Machine, I ended up bringing across some bizarro setting that caused the whole thing. I don’t know. I’m frustrated and concerned and really tired of messing with this stupid thing today. This is not how I planned to spend my Saturday.

Dear Steve, this is not cool. I have no idea what’s going on here. Why the f@*k should I not be able to restore from Time Machine and have it set permissions properly? Why the f@*k should I see messages telling me what happened, but not why or what I might do about it? Why the f@*k should iTunes think it was on a locked disk when it wasn’t?

I will keep updating this post as my latest install progresses…

23:45 Update: I did a third clean install and everything seems to be OK. At first my preferences were not being saved, just like before, but after a couple of logouts/reboots, it occurred to me that the installation DVD was still in the drive. I took it out and rebooted, and now things were working as expected. I can’t prove it, but it seems to me that the system was booting from the DVD, even though it didn’t appear to be. Or just the presence of the install DVD caused the OS to mount the main drive “differently.” I can’t say, but removing the DVD seems to have fixed the problem.

Once I realized that preferences and settings were getting saved and survived logouts/reboots, I started restoring from Time Machine. Rather than trying to do several directories at a time (Documents, Pictures, Music, Movies, etc.) I did them one at a time, verifying things once each restore was complete. I got none of the “operation not permitted” or “can’t copy because you can’t read the files” errors, which was a nice change.

After restoring my Music folder, I updated iTunes to the latest version and ran it. It came up fine, found my library and everything was fine.

Since I’m running up against my draconian Comcast bandwidth cap, I tried to copy things from my MBP where possible, rather than download them. I was able to copy several gigabytes of stuff over, which was nice. I was a bit worried that I wasn’t going to be able to copy the “Install Xcode” package, because when I tried, I did get the “you can’t read this” error. I had set everything to what I thought was proper, but still no go. So I tarred the whole package up and copied that. I untarred it on the Mac Pro, then from Terminal, I went into the package to inspect. Instead of a gid of “staff” it was “admin.” I did a chgrp on all the files in the package, and then ran it. It installed without a hitch and at the end, Xcode fired up just like it should.

The real test was did it destroy the MobileDevice.framework directory like it had before. Covering my eyes, I navigated to the directory and took a peek: everything was there! So then I plugged in my iPad and Xcode saw it, iPhoto saw it and iTunes saw it. The trifecta, w00t w00t!

I did end up having to reinstall iWork ’09 from DVD, and I had to reinstall iPhoto from the app store, which meant a 700MB download, but that was the only one.

So, if you decide to do a clean install for Lion, make certain your backups are good and once it seems to have finished installing, and dumps you to the Finder, don’t believe it! Eject the DVD and reboot.

OSX Lion To Lion File Sharing Not Working – How To Fix It

After upgrading both my Macs to Lion on Wednesday, I discovered this morning that I can no longer mount shared folders between them. I tried going in both directions, and both failed with a very non-intuitive “Connection failed” message. I went to Preferences, Sharing, File Sharing and tried turning it off and on again, but to no avail. I then tried googling for the problem and saw lots of people with the same situation, but this one guy hit upon the “solution” to get it going. You have to turn off AFP sharing, and just leave Windows sharing on. Here’s the original answer. To summarize:

  1. Go to Preferences
  2. Click on Sharing
  3. Click on File Sharing on the left-hand side
  4. Click the Options button
  5. Uncheck “Share files and folders using AFP”
  6. Check “Share files and folders using SMB (Windows)”
  7. Click the Done button.

At this point, you should be able to connect from the other machine. If you need to go in the other direction, perform these same steps on the other machine.

Steve, please get this fixed ASAP, OK?

Xcode 4.1 Not Installing? Try This.

Apple released OSX Lion earlier today, but Xcode 4.0.2 is not compatible with it. Later in the day, they released Xcode 4.1 for Lion through the Mac App Store. I saw some comments from people saying that at about 80% of the way through the installation, they got a popup telling them they needed to quit iTunes in order to continue, but iTunes wasn’t running. They were unable to continue.

Here’s what they missed: iTunesHelper. This is an additional iTunes process that is running, even when iTunes proper is not. It’s there so that when you attach an iOS device, it can fire up iTunes for you.

Go into Activity Monitor and find iTunesHelper. Select it, and then kill it. After a second or two, the “you need to quit iTunes” dialog will go away, and the installation will complete.

Make a Copy of the OSX Lion Installer BEFORE You Run It!

If you’re planning on downloading OSX Lion from the Mac App Store and installing it on multiple Macs, heed my warning to make a copy of the .dmg file before you actually install it. I learned the hard way this morning that once the install is complete, it deletes the installer. That’s a 4GB file, by the way. And it’s not in the trash can; it’s completely gone. If you fail to make a copy of it, as I did, your only option, apparently, is to re-download it on your other Macs. Which is fine, unless you are a Comcast customer with a bandwidth cap and a draconian exceed-the-cap-twice-in-six-months-and-we-cut-you-off-completely plan. I accidentally exceeded the cap last month for the first time, so I’m extremely conscious about my usage now. I’m pissed that I need to re-download a 4GB file.

Steve, you have failed me. It is asinine to automatically delete a file so big without asking me. I understand that some people are short on disk space, and may not want that big file hanging around, but for those of us who have lots of space available, let us decide whether to delete it or not.