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.

Posted in tech | Tagged , , , | 4 Comments

Write Your Congressmen: Please Do Not Support SOPA/PIPA

Depending on what sites you visit, you may or may not know that several sites have shutdown today, or have modified their logos, to protest SOPA/PIPA. These are bills before the House of Representatives and Senate, respectively, that would have a crippling effect on web sites that support user-uploaded content. Sites like Reddit, Youtube and Tumblr are just a few.

If you are concerned about Internet freedom, write your Congressmen. I just wrote both my Senators, Saxby Chambliss and Johnny Isakson, and my “representative” in the House, Rob Woodall. Here’s what I said (with SOPA and PIPA exchanged depending on the recipient):

I do not have a form letter or an eloquent defense of why you shouldn’t support PIPA. But from what I have read about PIPA (and SOPA, in the house), it is bad news for web sites that support user-uploaded content. In an effort to stop “piracy” of content, it places an undue burden on site owners that will cripple and/or shut down many sites. I am not saying piracy is not a problem or that it doesn’t exist. It does. But this bill is not the way to solve it.

Please do not support it.

I don’t really think that sites like Reddit, “going dark” for a day or Google slapping a black box over its logo will have much effect. Millions of people writing their Congressmen should have an effect, though without millions of dollars for lobbying, it remains to be seen how much of an effect it will have.

01/18/2012 1:13 PM Update: I just received this response from Senator Isakson’s office.

Dear Mr. Gibson:

Thank you for contacting me regarding intellectual property theft.  I appreciate hearing from you and I appreciate the opportunity to respond.

S.968, the Preventing Real Online Threats to Economic Creativity and Theft of Intellectual Property (PROTECT IP) Act of 2011, was introduced by Senator Leahy (D-VT) on May 12, 2011, and was referred to the Senate Judiciary Committee.  On May 26, 2011, it was reported out of Committee and is currently pending in the Senate.   The bill targets websites, particularly those registered outside of the United States, which are “dedicated to infringing activities.”  These rogue websites typically offer unauthorized downloading or streaming of copyrighted content or the sale of counterfeit goods including music, movies, and pharmaceutical drugs.

Websites targeted by this bill are foreign owned and outside the reach of U.S. laws despite the fact U.S. intellectual property is being infringed upon and U.S. consumers are the targets.  Rogue websites cost American workers jobs and cost businesses millions of dollars in lost revenue.  As online technology and commerce advances, we must see to it that injured parties have the ability to stop infringers from profiting from counterfeit products.  For example, a victim of infringement will have the authority to file a civil action against the owner or registrant of a rogue site.  If an order is granted by the court, third parties will be required to stop processing payments from the infringing sites, therefore, preventing infringers from collecting payments.  I will work to ensure that our laws our modernized to protect intellectual property, and will keep your thoughts on this bill in mind should it come before the Senate for a vote.

Thank you again for contacting me.  Please visit my webpage at http://isakson.senate.gov/for more information on the issues important to you and to sign up for my e-newsletter.

Sincerely,
Johnny Isakson
United States Senator

01/20/2012 4:40 PM Update: Today I received an email from Saxby Chambliss’ office. Here it is. Notice the bold text, which I added for emphasis:

Dear Mr. Gibson:

Thank you for contacting me regarding S. 968, the “Preventing Real Online Threats to Economic Creativity and Theft of Intellectual Property Act of 2011 (PROTECT IP),” and H.R. 3261, the ”Stop Online Piracy Act (SOPA).”  It is good to hear from you.

S. 968 was introduced on May 12, 2011, and referred to the Senate Judiciary Committee.  On May 26, it was reported out of committee and placed on the general legislative calendar.  If enacted, S. 968 would amend federal copyright law to authorize the Attorney General to file civil action against violators of copyright infringement law.

H.R. 3261 was introduced on October 26, 2011, and referred to the House Committee on the Judiciary.  On December 16, it was considered before the full committee; however, the bill was not voted out for consideration by the full House.  If enacted, H.R. 3261 would authorize the Attorney General to seek a court order against a U.S.-directed foreign Internet site committing or facilitating online piracy.

On January 23, 2012, a procedural vote on S. 968 was scheduled in the Senate; however, Majority Leader Reid announced that this vote will be postponed in order to allow for modifications to the bill to be made.  Furthermore, House Judiciary Chairman Lamar Smith announced that further consideration of H.R. 3261 would be postponed indefinitely.

It was always clear that SOPA and PROTECT IP needed to be perfected, and that legitimate concerns needed to be addressed before these bills could move forward.  Given this and my constituents concerns, it was always my intention to oppose moving forward until concerns had been addressed.  With the majority leader’s decision to postpone the cloture vote on the PROTECT IP Act originally scheduled for January 24, I withdrew my co-sponsorship to await the resolution of the outstanding issues.

I believe that online theft is a serious issue, and that Congress needs to make certain that our laws adequately protect the interests of rights holders.  When $58 billion in economic output is lost to the U.S. economy annually due to copyright theft of movies, music, packaged software and video games, and about one-quarter of all internet traffic is copyright infringing, there is a real problem that needs to be addressed.  I have complete faith that we will be able to work out a compromise in the future that addresses this, while still promoting free and open access to the internet. Should a bill addressing this topic come before the full Senate for consideration, I will keep your thoughts in mind.

If you would like to receive timely email alerts regarding the latest congressional actions and my weekly e-newsletter, please sign up via my web site at: www.chambliss.senate.gov .  Please let me know whenever I may be of assistance.

The bold part is interesting because he claims that he knew both bills were flawed and that he “always intended” to oppose “moving forward” until they were fixed. Given that he was a co-sponsor of PIPA, I don’t really think he’s being honest here. It seems a bit odd to be a co-sponsor of something you think is flawed.

Still, he’s withdrawn himself as a co-sponsor now, which is a good thing.

Posted in politics | Tagged , , , , , , , , , | 1 Comment

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 '1)
(import '(java.io PrintStream)
        '(org.htmlcleaner HtmlCleaner))

(defn get-artist-and-playcount [cell]
  (let [title (.getAttributeByName cell "title")
        [match artist playcount] (re-matches #"^(.+), played ([\w\d]+)\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.

Posted in java | Tagged , , , , | Leave a comment

We Have To Get the Money Out of Politics

It costs a lot to get elected to high political office. A lot. So much, in fact, that a candidate has to either be independently wealthy, or they have to sell their souls votes to those who would finance their campaigns. This is one of the many things that is wrong with our political system. There is no possible way that someone like me could run for anything higher than local office; I don’t have the money, and even if some donors wanted to fund me, I would’t want to be beholden to them on their pet issues. So what do we do about it?

For one, we overturn the horrible Citizens United case. Senator Sanders is introducing a Constitutional amendment, called the Saving American Democracy amendment, to do just that, stating in no uncertain terms that to be considered a “person,” a pulse is required. It would forbid corporations from being classed as “people” and from donating to any politician. It will never pass or be ratified, but at least he’s trying. You should watch this video of him explaining it on the floor of the Senate.

The second is public financing of elections. I used to think this was a horrible idea, but upon more level-headed reflection, it’s the only way to go. Michael Moore has a post today about this very thing. The worst example of the amount of money in elections was Meg Whitman, running for Congress in 2010, who spent $119 million of her own money. You can’t compete with that, unless you also have access to that sort of money. If elections were publicly funded, and everyone who runs for office has the same financial limitations placed upon them, the need for obscene amounts of cash to campaign goes away. Now, I don’t know how the determination would be made of who counts as a viable candidate, since we can’t very well fund everyone who says they want to run for office. That would have to be worked out later. But, just like Senator Sanders’ amendment, this will never happen.

Third, we have to stop the “revolving door” between the Congress and the lobby. In that same Michael Moore post, he mentions Senator Michael Bennett, a Democrat from Colorado, who has introduced something he calls a Plan for Washington Reform that would, among other things, place a lifetime ban on former Congressmen from becoming lobbyists. You have to read this! I just developed a man-crush on Senator Bennet as I was reading it. The things he proposes would fix so many problems in Washington. That means, of course, it has no chance of passing.

Oh, one more thing. Have you ever wondered what sort of financial distribution there is among our elected “representatives”? In other words, how many millionaires are there vs. how many average joes. Here’s a handy chart to answer that question.

Anyway, this wasn’t the most eloquent explanation, but that’s what I think needs to happen. Go read Michael Moore’s blog post, then watch Senator Sanders’ video, then read Senator Bennet’s proposal.

Posted in politics | Tagged , , , , , | Leave a comment

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

(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))

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.

(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))

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.

(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))

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?

Posted in tech | Tagged , , | 3 Comments

My New “Top Artists Last 7 Days” Widget

Note Redux: I changed my approach, yet again. Scroll farther down to see the latest.

Note: I changed my approach on this, so scroll down to see how I’m doing it now.

I’ve been wanting a widget or an auto-post on the blog for a while that would show my most-listened-to bands over the previous week. Tumblr users have had something like this for a while, and there were efforts to do this for WordPress before, but they either don’t seem to work with the latest versions of WP, or they only pulled top tracks (not artists), or they pulled album covers, instead of text. All of that is to say that I couldn’t find anything pre-made to use.

So, I had to roll my own. I did so in about 10 minutes using the PHP Code Widget and the script on this page. The only drawback to this is you have to get a developer account with last.fm, but it’s free, so no big deal there. I installed the PHP Code Widget , then pasted the script into a new widget. The only changes I had to make were to replace the appropriate bits in the script with my info, and to escape a couple of double-quotes. Now if you look down the right side of the blog, below the Twitter and Facebook links, you’ll see a rolling record of my top-artists. In case you were wondering what I’ve been listening to. :-)

The only thing I’m not sure about is how this will work with the two levels of caching I use (WP Super Cache and Cloudflare). I suppose we’ll see in the next few days, eh?

11/23/2011 Update: I decided that I didn’t like the way I was doing this, for a couple of reasons. First, each time someone viewed the page, it would be making a call to Last.fm for my stats. This is too often. Also, the values returned using the developer API were at odds with what you can get just going through the web. So what I did was write a Ruby script to pull the feed once a day, parse it and output HTML to a file. I then used the PHP Code Widget to include it. Far simpler, in my opinion.

Here’s the Ruby code:

#!/usr/bin/ruby

require 'rexml/document'
require 'open-uri'

include REXML

open("http://ws.audioscrobbler.com/2.0/user/joeyGibson/weeklyartistchart.xml") do |http|
	response = http.read
	doc = REXML::Document.new response

	index = 0

	File.open(ARGV[0], "w") do |out|
		out.write("<html><head>\n")
		out.write("<meta charset=\"UTF-8\"/>\n")
		out.write("<body><ol>\n")

		doc.elements.each("weeklyartistchart/artist") do |artist|
			break if index == 5

			out.write "<li><a href=\"#{artist.elements['url'].text}\">#{artist.elements['name'].text}</a>, Plays: #{artist.elements['playcount'].text}</li>\n"

			index += 1
		end

		out.puts("</ol></body></html>\n")
	end
end

and here’s the PHP that loads it:

<?php include("/tmp/artists.html"); ?>

That’s it.

11/26/2011 Update: Well, I’ve changed it again. I discovered that the RSS feed I was pulling is not updated with any sort of frequency. It certainly doesn’t represent the “last seven days” as it claims to. At any rate, it differs greatly from what Last.fm shows on the web. So I decided to grab the HTML and pull out the interesting bits. I wrote another Ruby script, this time using Hpricot to parse the HTML, which took about 10 minutes. So now, what you see on the right should be the current values for the “last seven days.” Here’s the latest script:

#!/usr/local/bin/ruby

require 'rubygems'
require 'hpricot'
require 'open-uri'

open("http://www.last.fm/user/your-username-here/charts?rangetype=week&subtype=artists") do |http|
  doc = Hpricot.parse(http.read)

  count = 0

  File.open(ARGV[0], "w") do |out|
    out.write("<html><head>\n")
    out.write("<meta charset=\"UTF-8\"/>\n")
    out.write("<body><ol>\n")

    doc.search("td[@class=subjectCell]").each do |subjectCell|
      break if count == 5

      artistString = subjectCell.get_attribute("title")

      artistString =~ /^(.+), played (\d+) times$/
      artist = $1
      playCount = $2

      subjectCell.search("a").each do |a|
        url = a.get_attribute("href")
        url = "http://last.fm#{url}"

        str = "#{artist}, #{url}, #{playCount}"

        out.write "<li><a href=\"#{url}\">#{artist}</a>, Plays: #{playCount}</li>\n"
      end

      count += 1
    end

    out.puts("</ol></body></html>\n")
  end
end

I’m hopeful this is the last change.

Posted in general | Tagged , , | Leave a comment

Lego VW Microbus

Thomas and I spent six hours this past weekend building this. It was my big splurge from our last trip to Disney World, back in October. What is it? It’s a classic, 1962 Volkswagen microbus. It was expensive, and had far too many pieces (1,332), but it was a blast putting it together. Now it’s sitting on my desk, where I can gaze at it and/or remove the roof and pretend it’s real… :-)

You can read more about the real microbus here.

Posted in life | Tagged , | Leave a comment

A Sad Day: Steve Jobs Is Gone

It’s a sad day in the world. A visionary man has left us. Thanks, Steve, for all the great products that I use every day.

I wish I could take credit for the sad Mac image, but I found it here.

Posted in mac | Tagged , | Leave a comment

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/

 

Posted in eclipse, java | Tagged , , | Leave a comment

You’re Thinking Of…

 

Posted in politics | Tagged , , , | Leave a comment

DirecTV’s Absurd Tech Support Script

I’ve been a mostly-happy DirecTV customer since 2001. In those 11 years, I’ve only had to call tech support three times, and the first two times were flawlessly executed. Those two times were a few years ago, and I was on the phone with them for less than 5 minutes before getting my problem solved.

That was then.

Yesterday, my wife turned on the TV in our bedroom, and got nothing but snow. It had worked the night before, and still had lights on it, so I first tried turning it off and on again. Nothing changed. I then pressed the red reset button. All the lights on the box went out and… nothing.

Then I pulled the power cord out of the back, waited about 20 seconds, and then plugged it back in. I could hear the fan inside the box come on, but still no lights on the box. I tried the buttons and the power button(s) on the remote, but still nothing. I let it sit for a couple of hours to see if it would magically come back on, but it never did. I resigned myself to a call to tech support.

It took me a couple of minutes to get through the phone tree and get a human. I explained the problem, including all of the troubleshooting I’d already done. In my opinion, I had done everything to prove that the unit had died. DirecTV didn’t share that opinion.

The first thing she had me do was turn on the TV and tell her what I saw: snow. Then she had me press the reset button: nothing. Then she said to pull the power cable out of the back of the unit and from the outlet. I told her that I had pulled the cord from the back of the unit, but that I could not unplug it from the outlet, because I would need to move a large armoir to do so. She then said that we could not continue the troubleshooting if I would not unplug it. This is when I started to get annoyed. I tried to reason this out with her, by saying, “Um, OK. Wouldn’t you agree that the fact that the fans are on inside the unit shows that power is getting to the unit?” She agreed. Then I said, “Which means that the outlet is good. There’s no reason to pull the plug from the outlet.” She then re-read me the script.

Now I’m getting pissed. I went through my thought experiment with her again, and again she agreed that it proved that power was getting to the unit. But she wouldn’t budge. I asked for her supervisor. The supervisor came on, and apart from saying, “I understand…” multiple times, she was no better than her subordinate.

At this point, I pretty much lost it. She said that if I “refused” to unplug the unit, then the only thing that could be done was for them to dispatch a technician to investigate. I then said to her, “Do you realize that if I had just lied to the first technician, we wouldn’t be having this conversation? This is absurd. I have proven that power is getting in to the unit. I would agree with you if the fan didn’t come on, but it does. That means the outlet is good.” She then re-read her script.

At this point, I blew a gasket. I told her how utterly absurd this was, but that since I apparently had no freaking choice, I would go move the damn furniture, unplug the cord, and call them back. After moving the furniture, and moving the plug, guess what happend. Nothing! That’s right, it worked exactly like it did the first time.

So I called them back, got a third person to talk to, and had her read the notes on the case. The supervisor had helpfully indicated that I had “refused” to complete the troubleshooting… grrrr…. I then told this person that I had moved the plug, and it still did the same thing: fans, but no lights or picture. She then had me check that the power cable was fully seated in the back of the unit, which it was, and then she wanted me to try plugging the other end into a different outlet, and plug something else into this one. Having learned my lesson, and having already done what she was now asking, I fiddled around with the cables, making some noise without actually doing anything, and then said, “Nope, same thing.”

She then authorized a free replacement unit, which I should have by Wednesday.

I understand that companies need tech support scripts. But when someone calls and clearly explains the problem, and has worked through all the scenarios, you have to allow your people to make judgments and go off-script to keep your customers happy. While on the phone with the first two people, I seriously considered telling them to cancel the service, and that I would get my TV elsewhere.

Posted in tv | Tagged , , , , | 2 Comments

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.

Posted in mac | Tagged , , , | 4 Comments

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.

Posted in mac | Tagged , , | Comments Off

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?

Posted in mac | Tagged , , , | 31 Comments

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.

Posted in mac | Tagged , , , , | 10 Comments

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.

Posted in mac | Tagged , , , , | 1 Comment

Google Chrome Sync Not Working? Try This

I use Google Chrome exclusively as my browser on both Mac and Windows, and I pretty much love everything about it. One of the things I love most about it is the ability to sync most of your settings between machines. This includes bookmarks, apps, themes, passwords, etc.

But the last three times I’ve done an install of Chrome on a machine (my friend’s loaned MacBook, my new MacBook Pro, and a Windows7 VM), when I entered my email address and password, I was told by Chrome that syncing was not available on my Google Apps account. Hmmmmm….

I don’t have an @gmail.com Google account, I have my own domain and a Google Apps account. While Google is trying to make Apps accounts and regular Gmail account identical, there are still some differences (like no profiles…). This can be frustrating, and I assumed that somehow my existing machines had been grandfathered in, but new ones were being excluded. (Also, both the Google Voice and GV Mobile+ apps on my iPhone failed to let me login, complaining about my email address or password being wrong.)

Then yesterday I noticed a comment on a forum (somewhere) suggesting a password mismatch between Google services might be to blame. I decided to give it a shot, so I went into my Google account settings and changed my password. Then I tried to enable sync on my MacBook Pro. BLAMMO! It worked. Then I enabled it on the Windows7 VM. Worked there, too. Then I tried to login using both the Google Voice and GV Mobile+ apps on my iPhone and both now allow me to login.

So, if you are having problems with a Google service or app, such as being told it’s not enabled for your apps account, or getting login failures, try changing your password.

Posted in general | Tagged , , , | 6 Comments

GV Places 1.1 Now Available In the App Store

After sitting in the to-be-reviewed queue at Apple for a week, I’m happy to announce that version 1.1 of GV Places is now available for purchase. The full list of changes is here.

Posted in iphone | Tagged , , , , , , | Comments Off

GV Places 1.1 Submitted To App Store

Yesterday, I submitted version 1.1 of GV Places to the App Store for review. I am hopeful that it won’t take as long to get through this time, but I’m not holding my breath.

The biggest news is that I dropped the iOS target version, so now people with Verizon iPhones can run it. I had hoped that the app store would not let someone download an app that they couldn’t run, but based on the 1-star review I got from a Verizon owner, that may not be the case. Here are the release notes

  • Should now work on Verizon iPhones.
  • Fixed a sorting/display bug that occurred when a place was autoswitched. The next time the app was run, the list would not be sorted properly.
  • Improved the region detection on iPhone 4. This should properly handle overlapping regions, which worked fine on the 3GS, but not so much on the iPhone 4.
  • Fixed a couple of memory leaks.
  • Note that when autoswitching is turned on, the app is not constantly running, looking for location changes. On the iPhone 4, it uses the region monitoring API, which means it tells the OS the regions it is interested in, and then goes to sleep. Whenever the phone enters one of those regions, the OS will wake the app up, telling it that it entered that region. This uses no extra battery on my iPhone 4, that I could tell. On the 3GS, it uses the significant location change monitoring API. With this API, the app tells the OS it is interested in significant location changes (this is mostly when cell towers change), and then goes to sleep. When one of these events occurs, the OS wakes the app up, telling it that a significant location change has occurred. The app then gets the current location and sees if it is within one of your places. If it is, it switches to that place. This is not as accurate as on the iPhone 4, but it’s all the 3GS has. This would probably use up a bit more battery than on the iPhone 4, because it has to do more work, but I didn’t notice any significant battery degradation on my 3GS.
  • Also note that autoswitching of places is NOT supported on the iPhone 3G, because neither of the APIs I described above were available on the 3G. Everything else works on the 3G.

Posted in iphone | Tagged , , , , , , | 2 Comments

Downgrading Your iPhone From iOS5 to iOS4.3.3: It Ain’t Easy

Like lots of other iPhone owners, I was excited about the announcement on Monday of iOS5, and all the new features. I don’t like to wait and since it isn’t going to be released until September, I had to get it somehow. Since I’m an iOS developer, I was able to download a developer seed of iOS5 and install it on my iPhone 3GS. I did so Tuesday morning.

It was painfully slow on the 3GS. Granted this is just beta 1, and it will probably improve before it launches, but it was nearly unusable.

So today, I went out and bought an iPhone 4. I had been wanting one for a long time anyway, and my contract was up in February so I’ve been able to get a subsidized price since then… Anyway, I bought a 4, and was not planning on putting iOS5 on it just yet. But when I attached it to iTunes and tried to restore my last 3GS backup to it, iTunes wouldn’t let me because the backup was of iOS5 and the iPhone 4 was running 4.3.3. So, against my better judgment, I installed iOS5 on it.

Big mistake.

While speed was no longer an issue, bugginess was. Lots of 3rd-party apps just seemed to not work right, and even some features of iOS were a bit squirrelly. A downgrade was in order. But, as the release notes tell you, you can’t downgrade.

Well, you can, but it’s a major pain in the butt. Below is a list of what I did to restore mine. But first, please be aware that your mileage may vary, use at your own risk, by reading this, you agree that I am not liable for any damage to your iPhone, iTunes, data, computer, house, car, cat, dog or anything else.

(This is in list form, but it’s not an instruction list, per se. It’s a list of what I did, thus the verbs are in the past tense.)

  1. Restored the entire ~/Library/Application Support/MobileSync/Backup directory from Monday, before I did the upgrade of the 3GS, using Time Machine. (On Windows, the directory is C:\Users\<UserName>\AppData\Roaming\Apple Computer\MobileSync\Backup)
  2. Downloaded the iOS 4.3.3 software image from links here (the links go to Apple) http://osxdaily.com/2011/05/04/ios-4-3-3-download/
  3. Launched iTunes, but hit the little ‘X’ button in the top area to stop it from syncing.
  4. Selected the iPhone 4 in the Devices section, then pressed Option while clicking on the “Check for Update” button. This popped up a dialog to find the .ipsw file that I had downloaded. I navigated to where I had saved it, and selected it.
  5. iTunes started to restore it, then barfed with one of those “unknown” errors. It did leave the iPhone in recovery mode.
  6. Out of paranoia, I shut down iTunes, deleted the partial backup that it had tried to do, thus leaving the Backup directory as it was on Monday.
  7. Started iTunes.
  8. iTunes popped up a dialog saying that the phone was in recovery mode and did I want to restore it. I said “yes.”
  9. It then showed me the EULA for 4.3.3, re-downloaded the .ipsw, then started the restore.
  10. Ten minutes later, it rebooted and showed up in iTunes, with iTunes asking if I wanted to restore it from one of my backups.
  11. I selected the 3GS backup and off it went.
  12. When the phone rebooted, iTunes started re-syncing it.
  13. Half an hour more, and it was done restoring all my data and settings. Then it started restoring 4,500 songs, which takes about 3 hours.

So, that’s it. All in all, it took me about 2 hours, start to finish. If you don’t have a backup of the Backup directory, you’re screwed.

I use pre-release software all the time, but this is the first time I’ve really, truly, gotten burned by it. I have now learned my lesson, and will at least wait for the release of iOS5… beta… 3 before trying again. :-)

Posted in iphone | Tagged , , , , , , , | 7 Comments