Some thoughts on Leopard

Posted almost 7 years back at Luke Redpath - Home

In case you missed the memo, Apple unleashed Leopard on Friday. I headed down to the Regent Street Apple Store to see if I could snag a copy; unfortunately, by 6pm the queue had reached epic proportions (at least a 45 minute wait) and I promptly left and instead chose to pick up a copy from Brent Cross on Saturday (I feel sorry for anybody who did bother queueing all evening – the Brent Cross store was no more busy than usual come Saturday afternoon).

Rather than spending time discussing Leopard’s much discussed new major features, I thought it would be interesting to point out some of the smaller, minor but useful updates that I have picked up on so far. I will update this list over the next week or two as I discover new things, good and bad:

  • Installation didn’t go too smoothly for me; there appears to be a bug in the install process affecting some machines that means that my hard drive wasn’t showing up in the “Select a destination” panel. Fortunately I was able to find out from the Apple discussion forums that after waiting 10 to 15 minutes your available drives will appear. One cup of tea later, and the install routine was back on track. I opted to perform an “Erase and Install” on my MacBook Pro to get rid of the sheer amount of crap that I had accumulated over the last 18 months which went as smoothly as I’d expected. I am yet to try the upgrade option on my Mac Mini so YMMV here.
  • My first impressions were that Leopard seemed faster and given that it was probably hard at work indexing my hard drive for Spotlight this was pretty impressive. My Airport problems in Tiger (the connection would frequently just stop responding or lose packets making it incredibly frustrating to do anything useful) appear to be resolved, at least, when running on mains power. When running on battery I still seem to be suffering from random disconnections although Leopard at least shows that it has lost its connection and reconnects pretty fast. This may be a problem with my router and still requires further investigation on my part.
  • The new dock is not as bad as everybody has made out and I have left it at the bottom for now even though I’m traditionally a dock-on-the-side person. The new Stacks functionality is useful and looks great although the cool “fan” effect only works when the dock is on the bottom. I imagine the novelty will wear off quite quickly and I will be back to having my dock on the side soon enough.
  • I’m sure that most Rails developers have been aware for a while now that Leopard will ship with Rails. The new Ruby/Rails stack in Leopard is well thought out and organised and comes with Ruby 1.8.6, Rails 1.2.3 and and a host of other useful gems. Rails itself is simply bundled as a gem and is easily updated. A good overview of the changes to Ruby in Leopard is available.
  • One utility that anybody who frequently uses SSH and public/private keys would not be without is SSHKeychain which integrates with Apple Keychain and acts as an SSH agent. In my experience SSHKeychain could be flaky and would sometimes silently crash for no apparent reason; good news then because as of Leopard, OSX maintains its own Keychain-integrated ssh-agent making passphrase-protected keys painless to use out of the box.
  • Speaking of which, the new Leopard Terminal finally supports tabs and is much easier to customize thanks to built-in themes. Despite some niggles (like not being able to jump to a specific tab using Cmd+number) I think that it is finally time to say goodbye to iTerm.
  • Connecting to your mail server over SSL using a self-signed certificate in Mail.app is no longer a pain in the arse. Before, Mail would prompt you that the server certificate was not from a trusted source every time you tried to connect unless you manually dragged the certificate to the desktop and added it to your keychain. In Leopard, Mail finally has an option to “always trust this certificate” as well as a number of other fine-grained trust options.
  • The new version of Front Row, based on the Apple TV software, seems like a regression to me. The new interface doesn’t seem as slick and suffers from some annoying bugs like not being able to view album artwork on a shared library and most annoying of all: there doesn’t seem to be any way to get Front Row to open on a second monitor. In Tiger, Front Row would always open on the primary display – this was documented behavior and in Leopard this behavior seems to have disappeared. I like to hook my MBP up to my plasma TV but now Front Row will only open on my MBP screen, even if its not the primary display, severely limiting its usefulness.
  • On the plus-side, Quicktime now has some useful full-screen options including options to stretch or fill a widescreen display when viewing videos in a 4:3 aspect ratio. Quicktime does work on a second display and allows you to select which screen it will display on in full-screen mode independently of your primary display settings.

Update 1: Airport Woes

When running in battery mode, Airport performance is horrendous, even after installing the latest keychain fix. The signal will go up and down and the transmit rate will jump up and down wildly between 0 and 54 before eventually just disconnecting – it seems to disconnect every couple of minutes.

The question is, is this a) a continuation of the connection stability problems I was having in Tiger but manifesting itself with different symptoms (or simply that Leopard is more responsive to Airport connection status changes than Tiger), b) an entirely new problem created by the latest Airport drivers, c) a hardware issue (dodgy Airport cards?) or d) a problem with my router.

Until I can test out Airport performance on my Mac Mini in Leopard, I can’t rule out D although the fact that many other people are having the same problem seems to suggests this is not the case. Airport performance seems reliable when connected to the mains, so maybe its an issue of power consumption by the Airport card?

Something else that I just noticed: there appears to be a rather nasty looking, if ultimately harmless, rendering bug when scrolling in Finder when in column mode:

More Airport updates

I’m beginning to become more and more convinced that the problem with Airport is a power issue. My Airport connection seems to be very stable with no disconnections when running on mains power but in battery mode the disconnections come very frequently. I’ve also managed to perform the following test with reliable results: plug in the power adapter and wait a few minutes to confirm a stable Airport connection. Now remove the power adapter – in my observations, about 80% of the time the Airport connection will drop within 10 seconds. This would indicate to me that the problem lies in the Airport card not being able to draw enough power to operate in a stable manner whilst running in battery mode.

Yet another update

I mentioned earlier that I was having trouble getting Front Row to display on my TV even though it was set as the primary monitor. Last night I gave it another try and et voila; Front Row was displaying on my TV. Further investigation led me to this post on the Apple discussion forums:

“Not sure if this is related to the bugs you are having, but one I’ve noticed and reported to apple is this: When you first start front row it appears on your primary display, it also remembers which display it first started on. So, if you exit but don’t kill the front row process (in activity manager), front row will always display on that initial primary monitor, even if you swap your primary/secondary in sys pref. I haven’t tried mirroring the displays. " cmendill, Apple Discussion Board

I haven’t had the change to verify this (yet) but it makes sense – if exiting Front Row doesn’t actually kill the process, then Front Row will not pick up changes to your primary display settings until you do. I still consider this to be a bug but at least it’s an explanation!

Leopard reviews:

Episode 77: Destroy Without JavaScript

Posted almost 7 years back at Railscasts

If the user has JavaScript disabled, the "Destroy" link might not work properly. In this episode I will explore a number of ways to work around this issue.

YouCast: White-label video sharing site

Posted almost 7 years back at Shane's Brain Extension

YouCast? is a Ruby on Rails video sharing application that you host on your own servers. It can be rebranded easily for your company or used as is.

Main features:

  • Upload videos, images, and music via web or mobile phone via SMS/MMS attachment
  • Create a playlist of your videos, images, and music
  • Play your media in a Flash player
  • Get the code for the player to embed in any site (myspace, blog, etc)
  • Generates thumbnails for videos
  • Multi-user support with user login and user management
  • Export your playlist in XSPF/Spiff format

Tech specs:

  • Ruby on Rails application designed with RESTful methodology
  • Supports all major video and image formats, and mp3 for music
  • Encodes all video to Flash
  • Uses MMS2R for mobile media processing
  • XSPF/Spiff format used for playlists for maximum portability

What you get:

  • Full source code
  • 10 hours of free consulting, including help with installation and migration
  • Option to hire me for additional consulting

What can you do with YouCast??

  • Create an internal video sharing site for your company or small business
  • Use it as a base for your own video-related site
  • Merge it with your existing site to add video and mobile media support
  • Re-create YouTube to impress your friends

How much does it cost?

  • YouCast? will cost a yet-to-be-determined one-time fee, which includes free updates to that version. I will determine the cost once I get a better idea of demand.

Email me at the address in the About Me page if you are interested in seeing a demo and/or purchase.

YouCast: White-label video sharing site

Posted almost 7 years back at Shane's Brain Extension

YouCast? is a Ruby on Rails video sharing application that you host on your own servers. It can be rebranded easily for your company or used as is.

Main features:

  • Upload videos, images, and music via web or mobile phone via SMS/MMS attachment
  • Create a playlist of your videos, images, and music
  • Play your media in a Flash player
  • Get the code for the player to embed in any site (myspace, blog, etc)
  • Generates thumbnails for videos
  • Multi-user support with user login and user management
  • Export your playlist in XSPF/Spiff format

Tech specs:

  • Ruby on Rails application designed with RESTful methodology
  • Supports all major video and image formats, and mp3 for music
  • Encodes all video to Flash
  • Uses MMS2R for mobile media processing
  • XSPF/Spiff format used for playlists for maximum portability

What you get:

  • Full source code
  • 10 hours of free consulting, including help with installation and migration
  • Option to hire me for additional consulting

What can you do with YouCast??

  • Create an internal video sharing site for your company or small business
  • Use it as a base for your own video-related site
  • Merge it with your existing site to add video and mobile media support
  • Re-create YouTube to impress your friends

How much does it cost?

  • YouCast? will cost a yet-to-be-determined one-time fee, which includes free updates to that version. I will determine the cost once I get a better idea of demand.

Email me at the address in the About Me page if you are interested in seeing a demo and/or purchase.

Rob McKinnon: TheyWorkForYou.co.nz - Ruby on Rails Podcast

Posted almost 7 years back at Ruby on Rails Podcast

A London-based developer talks about keeping government accountable in New Zealand and around the world.
Also mentioned:

wrapping processes in IO.popen and festivaltts4r

Posted almost 7 years back at Mike Mondragon

There is a cool gem called Festival TTS for Ruby . What it does is take text, pass it into the The Festival Speech Synthesis System , then transform the WAV from Festival into an MP3. festivaltts4r provides a programming interface to use its functionality in an application. The project includes a Flash media player so that you can use festivaltts4r easily in a Rails application. Listen to their example Rails application. To use the Flash player you need to check out the project as a plugin to your Rails app like so:

wrapping processes in IO.popen and festivaltts4r

Posted almost 7 years back at Mike Mondragon

There is a cool gem called Festival TTS for Ruby . What it does is take text, pass it into the The Festival Speech Synthesis System , then transform the WAV from Festival into an MP3. festivaltts4r provides a programming interface to use its functionality in an application. The project includes a Flash media player so that you can use festivaltts4r easily in a Rails application. Listen to their example Rails application. To use the Flash player you need to check out the project as a plugin to your Rails app like so:

ruby script/plugin install svn+ssh://rubyforge.org/var/svn/festivaltts4r/plugins/festivaltts_on_rails

festival4r.rb adds #to_speech and #to_mp3 methods to String and each make a simple call to Kernel#system to execute their programs. That is a quick and easy approach as #system returns false on failure, true on success, and the exit status of the process in $?

However, many processes output text as the they are being executed such as status or error messages. Before I came across festivaltts4r I had actually written my own kind of festivaltts4r for a Rails project. My approach is to capture all of the output of the process and if there is an error returned from the process use the output as the message for an Exception. The process is executed by IO.popen which also captures the text of the process. Process.wait is then called to ensure to wait for the process to finish (beware of hung processes!). Eric Hodel suggested the use of IO.popen in this manner.

Here is the model I used for my implementation of festivaltts4r. The model uses Single Table Inheritance, look at the schema annotation for clues about the overall strategy/pattern of my MediaTransform model. Also note that MediaTransformError is just a custom Exception my application raises and catches as a part of its behavior for transforming text to mp3. btw LAME is used to encode the WAV from Festival to MP3

# == Schema Information
# Schema version: 12
#
# Table name: media_transforms
#
#  id                :integer(11)   not null, primary key
#  type              :string(255)   
#  media_bot_id      :integer(11)   
#  text2wave_program :string(255)   default("/usr/bin/text2wave -scale 7 -o \"OUTWAV\" \"INTEXT\" 2>&1")
#  wav2mp3_program   :string(255)   default("/usr/bin/lame -h \"INWAV\" \"OUTMP3\" 2>&1")
#  watermark         :string(255)   
#  watermark_program :string(255)   default("/usr/bin/composite -gravity southeast -watermark 25 \"WMIMAGE\" \"INIMAGE\" \"OUTIMAGE\" 2>&1")
#  created_at        :datetime      
#  updated_at        :datetime      
#

class RobotTransform < MediaTransform

  def self.transform_mime_type
    'text/plain'
  end

  def transform(text)

    # get a unique temp dir to output text2wav to
    tmp_dir = Media.create_tmp_dir(text.id)

    # set up names and paths for processing
    name = File.basename(text.filename)
    wav_file = File.expand_path(File.join(tmp_dir, name.sub(/\.[^.]+$/, ".wav")))
    mp3_file = File.expand_path(File.join(tmp_dir, name.sub(/\.[^.]+$/, ".mp3")))

    # run the text2wave program
    program = text2wave_program.gsub('INTEXT', text.full_filename)
    program.gsub!('OUTWAV', wav_file)
    begin
      out = IO.popen("#{program}")
      Process.wait
      e = $?.exitstatus
    rescue StandardError => err
      raise MediaTransformError.new(err)
    else
      raise MediaTransformError.new("0 not returned:\n#{program}\n#{out.readlines}"
        ) unless e.eql?(0)
    end

    # run the wav2mp3 program
    program = wav2mp3_program.gsub('INWAV', wav_file)
    program.gsub!('OUTMP3', mp3_file)
    begin
      out = IO.popen("#{program}")
      Process.wait
      e = $?.exitstatus
    rescue StandardError => err
      raise MediaTransformError.new(err)
    else
      raise MediaTransformError.new("0 not returned:\n#{program}\n#{out.readlines}"
        ) unless e.eql?(0)
    end

    fu = FuFile.new('audio/mpeg', mp3_file)
    mp3 = FileSystemMedia.new
    mp3.uploaded_data = fu
    mp3.save!

    FileUtils.rm_rf(tmp_dir)
    mp3
  end
end

JQueryCamp Is Tomorrow!

Posted almost 7 years back at zerosum dirt(nap) - Home

For anyone who’s registered (and presumably in or around the greater Boston area), don’t forget that JQueryCamp is tomorrow! I’ll be there, and looking forward to talks by John Resig, Yehuda Katz (whom I probably owe a beer), and many others.

Cookie Session Store for Facebook Applications

Posted almost 7 years back at Darwinweb

I was recently recruited to build a “facebook”:http://facebook.com application on top of an existing Rails codebase running on edge. Having been on edge with my previous project for at least 6 months, I’ve gotten used to all the Rails 2.0 goodness.

One of my favorite features is the “cookie session store”:http://ryandaigle.com/articles/2007/2/21/what-s… which is a huge slam dunk for scalability and general maintainenance—that is to say, no maintenance.

Unfortunately facebook does not store cookies (as far as I can tell), and there is really no documentation of this to speak of out there on the web. If you are using the cookie session store, nothing blows up, you just don’t have a session. It’s pretty obvious when you think about it, but I spent a couple hours figuring out why my flash messages weren’t coming through. If this post saves one person 20 minutes, then it was time well spent.

Cookie Session Store for Facebook Applications

Posted almost 7 years back at Darwinweb

I was recently recruited to build a facebook application on top of an existing Rails codebase running on edge. Having been on edge with my previous project for at least 6 months, I’ve gotten used to all the Rails 2.0 goodness.

One of my favorite features is the cookie session store which is a huge slam dunk for scalability and general maintainenance—that is to say, no maintenance.

Unfortunately facebook does not store cookies (as far as I can tell), and there is really no documentation of this to speak of out there on the web. If you are using the cookie session store, nothing blows up, you just don’t have a session. It’s pretty obvious when you think about it, but I spent a couple hours figuring out why my flash messages weren’t coming through. If this post saves one person 20 minutes, then it was time well spent.

Revisiting date localization for Ruby 1.8.6

Posted almost 7 years back at poocs.net - Home

Welcome to my yearly post about a revised version of a simple way to localize Ruby’s Time#strftime method (after my original post in ‘05 and the update in ‘06).

What’s changed?

In my original methodology, the arrays in the Date class containing the actual day and month names in clear text had to be replaced by strings wrapped in the infamous _() call of GetText in order to spit out their localized versions when requested from the modified Time#strftime call.

When Ruby 1.8.6 came along, it had its Date array constants frozen. While I agree it’s generally not a good idea to modify the contents of a constant (it’s a constant after all, mind you), the implementation I came up with 2 years ago worked fine up to and including today.

Since, also, most of the sites I’m working on require multiple languages (as opposed to, say, a single language set at application boot time), the contents of those Date arrays truly need to be modified at runtime and having those arrays frozen meant jumping through all sorts of hoops to address a supposedly simple issue.

What now?

Well, I had to come up with a way to actually execute the gettext functionality in the context of an object that has the current GetText locale bound to it. The most obvious object with that kind of property is ApplicationController.

But this still leaves us with the issue that we cannot modify the frozen Date constants and that everything we put into these constants is evaluated right away instead of at a point where we have the desired locale set.

What I came up with was a proxy object derived from the Array class that would basically just wrap the cleartext contents that are already in each of the Date arrays but not before they’re actually accessed/output.


    # lib/date_localization.rb
    class GetTextDateProxy < Array

      cattr_accessor :gettext_proxy

      def [](key)
        _(at(key))
      end

      def _(string)
        return string unless gettext_proxy
        gettext_proxy.instance_eval { gettext(string) }
      end

    end

As you can see, the proxy object is pretty simple after all. It just overwrites the default of Array#[] to look up the requested key and then wrap the output in _().

Since I couldn’t actually be bothered to include the whole of Ruby-GetText into my poor little proxy object, I then made room for it to hold a pointer to an instance of ApplicationController in a class attribute called gettext_proxy. The local underscore method of my proxy class then wraps around the actual gettext implementation available to the gettext proxy (read: ApplicationController), returning the string unchanged if there is no gettext proxy and if there is, run the string through the proxy’s gettext method.

Dealing with a state of not having a gettext proxy available is actually necessary in cases where there are calls to these arrays before ApplicationController gets to hook itself up to GetTextDateProxy.

But how does this actually hook into the Date class now? Let’s take a look:


    # lib/date_localization.rb
    class Date

      silence_warnings do
        %w(
          MONTHNAMES DAYNAMES ABBR_MONTHNAMES ABBR_DAYNAMES
        ).each do |array|
          class_eval %( #{array} = GetTextDateProxy.new(#{array}) )
        end
      end

    end

While this still looks a little tedious, it’s far less tedious than repeating the arrays’ contents simply wrapped in _() all over the place, like we had to do in previous incarnations of this methodology.

Basically, now every array is hooked up with their very own instance of GetTextDateProxy which then takes care of running the strings through gettext in the appropriate moments.

Wiring it all up

For the last part, we need to get ApplicationController to hook itself into GetTextDateProxy after having received the appropriate locale for the request it’s dealing with.

The best fit for this is the after_init_gettext hook provided by Ruby-GetText. Adding this code to ApplicationController will take care of the last required step.


    # app/controllers/application.rb
    after_init_gettext { GetTextDateProxy.gettext_proxy = self }    

Here you go, working (albeit hackish) localization for Ruby’s Time#strftime working up to and including the most recent version of Ruby, which is 1.8.6 as of this writing.

Enjoy.

Google Docs Basically Sucks

Posted almost 7 years back at Ryan Tomayko's Writings

The Google Docs editing UI is quite adequate, export to PDF / OpenOffice / Word is wonderful, and the collaboration stuff is strong but why cannot we produce modestly sane HTML or attach custom stylesheets?

Google Docs - Basically Sucks

Joho the Blog (in March 2007):

I've been using Google Docs to write documents that are collaborative. It’s a good first gen product, and I enjoy using it, but it would take a giant step forward if it let me apply a CSS style sheet to the docs I'm composing.

No shit. This is such an obvious idea that there must be something obviously wrong with it.

Joho the Blog continues…

This is such an obvious idea that there must be something obviously wrong with it.

Jinks!

Let me have a single URL box on the document and group settings page. Take whatever I put in there and stuff it in a <link rel='stylesheet' ...> in the head. At the very least, if I happen to plop something like that in via Edit HTML, let it through your sanitizer. And don’t even start on about <link> and <style> not being valid in the <body> – the generated HTML is such a complete mess that a minor offense like that is the least of your worries. Look at this (from a preview of a document):

<style>
BODY, P, DIV, TD {
   direction: inherit;
</style>

You have a better chance at validity from /dev/random.

I'm sure there’s all kinds of scripting vulnerabilities we’re worried about here but right now I'm just trying to Get Stuff Done and this is killing me.

What are some alternatives? I stopped reading TechCrunch but there has to be at least ten fairly mature browser based word processors out there by now. I like jottit’s URLs and overall simplicity but I also need the WYSIWG and I like being able to go out to .pdf, .doc, and .odt. But forget all that, is there anybody in this space that gives a shit about the HTML being generated? Let’s start there.

Want to know what Toronto's councillors are spending your money on ?

Posted almost 7 years back at work.rowanhick.com

Check this out. Council Expenses (robford.ca) Absolutely brilliant, and questionable all at the same time...

Mephisto gets a core team

Posted almost 7 years back at Beyond The Type - Home

Good news for Mephisto users. The core team has been decided and the ideas for the 1.0 release are being finalised.

Interestingly enough there may also be a push to switch over to using Git which is gaining a bit of traction in the Rails community. I’m an avid user of SVK and gave Git a try a while back but stopped short after hearing tales of woe with git-svn… I may revisit at some point.

Episode 76: scope_out

Posted almost 7 years back at Railscasts

The scope_out plugin will generate several helpful find methods for you automatically! It's the best way to move the find conditions into your model. Watch this episode for details.