Monday, October 11, 2010

MarkUp

Draw on any webpage. Share your ideas
Capture your thoughts quickly and easily by drawing on any webpage. Share your ideas with coworkers, colleagues, and friends. MarkUp works in your browser, so there’s nothing to download and install; just drag the Get MarkUp icon into your bookmarks bar. When you want to make notes on a webpage, click your bookmarklet to load the MarkUp toolbar. Publish when you’re ready to share your thoughts.
  • Draw on any webpage with MarkUp
  • Stay in your browser; nothing to download
  • Get MarkUp by bookmarking this icon
  • Make shapes with the Magic Marker
  • Write with the Text tool
  • Publish to share your ideas
http://markup.io/

Tuesday, October 5, 2010

Microsoft Commits Code to jQuery!

This week on Web Camps TV, Stephen Walther from the ASP.NET Team joins James Senior (@jsenior) to discuss an exciting announcement: Microsoft is about to make the first contributions to the jQuery open source project!

In the past 6 months, we've been busy working on three features:
  1. Templating
  2. Data-Linking
  3. Globalization
In this video, we show demos of the contributions in action and how/when they will be available for developers to use!

Find out more at www.jquery.com and be sure to sign up for a freeWeb Camp to learn more about the jQuery contributions.

http://channel9.msdn.com/Shows/Web+Camps+TV/Web-Camps-TV-5-Microsoft-Commits-Code-to-jQuery

Using acts_as_archive instead of soft delete

For the application I am working on right now, the ability to restore content that has been deleted is one of the requirements. A lot of people would just go ahead and add acts_as_paranoid or is_paranoid and be done with it, but I've had trouble with that approach before.
I've been reading a lot about the trouble with "soft deletes" (flagging a record as deleted instead of deleting it). Using a plugin that monkey patches ActiveRecord can go a long way towards fixing thesee problems, but it's a leaky abstraction and will bite you in the ass in unexpected ways. For example, all your uniqueness validations (and indexes) become much more complicated.
That's why Jeffrey Chupp decided to kill is_paranoid and Rick Olson doesn't use acts_as_paranoid any more.
There are other problems too. If you delete a lot of records, and you keep them in the same table, your table can get quite large, and all your queries slow down. At this point you have to use partitioning or partial indexes to get acceptable performance.

Alternatives to soft delete

In my reading, I found two alternatives to soft delete to be compelling.
The first was the suggestion to properly model your domain. Why do you want to delete a record? What does that mean? Udi Dahan puts it this way:
Orders aren’t deleted – they’re cancelled. There may also be fees incurred if the order is canceled too late.
Employees aren’t deleted – they’re fired (or possibly retired). A compensation package often needs to be handled.
Jobs aren’t deleted – they’re filled (or their requisition is revoked).
Keeping that in mind, what if the task at hand really is to delete the record? The other idea that I liked was to archive the records in another table.
The first Rails plugin I came across that implemented this was acts_as_soft_deletable which besides being misnamed doesn't appear to be actively maintained. The author even disavows the plugin somewhat for Rails 2.3:
Before using this with a new Rails 2.3 app, you may want to consider using the new default_scope feature (or named_scopes) with a deleted_at flag.
Then I found acts_as_archive which is more recently maintained and used in production for a major Rails website.
There was only one problem -- acts_as_archive didn't support PostgreSQL. Fortunately, that was easy enough to fix.

Restoring deleted records with acts_as_archive

acts_as_archive has the ability to restore a deleted record, but only that record, not associated records.
I was troubled by this at first, but after thinking about it I came to the conclusion that restoring a network of objects is an application-dependant problem. Here's one way to achieve it.
Imagine you have a model like this, with Posts having many Comments and Votes.
Post model
A Post can be deleted, and when it is, it should take the Comments and Votes with it:
class Post
  acts_as_archive

  has_many :votes, :dependent => :destroy
  has_many :comments, :dependent => :destroy
end
(Assume Comment and Vote also have acts_as_archive.)
Now, I can restore a Post with its associated Votes and Comments like this:
def self.restore(id)
  transaction do
    Post.restore_all(["id = ?", id])
    post = Post.find(id)

    Vote.restore_all(Vote::Archive.all(:conditions => ["post_id = ?", id]).map(&:id))
    Comment.restore_all(Comment::Archive.all(:conditions => ["post_id = ?", id]).map(&:id))
  end
In my real code, I've broken apart the two pieces of this into a class method restore and an instance method post_restore which the freshly restored object uses to find its associated records and restore them. post_restore also takes care of post-restore tasks like putting the object back in the Solr index.
This all works great. But now let's say Comments can be deleted individually, and we want to restore them.
Here the logic is a little different, because a Comment can't be restored unless its parent Post still exists (unless it's being restored by the Post, as above).
I take care of this logic in the administrative controller, by only showing child objects that it's valid to restore, and my foreign key constraints prevent anyone from getting around that.

I really wanted to delete that!

Sometimes you don't want to archive a deleted object. For example, in the application I'm working on, votes are canceled by re-voting. I don't want to save those votes -- there's no point, and it can even cause problems with restoring. Imagine having several archived votes from a user for a Post, and then deleting and restoring that Post. The restoration will try to bring back all the votes. Again, I catch this with a uniqueness constraint, but I don't want it to happen in the first place.
Fortunately acts_as_archive has me covered.
To destroy a record without archiving it, you can use destroy!. Likewise for deleting, there is delete_all!.

http://railspikes.com/2010/2/26/acts-as-archive?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+RailSpikes+%28Rail+Spikes%29

RequireJS

RequireJS loads plain JavaScript files as well as more defined modules. It is optimized for in-browser use, including in a Web Worker, but it can be used in other JavaScript environments, like Rhino and Node. It implements the CommonJS Transport/C proposal API.
RequireJS uses plain script tags to load modules/files, so it should allow for easy debugging. It can be used simply to load existing JavaScript files, so you can add it to your existing project without having to re-write your JavaScript files.
RequireJS includes an optimization tool you can run as part of your packaging steps for deploying your code. The optimization tool can combine and minify your JavaScript files to allow for better performance.
If the JavaScript file defines a JavaScript module via require.def(), then there are other benefits RequireJS can offer: better CommonJS support and loading multiple versions of a module in a page. RequireJS also allows for module modifiers and has a plugin system that supports features like i18n string bundles, text file dependencies, and JSONP service dependencies.
RequireJS does not have any dependencies on a JavaScript framework. It is tri-licensed -- BSD, MIT, and GPL.
The standard require.js file is around 4.9KB when minified via Closure Compiler and gzipped. require.js can be built without some features, with the smallest option (just dependency tracking and simple module loading) weighing in at 3.9KB minified, gzipped.
RequireJS works in IE 6+, Firefox 2+, Safari 3.2+, Chrome 3+, and Opera 10+.

http://requirejs.org/

Monday, October 4, 2010

Return the device name

This will return the name of the device on which the file resides on ...

class File::Stat
  def self.device_name(file)
    Dir['/dev/*'].inject({}) { |h, v|
      h.update(File.stat(v).rdev => v)
    }.values_at(File.stat(file).dev).first || nil
  end
end


Simple use-case:

(main):001:0> File::Stat.device_name('/etc/resolv.conf')
=> "/dev/sda3"


Please note that this code may not be portable enough as it relies on the content of /dev.

Check if string has JSON inside

module JSON
  def is_json?(string)
    begin
      parse(string).all?
    rescue ParserError
      false
    end
  end
end

Check whether a process is alive

Check whether a process is running (actually, present and alive) on a particular machine and/or system using its PID ...

Quick version ...

module Process
  class << self
    def process_alive?(pid)
      begin
        Process.kill(0, pid)
        true
      rescue Errno::ESRCH
        false
      end
    end
  end
end


A little bit slower version using /proc file system lookup ...

module Process
  class << self
    def process_alive?(pid)
      Dir['/proc/[0-9]*'].map { |i| i.match(/\d+/)[0].to_i }.include?(pid)
    end
  end
end


Simple use-case:

irb(main):013:0> puts `ps aux | grep -i [t]omboy`
1000 6862  0.0  0.2 103972  9592 ? Sl Sep28 0:09 mono /usr/lib/tomboy/Tomboy.exe
=> nil
irb(main):014:0> Process.process_alive?(26862)
=> true
irb(main):015:0> Process.process_alive?(12345)
=> false
irb(main):016:0> 

http://snippets.dzone.com/posts/show/12347

Polaroid Photobar Gallery with jQuery


In this tutorial we are going to create an image gallery with a Polaroid look. We will have albums that will expand to sets of slightly rotated thumbnails that pop out on hover. The full image will slide in from the bottom once a thumbnail is clicked. In the full image view the user can navigate through the pictures or simply choose another thumbnail to be displayed.
For this gallery we will be using the 2D Transform plugin to animate rotations.
The beautiful photos used in the demo are by talented Tetsumo. Visit his blog here.

http://tympanus.net/codrops/2010/09/28/polaroid-photobar-gallery/

Sunday, October 3, 2010

SlowGrowl

Rails 3 plugin which surfaces slow code paths in your Rails application by integrating with the new Notifications API in Rails 3 with your system Growl (OSX) or libnotify (Linux) notification service. By default, any activity which takes longer than one second, will generate a growl alert, with the description of the action, time taken, and other meta data. A preview in action:
slowgrowl notification

http://github.com/igrigorik/slowgrowl