Archive for the ‘General’ Category

That was fast

Saturday, February 2nd, 2008

It was just a few hours ago that I posted my Goals for 2008 and I’m releasing my first project of the year.

It’s nothing big, but it was a fun little distraction.

The hide-an-image-in-text-with-css3-creator-thing

If you’re one of those folks who might care about how something like this might work, here’s the source.

My goals for 2008

Friday, February 1st, 2008

It’s February 1st 2008 and this is going to serve as my list of yearly goals. I’m going to review these periodically throughout the year, and have a followup next February.

  1. Finish this blog post
  2. Be the best father and husband I can be
  3. “Ship” 10 projects
    • 1+ on Amazon’s cloud
    • 1+ with a new-to-me language (Smalltalk, Io, Python, etc)
  4. Drop 20lbs of fat

BravoNation bookmarklet

Thursday, December 27th, 2007

Andy at waxy was kind enough to invite me to Bravo Nation — A site for web-based achievements (kinda like iminlikewithyou meets xbox). After playing with their un-finished drawing tool, I wanted a way to do more with it

Since I fancy myself a hacker, I made a bookmarklet to overlay an image and draw behind it.

I grossly underestimated this task! I won’t bore you with the details (email me if you wanna discuss it: kastner@gmail), but long story short: “It works for me!”

Here’s the bookmarklet code:
DrawOverFlash.

Here’s something I made with it: Weighted Companion Cube

Here’s a video of me using it (double click to lock the image):

My Bookmarklet for BravoNation from kastner on Vimeo.

Here’s an image I made on Ze Frank’s Scribbler:
I've made a note here: "Huge Success"

The new project - befuddlr

Sunday, November 25th, 2007

I almost (co)wrote a book.

Sometime last year, Amy Hoy invited me to work on a book with her - “Web Scripting Power Tools”. It was going to be an advanced guide to javascript. Some things diverted my attention and the book project went away.

Amy Hoy doesn’t hate me and today we launched a project that came out of working on the book. Befuddlr!

The code is mostly JS (moo tools), but all the pretty is due to Amy’s keen eye (and keen PS skillz).

Restoring XEN DomU’s in debian etch

Tuesday, October 23rd, 2007

I ran into a small problem with xendomain saving and restoring domains on shutdown. It turns out the obscure unix command
cut was to blame.

the way that /etc/init.d/xendomains reads from xm list is to use this cut command:

cut -c0-19

I got it to work by changing that to

cut -f1 -d' '

and replace the $rest with

cut -f2- -d' '

Hope this helps someone (even if it’s just me in the future!)

Gary’s Conan vid.

Friday, August 3rd, 2007

We knew that Gary’s vid would show up on YouTube, but FROM NBC? that’s insane

Here it is:

Gary Vaynerchuk on Conan tonight

Wednesday, August 1st, 2007

Wow… when WLTV started, I had NO idea it would go this far (and I’m starting to get the feeling that this is just the beginning.)

The first few episodes were shot with a crappy sony DVD camcorder and thrown up on our own bandwidth. Some things change, others don’t. Each day Gary still “brings the thunder”. It’s still edited in iMovie. It’s still just Gary, a camera and a camera operator (Chris took over for me a WHILE ago!)

I’m thrilled that I’m a part of WLTV, and so proud of G! (I just wish he’d stop Twittering every 10 seconds ;).)

Your first few days on RubyCocoa

Sunday, May 27th, 2007

I’ve been playing with RubyCocoa lately and really enjoying how easy it is to create OS X GUI apps with just a few lines of Ruby. After playing with this stuff for the past few days, I’m even more excited about Apple’s inclusion of Ruby for Cocoa Development officialy in Leopard.

This post will walk you through the first steps into the RubyCocoa world (frankly, I’m not much beyond the first steps myself!). Before we get to the codin’ let’s get everything set up.

Step 1: Get your Ruby Ready RubyCocoa requires the --enabled-shared configure flag (”build a shared library for Ruby.”) to work from the command line. I’m going to assume that if you’re reading this (and following along), you’re not using OS X’s default Ruby binary (1.8.2). I’m going to also assume you have the ruby source tree somewhere on your harddrive (~/src maybe?). If you have a different setup, adjust accordingly. Go into your source tree and re-configure with your previous ./configure command (which can be found at the top of config.log) while adding –enable-shared to it. Here’s how mine looked:


  ./configure --prefix=/usr/local --enable-pthread --with-readline-dir=/usr/local --enable-shared

When that’s all done, run make followed by sudo make install.

Step 2: Install RubyCocoa
Since your Ruby is in a different location than the OS X default (/usr/local/bin instead of /usr/bin), you need to compile RubyCocoa from source instead of using the binary release. Fetch the latest RubyCocoa version from source forge (0.11.0 as of this writing - 2007-05-28), or grab it from the RubyCocoa SVN.

Then configure, compile and install RubyCocoa:


  $ ruby install.rb config
  $ ruby install.rb setup
  $ sudo ruby install.rb install

Step 3: Install the newcocoa gem
Jumping head-first into the world of Xcode (and away from my beloved TextMate) was a bit too much for me. Justin Palmer’s pointer to newcocoa was the final piece I needed to really get into RubyCocoa. Get it like you would any other gem:

sudo gem install newcocoa

With all that out of the way, let’s get started with our first little app.

I made a short screencast of myself making this app.

Create the project with the newcocoa command

newcocoa HelloWorld

Edit the Rakefile. By default the Rakefile generated with newcocoa has targets to ppc and intel. I haven’t figured out how to make a universal binary yet, but for now remove the -arch (ppc in my case, this was made on a MacBook) line you don’t have.


  cd HelloWorld
  mate Rakefile

Edit the .nib with Interface Builder


  open English.lproj/Main.nib

Subclass NSObject to create your controller
Subclass NSobject

Name the new Class “Controller”

Right-click on the newly created controller and instantiate it
Instantiate Controller
This gives you a cool icon in the “Instances” tab.

Add a button and text control to your window
Drag Button
(The text control is the same method - on the Cocoa-Text tab drag a “System Font Text” over to your window)
Double click your new button and change the text to “Hello World”. Then double click your text control and remove all the text.

Add 2 outlets and 1 action to your controller. Open the inspector window ( ⌘ ⇧ I) and select the connections page (⌘ 2). Double click the instance of your controller in the Main.nib floating window (it should be a blue cube). Under actions hit Add and type “sayHello:”. Then in the Outlets page add “helloButton” and “textString”.
Outlets

Link the controller’s outlets and action to the window
Linking Actions and Outlets
While holding down control, click on the Controller instance (blue cube) and drag up to your button. Then double click the “helloButton” outlet. Repeat for the text field (and double click textString). Then, while holding control, click on the Hello Button and drag down to your Controller instance. Now double click sayHello: under actions. This is how you define the connections between an interface (the VIEW) and an instance (the CONTROLLER). (Sidebar: Where are models? We’re not that far yet!)

Save your nib and go back to your terminal

run newcocoa -c
This command inspects your NIB files for subclasses and linked actions/outlets and creates skeleton files for them. Since you named your controller as “Controller”, you now have Controller.rb in your project directory.

Edit Controller.rb
Here is where the bulk of your code will go (or in this project, all of it). You have access to the full Ruby / Cocoa bridge, which has most (all?) of the cocoa API methods available. The only code you’ll be adding is:


@textString.setStringValue("HelloWorld")

inside of def sayHello. Pretty cool huh?

Run Rake. Click your button. Rejoice.

That’s it!

I like to clean up the generated controller file like so:

require 'osx/cocoa'
include OSX

class Controller < NSObject
  ib_outlets :helloButton, :textLine

  def sayHello(sender)
    @textLine.setStringValue("Hello, world!")
  end

  def awakeFromNib
  end
end

`rake` if $0 == __FILE__

The last line let’s me hit ⌘ R inside of textmate to launch my project -Agile!


Extra Credit.
Subclass NSWindow (call it MyWindow) and then set your windows “Custom Class” to “MyWindow”. Run newcocoa -c again (it skips Controller.rb this time) you’ll now have MyWindow.rb. Putting the following code in there will implement an “edge-snapping” effect.

require 'osx/cocoa'
include OSX

class MyWindow < NSWindow
  def awakeFromNib
    @moving = false

    NSNotificationCenter.defaultCenter.addObserver_selector_name_object(
      self,
      :window_moved,
      "NSWindowDidMoveNotification",
      self
    )
  end

  def window_moved(notification)
    unless @moving
      @moving = true

      pillow = 10 # how far from the edge before the "snap"

      # 0,0 in os x is the LOWER LEFT corner, not the upper left.

      # set up the objects to grab from
      origin = self.frame.origin
      window = self.frame.size
      screen = self.screen.frame.size

      # the ideals (set the allowances for messed up windows here)
      ideal_left = 0
      ideal_bottom = 0
      ideal_top = screen.height
      ideal_right = screen.width

      # current x and y
      x, y = origin.x, origin.y

      # current edges
      top     = origin.y + window.height
      right   = origin.x + window.width
      bottom  = origin.y
      left    = origin.x

      # the snapping code - set the paddings here
      x = ideal_left                    if ((ideal_left - 100)..(ideal_left + pillow)).include?(left)
      y = ideal_top - window.height     if ((ideal_top - pillow)..(ideal_top + 100)).include?(top)
      x = ideal_right - window.width    if ((ideal_right - pillow)..(ideal_right + 100)).include?(right)
      y = ideal_bottom                  if ((ideal_bottom - 100)..(ideal_bottom + pillow)).include?(bottom)

      setFrameOrigin(NSPoint.new(x, y)) if (x != origin.x or y != origin.y)

      @moving = false
    end
  end
end

`rake` if $0 == __FILE__

Fun with active_record and sqlite3

Friday, April 20th, 2007

Active Record, the ORM layer in the Rails cake (and camping, and Merb, etc) is strong magic.

Before stumbling on this trick, I would create new rails projects for every little thing I needed to figure out. Running
rails test_proj -d sqlite3
is just so easy!

Yesterday, I needed to figure out a way to have a search term provide alternates (”dog” might have “puppy”, “hound”, etc.) After thinking about it for a few minutes, I decided I needed to figure out how to play with ActiveRecord without a full rails project. Here it is: ar_playground

[source:ruby]
#!/usr/bin/env ruby

%w|rubygems active_record irb|.each {|lib| require lib}

ActiveRecord::Base.establish_connection(
:adapter => “sqlite3″,
:database => “test.db”
)

ActiveRecord::Schema.define do
create_table :fruits, :force => true do |t|
t.column :name, :string
end
end

class Fruit < ActiveRecord::Base
validates_presence_of :name
end

Fruit.create(:name => “apple”)

IRB.start if __FILE__ == $0
[/source]

This will create a sqlite3 database in the directory where it’s run, and drop you into an IRB shell with all the Classes available for playing.

If you have trouble with sqlite3, you can use mysql, or get sqlite3 running by checking out:
SQLite3 announcement on Jamis’ blog

If you’re curious what I came up with for my problem, here’s the pastie.

Peglist - my first real camping project

Wednesday, April 11th, 2007

Update: I forgot to link to the repos! Here it is:
http://opus.winelibrary.com/peglist/trunk/.
There is a key for a popular photosharing site in there (rhymes with ticker), please don’t abuse it.

Camping, a ruby “micro-framework” is really a lot of fun once you get into it. It has sessions, ActiveRecord, MVC and a few other niceties that are great for “quick” things that don’t need to be full Rails projects.

So, in my spare time I’ve been playing with rewriting a php tool I wrote a while back for helping me memorize my Peg list. I made it for a few reasons: To play with Camping again, to work on my design skills, and make my old system much more usable.

Peg list by Meta | ateM.

    I wanted anyone to be able to play with the tool, I’ve added a few features that should allow anyone to jump right in, even if they have no interest in memory pegs:

  1. OpenID Logins
    These were pretty easy to get working in Camping. Even so, I’d like to make (or have) a plugin for Camping that would let me drop in OpenID auth anywhere.
  2. an “I’m too lazy for this. Do it for me.” button
    I figured that most people I showed this too wouldn’t really care about pegs. What better way then to pre-populate pegs for those people?
  3. Avatars from Flickr and Twitter
    Why bother writing an image uploader / cropper when I can just take a username and grab an existing avatar? I could add other services easily (like gravatar) and I might do that one day!
  4. Flickr API integration
    This is one of the few things my old tool did have. I’ve expanded it and made searching for an image easier and slicker.
  5. A Favicon!
    I always forget to make favicons. Thanks to Dan at Simplebits (from a recent set of slides he put up), I decided that this project HAD to have a favicon. It wasn’t hard, and ads a bit of polish to the site.