Printing on Canvas

I've wanted to print on Canvas for a while, so last week I went in to London Drugs and had two of my pictures printed up. Cost about $40 per without frames. The reason for printing without frames is London Drugs uses precut wood struts and they come in set sizes which would restrict my aspect ratios.

After they were printed I called around and found that it was going to cost $130 each to have them 'stretched' and framed. This seemed a little excessive so I did some research and came across this site on canvas framing. It helped immensely and I quickly had the tools and materials to construct my own.

Picture gallery of the process.

Rate My Route on iPhone

Been working on the iPhone application for a while now, loaded it up on my actual phone for the first time today! Here are some juicy screen shots of it in action.

 

Vancouver Island Coffee

Espresso

Like all north west coasters us Vancouver Islanders are obsessed with coffee. Why just yesterday I learnt that Nanaimo is getting another Starbucks in Port Place Mall when it is rebuilt. It is still remarkably hard to find good coffee here though, for the longest time if I wanted good coffee I was buying it in Parksville at Cha Cha's, which roasts their own coffee, but even here it was hit and miss as to whether they had a good light roast.

Drumroaster Espresso Machine

Drumroaster to the rescue; my first experience with their coffe was at Mon Petit Choux and their espresso. After tracking down the roaster and purchasing a bag of 'El Salvador Pacamara' I can safely say this is some of the best coffee I've had since moving to the island.

Social site around the indoor climbing gym

The other day I was sitting around the gym talking with a fellow climber who also sets routes here and we came to the conclusion it would be nice to have a piece of paper beside each route to leave comments. Well, I work in the web-o-sphere so quickly realized that I can turn something like this out pretty quickly.

After meeting with my good friend Guy and selling him on the idea he whipped up a look and I built the back end. Our finished product: ratemyroute.com

Enjoy!

Apple Todo.webapp

Last night I was struck with an idea, so today I started the coding part and ended up with  a library to pull down (over IMAP) and parse Apple Mail.app formatted todos. Surrounding this library with a light weight Sinatra layer.

Git repo

1/2 Juan de Fuca Trail

Phillips canceling one of its best beers

My letter to Phillips, I encourage you to write one as well!

Dear Brewmaster,

I recently had the pleasure of trying the Hop Circle IPA and enjoyed it immensely, thank you for another fantastic beer. Now we come to the sad part of this communiqué, I have read that you are no longer going to produce the regular IPA as the Hop Circle IPA will be its replacement. The Phillips IPA, yes the one with the cute elephants on the label, is one of my favourite beers and as good as the Hop Circle IPA is it has big shoes to fill. I don't think the Hop Circle IPA measures up to the legendary IPA.
Please don't discontinue this tasty beer.

Long time enjoyer of your fine beers first time writer,

Hez

Climbing Photos

So, I've been getting outside and taking pictures again, this time I've got some climbers in the sights. It is turning out to be a lot more work then I thought it would be, setting up the rigging safely and flexible so I can get in and get the shot will take some experimentation.

Check out my recent shoot at the river. More to be posted soon.

Photo credit: Jason Connelly.

JQuery Date/Datetime picker

I recently ran across this helpful post on a Merb Datetime picker and it was good, that is until I wanted to use the JQuery Date picker. Well a bit of hacking later we have this:

<%= form_for @person %>
  <%= jquery_date_field :birth_date :label => 'Birthdate' %>
  <%= jquery_datetime_field :birth_date_and_time, :label => 'Birthdate and time' %>
<% end =%>
module Merb
  module GlobalHelpers
    # Jquery date picker
    module Merb::Helpers::Form
      def jquery_date_field(*args)
        if bound?(*args)
          current_form_context.jquery_bound_date_field(*args)
        else
          current_form_context.jquery_unbound_date_field(*args)
        end
      end

      def jquery_datetime_field(*args)
        if bound?(*args)
          current_form_context.jquery_bound_datetime_field(*args)
        else
          current_form_context.jquery_unbound_datetime_field(*args)
        end
      end

      module Builder
        class Base
          def jquery_bound_date_field(method, attrs = {})
            name = control_name(method)
            update_bound_controls(method, attrs, nil)
            jquery_unbound_date_field({:name => name}.merge(attrs))
          end

          def jquery_bound_datetime_field(method, attrs = {})
            name = control_name(method)
            update_bound_controls(method, attrs, nil)
            jquery_unbound_datetime_field({:name => name}.merge(attrs))
          end

          def jquery_unbound_date_field(attrs)
            if attrs[:name] =~ /\[(.*)\]/
              date = @obj.send($1)
            end
            date ||= attrs[:value] || Time.now

            date_attrs = attrs.merge(
                :class => 'jquery_date_picker',
                :value => date.to_date.to_s,
                :name => attrs[:name].to_s + '[date]',
                :id => attrs[:id] + '_input',
                :label => attrs[:label]
            )
            hidden_attrs = attrs.merge(
                :value => '',
                :label => nil
            )
            unbound_text_field( date_attrs ) +
              unbound_hidden_field( hidden_attrs.merge(:name => attrs[:name].to_s + '[year]', :id => attrs[:id] + '_year', :value => date.year) ) +
              unbound_hidden_field( hidden_attrs.merge(:name => attrs[:name].to_s + '[month]', :id => attrs[:id] + '_month', :value => date.month) ) +
              unbound_hidden_field( hidden_attrs.merge(:name => attrs[:name].to_s + '[day]', :id => attrs[:id] + '_day', :value => date.day) ) +
              "<script type=\"text/javascript\">
              $(function() {
                  $(\"##{date_attrs[:id]}\").datepicker({
                    dateFormat: 'yy-mm-dd',
                    onSelect: function(dateText, inst) {
                      var myDatesSplit = $(\"##{attrs[:id]}_input\")[0].value.split( '-' );
                      $(\"##{attrs[:id]}_year\")[0].value = myDatesSplit[0];
                      $(\"##{attrs[:id]}_month\")[0].value = myDatesSplit[1];
                      $(\"##{attrs[:id]}_day\")[0].value = myDatesSplit[2];
                    }
                  });
                });
              </script>"
          end

          def jquery_unbound_datetime_field(attrs)
            if attrs[:name] =~ /\[(.*)\]/
              date = @obj.send($1)
            end
            date ||= attrs[:value] || Time.now

            hour_attrs = attrs.merge(
              :class => "date hour",
              :selected => date.hour.to_s,
              :name => attrs[:name].to_s + '[hour]',
              :id => attrs[:id] + '_hour',
              :collection => (0..24).map{|i|[i, i.to_s]},
              :label => nil
            )

            minute_attrs = attrs.merge(
              :class => "date minutes",
              :selected => date.min.to_s,
              :name => attrs[:name].to_s + '[min]',
              :id => attrs[:id] + '_min',
              :collection => %w[00 05 10 15 20 25 30 35 40 45 50 55].map{|i|[i.to_i, i]},
              :value_method => :first,
              :text_method => :last,
              :label => nil
            )

            jquery_unbound_date_field(attrs) + ' ' + unbound_select(hour_attrs) + ':' + unbound_select(minute_attrs)
          end
        end
      end
    end
    # end Jquery date picker
  end
end

Datamapper paranoid delete quirks

Recently discovered some quirks while working with Datamapper (ver 0.10.2). If you want to fetch deleted objects you need to use the syntax:

Model.with_deleted { Model.all }

Which by the way will only find deleted objects, if you want all the objects your going to have to do something like

Model.with_deleted { Model.all } | Model.all

The next quirky bit is if you want to undelete things you can't simply do:

m = Model.with_deleted { Model.get(1) }

m.update( :deleted_at => nil )

You actually have to do:

m = Model.with_deleted { Model.get(1) }

m.deleted_at

m.update( :deleted_at => nil )

Due to the lazy loading that Datamapper does it actually doesn't load the :deleted_at property until you have accessed and apparently won't save changes to it either.

Full example:

class Test
  include DataMapper::Resource
  
  property :id, Serial
  property :deleted_at, ParanoidDateTime
end

t = Test.new
t.save                          #~ (0.354887) INSERT INTO "tests" DEFAULT VALUES
t = Test.new
t.save                          #~ (0.089852) INSERT INTO "tests" DEFAULT VALUES
t = Test.first                  #~ (0.000191) SELECT "id" FROM "tests" WHERE "deleted_at" IS NULL ORDER BY "id" LIMIT 1
t.destroy                       #~ (0.002124) UPDATE "tests" SET "deleted_at" = '2010-04-15T17:02:14-07:00' WHERE "id" = 1
t = Test.with_deleted { Test.first }  #~ (0.000092) SELECT "id" FROM "tests" WHERE NOT("deleted_at" IS NULL) ORDER BY "id" LIMIT 1
t.deleted_at = nil
t.save                          # true
t = Test.with_deleted { Test.first }  #~ (0.000094) SELECT "id" FROM "tests" WHERE NOT("deleted_at" IS NULL) ORDER BY "id" LIMIT 1
t.deleted_at                    #~ (0.000429) SELECT "id", "deleted_at" FROM "tests" WHERE "id" = 1 ORDER BY "id"

View older posts »

Music

No tracks have recently been played.

Interesting