Highrise API and tagging 2

Posted by Colin A. Bartlett Mon, 18 Feb 2008 18:28:00 GMT

Like many, I was disappointed that the Highrise API does not support tagging of people. However, I found a way to easily add the capability to the 37signals-supplied Ruby wrapper class, even if it is unsupported. I added a #tag! instance method to the Person class and used a call directly to the site, not through the API.

class Person < Subject
  ...
  def tag!(tag_name)
    `curl -s -d 'name=#{tag_name}' #{ENV['HIGHRISE_URL']}parties/#{id}/tags`
  end
end

The output is a bunch of javascript to update the page to reflect the change, but one can safely ignore this. The tag is added and everything works great. Not sure how well this would work on Windows, as the curl command-line program is likely unavailable.

We use this method in our latest project to add appropriate tags to people as they are created. It helps us segment people added to Highrise for the project from the rest of our contacts in Highrise.

Capistrano Twitter task, take 2 2

Posted by Colin A. Bartlett Sat, 16 Feb 2008 16:17:00 GMT

In my original post, I explained how I used the twitter4r gem to post when we deployed an app with capistrano. Chris Matthieu posted a comment about how to do it without the twitter4r gem. I actually like this better, especially after we started having trouble with the twitter4t gem. So, here’s his version that I adapted slightly:

desc 'posts to twitter that an application has been deployed to a web server'
task :send_tweet do
  require 'open-uri'
  require 'net/http'

  url = URI.parse('http://twitter.com/statuses/update.xml')
  req = Net::HTTP::Post.new(url.path)
  req.basic_auth 'your_username' + ":" + 'your_password', ''
  req.set_form_data({'status' => "Deployed #{application} to #{rails_env}"})
  res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
end

Thanks, Chris!

The trouble with services, part 2 7

Posted by Colin A. Bartlett Fri, 15 Feb 2008 14:45:00 GMT

In our last installment, during a Basecamp outage, I concluded that occasional service interruptions didn’t dissuade me from using hosted services. I’d rather have someone else running around working to fix the problem then me.

In today’s installment all of Amazon web services are in-operational.

That means all of Web 2.5, as Justin calls it, is down for the count. I first noticed this on WIRE. After I got over the initial panic of not being able to see a picture of Randy’s Cherios cereal bar, I realized Basecamp, Twitter, and a ton more all depend on Amazon.

This brings us back to the debate over hosted services. And I think there’s one component I missed last time: the number cogs in a wheel. It seems like having services that depend on services that depend on services can bring in additional complexity. So now, not only does using Basecamp require all their servers to be running but it also requires the Amazon servers to be running.

We have debated using Amazon S3 and EC2 here on a few projects recently. Andy asked me straight up not two weeks ago how much I trusted Amazon for reliability. I replied: “100%. They’re Amazon.” I suppose I should have remembered that being a big ass corporation doesn’t make them exempt from downtime. And if one truly needs 100% uptime, one needs to use multiple services with redundant backups. That’s what we all thought we were getting with Amazon web services. I guess not.

Starting to Get Thin, v0.6.3 6

Posted by Justin Reagor Wed, 13 Feb 2008 03:16:00 GMT

When I first heard about Thin I was slightly intrigued, but less enthusiastic when I attempted to run it (not sure what version). Anyway, now that Thin has matured a bit more, and Merb 0.9 is bringing the love of Rack to the masses… I’m really really really starting to see what all the fuss is about. 3000+ requests a second of fuss.

The Skinny

Thin is actually a mash-up of current back-end web serving technologies.

  1. the Mongrel parser, I’m speculating its the Ragel executable state machine portion
  2. Event Machine, and the tough, concurrent service request handling of the Reactor Pattern
  3. and Rack, our new hero which brings a common web server gateway interface to all of our favorite Ruby web frameworks.

Fancy technologies (and citations), but how’s this going to help good’ole Geoffrey Grosenbach?

Installation

$ sudo gem install thin

...or if you know what your doing…

$ git clone git://github.com/macournoyer/thin.git

If not, go directly to FAIL

Show’em Some Ruby

Lets take a quick glimpse at the adapter example that is included with the gem (examples/adapter.rb).

I’ll try not to ramble on about Rack too long but… This really shows you how damn simple it can be to plug and play applications into a Rack stack, and the power that Thin brings along with its speed!

require File.dirname(__FILE__) + '/../lib/thin'

class SimpleAdapter
  def call(env)
    body = ["hello!"]
      [      200,  
        {
          'Content-Type'   => 'text/plain',
          'Content-Length' => body.join.size.to_s,
        }, body
      ]  
   end
end 

Thin::Server.start('0.0.0.0', 3000) do  

  use Rack::CommonLogger

  map '/test' do    
    run SimpleAdapter.new  
  end  

  map '/files' do    
    run Rack::File.new('.')  
  end

  run Rack::Adapter::Rails.new(:root =>/Users/justin/apps/whatsyomammabeensmokin.com‘)
end

Very briefly, this example is a thin/Thin adapter specification and server initialization. Its also an insanely small example of a Rack adapter (which may, or may not work; reference the real examples in the gem).

We can see, after loading our necessary library file, we create a class used as an adapter, called SimpleAdapter.

This holds in it a means to handle status code 200 requests. With a simple output of plain text content-type, set in its header hash. It also includes a simple body of text, “hello!” to be returned as content. Literally the Rack adapter, handling a request, need only return this sort of array as a response. [status, header, body].

Finishing up the script is Thin’s server stack initialization. Resembling a Rack config.ru configuration file, Thin initializes a server for our localhost on port 3000. As well as some middle ware setups using our SimpleAdapter.

First, inside the setup block you should quickly notice a few “map” method calls that resemble Rails routes. “map” is actually just that, a simple way to set Rack::URLMap’s, or web URI paths, inside the main server start block.

Second, the “use” method actually adds middle ware to the stack.

Finally, notice “run”. This literally dispatches middle ware logic to the server.

I’ve taken the liberty of adding a call to a local Rails application to point out how easy it is to include new applications straight into a running Rack/Thin server stack. Pretty much just as easy as it is to “include” a mix-in into a class in Ruby.

If you would like to work more closely with some real code, take a look here…

Thin Rails

Ok… woosh, back to the easy stuff…

Since Thin supports Rails natively through what I believe is an included Rack adapter… you can start playing with it right out of the box on any of your current Rails projects.

Once you have the Thin gem installed, simply do a…

$ thin start

If you’d like to explicitly set your Rails environment…

$ thin start -e development

“—help” provides more information as usual. Thin’s main site has a lovely amount of info with a beautiful web design. Be it tiny lil text (get it, thin).

You can also try out a middle ware script that comes with Thin called “stats”.

$ thin --stats=/public_thin/stats start

This will give you a technical details of your Thin server stats, map’d to “localhost:3000/public_thin/stats”.

To Deployment, and Beyond

I have yet to really attempt a deployment with Thin, but I have one coming up shortly to assist with and will definitely be trying this out.

From what I’ve read you can just as easily replace mongrel_cluster with thin like so.

# thin config -C config/thin.yml --servers 3 --port 5000 --chdir ...
# thin start -C config/thin.yml

If anyone has tried this yet please let me know how it went.

The Year 2000

Hopefully your interested now and will check into this speedy fast Mongrel replacement. Did I even mention it was fast…? >;)

In the near future I’ll attempt to report back on deployments and middle ware scripts. I’m eager to see what useful little apps I can come up with that sit between the web server and my actual Rails application. But I can imagine 8 bazillion possibilities (especially logging and transparent statistics harvesting).

So yeah… cheers to the author!!

Capistrano Twitter task 1

Posted by Colin A. Bartlett Sun, 10 Feb 2008 15:37:00 GMT

Justin had an idea that we should post to Twitter whenever we deploy a new version of our apps to either a staging site or the production app. Turns out, this is really easy with the twitter4r gem. I used a twitter account that Justin created expressly for our internal notices and set its updates to be private. Then I created this task:

desc 'posts to twitter that something was deployed'
task :send_tweet do
  require 'rubygems'
  gem 'twitter4r'
  require 'twitter'
  require 'twitter/console'
  twitter = Twitter::Client.from_config('config/twitter.yml',rails_env)
  status = twitter.status(:post, "deployed #{application} to #{rails_env}")
end

The twitter4r library loads a simple yaml file that contains the username and password of the twitter account to use. And one line of code posts the status update with the name of the app and the environment from previously-defined variables.

That’s it! The great thing about using Twitter for this, as Justin pointed out, is that each one of us developers can consume this information how we choose: IM, Growl messages with Twitterific, SMS, etc. So it’s really just the syndication technology that we’re taking advantage of.

Update

Chris’s comment below prompted me to come up with a new version

Soar with Merb-Core and Merb-More (0.9) 5

Posted by Justin Reagor Sat, 09 Feb 2008 06:31:00 GMT

I haven’t been around in awhile, frankly because I’ve had my own things to attend to… but I’ve felt somewhat ashamed that I’ve left my kind Kinetic audience a float. So here is another “Up and Running” treat. Cloning Merb-core and -more, from Git[hub] to dummy project.

BTW, it should be any day now for the official 0.9 release. Rumors have it that Ezra will be releasing it at ActsAsConference.

Preperation

Your going to want to remove any old gems in the following list, as you will be installing trunk versions in this tutorial.

merb (< 0.9)
merb_datamapper (< 0.9)
merb_helpers (< 0.9)
datamapper (< 0.3.0)

You can go ahead and gem install the following. I’ve listed the version numbers I use currently.

sqlite3-ruby (1.2.1)
data_objects (0.2.0)
do_sqlite3 (0.2.3)
do_mysql(0.2.2)
rack (0.2.0)

Along with the regular Merb dependencies listed in the API.

# gem install mongrel json json_pure erubis mime-types rspec hpricot mocha rubigen haml markaby mailfactory Ruby2Ruby -y

Thats a lotta gems right? Well, taking a closer look you should have most of these already… and if you don’t you should.

Installing Git

You installed it already, otherwise… EPIC FAIL!

You DO have a Github account

If you have a Github account, you’ll most likely want to fork merb-core and merb-more so you have your own fork’s to mess about with. If you find anything interesting you can always submit a bug/patch and help the wonderful Merb team out! Or start building some new framework forked from Merb. Either way…

To do this, login to Github and…

http://github.com/wycats/merb-core/fork
http://github.com/wycats/merb-more/fork
http://github.com/wycats/merb-plugins/fork

You’ll then want to clone these like the next section…

You DON’T have a Github account

If you don’t have an account yet for Github you’ll still need Git installed like I noted above. From within a fresh directory in Terminal run the following commands.

# git clone git://github.com/wycats/merb-core.git
# git clone git://github.com/wycats/merb-more.git
# git clone git://github.com/wycats/merb-plugins.git

Installing these Git forks/clones

Simply enter the directories “merb-core” and “merb-more” and run…

# sudo rake install

You’ll also want to do this under “merb-plugins/merb_datamapper” and “merb-plugins/merb_helpers”. Including any others in “merb-plugins” you would like installed.

Installing Datamapper Trunk

Currently, Datamapper is still under SVN. I’m positive this will change in the near future. But for now…

# svn co http://datamapper.rubyforge.org/svn/trunk/ data_mapper

Then simply go into the data_mapper/ directory created and do…

# sudo rake install

Merb-gen is your Friend?

I’ve just recently discovered that they’ve changed, yet again, the default way of creating a new Merb project. I guess because “merb -g” or “merb” was getting annoying, so “merb-gen [projectname]” is some how much simpler. You also use this to generate models/controllers/resources/etc… :/

I’m going to take another guess and say this is somehow based on the project directory no longer needing to conform to a certain structure like Rails. I’ve heard this, but I haven’t tested it out for fact… so let me know your experiences.

Either way…

# merb-gen lovely-app

Going into Toshi Station to pick up some power converters

This is where it starts to get exciting. The fruit of our labors dance in unison to form a euphoric aura called “0.9”... not so fast though.

1. If your not already, make sure your in the “lovely-app/” project directory.

2. Open up “config/init.rb” and uncomment…

use_orm :datamapper

Rspec should be your testing framework by default.

3. Back in your shell, run…

# rake --tasks

4. This should auto-generate “config/database.sample.yml

5. Overwrite the entire thing with the following, and save as “config/database.yml”...

---
:development: &build
  :adapter: sqlite3
  :database: db/dev.db

:test:
  <<: *build
  :database: db/test.db

:production:
  :adapter: mysql
  :database: lovely_app
  :username: root
  :password: ""

6. Your going to now want to create those sqlite databases. If not both just db/dev.db.

# mkdir db/
# sqlite3 db/dev.db
SQLite version 3.5.1
Enter ".help" for instructions
sqlite> .databases
seq  name             file                                                      
---  ---------------  ----------------------------------------------------------
0    main             /Users/bionicebonics/lovely-app/db/dev.db                     
sqlite> .quit

You should be able to run a successful “rake—tasks” if you did everything correctly. You may also want to test and see if you can run the daemon, and pull up a browser window. Run “merb” by itself from Merb.root or project root directory.

In short, just start hacking! Reference the API for help, not me.

The Sugar

You should now have a base process for exploring Merb 0.9 development.

The Salt

If for some weird reason your getting errors running “merb”, make sure you removed any old versions of Merb <= 0.5.x.

Also try uninstalling merb-core and reinstalling it from a new Git clone of the main repo. I had to do this for some odd reason whilst running through this tutorial.

Shameless Kinetic/PhillyOnRails

Colin will be giving a talk on Merb at our local PhillyOnRails Users Group, so stay tuned for info on that.

Update

Gotta love Merb integrating Rack/WSGI!

Following a few discussions on the Thin webserver mailing list, I just tried Merb on Thin… this is working out excellent! I’ve also heard that Ezra just got 2200 req/sec using Thin.

If you would like to explore the possibilities of this incredibly fast setup, simply do…

# sudo gem install thin
# cd lovely-app
# merb -a thin

This will load Merb on Thin. If you don’t know about Thin, I’m not going to sit here and explain it. I’m just not like that. You’ll have to FOFY, find-out-for-yourself.

Older posts: 1 2