That Computer Won't Work

Posted by Ben Reubenstein Sun, 13 Jan 2008 20:00:00 GMT

My nephew has been saving his money to purchase a new laptop. He enjoys playing flashed based games, and is known to play RuneScape. Just recently he managed to scrap together $350.00 for the purchase. I found a laptop for exactly $350, but after closer examination found it did not include wireless. For $50 more I found a Lenovo 3000 N200 with wireless so with a little help from his Grandpa to make up the difference, we were off to the store.

Here are the specs for the box:

  • 15.4" widescreen WXGA TFT LCD display
  • Intel Celeron M 1.73GHz Processor
  • 512MB DDR2 Memory and 80GB Hard Drive
  • Windows Vista Home Basic
  • CD-RW / DVD-ROM Combo Drive
I found an employee at MicroCenter and requested to purchase the machine. He enquired if I had been told about it and I replied no, I would like to buy that machine. He informed me that it was only good for Internet and "wouldn't do pictures" since it was not very fast. I told him I was planning to ditch the Vista Home Basic for Linux. He was convinced that wouldn't work, so at that point I gave up, and told him flat out, please just get me the box. On our way out I think he told his supervisor that I was crazy, but oh well I was out the door.

Now I know this is a Windows world, so the plan is to setup a dual boot. Just starting the machine for the first time however took 20 minutes. Windows Vista had to check out the performance of the box, and slowly allow me in. Once in my nephew and I were greeted with 6 shortcuts on the desktop to products we could purchase and a ton of tiny icons already running in the task bar for various media programs and other crap.

We installed Ubuntu on the box next. This process took about 20 minutes, and it handled resizing the existing windows partition and putting the necessary GRUB entries in. It started up quickly and the only time consuming issue I had was getting the wireless card to work. After that however, we were cooking. The machine was extremely responsive compared to Windows Vista. It also included all the productivity software my nephew would need.

It is criminal that this machine is sold with Windows Vista. It is in no way capable of running it with out a significant bump in RAM. I can now understand the hesitance with which it was sold to me.

Tags ,  | 3 comments

attachment_fu Now With Local File Fu

Posted by Ben Reubenstein Fri, 04 Jan 2008 17:50:00 GMT

In the beginning there was file_column. It was an excellent plugin for handling file uploads and image processing with the added bonus of being able to simply pass a file to it and have it work without a file upload via a form. One thing that file_column didn't do was fill in your db with file attribute goodness that could be used to create logic around a particular file. attachment_fu handled this along with the ability to use multiple image processors. For detailed info on attachment_fu, check out Mike Clark's article.

In order to add some local_file_fu to attachment_fu so you can pass a local file directly to it, you have to take your local file and turn it into a temporary file that you can pass to attachment_fu's uploaded_data method. I altered the solution outlined here for my solution.

1. Create a class in your models directory in a file called local_file.rb.

require 'tempfile'
class LocalFile
 # The filename, *not* including the path, of the "uploaded" file
 attr_reader :original_filename
 # The content type of the "uploaded" file
 attr_reader :content_type

 def initialize(path)
  raise "#{path} file does not exist" unless File.exist?(path)
  content_type ||= @@image_mime_types[File.extname(path)]
  raise "Unrecognized MIME type for #{path}" unless content_type
  @content_type = content_type
  @original_filename = File.basename(path)
  @tempfile = Tempfile.new(@original_filename)
  FileUtils.copy_file(path, @tempfile.path)
 end

 def path #:nodoc:
  @tempfile.path
 end
 alias local_path path

 def method_missing(method_name, *args, &block) #:nodoc:
  @tempfile.send(method_name, *args, &block)
 end
end


2. In order for attachment_fu to pass validations, you need to set the mime type of the file. This would usually come from the form when it is uploaded, but since we are using a local file, we'll set our mime types in environment.rb. At the end of the file add the various mime types you will need:

@@image_mime_types ||= { ".gif" => "image/gif", ".ief" => "image/ief", ".jpe" => "image/jpeg", ".jpeg" => "image/jpeg", ".jpg" => "image/jpeg", ".pbm" => "image/x-portable-bitmap", ".pgm" => "image/x-portable-graymap", ".png" => "image/png", ".pnm" => "image/x-portable-anymap", ".ppm" => "image/x-portable-pixmap", ".ras" => "image/cmu-raster", ".rgb" => "image/x-rgb", ".tif" => "image/tiff", ".tiff" => "image/tiff", ".xbm" => "image/x-xbitmap", ".xpm" => "image/x-xpixmap", ".xwd" => "image/x-xwindowdump" }.freeze

3. Now in your code that creates the model that has_attachments you can simply do the following:

model = Model.new()
model.uploaded_data = LocalFile.new(FULL_PATH_TO_FILE)
model.save


As always, comment on anything you have issues with or suggestions.

Posted in  | Tags ,  | 8 comments

Taking Merb to Production

Posted by Ben Reubenstein Mon, 24 Dec 2007 15:11:00 GMT

This past week I needed to implement a small webservice that needed to be fast and work well under a heavy load. I had part of the service implemented in Rails, but it was not as fast as I thought it could be so I decided to check out Merb. Merb is a lightweight MVC framework much like Rails. Merb however doesn't try to put a lot of "magic" at its core, so overall less time is spent in the framework and more time is spent in your code.

When I jumped into Merb, there were a lot of good articles but not much on how to productionize Merb, so I hope I can fill in the gap with this article.

NOTE: I am explaining a lot here, so if you run into spots that are confusing or you think could be done more efficiently, comment and I will get those adjustments into the doc.

Setting up Capistrano (Using 2.0)
Install Capistrano:

gem install capistrano

Like Rails apps there are certain files that will change in the production environment so they should not be in your repo. The ones I chose to exclude:
config/merb.yml
config/database.yml
Your excluded files may differ depending on the ORM you chose. I setup DataMapper for this particular application, though you could install the merb_activerecord gem and plug right into ActiveRecord.

Just like in a rails app run the capify command to get rolling:

$ capify .
[add] writing `./Capfile'
[add] writing `./config/deploy.rb'
[done] capified!

Edit your config/deploy.rb to match your settings here is my example with some notes:


set :application, "YOUR_APPLICATION_NAME"

# Set the path to your version control system (Subversion assumed)
set :repository, "http://something.com/svn/yourapplication/trunk"

# Set your SVN and SSH User
set :user, "your_ssh_user"
set :svn_user, "your_svn_user"
#Set the full path to your application on the server
set :deploy_to, "/PATH/TO/YOUR/#{application}"

#Define your servers
role :app, "your.appserver.com"
role :web, "your.webserver.com"
role :db, "your.databaseserver.com", :primary => true

desc "Link in the production extras and Migrate the Database ;)"
task :after_update_code do
  run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
  run "ln -nfs #{shared_path}/config/merb.yml #{release_path}/config/merb.yml"
  run "ln -nfs #{shared_path}/log #{release_path}/log"
  #if you use ActiveRecord, migrate the DB
  #deploy.migrate
end

desc "Merb it up with"
deploy.task :restart do
  run "cd #{current_path};./script/stop_merb"
  run "cd #{current_path};env EVENT=1 merb -c 4"
# If you want to run standard mongrel use this:
# run "cd #{current_path};merb -c 4"
end

#Overwrite the default deploy.migrate as it calls:
#rake RAILS_ENV=production db:migrate
#desc "MIGRATE THE DB! ActiveRecord"
#deploy.task :migrate do
#  run "cd #{release_path}; rake db:migrate MERB_ENV=production"
#end


Use Capistrano to initiate the environment, setting up the necessary directories on the server.
$ cap deploy:setup

Next, install the Gems you need on the Production server.

Note: if you are on the gem 0.9.4 run this upgrade, 0.9.5 is super nice ;). the -y / --include-dependencies option is on by default.

sudo gem update --system

sudo gem install merb
sudo gem install rspec

# For ActiveRecord
sudo gem install merb_activerecord
# For DataMapper
sudo gem install datamapper
sudo gem install do_mysql

# For Evented Mongrel
sudo gem install swiftiply

Create the directories and files that will be linked in.

mkdir /YOURDEPLOYPATH/shared/config
touch /YOURDEPLOYPATH/shared/config/database.yml
touch /YOURDEPLOYPATH/shared/config/merb.yml

Edit the .yml files to your liking and then be sure to create your database in MySQL! There is probably some neat deploy tricks you can do here with Capistrano, comment if you know it and I will update this section.

Deploy your app:

cap deploy

Now if you are amazing, it works the first time. If not check the errors. Most of them will likely be paths or a gem you missed.

Recap: We should now have our app deployed to the server and if you used the example config, 4 instances running. Hooray!

Setting up: NGINX
General Tip: If your server is still using Apache and you are just starting to experiment, run NGINX on another port, like 81. Be sure to clear a path through your Firewall ;)

Add the appropriate ip:ports to the upstream section for the merb instances you are running. The port that merb runs on and number of instances started are controlled by the deployment script and the merb.yml file.

upstream YOURUPSTREAMNAME {
 server 127.0.0.1:4000;
 server 127.0.0.1:4001;
 server 127.0.0.1:4002;
 server 127.0.0.1:4003;
}

Next lets add in a host section. This is just like a Rails host.


server {
 listen 80;

 client_max_body_size 50M;

 server_name YOURSERVERNAME;

 root /YOURPATH/current/public;

 #Want to log? include this
 #access_log /var/log/nginx/nginx.YOURAPPNAME.access.log main;

 if (-f $document_root/system/maintenance.html) {
  rewrite ^(.*)$ /system/maintenance.html last;
  break;
 }

 location / {
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_redirect false;
  proxy_max_temp_file_size 0;
  if (-f $request_filename) {
   break;
  }
  if (-f $request_filename/index.html) {
   rewrite (.*) $1/index.html break;
  }

  if (-f $request_filename.html) {
   rewrite (.*) $1.html break;
  }

  if (!-f $request_filename) {
   proxy_pass http://YOURUPSTREAMNAME;
   break;
  }  }

 error_page 500 502 503 504 /500.html;
 location = /500.html {
  root /YOURPATH/current/public;
 }
}


Restart nginx and enjoy your new Merb application!

Thanks to the folks in #merb and #datamapper for answering questions I had. Special thanks to Ezra for creating Merb and pushing performance in the Ruby web application world.

Resources:

Tags , , ,  | 10 comments

Ruby Script to Simplify Setting up Subversion, Trac, and Apache

Posted by Ben Reubenstein Tue, 18 Dec 2007 13:35:00 GMT

I host svn and trac projects via apache on several servers. I found the task of setting them up repetitive so I set up this little script:

add_project.rb

Tags , , ,  | no comments

Crysis Engine is Nifty

Posted by Ben Reubenstein Mon, 17 Dec 2007 12:20:00 GMT

Posted in  | Tags ,  | no comments

Zero Punctuation == Good Times

Posted by Ben Reubenstein Wed, 12 Dec 2007 14:26:00 GMT

Posted in  | no comments

Zombie Crawl Oct. 20, 2007

Posted by Ben Reubenstein Fri, 05 Oct 2007 12:54:00 GMT

This is going to be fun!

Posted in  | Tags , ,  | 2 comments

Bob Dylan: No Direction, Period

Posted by Ben Reubenstein Fri, 28 Sep 2007 15:41:00 GMT

Posted in  | Tags , , ,  | no comments

iPhone Tech Talk

Posted by Ben Reubenstein Thu, 23 Aug 2007 13:35:00 GMT

I am sitting at DIA getting ready to fly out to San Francisco for the iPhone tech talk. Should be interesting to meet some other developers and get insight on the platform. I will be live txt'ing right here, so simply tune in every so often to see new pics and messages. Live feed removed now that event has ended.

Posted in  | Tags  | 1 comment

Debug Output For Migrations in Ruby on Rails

Posted by Ben Reubenstein Tue, 31 Jul 2007 13:04:00 GMT

Today I was doing some massive migrations that rocked the very foundations of an app I am working on. Problem was that during the migration I was moving objects around the database and validations were failing for my saves. To get some debugging going, I started out trying to write to the logger, with some good ol' logger.debug, but that does not work within a migration. To output information in a migration, use puts. So for example to see all the errors that prevented object g from being saved:
class MyMigration < ActiveRecord::Migration
  def self.up
    g = G.new(:name => "name" )
    if g.save
      #More object manipulation here
    else
      g.errors.each do |x|
        puts x
      end
    end
  end

  def self.down
    #Down Method Code Here
  end
end

Posted in  | Tags , , ,  | 2 comments

Older posts: 1 2 3 4 ... 13