Recently in rails Category

Mortimer Password Manager, Redesigned (v1.2)

Mortimer, our multi-user, Rails-based password manager, has received a complete, front-end redesign along with multiple bug fixes and security improvements. Here are some screenshots of the latest release:

mortimer-login.png

mortimer-passwords.png

Comparing this to the original application's design, you'll see huge improvements in usability and aesthetics. Many thanks to Devin Ikram for the novel design work and to Ashley Cross, Skottey Forden, and Tom Rosario for the solid, cross-browser, front-end implementation.

Enjoy this latest release of Mortimer. If you'd like to participate in Mortimer's development, don't hesitate to fork us on Github.



Labels: , ,

Tip: Using Procs with Thoughtbot's Paperclip

Thoughtbot's Paperclip allows easy and reliable management of attachments. Using it is as simple as adding a few columns to your model and invoking the has_attached_file class method with the desired options.

One of Paperclip's as-yet-undocumented features is the option to pass an anonymous function to the :url, :path, and :styles parameters of the has_attached_file class method.

In the example below, a Product has many ProductImages. No problem, except that I might not want every product image to have the same style attributes (e.g., a product could have a header image of '200x400' and a main image of '300x300'). Certainly one way to handle this would be to create a distinct class for each type of product image (HeaderProductImage, MainProductImage, etc.).

But another, and perhaps more interesting solution, is to pass an anonymous function to the :styles parameter. That function can then return a customized style attribute for any kind of image:




class Product < ActiveRecord::Base

has_many :images, :class_name => "ProductImage"

end

class ProductImage < ActiveRecord::Base

belongs_to :product

has_attached_file :image,
:storage => :filesystem,
:path => ":rails_root/public/images/products/:attachment/:id/:style/:basename.:extension",
:url => "/images/products/:attachment/:id/:style/:basename.:extension",

# Because the :styles key can take a Proc object as an argument, we can specify the image
# styles dynamically based on the image's label.
:styles => Proc.new {|this|
defionition = ProductImageDefinitions.detect {|spec| spec[:label] == this.instance.label}
definition[:styles].merge(:thumb => '200x200>')
}

end


When Paperclip processes the attachment, it passes itself to the anonymous function. The model can then be accessed by calling the #instance attribute on the passed-in reference (see above).

The ProductImage class defines a #label attribute. The label acts as a key to a hash, ProductImageDefinitions, which specifies styles for various kinds of product images (you might define this somewhere in config/initializers).




ProductImagesDefinitions = {
'main' => {:styles => {:large => "1200x600!", :medium => "600x300!"},

'header' => {:styles => {:large => "400x600!", :medium => "200x300!"}
}


This allows for a high level of flexibility since adding a new kind of product image is simply a matter of modifying the ProductImageDefinitions hash. For a nice interface, you might write a module like this one to allow for the following manipulation of product images:




# Create product images.
@product.product_images.create(:label => 'main', :image => # Attachment object)
@product.product_images.create(:label => 'header', :image => # Attachment object)

# Access product images.
@product.available_images('main')
@product.available_images('header')


Not bad, right? The same kind of on-the-fly configuration can be applied to the :url and :path parameters. Thus does Paperclip's support for anonymous functions enhance an already superb library.

For the record, I myself am still on the fence about whether this application of anonymous functions can be considered a good practice in terms of readability and maintainability.

But from the perspective of the sheer fun and practicality of the functional paradigm in Ruby, I'm going to consider it a worthwhile excursion.



Labels: , , ,

Ruby Did My Taxes

Over the weekend, like many Americans, I did my taxes. I'm required to file a couple of different Schedule C's for various side-businesses I have, and when it comes time to hunt for deductions, it sure is nice to be a programmer.

I had initially thought that I would be able to download the entire year's bank transactions into a CSV file, but alas, my bank (and many others, I'm finding) only provide 45 days of history. They do, however, allow you to download PDF files of all of your statements, and so there I was staring at thousands of transactions in PDFs, dreading retyping them into Excel.

Enter my skills as a Rubyist. I sought out the PDF::Reader library, which allows you to hook its parsing engine to a custom callback and do what you want with it. This definitely parsed the PDF fine, but I had no context; no idea where I was in my statement, because there's no callback for a "new line" character - it's just a stream of words. I found that if I used Adobe Acrobat to save the files as text-accessible, then I started to have statements I was able to work with.

Now that I had 'lines', I was able to use the power of regular expressions to get the data I needed. The lines I was interested in started with a date and an amount, and the rest was just description for my transaction.

Here's the warts-and-all code I used to compile the year's worth of spreadsheet data. It's truly "quick-and-dirty", but it saved me tons of time. The next step, of course, would be to implement regular expressions against the 'memo' field of these transactions, and pre-suppose categories and deductions based on these patterns. But then again, maybe it's time to just use Quicken and stop waiting until the last minute.



Labels: , ,

Mortimer: A Rails Password Manager

Today we release mortimer, our Rails-based password management application. The goal was to produce a secure, multi-user password vault providing basic user permissions and a simple interface. Here's a screenshot from the current app:

mortimer.png


Public-key Cryptography

mortimer secures password using public-key cryptography. Each user on the system has a unique key pair. When you create a password entry, mortimer stores a uniquely-encrypted version of that password entry for each user with access to that password. This ensures that any time a password changes, all users have access to the change, with no compromise in security. And since all private keys are symmetrically encrypted with the user's password, even a compromised database is fairly useless.


Precautions

Many would still argue that "web application" and "password manager" are mutually exclusive terms. It depends. We recommend, at minimum the following:
  • Do not expose mortimer to the public internet.
  • Run it over SSL (this is, in fact, required).
  • Use strong passwords, and limit access to the production environment.

A work in progress

mortimer should be considered alpha as it will remain under active development. Expect improvement to the UI, along with security tweaks and cross-browser compatibility. Let us know if you find it useful.


Contributions are welcome. Clone or fork us on GitHub.



Labels: , ,

Wither Windows?

So quite recently, the Ruby on Rails open source web framework announced that they would be migrating from the Subversion code repository they had to a new one managed by Git.  Git is a version control system created by Linus Torvalds to manage the Linux kernel.  Linus had several requirements in mind when he made Git, requirements that involved specific sets of features, scaleability, stability etc.


As might be expected from the creator of the Linux kernel, none of these requirements included running well on Windows.

Git does technically run on Windows, but its kind of a hack, and Redmond's favorite platform is definitely treated like a second class citizen (ooh... irony...).  So naturally when Rails moved to Git, there was a number of Windows users who were concerned they were being left behind.  Interestingly, the Rails maintainers responded that amongst the core developers of Ruby on Rails, Windows users were a small minority.

So then, in this other piece I was reading (I need to see at least two things before I declare an Official Trend) John Dvorak rips on Dell, claiming they're stuck in a 90's mentality.  In the article, he says Dell isn't keeping up and startups in Silicon Valley these days tend to use laptops, and many many of these laptops are Macs.

Even Senator Schmelkin, a long time Windows guy, switched completely over to a Mac a couple of months ago (I tried to get him to blog it...sorry, no luck...).

Okay - I knew Apple was getting a boost from the whole  iPod thing, but I never expected to see quite this level of momentum (and yes, yes...I'm sure in the accounting and parking facility businesses Windows still has 18456% market share...).  There seems to be an accelerating trend, especially in the software and web world where not only is it more desirable to work on a Mac, but its beginning to look like people are beginning to take the position that Windows doesn't matter.  It's like it's deprecated.

(Disclosure - I was a Mac guy from before it was cool, except for a span of about 5 years that I spent trying to install Linux on a laptop).

The Rails guys do tend to be a bit religious at times - "my way or the highway".  But I do find the basis for their switch interesting.  The lack of first-class support for Windows was simply not a consideration.  Has the world finally changed?  Is the wicked witch finally dead?



Labels: , , , ,