Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

About this user

Hendrik Mans http://www.mans.de

« Newer Snippets
Older Snippets »
Showing 1-10 of 13 total  RSS 

Mongrel and Apache fun with Capistrano 2.0

I got the Mongrel recipes from somewhere else -- I sadly don't remember where -- and modified them a bit.

namespace :deploy do
  namespace :mongrel do
    [ :stop, :start, :restart ].each do |t|
      desc "#{t.to_s.capitalize} the mongrel appserver"
      task t, :roles => :app do
        run "mongrel_rails cluster::#{t.to_s} --clean -C #{mongrel_conf}"
      end
    end
  end
  
  namespace :apache do
    desc "Start Apache"
    task :start, :roles => :web do
      sudo "/etc/init.d/httpd start > /dev/null"
    end

    desc "Stop Apache"
    task :stop, :roles => :web do
      sudo "/etc/init.d/httpd stop > /dev/null"
    end

    desc "Restart Apache"
    task :restart, :roles => :web do
      sudo "/etc/init.d/httpd restart > /dev/null"
    end
  end

  desc "Custom restart task for mongrel cluster"
  task :restart do
    deploy.mongrel.restart
    deploy.apache.restart
  end

  desc "Custom start task for mongrel cluster"
  task :start, :roles => :app do
    deploy.mongrel.start
    deploy.apache.start
  end

  desc "Custom stop task for mongrel cluster"
  task :stop, :roles => :app do
    deploy.apache.stop
    deploy.mongrel.stop
  end

end

Update selected attributes from a list

This transfers a list of selected attributes from a list (typically inside params[]) to an AR model object. More useful than attr_accessible, attr_protected et al.

class ActiveRecord::Base
  def transfer_attributes(source, *keys)
    keys.each do |key|
      self.send("#{key}=", source[key])
    end
  end
end

Sanitize (HTML-based) user input

These two helpers will strip all HTML tags from user input you don't want and also auto-close tags that were accidentally (?) left open.

  def format_user_text(input)
    output = "<p>#{input.strip}</p>"

    # do some formatting
    output.gsub!(/\r\n/, "\n")       # remove CRLFs
    output.gsub!(/^$\s*/m, "\n")     # remove blank lins
    output.gsub!(/\n{3,}/, "\n\n")   # replace \n\n\n... with \n\n
    output.gsub!(/\n\n/, '</p><p>')  # embed stuff in paragraphs
    output.gsub!(/\n/, '<br/>')      # nl2br
    
    sanitize_fu output
  end

  # Adapted from http://ideoplex.com/id/1138/sanitize-html-in-ruby
  def sanitize_fu(html, okTags = 'a href, b, br, p, i, em')
    # no closing tag necessary for these
    soloTags = ["br","hr"]

    # Build hash of allowed tags with allowed attributes
    tags = okTags.downcase().split(',').collect!{ |s| s.split(' ') }
    allowed = Hash.new
    tags.each do |s|
      key = s.shift
      allowed[key] = s
    end

    # Analyze all <> elements
    stack = Array.new
    result = html.gsub( /(<.*?>)/m ) do | element |
      if element =~ /\A<\/(\w+)/ then
        # </tag>
        tag = $1.downcase
        if allowed.include?(tag) && stack.include?(tag) then
          # If allowed and on the stack
          # Then pop down the stack
          top = stack.pop
          out = "</#{top}>"
          until top == tag do
            top = stack.pop
            out << "</#{top}>"
          end
          out
        end
      elsif element =~ /\A<(\w+)\s*\/>/
        # <tag />
        tag = $1.downcase
        if allowed.include?(tag) then
          "<#{tag} />"
        end
      elsif element =~ /\A<(\w+)/ then
        # <tag ...>
        tag = $1.downcase
        if allowed.include?(tag) then
          if ! soloTags.include?(tag) then
            stack.push(tag)
          end
          if allowed[tag].length == 0 then
            # no allowed attributes
            "<#{tag}>"
          else
            # allowed attributes?
            out = "<#{tag}"
            while ( $' =~ /(\w+)=("[^"]+")/ )
              attr = $1.downcase
              valu = $2
              if allowed[tag].include?(attr) then
                out << " #{attr}=#{valu}"
              end
            end
            out << ">"
          end
        end
      end
    end

    # eat up unmatched leading >
    while result.sub!(/\A([^<]*)>/m) { $1 } do end

    # eat up unmatched trailing <
    while result.sub!(/<([^>]*)\Z/m) { $1 } do end

    # clean up the stack
    if stack.length > 0 then
      result << "</#{stack.reverse.join('></')}>"
    end

    result
  end

User model basics: age calculations

class User < ActiveRecord::Base
  # ...
  
  def age
    (Time.now.year - birthday.year) - (turned_older? ? 0 : 1) rescue 0
  end
 
  def next_birthday
    birthday.to_time.change(:year => (turned_older? ? 1.year.from_now : Time.now).year)
  end
 
  def turned_older?
    (birthday.to_time.change(:year => Time.now.year) <= Time.now)
  end
end

User model basics: SHA256 passwords

class User < ActiveRecord::Base
  # ...

  def password ; @password ; end
  def password=(value)
    self.password_salt = [Array.new(6){rand(256).chr}.join].pack("m").chomp
    self.password_sha  = self.encrypt_password(value)
    @password = value
  end
  
  def encrypt_password(cleartext)
    Digest::SHA256.hexdigest(cleartext + self.password_salt)
  end
  
  def self.authenticate(nickname, password)
    user = self.find_active_by_nickname(nickname)
    raise "Username or Password invalid" if user.blank? || user.encrypt_password(password) != user.password_sha
    return user
  end
end

Bootstrapping a fresh Rails project with my favorite plugins

These is my current set of "must-have" Rails plugins. None of these require any additional configuration except for the exception_notification plugin (see README).

cd vendor/plugins
piston import http://scope-out-rails.googlecode.com/svn/trunk/ scope_out_rails
piston import http://svn.cardboardrocket.com/paginating_find
piston import http://opensvn.csie.org/rails_file_column/plugins/file_column/trunk file_column
piston import http://svn.techno-weenie.net/projects/plugins/test_spec_on_rails
piston import http://svn.2750flesk.com/plugins/trunk/acts_as_sluggable
piston import http://dev.rubyonrails.org/svn/rails/plugins/simply_helpful
piston import https://svn.greenpeace.org/repositories/rails_plugins/validates_as_email/trunk/ validates_as_email
piston import http://dev.rubyonrails.org/svn/rails/plugins/exception_notification/

Handy find shortcut

environment.rb:

class <<ActiveRecord::Base
  alias_method :[], :find
end


Thanks, Jamis.

Send files from the shell

uuencode filename filename | mail -s "subject" foo@bar.com

Better textilize

A better textilize helper that doesn't use the :hard_breaks option of RedCloth, like Rails' built-in textilize does (for whatever reason). Also escapes any HTML entered by the user (instead of dismissing it, as RedCloth's :filter_html option would do).

This my not be what you need, but it's exactly what I need. :)

  def textilize(text)
    RedCloth.new(text.gsub(/</, '&lt;').gsub(/>/, '&gt;')).to_html
  end

Escape single quotes in Ruby strings

class String
  def escape_single_quotes
    self.gsub(/[']/, '\\\\\'')
  end
end


Useful if you ever get the idea of shoving Ruby strings into JavaScript code.
« Newer Snippets
Older Snippets »
Showing 1-10 of 13 total  RSS