<repo_name>frontweb/vouchers<file_sep>/db/migrate/20100228181210_add_email_to_ad.rb
class AddEmailToAd < ActiveRecord::Migration
  def self.up
    add_column :ads, :email, :string, :limit => 100
  end

  def self.down
    remove_column :ads, :email
  end
end
<file_sep>/app/controllers/admin/comments_controller.rb
class Admin::CommentsController < ApplicationController
  before_filter :admin_required
  layout 'admin'
  
  # GET /admin/comments
  def index
    @comments = Comment.paginate :page => params[:page], :order => 'created_at DESC'
  end
  
  # DELETE /admin/comments/1
  def destroy
    Comment.find(params[:id]).destroy
    redirect_to admin_comments_url
  end
end
<file_sep>/app/models/ad.rb
class Ad < ActiveRecord::Base
  apply_simple_captcha :message => "Codul de verificare introdus e gresit"
  
  belongs_to :city

  validates_presence_of :city, :message => "Trebuie precizat un oraș"
  validates_presence_of :price, :message => "Trebuie precizat prețul (in Euro)"
  validates_presence_of :phone_number, :message => "Trebuie introdus un număr de telefon mobil"
  validates_numericality_of :price, :message => "Prețul trebuie să fie între 100 și 700 de Euro", :only_integer => true, :greater_than_or_equal_to => 100, :less_than_or_equal_to => 700, :if => Proc.new { |ad| ad.price != nil }
  validates_format_of :phone_number, :with => /^07[0-9]{8}$/, :message => "Trebuie un numar de telefon mobil (10 cifre). Introduceți doar cifre (07...)", :if => Proc.new { |ad| ad.price != nil && !ad.phone_number.empty? }
  validates_presence_of :email, :message => "Trebuie introdusă o adresa de email"
  validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :message => "Adresa de email introdusă nu e corectă", :if => Proc.new { |ad| ad.email != nil && !ad.email.empty? }
  
  def before_create
    self.secret_code = random_code
  end
  
  def self.per_page
    30
  end
  
private

  def random_code(length = 6)
    #a = ('a'..'z').to_a + (0..9).to_a
    a = [:a, :b, :c, :d, :e, :h, :k, :m, :n, :p, :r, :s, :t, :u, :v, :x, :z, 2, 3, 4, 5, 6, 7, 8, 9]
    c = ''
    1.upto(length) { c += a[rand(a.size)].to_s }
    return c
  end
end
<file_sep>/app/models/city.rb
class City < ActiveRecord::Base
  has_many :ads
  
  validates_presence_of :name
end
<file_sep>/lib/tasks/populate.rake
namespace :db do
  desc "Loads initial database models"
  task :populate_all => :environment do
    Dir[File.join(RAILS_ROOT, 'db', 'fixtures', '*.rb')].sort.each { |fixture| load fixture }
    Dir[File.join(RAILS_ROOT, 'db', 'fixtures', RAILS_ENV, '*.rb')].sort.each { |fixture| load fixture }
  end
  
  desc "Load a single file"
  task :populate => :environment do
    unless ENV['file']
      puts "usage: rake db:populate file=regions"
      exit
    end
    
    fixture = File.join(RAILS_ROOT, 'db', 'fixtures', "#{ENV['file']}.rb")
    load fixture
  end
end
<file_sep>/app/controllers/comments_controller.rb
class CommentsController < ApplicationController
  layout 'public'
  
  # GET /article/1/comments/new
  def new
    @comment = Article.find(params[:article_id]).comments.new
  end
  
  # POST /article/1/comments
  def create
    @article = Article.find(params[:article_id])
    @comment = @article.comments.new(params[:comment])
    @comment.ip = request.remote_ip
    
    if @comment.save_with_captcha
      flash[:success] = "Comentariul a fost adăugat."
      redirect_to article_url(@article)
    else
      render :action => "new"
    end
  end
end
<file_sep>/app/controllers/application_controller.rb
# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.

class ApplicationController < ActionController::Base
  include SimpleCaptcha::ControllerHelpers
  
  helper :all # include all helpers, all the time
  protect_from_forgery # See ActionController::RequestForgeryProtection for details

  # Scrub sensitive parameters from your log
  # filter_parameter_logging :password
  
protected
  def admin_required
    authenticate_or_request_with_http_basic do |username, password|
      username == 'admin' && password == '<PASSWORD>'
    end if RAILS_ENV == 'production' || params[:admin_http]
  end

end
<file_sep>/app/models/article.rb
class Article < ActiveRecord::Base
  has_friendly_id :title, :use_slug => true, :strip_diacritics => true
  
  has_many :comments, :order => 'created_at DESC', :dependent => :destroy
  
  validates_presence_of :title, :message => 'Titlul trebuie completat'
  validates_presence_of :content, :message => 'Continutul trebuie completat'
  
  def self.per_page
    10
  end
end
<file_sep>/app/controllers/page_controller.rb
class PageController < ApplicationController
  layout 'public'

  def about
  end
  
  def contact    
  end
  
  def cities
    @cities = City.all :order => 'name'
  end
end
<file_sep>/app/models/notifications.rb
class Notifications < ActionMailer::Base
  def new_ad(ad)
    subject     'Publicare anunt voucher rabla'
    recipients  ad.email
    from        %("<NAME>" <EMAIL>)
    body        :ad => ad
  end
end
<file_sep>/app/helpers/ads_helper.rb
module AdsHelper
  def format_phone_number(s)
    "#{s[0..3]}.#{s[4..6]}.#{s[7..9]}"
  end
end
<file_sep>/db/fixtures/cities.rb
City.create_or_update :id => 1, :name => "Bucuresti"
City.create_or_update :id => 2, :name => "Ilfov"
City.create_or_update :id => 3, :name => "<NAME>"
City.create_or_update :id => 4, :name => "Arad"
City.create_or_update :id => 5, :name => "Pitesti"
City.create_or_update :id => 6, :name => "Bacau"
City.create_or_update :id => 7, :name => "Oradea"
City.create_or_update :id => 8, :name => "Bistrita"
City.create_or_update :id => 9, :name => "Botosani"
City.create_or_update :id => 10, :name => "Braila"
City.create_or_update :id => 11, :name => "Brasov"
City.create_or_update :id => 12, :name => "Buzau"
City.create_or_update :id => 13, :name => "Calarasi"
City.create_or_update :id => 14, :name => "Resita"
City.create_or_update :id => 15, :name => "Cluj"
City.create_or_update :id => 16, :name => "Dej"
City.create_or_update :id => 17, :name => "Constanta"
City.create_or_update :id => 18, :name => "Covasna"
City.create_or_update :id => 19, :name => "Targoviste"
City.create_or_update :id => 20, :name => "Craiova"
City.create_or_update :id => 21, :name => "Galati"
City.create_or_update :id => 22, :name => "Giurgiu"
City.create_or_update :id => 23, :name => "<NAME>"
City.create_or_update :id => 24, :name => "<NAME>"
City.create_or_update :id => 25, :name => "Hunedoara"
City.create_or_update :id => 26, :name => "Slobozia"
City.create_or_update :id => 27, :name => "Iasi"
City.create_or_update :id => 28, :name => "<NAME>"
City.create_or_update :id => 29, :name => "<NAME>"
City.create_or_update :id => 30, :name => "<NAME>"
City.create_or_update :id => 31, :name => "Roman"
City.create_or_update :id => 32, :name => "<NAME>"
City.create_or_update :id => 33, :name => "<NAME>"
City.create_or_update :id => 34, :name => "Slatina"
City.create_or_update :id => 35, :name => "Ploiesti"
City.create_or_update :id => 36, :name => "Zalau"
City.create_or_update :id => 37, :name => "<NAME>"
City.create_or_update :id => 38, :name => "Medias"
City.create_or_update :id => 39, :name => "Sibiu"
City.create_or_update :id => 40, :name => "Suceava"
City.create_or_update :id => 41, :name => "Teleorman"
City.create_or_update :id => 42, :name => "Timisoara"
City.create_or_update :id => 43, :name => "Tulcea"
City.create_or_update :id => 44, :name => "Valcea"
City.create_or_update :id => 45, :name => "Vaslui"
City.create_or_update :id => 46, :name => "Focsani"
<file_sep>/app/controllers/ads_controller.rb
class AdsController < ApplicationController
  before_filter :ad_found?, :only => [:edit, :update, :remove, :destroy]
  layout 'public'
  
  # GET /ads
  def index
    # Order
    session[:order_column] ||= 'created_at DESC'
    order_column = params[:o] ? (params[:o] == 'price' ? 'price' : 'created_at DESC') : session[:order_column]
    session[:order_column] = order_column
    
    # Filter by city
    @city = nil
    if params[:c] && params[:c] == 'all'
      session[:city_id] = nil
    elsif params[:c]
      session[:city_id] = @city.id if @city = City.find(params[:c])
    elsif session[:city_id]
      @city = City.find(session[:city_id])
    end
    if @city
      @ads = Ad.paginate(:page => params[:page], :conditions => { :city_id => @city.id }, :order => order_column)
    else
      @ads = Ad.paginate(:page => params[:page], :order => order_column)
    end
    
    @articles = Article.all :order => 'created_at DESC', :limit => 3
  end
  
  # GET /ads/1
  def show
    @ad = Ad.find(params[:id])
  end
  
  # GET /ads/new
  def new
    @ad = Ad.new
  end

  # POST /ads
  def create
    @ad = Ad.new(params[:ad])

    if @ad.save_with_captcha
      Notifications.deliver_new_ad(@ad)
      flash[:success] = "Anuntul a fost creat. O confirmare a fost trimisa pe email-ul dumneavoastra."
      redirect_to ad_url(@ad)
    else
      render :action => 'new'
    end
  end
  
  # GET /ads/1/edit?c=secret_code
  def edit
  end
  
  # PUT /ads/1
  def update
    if @ad.update_attributes(params[:ad])
      flash[:success] = "Modificarile au fost salvate."
      redirect_to ad_url(@ad)
    else
      render :action => 'edit'
    end
  end
  
  # GET /ads/1/remove?c=secret_code
  def remove
  end
  
  # DELETE /ads/1?c=secret_code
  def destroy
    @ad.destroy
    flash[:success] = "Anuntul a fost sters."
    redirect_to ads_url
  end
  
private

  def ad_found?
    @ad = Ad.find(:first, :conditions => ["id = ? AND secret_code = ?", params[:id], params[:c]])
    unless @ad
      flash[:error] = "Anuntul nu a fost gasit."
      redirect_to ads_url
      return false
    end
  end
end
<file_sep>/db/migrate/20100228124132_create_ads.rb
class CreateAds < ActiveRecord::Migration
  def self.up
    create_table :ads do |t|
      t.belongs_to :city
      t.integer :price
      t.string :notes, :phone_number
      t.string :secret_code, :limit => 20
      t.timestamps
    end
    
    add_index(:ads, :city_id)
    add_index(:ads, :price)
    add_index(:ads, :created_at)
  end

  def self.down
    drop_table :ads
  end
end
<file_sep>/app/models/comment.rb
class Comment < ActiveRecord::Base
  apply_simple_captcha :message => "Codul de verificare introdus e gresit"
  
  belongs_to :article
  
  validates_presence_of :article_id, :message => "Comentariul trebuie sa apartina unui articol"
  validates_presence_of :name, :message => 'Trebuie sa va introduceti numele'
  validates_presence_of :email, :message => 'Trebuie sa introduceti o adresa de email'
  validates_presence_of :content, :message => 'Comentariul nu poate fi gol'
  validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :message => "Adresa de email introdusă nu e corectă", :if => Proc.new { |c| c.email != nil && !c.email.empty? }
  
  def self.per_page
    30
  end
end
<file_sep>/app/helpers/application_helper.rb
# Methods added to this helper will be available to all templates in the application.
module ApplicationHelper
  def error_messages_for(object_name, options = {})
    options = options.symbolize_keys
    object = instance_variable_get("@#{object_name}")
    if object && !object.errors.empty?
      txt = ""
      object.errors.each { |attr, msg| txt += content_tag("li", msg) }
      content_tag("div",
        content_tag(options[:header_tag] || "h2", "Corectați erorile următoare:") + content_tag("ul", txt), 
        :id => options[:id] || "errorExplanation", :class => options[:class] || "errorExplanation"
      )
    else
      ""
    end
  end
  
  # Set title of a page
  def title(page_title)
    content_for(:title) { page_title }
  end
  
  # Set 'description' meta
  def meta_description(description)
    content_for(:description) { description }
  end
  
  # Set 'keywords' meta
  def meta_keywords(keywords)
    content_for(:keywords) { keywords }
  end
end
<file_sep>/test/unit/notifications_test.rb
require 'test_helper'

class NotificationsTest < ActionMailer::TestCase
  test "new_ad" do
    @expected.subject = 'Notifications#new_ad'
    @expected.body    = read_fixture('new_ad')
    @expected.date    = Time.now

    assert_equal @expected.encoded, Notifications.create_new_ad(@expected.date).encoded
  end

end
<file_sep>/config/deploy.rb
ssh_options[:port] = 383

set :user, "radu"
set :use_sudo, false
set :application, "www.vouchererabla.ro"
set :deploy_to, "/var/apps/#{application}"

set :scm, :git
set :repository, "<EMAIL>:frontweb/vouchers.git"
set :branch, "master"
set :deploy_via, :remote_cache

set :keep_releases, 3
after "deploy:update", "deploy:cleanup"

server "172.16.17.32", :app, :web, :db, :primary => true

namespace :deploy do
  desc "Restarting mod_rails with restart.txt"
  task :restart, :roles => :app, :except => { :no_release => true } do
    run "touch #{current_path}/tmp/restart.txt"
  end
 
  [:start, :stop].each do |t|
    desc "#{t} task is a no-op with mod_rails"
    task t, :roles => :app do ; end
  end
end

namespace :my do
  desc "Share database"
  task :symlink_shares do
    run "ln -s #{deploy_to}/#{shared_dir}/database.yml #{release_path}/config/database.yml"
  end
end
before "deploy:symlink", "my:symlink_shares"

desc "Tail production log file"
task :tail_log, :roles => :app do
  run "tail -f #{shared_path}/log/production.log" do |channel, stream, data|
    puts "#{channel[:host]}: #{data}"
    break if stream == :err
  end
end

desc "Download and load data from production database"
task :db_get, :roles => :app do
  require 'yaml'

  # Get production database configuration
  get "#{current_path}/config/database.yml", "tmp/database.yml"
  db = YAML::load_file("tmp/database.yml")
  system "rm -f tmp/database.yml"
  
  # Download gzip database dump
  run "/usr/bin/mysqldump -u #{db['production']['username']} --password=#{db['production']['password']} --complete-insert #{db['production']['database']} > #{deploy_to}/#{shared_dir}/db.sql"
  run "cd #{deploy_to}/#{shared_dir} && tar -czvf db.tar.gz db.sql"
  get "#{deploy_to}/#{shared_dir}/db.tar.gz", "tmp/db.tar.gz"
  run "rm -f #{deploy_to}/#{shared_dir}/db.sql && rm -f #{deploy_to}/#{shared_dir}/db.tar.gz"
  
  # Untar database
  system "cd tmp && tar -xzvf db.tar.gz db.sql"
  system "rm -f tmp/db.tar.gz"
  
  # Get development database configuration
  db = YAML::load_file("config/database.yml")

  # Insert development database name at the begining of the file
  File.open("tmp/dump.sql", 'w') do |f|
    f.puts "USE '#{db['development']['database']}'"
    f.puts File.read("tmp/db.sql")
  end
  system "rm -f tmp/db.sql"

  # Restore dump
  system "cat tmp/dump.sql | /usr/local/mysql/bin/mysql -u root"
  system "rm -f tmp/dump.sql"
end
<file_sep>/config/initializers/will_paginate.rb
WillPaginate::ViewHelpers.pagination_options[:previous_label] = '&laquo; Pagina anterioară'
WillPaginate::ViewHelpers.pagination_options[:next_label] = 'Pagina următoare &raquo;'
<file_sep>/app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  layout 'public'
  
  # GET /articles
  def index
    @articles = Article.paginate :page => params[:page], :order => 'created_at DESC'
  end
  
  # GET /articles/1
  def show
    @article = Article.find(params[:id])
    @comment = @article.comments.new
    @articles = Article.all :order => 'created_at DESC'
  end
end
