Hamza Khan-Cheema

Freelance Ruby on Rails Developer

 

Blog
Web-Dev - A story of just another web developer

subscribe to RSS feed

22
Mar
2010

Generate a Barcode in Ruby with Barby and a small extension

For an inventory application I am currently developing, I needed a way to generate a barcode for products that were input into the system.

Fortunately Tore Darell has developed a super simple barcode library named Barby

Barby generated the barcodes perfectly. I choose to use the RMagick outputter, as I already had that set up on my system.

Simple Example using the RMagick Outputter

require 'rubygems'
require 'barby'
require 'barby/outputter/rmagick_outputter'

barcode = Barby::Code128B.new('Barcode Code Here')
File.open('code128B.png', 'w'){|f|
  f.write barcode.to_png
}

Produces

See the Barby documentation for the different barcodes that are currently supported. The above example uses 128 with type B. (I don’t really understand all the different types of barcodes yet).


Extension

The above image is fine, but I needed to also output the code that was input underneath the barcode. The reason for this is so a human can recognise the codes without getting the barcode scanner out.

So I wrote this very quick extension to the Rmagic Outputter. It basically uses Rmagic to extend the canvas by 10 px in height and outputs the code at the bottom

Here is the extension with example usage at the bottom:


require 'rubygems'
require 'barby'
require 'barby/outputter/rmagick_outputter'

module Barby
  class CustomRmagickOutputter < RmagickOutputter
    register :to_image_with_data
    def to_image_with_data
      #Make canvas  bigger
      canvas = Magick::ImageList.new
      canvas.new_image(full_width , full_height + 10)
      canvas << to_image
      canvas = canvas.flatten_images
      #Make the text
      text = Magick::Draw.new
      text.font_family = 'helvetica'
      text.pointsize = 14
      text.gravity = Magick::SouthGravity
      text.annotate(canvas , 0,0,0,0, barcode.data)
      canvas
    end
  end
end

barcode = Barby::Code128B.new('Barcode Code Here')
barcode.to_image_with_data.write('barcode_2.png')

This outputs:

As you can see the code is on the bottom which is what I needed. I hope this has helped someone. I would love to hear your comments.

You might also have noticed I have removed all the spam comments and am now using Disqus

Hamza


Comments

04
Apr
2009

Local Assets - Dead Simple Blog


I am still in the process of making my simple blog engine opensource. I just need to sort out some fundamental issues. One of these issues is how to address the storage of external assets, mainly images.

While I was working at openDemocracy and developing the new version of the site, we took the decision to move all images to our pro flickr account. We used the automated thumbnail system to display the image on the homepage and then to display the bigger image in the actual article.

Together with caching this process worked very well and saved on bandwidth and hard drive space. We did not have to thumbnail the images manually, we did not have to upload the images while publishing articles. All we needed was the flickr image ID and the system would automatically look up the image. All the image managment and orginisation was managed by flickr’s excellent interface.

While developing this current blog engine I am thinking that I will use a similar technique to manage external assets. If this is done the blog interface can be quite minimal. After all I am trying to go for a no thrills simple blog engine. Mephisto handled assets in a nice way. But what if they did not have to? I am sure the interface would be less cluttered.

In my effort to make things minimal, I do not want to remove functionality which people have come to expect from any blogging platform. Pushing things to external services seems like a good option to me. I am also looking into using an external service for managing comments and discussions. That will allow me to remove all of the comment functionality from my code.

I am going to try and take this as far as I can, just because I want to see where it gets and what kind of minimal but functional interface can be built.

Any thoughts?

Comments

20
Feb
2009

Git and Linux group access

For a recent project I had to setup a remote Git repository that was going to be used by multiple contributors. I had a few issues with permissions that I had to work thorough, so I thought I would make a note of them in case anyone else has similar issues.

I first created a new Linux user for the project and then created a bare Git repository by following these instructions in the new users home directory. For examples sake lets say that the new git repository is owned by the work user with the work group.

I then created new user accounts for each of the developers. This would allow them to have ssh access to the box and commit to the repository.

I then added each new user to the work group by using the following command:

usermod -G [group_name] [user_name]

So I thought that was that, but then I came across a few problems and found out that I also needed to change the default group of the new developer accounts I created. This would enable the user to maintain the correct group ownership when they change the repository (through git pull for example). In our example it will make/update files with the group work

To do this I did:

newgrp [group_name]

To verify the default user group just type in this command whilst logged in as the user.

id

The first gid should be set to the new group. Or you could just create a file and have a look at the group ownership.

I also found out that I need to add the following line into my config file under my remote git repository

sharedrepository = 1

It all seems to be working correctly. Multiple people can commit to the repository and they can do git pulls on the server maintaining correct group permissions.

References:


Image from : silversprite

Comments

26
Jan
2009

RSpec - RJS redirect (page.redirect_to)

Recently I wanted to use RSpec to test if a javascript request to my controller was being redirect to the correct place. I was using page.redirect like so:


render :update do |page|
    page.redirect_to edit_my_account_cropping_url(resource.id)
end

I could not just use the standard response.should redirect to() because the response was actually rendering html that was outputting a javascript redirect.

In the end it turned out that it was quite simple. Here is the code:

it "should redirect to cropping controller" do
    do_put # (not shown)
    response.body.should =~ /#{my_account_cropping_url(@traveller)}/
end

Basically the do_put is a method call that I have defined which issues a put request. The response has a body element that issues a javascript redirect. We then check to see if the expected url is included in the body. If it is we can assume that the redirect is working.

Let me know if there is a better way of doing this. I don’t have any issues with the above implementation though.

Picture taken from getdown

Comments

31
Dec
2008

Linode Ruby on Rails Setup Script

As I stated in my previous post I have just launched the redesign/redevelopment of my site.

Along with this change I am also using a new Virtual Machine Host called Linode I am sure you know of them from Rails Rumble as they provided the VPS for the competitors. One of my friends recommended them to me last summer.

I have to say that I am very impressed with them so far. I have been on a lot of VPS solutions and this is one of the fastest I have used and above all the price can’t be beaten!

However before I deployed the new site, I had to install Ruby on Rails and all that goes along with it.

I made a shell script that automated the entire set up process including installing Passenger and the required libraries.

To start off, I opted to install Ubuntu 8.10 as my operating system of choice using the nifty interface provided by Linode.

After that I went about setting up the box, doing a bunch of apt-gets and a few wgets. So I thought that I would put all this set up into a bash shell script, just in case I had to do it again in the future or that it might help anyone else who needed a RoR quick set up.

So I went about looking at my history file and making the script. I then deleted my blank and configured vps and restored a brand new copy of Ubuntu to test if it actually worked so I could post it here with a certain degree of confidence.

So this is what the script installs:

  • Ruby Gems
  • Ruby
  • Ruby on Rails (with version switch)
  • Apache2
  • Passenger (including the passenger module)
  • Mysql 5
  • RedCloth
  • Vim
  • Git
  • haml (Because all your apps should be using this kick ass template language)

It also installs a few dependency libraries so all the above apps install.

All you have to do now is upload you app, and add a virtual host and away you go.

Passenger

I did have a few issues with passenger. For some silly reason I uploaded my app as root and tried to start Passenger. Passenger does not like this (rightfully so). If it detects that environment.rb is owned by root it bails So make sure that your app is not owned by root.

So all this talk and no link?

Here is the file

rails_linode.txt

You wil notice that I have a few variables at the top. This is if you want to change the version of Ruby Gems or Rails. I am using the 2.1 branch, so the script sets the version to that. Pretty easy to change.

Let me know if anyone has any problems or improvements.

Hamza

Comments

28
Dec
2008

New Site Launched

It has been along time since I have posted anything to this blog. Life has been hectic lately.

In my spare time I have been working on the new design for this site (using grid960 , which I highly recommend) and rolling my own simple blog system (using Rails 2) which I deployed today.

I am also pushing myself a bit more as a freelance Ruby on Rails developer, so if anyone is interested just let me know .

I wanted something a bit simpler then Mephisto . I have great respect for the platform and it does a good job. But I feel that the code is quite complex. I also feel that some of the stuff is unnecessary in the admin interface. For example if I want to change the theme, I don’t want to change it using the admin pages, I want to change the file by hand. I also do not want to use Liquid as the templating language (I know you can change that though). I also do not want to have the options to set posts to use Textile or Markdown or plain html. I feel that it should not give these options, just make a decision and stick with it . I also have a few more problems with it, but I don’t want to take away from the great job it is currently doing.

So I made a back to basics blog system (it seems to be all the rage now) called dead-simple-blog for people who know there way around a rails app. I have tried to keep the code and features as light as possible. That way anyone can change the code as they see fit.

I will be realising it soon (2-3 weeks) on github, if anyone is interested. I just need to sort out a few things first, and test it in the wild.

Hopefully this will lead to more blogging in the future. I sure hope so!

Hamza

Comments

05
May
2008

Attach Files Using Paperclip

I have used a number of plugins to attach files to applications with Rails. These include file_upload (remember that) , acts_as_attachment and attachment_fu.

I came across a plugin called Paperclip a few months ago. It looked like the best solution I have seen to simple file attachments since file_upload and it did not rely on the memory monster that is RMagick. I said to myself the next project I work on, paperclip is the way to go.

I have recently had the opportunity to use it on a project I am working on. I have to say that I am very impressed so far, and if any of you have not used it yet, I would advise you to give it a go.

In terms of tutorials, I would highly advise that you start with this tutorial by Jim Neath. I have to say that I was a bit confused in the beginning, but this tutorial helped me on my way.

Image Permissions

As part of the project I needed to direct all requests to the image through an action, to check if the current user that is logged in has permission to see the image. I had a few issues doing this, so I thought I would share how I did that here.

Model:

class User < ActiveRecord::Base

 has_attached_file :photo, :styles => { :medium => "300x300>", :thumb =>  "100x100>" } ,
 :url => "/images/show/:id/:style/",
 :path => "#{RAILS_ROOT}/attachments/:class/:id/:style/:basename.:extension"

 end

I removed all the files from the public directory. That way I was sure that no one can get access to it. That is where the :path => Hash is used. I stored the images in a folder called ‘attachments’ contained within the Rails root folder Here is a list of what the url params are used for:

  • class — This is the name of the class the attachment is associated to. In this case User
  • id — This is the unique ID of the model the attachment is associated to.
  • style — The name of the style. In this case we would have a folder called ‘thumb’ and a folder called ‘medium’ and also a folder called ‘original’
  • basename — The file name without the file extension
  • extension — Filename extension

For some reason I could not get the :url hash to work when I used url placeholders. It just did not seem to want to pass on the parameters to my controller. So the only option I had was to create the url using the good old fashioned way.

The :url hash is directing all image requests to the images controller, making sure to pass all the relevant parameters along with it.

Next I am going to detail the very simple controller :

class ImagesController < ApplicationController

  def show
    if logged_in? && current_user.allowed_to_view_image?(params[:id])
      send_file(current_user.photo.path(params[:style]) , :disposition => 'inline')
    else
      '#'
    end    
  end 
end

As you can see it is very simple. All requests are passed to the show action. The first thing it does is check to see if the user is allowed to see the image using a method called on the User object (I have not detailed it here as it will be different for everybody).

Once permission has been granted simply display an inline send_file request with the same directory structure as defined in the :path url.

Linking

As I am not using Rails 2 for this project, I came across a problem with using image_tag as it saw fit to append a .png to the request. I am not sure how to turn this off and I know it has been ‘fixed’ in Rails 2. My only current solution is to use the old school “img” tag in my views.

Let me know your thoughts

UPDATE

As you can see from Jon Yurek’s (creator of this plugin) comment, the old way I was doing it was not necessary. So I have updated the code to reflect those changes and tested it. However if you do this, you will also have to add an extra Route to your config. Here is the one I added :

map.connect '/images/:action/:id/:style' , :controller => 'images'

Thanks Jon!

Hamza

Comments

26
Dec
2007

Arabibay and Responds to parent error

I know it has been a very very long time since I last posted. Quite a few things have been happening in my life the past 4 months. But I will not bore you with the details :)

I have been working on a few sites lately. The latest project which has just been made live is Arabibay.com

Arabibay is a free classifieds website that allows people to post adverts around the world. As you can tell by the title, it is aimed at the Middle East, but all countries are supported. Check it out and leave some feedback, as always your comments are greatly appreciated.

Responds To Parent

As I can’t post without mentioning something technical (however insignificant). For this project I needed to allow users the ability to upload images to the system via AJAX. I came across this very good tutorial and a really useful plugin called Responds to Parent .

However I had a few issues setting up the plugin. I installed the plugin like so


  script/plugin install http://responds-to-parent.googlecode.com/svn/trunk/ 

It installed it into a folder called trunk, so immediately I changed the folder name to responds-to-parent. So far so good.

I then tried to restart the app but the app failed to start with this plugin installed. So I looked around on the net for the error I was getting, but nothing came about.

To cut a long story short, I needed to rename the folder to responds_to_parent as in the init.rb, it is obviously requiring RespondsToParent, which assumes responds_to_parent.

Hopefully this can save someone some time :)

Future Posts

I know that I have said this before, but now that I have settled down a bit, I am hoping to blog on a more regular basis.

Hamza

Comments

18
May
2007

attachment_fu Thumbnail Size

As I mentioned earlier, when working with attachment_fu and image science the width and height of thumbnails were not being set correctly. So here is a method that I use to make sure that the data is set.



def set_image_dimensions
  if @image.width.blank? || @image.height.blank?
    ImageScience.with_image("#{RAILS_ROOT}/public/" << @image.public_filename) do |img|
      @image.height = img.height
      @image.width = img.width
    end
    @image.update_attribute('height',@image.height)
    @image.update_attribute('width',@image.width)
  end
end

Is anyone doing it differently ? Has this been addressed ?

Comments welcome.

Hamza

Comments

12
May
2007

Fun with attachment_fu

As I mentioned in my previous post I am going to outline my experiences with attachment_fu. I will try to extend the brilliant tutorial that first introduced me to attachment_fu and to ImageScience.

The problem

The simple problem I had was that I wanted to be able to associate a image (and thumbnails) to a article. Although this sounds easy, I had some trouble along the way (hence the post).

Write the Migration models



class CreateImages < ActiveRecord::Migration
  
  def self.up
    create_table :images do |t|
      t.column :parent_id,  :integer
      t.column :content_type, :string
      t.column :filename, :string    
      t.column :thumbnail, :string 
      t.column :size, :integer
      t.column :width, :integer
      t.column :height, :integer
      t.column :content_id, :integer
    end
  end

  def self.down
    drop_table :images
  end
end

class CreateContents < ActiveRecord::Migration
  
  def self.up
    create_table :contents do |t|
      t.column :title , :string
      t.column :summary, :text
      t.column :body, :text
      t.column :status, :string
    end
  end

  def self.down
    drop_table :contents
  end
end

The only thing to note here is that I have placed a content_id foreign key into the image table, to allow them to be linked.

Write the models

The models are going to have two different associations, both of type has_one. The first association has an extra condition that allows it to only return the parent image, the second association returns the parent image and all its associated thumbnails.


class Content < ActiveRecord::Base
  has_one :image, :conditions => 'parent_id is null'
  has_one :all_images, :class_name => 'Image' # all photos + thumbnails
end

The Image model has the standard attachment_fu declaration along side the thumbnail declarations.


class Image < ActiveRecord::Base
  has_attachment :content_type => :image, 
                   :storage => :file_system,
                   :thumbnails => { :thumb => '107x76>'}    
end

Write the form view


<% form_for(:content, :url => { :action=>'create'}, 
                      :html => { :multipart => true }) do |f| -%>

<p>
  <label for="title">Title</label><br/>
  <%= f.text_field :title %>
</p>

<p>
  <label for="summary">Summary</label><br/>
  <%= f.text_area :summary %>
</p>

<p>
  <label for="title">Body</label><br/>
  <%= f.text_area :body %>
</p>

 <p>
    <label for="image">Associate Image:</label><br/>
    <%= file_field 'image','uploaded_data' %>
  </p>
  <p>
    <%= submit_tag 'Create' %>
  </p>
<% end -%>

As you can see I have placed the image in a different hash, as you can’t associate the file directly to the model. All of the other fields are pretty standard. To test out the update method you just need to change the URL to point to the update method and pass it the content id. I will leave it out here for simplicity.

Write the controller

This is where I was having most trouble. No matter what I did, it just did not save the dam thing. So here is my create and update actions in my contents controller


def create
    #Create the content
    @content = Content.new(params[:content])
    respond_to do |format|
      if @content.save
        #Here comes the important bit!
        if !params[:image][:uploaded_data].blank?
          @content.image = Image.create(params[:image])       
        end
        flash[:notice] = 'Content was successfully created.'
        format.html { redirect_to :action=>'show', :id=>@content }
      else
        format.html { render :action => "new" }
      end
    end
  end  

OK that was not that hard :). But I was having problems on the update action. The create action seemed to be working fine. Here is the update action.


  def update
      @content = Content.find(params[:id])
      respond_to do |format|
        if @content.update_attributes(params[:content])
          # Heres the important bit!
          if !params[:image][:uploaded_data].blank?
            #find current image
            @image = @content.image ||= Image.new
            @image = @content.image.build(params[:image])
            @image.save       
          end
          format.html { redirect_to :action=>'show', :id=>@content }
        else
          format.html { render :action => "edit" }
        end
      end
    end
 

As you can see I am using the build method to create the image. I am not sure why, but If I put the build method into the create method it just fails. Oh yeah and in a real application I would group the image methods into their own respective functions.

The content view

So for all the code we have written we can now show the images that are associated with a specific article.


  <h2><%=@content.title%> </h2>
  <p><%=@content.summary%></p>

<%if !@content.image.blank?%> 
  <p>
    Original Image : <%=image_tag @content.image.public_filename %>
  </p>
  <p>
    Thumbnail : <%=image_tag @content.image.public_filename(:thumb) %>
  </p>
  <p>
    <%=@content.body%>
  </p>
<%end%>

Outstanding issues

There a few bugs in attachment_fu that I came across, they are :

  • The width and the height are not being set for thumbnails when I use ImageScience and attachment_fu.
  • The size (in the database field) of the thumbnails are not correct. They just display the original file’s image size.

I will blog again regarding these issues in the near future.

Code

In writing this post, I made a test rails app so I could make sure that the code I have above is correct and compiles without any errors. If anyone wants this I can put a link to it here, just leave a comment.

As usual all comments welcome.

Hamza

Comments

Previous Posts