Merge branch 'design_team' into ldap
Conflicts: Gemfile app/models/ad_banner.rb
This commit is contained in:
		
						commit
						f950f77f36
					
				
							
								
								
									
										1
									
								
								Gemfile
								
								
								
								
							
							
						
						
									
										1
									
								
								Gemfile
								
								
								
								
							| 
						 | 
				
			
			@ -34,6 +34,7 @@ gem 'sprockets'
 | 
			
		|||
gem 'tinymce-rails'
 | 
			
		||||
gem 'therubyracer' if RUBY_PLATFORM.downcase.include?("linux")
 | 
			
		||||
 | 
			
		||||
gem "impressionist", :require => "impressionist", :path => "vendor/impressionist"
 | 
			
		||||
 | 
			
		||||
# Gems used only for assets and not required
 | 
			
		||||
# in production environments by default.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,13 @@ GIT
 | 
			
		|||
      activesupport (>= 3.0.0)
 | 
			
		||||
      railties (>= 3.0.0)
 | 
			
		||||
 | 
			
		||||
PATH
 | 
			
		||||
  remote: vendor/impressionist
 | 
			
		||||
  specs:
 | 
			
		||||
    impressionist (1.1.1)
 | 
			
		||||
      httpclient (~> 2.2)
 | 
			
		||||
      nokogiri (~> 1.5)
 | 
			
		||||
 | 
			
		||||
GEM
 | 
			
		||||
  remote: http://rubygems.org/
 | 
			
		||||
  specs:
 | 
			
		||||
| 
						 | 
				
			
			@ -92,6 +99,7 @@ GEM
 | 
			
		|||
    hike (1.2.1)
 | 
			
		||||
    hoe (2.16.1)
 | 
			
		||||
      rake (~> 0.8)
 | 
			
		||||
    httpclient (2.2.5)
 | 
			
		||||
    i18n (0.6.0)
 | 
			
		||||
    jquery-rails (1.0.19)
 | 
			
		||||
      railties (~> 3.0)
 | 
			
		||||
| 
						 | 
				
			
			@ -277,6 +285,7 @@ DEPENDENCIES
 | 
			
		|||
  exception_notification
 | 
			
		||||
  execjs
 | 
			
		||||
  factory_girl_rails
 | 
			
		||||
  impressionist!
 | 
			
		||||
  jquery-rails
 | 
			
		||||
  jquery-ui-rails
 | 
			
		||||
  kaminari!
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
// JavaScript Document
 | 
			
		||||
 | 
			
		||||
// can copy code to any of ur desired javascsript 
 | 
			
		||||
 | 
			
		||||
//extended jquery to search fast.
 | 
			
		||||
$.extend($.expr[':'], {
 | 
			
		||||
	'containsi': function (elem, i, match, array) {
 | 
			
		||||
		return (elem.textContent || elem.innerText || '').toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
var interval,sval;
 | 
			
		||||
$(document).ready(function(){
 | 
			
		||||
	$("#user_filter").keyup(function(e){
 | 
			
		||||
		if((e.which>96 && e.which<123) || (e.which>64 && e.which<92) || (e.which == 32) || (e.which == 8)){ 
 | 
			
		||||
			sval = $(this).val();
 | 
			
		||||
			$(".checkbox").popover("hide");
 | 
			
		||||
			$("div.checkblock").hide();
 | 
			
		||||
			clearInterval(interval);
 | 
			
		||||
			interval = setInterval(waitForSearch,1000);
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
})
 | 
			
		||||
var waitForSearch = function(){
 | 
			
		||||
	if(sval){
 | 
			
		||||
		var totalfoundbyname = $("div#users_checkbox_ary label.member-name:containsi("+sval+")").length
 | 
			
		||||
		if(totalfoundbyname!=0){
 | 
			
		||||
			$("div#users_checkbox_ary label.member-name:containsi("+sval+")").parent().parent().show();				
 | 
			
		||||
		}else if(totalfoundbyname==0){
 | 
			
		||||
			$("div#users_checkbox_ary div.for_unit:containsi("+sval+")").parent().show();
 | 
			
		||||
		}	
 | 
			
		||||
	}else{
 | 
			
		||||
		$(".checkbox").popover('hide');	
 | 
			
		||||
		$("div.checkblock").show();
 | 
			
		||||
	}
 | 
			
		||||
	clearInterval(interval);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ class Admin::DashboardsController < ApplicationController
 | 
			
		|||
  def index
 | 
			
		||||
  	@module_app_contents, @module_app_contents_total = get_module_app_count('bulletin', 'news_bulletin', 'page_context', 'web_link')
 | 
			
		||||
  	@recent_updated = get_recently_updated('bulletin', 'news_bulletin', 'page_context', 'web_link')
 | 
			
		||||
    @most_visited = get_most_visited('bulletin', 'news_bulletin', 'page_context')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  protected
 | 
			
		||||
| 
						 | 
				
			
			@ -35,5 +36,18 @@ class Admin::DashboardsController < ApplicationController
 | 
			
		|||
  	sorted_objects = a.sort {|a,b| b[1]<=>a[1]}
 | 
			
		||||
  	sorted_objects[0..9]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def get_most_visited(*args)
 | 
			
		||||
    a = {}
 | 
			
		||||
    args.each do |module_app|
 | 
			
		||||
      module_app_class = module_app.classify.constantize
 | 
			
		||||
      objects = module_app_class.order_by(:view_count, :desc).limit(10)
 | 
			
		||||
      objects.each do |object|
 | 
			
		||||
        a.merge!(object => object.view_count) if object.view_count > 0
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    sorted_objects = a.sort {|a,b| b[1]<=>a[1]}
 | 
			
		||||
    sorted_objects[0..9]
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,7 @@
 | 
			
		|||
class Admin::ObjectAuthsNewInterfaceController < OrbitBackendController
 | 
			
		||||
  include OrbitCoreLib::PermissionUnility
 | 
			
		||||
  layout "new_admin"
 | 
			
		||||
  before_filter :force_order
 | 
			
		||||
 | 
			
		||||
  layout "new_admin"
 | 
			
		||||
  before_filter :force_order
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  def setting
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ class PagesController < ApplicationController
 | 
			
		|||
  def index
 | 
			
		||||
    @item = Page.find_by_name('home')
 | 
			
		||||
    if @item
 | 
			
		||||
      impressionist(@item)
 | 
			
		||||
      render_page
 | 
			
		||||
    else
 | 
			
		||||
      render :text => 'You need a home page'
 | 
			
		||||
| 
						 | 
				
			
			@ -14,18 +15,19 @@ class PagesController < ApplicationController
 | 
			
		|||
  end
 | 
			
		||||
  
 | 
			
		||||
  def show  
 | 
			
		||||
     #begin  
 | 
			
		||||
       @item = Item.first(:conditions => {:path => params[:page_name]})
 | 
			
		||||
       if @item && @item.is_published && (@item.enabled_for.nil? ? true : @item.enabled_for.include?(I18n.locale.to_s))
 | 
			
		||||
         case @item._type
 | 
			
		||||
           when 'Page'    
 | 
			
		||||
             render_page
 | 
			
		||||
           when 'Link'
 | 
			
		||||
             redirect_to "http://#{@item[:url]}"
 | 
			
		||||
         end
 | 
			
		||||
       else
 | 
			
		||||
         render :file => "#{Rails.root}/public/404.html", :status => :not_found
 | 
			
		||||
       end
 | 
			
		||||
    #begin  
 | 
			
		||||
      @item = Item.first(:conditions => {:path => params[:page_name]})
 | 
			
		||||
      if @item && @item.is_published && (@item.enabled_for.nil? ? true : @item.enabled_for.include?(I18n.locale.to_s))
 | 
			
		||||
        impressionist(@item)
 | 
			
		||||
        case @item._type
 | 
			
		||||
          when 'Page'    
 | 
			
		||||
            render_page
 | 
			
		||||
          when 'Link'
 | 
			
		||||
            redirect_to @item[:url]
 | 
			
		||||
        end
 | 
			
		||||
      else
 | 
			
		||||
        render :file => "#{Rails.root}/public/404.html", :status => :not_found
 | 
			
		||||
      end
 | 
			
		||||
     #rescue
 | 
			
		||||
     #  render :file => "#{Rails.root}/public/404.html", :status => :not_found
 | 
			
		||||
     #end
 | 
			
		||||
| 
						 | 
				
			
			@ -55,11 +57,7 @@ class PagesController < ApplicationController
 | 
			
		|||
   
 | 
			
		||||
   def get_item
 | 
			
		||||
      module_app = ModuleApp.first(:conditions => {:key => params[:app_name]})
 | 
			
		||||
      # if params[:category_id]
 | 
			
		||||
      #   @item = Item.first(:conditions => {:module_app_id => module_app.id, :app_frontend_url => params[:app_action], :category => params[:category_id]})  
 | 
			
		||||
      # else 
 | 
			
		||||
        @item = Item.first(:conditions => {:module_app_id => module_app.id, :app_frontend_url => params[:app_action]})
 | 
			
		||||
      # end
 | 
			
		||||
      @item = Item.first(:conditions => {:module_app_id => module_app.id, :app_frontend_url => params[:app_action]})
 | 
			
		||||
   end
 | 
			
		||||
  
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,26 +3,26 @@ module Admin::DashboardHelper
 | 
			
		|||
	def get_link(title)
 | 
			
		||||
		case title
 | 
			
		||||
			when 'bulletin'
 | 
			
		||||
				panel_announcement_back_end_bulletins_path
 | 
			
		||||
				panel_announcement_front_end_bulletins_path
 | 
			
		||||
			when 'news_bulletin'
 | 
			
		||||
				panel_news_back_end_news_bulletins_path
 | 
			
		||||
				panel_news_front_end_news_bulletins_path
 | 
			
		||||
			when'page_context'
 | 
			
		||||
				panel_page_content_back_end_page_contexts_path
 | 
			
		||||
				panel_page_content_front_end_page_contexts_path
 | 
			
		||||
			when'web_link'
 | 
			
		||||
				panel_web_resource_back_end_web_links_path
 | 
			
		||||
				panel_web_resource_front_end_web_links_path
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	def get_link_to_object(object)
 | 
			
		||||
		case object._type.underscore
 | 
			
		||||
			when 'bulletin'
 | 
			
		||||
				panel_announcement_back_end_bulletin_path(object)
 | 
			
		||||
				panel_announcement_front_end_bulletin_path(object)
 | 
			
		||||
			when 'news_bulletin'
 | 
			
		||||
				panel_news_back_end_news_bulletin_path(object)
 | 
			
		||||
				panel_news_front_end_news_bulletin_path(object)
 | 
			
		||||
			when'page_context'
 | 
			
		||||
				panel_page_content_back_end_page_context_path(object)
 | 
			
		||||
				panel_page_content_front_end_page_context_path(object)
 | 
			
		||||
			when'web_link'
 | 
			
		||||
				panel_web_resource_back_end_web_link_path(object)
 | 
			
		||||
				panel_web_resource_front_end_web_link_path(object)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,7 +96,6 @@ module ApplicationHelper
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def visible_for_controllers(*controller_names)
 | 
			
		||||
    puts controller_names
 | 
			
		||||
    (controller_names.include?(controller.controller_name) || controller_names.include?(request.fullpath)) ? '' : 'hide'
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
| 
						 | 
				
			
			@ -173,4 +172,28 @@ module ApplicationHelper
 | 
			
		|||
    locale.to_sym == I18n.locale ? 'active in': ''
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def dislpay_view_count(object)
 | 
			
		||||
    "#{t(:view_count)}: #{object.view_count}"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def display_visitors(options={})
 | 
			
		||||
    Impression.where(options).distinct(:session_hash).count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def display_visitors_today
 | 
			
		||||
    display_visitors(created_at: {'$gte' => Date.today.beginning_of_day, '$lte' => Date.today.end_of_day})
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def display_visitors_this_week
 | 
			
		||||
    display_visitors(created_at: {'$gte' => Date.today.beginning_of_week, '$lte' => Date.today.end_of_week})
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def display_visitors_this_month
 | 
			
		||||
    display_visitors(created_at: {'$gte' => Date.today.beginning_of_month, '$lte' => Date.today.end_of_month})
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def display_visitors_this_year
 | 
			
		||||
    display_visitors(created_at: {'$gte' => Date.today.beginning_of_year, '$lte' => Date.today.end_of_year})
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@ class AdBanner
 | 
			
		|||
  include Mongoid::Timestamps
 | 
			
		||||
  include Mongoid::MultiParameterAttributes
 | 
			
		||||
  include OrbitCoreLib::ObjectAuthable
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  field :title
 | 
			
		||||
  field :transition_msec,type: Integer
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,10 +2,20 @@ class Link < Item
 | 
			
		|||
  
 | 
			
		||||
  field :url
 | 
			
		||||
  
 | 
			
		||||
  validates_presence_of :url
 | 
			
		||||
  validates :url, :presence => true, :format => /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/ix
 | 
			
		||||
 | 
			
		||||
	before_validation :add_http
 | 
			
		||||
 | 
			
		||||
  def link
 | 
			
		||||
    ApplicationController.helpers.link_to(self.name, self.url)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  protected
 | 
			
		||||
 | 
			
		||||
	def add_http
 | 
			
		||||
	  unless self.url[/^http?s:\/\//]
 | 
			
		||||
	    self.url = 'http://' + self.url
 | 
			
		||||
	  end
 | 
			
		||||
	end
 | 
			
		||||
    
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,14 @@
 | 
			
		|||
class Page < Item
 | 
			
		||||
  include Impressionist::Impressionable
 | 
			
		||||
  
 | 
			
		||||
  is_impressionable :counter_cache => { :column_name => :view_count }
 | 
			
		||||
  
 | 
			
		||||
  field :content
 | 
			
		||||
  field :app_frontend_url
 | 
			
		||||
  field :theme_id, :type => BSON::ObjectId, :default => nil
 | 
			
		||||
  field :category
 | 
			
		||||
  field :tag
 | 
			
		||||
  field :view_count, :type => Integer, :default => 0
 | 
			
		||||
  
 | 
			
		||||
  belongs_to :design
 | 
			
		||||
  belongs_to :module_app
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -380,49 +380,7 @@
 | 
			
		|||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="item element">
 | 
			
		||||
        <h3><i class="icons-"></i><a href=""><%= t(:traffic) %></a></h3>
 | 
			
		||||
        <div class="detail w-a h-a">
 | 
			
		||||
            <p class="totle"><span><%= t(:total_visitors) %></span>438,913</p>
 | 
			
		||||
            <table class="table table-striped">
 | 
			
		||||
                <thead>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th><%= t(:item) %></th>
 | 
			
		||||
                        <th class="span2"><%= t(:data) %></th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </thead>
 | 
			
		||||
            </table>
 | 
			
		||||
            <div class="detal-list my_scroll">
 | 
			
		||||
                <div class="scrollbar">
 | 
			
		||||
                    <div class="track">
 | 
			
		||||
                        <div class="thumb">
 | 
			
		||||
                            <div class="end"></div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="viewport">
 | 
			
		||||
                    <div class="overview">
 | 
			
		||||
                        <table class="table table-striped">
 | 
			
		||||
                            <tbody>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <td>Visitors Today</td>
 | 
			
		||||
                                    <td>2,304</td>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <td>Visitors This Month</td>
 | 
			
		||||
                                    <td>783</td>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <td>Visitor This Tear</td>
 | 
			
		||||
                                    <td>45</td>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                            </tbody>
 | 
			
		||||
                        </table>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
    <div class="item element">
 | 
			
		||||
        <h3><i class="icons-"></i><a href=""><%= t(:site_info) %></a></h3>
 | 
			
		||||
        <div class="detail noStatistics w-b h-a">
 | 
			
		||||
| 
						 | 
				
			
			@ -481,6 +439,56 @@
 | 
			
		|||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div> -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <div class="item element">
 | 
			
		||||
        <h3><i class="icons-"></i><%= t(:traffic) %></h3>
 | 
			
		||||
        <div class="detail w-a h-a">
 | 
			
		||||
            <p class="totle"><span><%= t(:total_visitors) %></span><%= display_visitors %></p>
 | 
			
		||||
            <table class="table table-striped">
 | 
			
		||||
                <thead>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th><%= t(:item) %></th>
 | 
			
		||||
                        <th class="span2"><%= t(:data) %></th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </thead>
 | 
			
		||||
            </table>
 | 
			
		||||
            <div class="detal-list my_scroll">
 | 
			
		||||
                <div class="scrollbar">
 | 
			
		||||
                    <div class="track">
 | 
			
		||||
                        <div class="thumb">
 | 
			
		||||
                            <div class="end"></div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="viewport">
 | 
			
		||||
                    <div class="overview">
 | 
			
		||||
                        <table class="table table-striped">
 | 
			
		||||
                            <tbody>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <td><%= t(:visitors_today) %></td>
 | 
			
		||||
                                    <td><%= display_visitors_today %></td>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <td><%= t(:visitors_this_week) %></td>
 | 
			
		||||
                                    <td><%= display_visitors_this_week %></td>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <td><%= t(:visitors_this_month) %></td>
 | 
			
		||||
                                    <td><%= display_visitors_this_month %></td>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <td><%= t(:visitors_this_year) %></td>
 | 
			
		||||
                                    <td><%= display_visitors_this_year %></td>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                            </tbody>
 | 
			
		||||
                        </table>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="item element">
 | 
			
		||||
        <h3><i class="icons-"></i><%= t(:recent_update) %></h3>
 | 
			
		||||
        <div class="detail noStatistics w-b h-a">
 | 
			
		||||
| 
						 | 
				
			
			@ -517,4 +525,43 @@
 | 
			
		|||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="item element">
 | 
			
		||||
        <h3><i class="icons-"></i><%= t(:most_visited_page) %></h3>
 | 
			
		||||
        <div class="detail noStatistics w-b h-a">
 | 
			
		||||
            <table class="table table-striped">
 | 
			
		||||
                <thead>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th><%= t(:title) %></th>
 | 
			
		||||
                        <th class="span2"><%= t(:module) %></th>
 | 
			
		||||
                        <th class="span2"><%= t(:hits) %></th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </thead>
 | 
			
		||||
            </table>
 | 
			
		||||
            <div class="detal-list my_scroll">
 | 
			
		||||
                <div class="scrollbar">
 | 
			
		||||
                    <div class="track">
 | 
			
		||||
                        <div class="thumb">
 | 
			
		||||
                            <div class="end"></div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="viewport">
 | 
			
		||||
                    <div class="overview">
 | 
			
		||||
                        <table class="table table-striped">
 | 
			
		||||
                            <tbody>
 | 
			
		||||
                                <% @most_visited.each do |object| %>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td><%= link_to ((object[0].title[I18n.locale] rescue nil) || (object[0].page.i18n_variable[I18n.locale] rescue nil)), get_link_to_object(object[0]) %></td>
 | 
			
		||||
                                        <td class="span2"><%= link_to t("dashboard.#{object[0]._type.underscore}"), get_link(object[0]._type.underscore) %></td>
 | 
			
		||||
                                        <td class="span2"><%= object[1] %></td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                <% end %>
 | 
			
		||||
                            </tbody>
 | 
			
		||||
                        </table>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
# Use this hook to configure impressionist parameters
 | 
			
		||||
Impressionist.setup do |config|
 | 
			
		||||
  # Define ORM. Could be :active_record (default) and :mongo_mapper
 | 
			
		||||
  # config.orm = :active_record
 | 
			
		||||
  config.orm = :mongoid
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -42,6 +42,7 @@ en:
 | 
			
		|||
  sure?: Are you sure?
 | 
			
		||||
  update: Update
 | 
			
		||||
  view: View
 | 
			
		||||
  view_count: View count
 | 
			
		||||
  yes_: "Yes"
 | 
			
		||||
 | 
			
		||||
  all_content: All Content
 | 
			
		||||
| 
						 | 
				
			
			@ -67,6 +68,11 @@ en:
 | 
			
		|||
  total_visitors: Total Visitors
 | 
			
		||||
  traffic: Traffic
 | 
			
		||||
 | 
			
		||||
  visitors_today: Today's visitors
 | 
			
		||||
  visitors_this_week: This week's visitors
 | 
			
		||||
  visitors_this_month: This month's visitors
 | 
			
		||||
  visitors_this_year: This year's visitors
 | 
			
		||||
 | 
			
		||||
  admin:
 | 
			
		||||
    access:
 | 
			
		||||
      denied:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,11 +39,12 @@ zh_tw:
 | 
			
		|||
  sure?: 您肯定嗎?
 | 
			
		||||
  update: 更新
 | 
			
		||||
  view: 檢視
 | 
			
		||||
  view_count: 查看次數
 | 
			
		||||
  yes_: "Yes"
 | 
			
		||||
 | 
			
		||||
  all_content: 全部內容有:
 | 
			
		||||
  all_file: 全部檔案有:
 | 
			
		||||
  all_member: 成員總數:
 | 
			
		||||
  all_content: 全部內容有
 | 
			
		||||
  all_file: 全部檔案有
 | 
			
		||||
  all_member: 成員總數
 | 
			
		||||
  content: 內容
 | 
			
		||||
  data: 數據
 | 
			
		||||
  file: 檔案
 | 
			
		||||
| 
						 | 
				
			
			@ -61,9 +62,14 @@ zh_tw:
 | 
			
		|||
  site_name: 網站名稱
 | 
			
		||||
  statistics: 統計
 | 
			
		||||
  title: 標題
 | 
			
		||||
  total_visitors: 造訪次數:
 | 
			
		||||
  total_visitors: 造訪次數
 | 
			
		||||
  traffic: 流量
 | 
			
		||||
 | 
			
		||||
  visitors_today: 今日造訪
 | 
			
		||||
  visitors_this_week: 本星期造訪
 | 
			
		||||
  visitors_this_month: 本月造訪
 | 
			
		||||
  visitors_this_year: 今年造訪
 | 
			
		||||
 | 
			
		||||
  admin:
 | 
			
		||||
    access:
 | 
			
		||||
      denied:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,7 +27,8 @@ module ParserCommon
 | 
			
		|||
    res << "_#{i}" if i
 | 
			
		||||
    res << " active" if (current_page.id.eql?(page.id) || current_page.descendant_of?(page))
 | 
			
		||||
    res << "'>"
 | 
			
		||||
    res << "<a href='/#{edit ? admin_page_path(page.id) : page.path}'><span>#{page.i18n_variable[I18n.locale]}</span></a>"
 | 
			
		||||
    root = "/"
 | 
			
		||||
    res << "<a href='#{edit ? root + admin_page_path(page.id) : (page._type.eql?('Page') ? root + page.path : page.url)}'><span>#{page.i18n_variable[I18n.locale]}</span></a>"
 | 
			
		||||
    if page.visible_children.size > 0 && current <= menu.levels
 | 
			
		||||
      res << "<span class='dot'></span>"
 | 
			
		||||
      res << menu_level(page, current_page, current + 1, menu, edit)
 | 
			
		||||
| 
						 | 
				
			
			@ -119,7 +120,8 @@ module ParserCommon
 | 
			
		|||
        res << "<ul class='list'>"
 | 
			
		||||
        menu_page.visible_children.each do |child|
 | 
			
		||||
          res << "<li class='#{page.id.eql?(child.id) ? 'active' : nil}'>"
 | 
			
		||||
          res << "<a href='/#{edit ? admin_page_path(child.id) : child.path}'>#{child.i18n_variable[I18n.locale]}</a>"
 | 
			
		||||
          root = "/"
 | 
			
		||||
          res << "<a href='#{edit ? root + admin_page_path(child.id) : (child._type.eql?('Page') ? root + child.path : child.url)}'>#{child.i18n_variable[I18n.locale]}</a>"
 | 
			
		||||
          res << "</li>"
 | 
			
		||||
        end
 | 
			
		||||
        res << "</ul>"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,7 @@ class Panel::Announcement::FrontEnd::BulletinsController < OrbitWidgetController
 | 
			
		|||
      preview_content
 | 
			
		||||
    else
 | 
			
		||||
      @bulletin = Bulletin.can_display.where(_id: params[:id]).first
 | 
			
		||||
      impressionist(@bulletin)
 | 
			
		||||
      get_categorys
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,9 @@ class Bulletin
 | 
			
		|||
  include Mongoid::Document
 | 
			
		||||
  include Mongoid::Timestamps
 | 
			
		||||
  include Mongoid::MultiParameterAttributes
 | 
			
		||||
  include Impressionist::Impressionable
 | 
			
		||||
 | 
			
		||||
  is_impressionable :counter_cache => { :column_name => :view_count }
 | 
			
		||||
 | 
			
		||||
  has_one :title, :class_name => "I18nVariable", :as => :language_value, :autosave => true, :dependent => :destroy
 | 
			
		||||
  has_one :subtitle, :class_name => "I18nVariable", :as => :language_value, :autosave => true, :dependent => :destroy
 | 
			
		||||
| 
						 | 
				
			
			@ -23,6 +26,7 @@ class Bulletin
 | 
			
		|||
  field :is_pending, :type => Boolean, :default => true 
 | 
			
		||||
  field :is_rejected, :type => Boolean, :default => false 
 | 
			
		||||
 | 
			
		||||
  field :view_count, :type => Integer, :default => 0
 | 
			
		||||
  
 | 
			
		||||
  field :not_checked_reason
 | 
			
		||||
  
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -99,12 +99,6 @@
 | 
			
		|||
							<% end %>
 | 
			
		||||
						<% end %>
 | 
			
		||||
					</p>
 | 
			
		||||
		           	<span class="label label-tags">Default<a href><i class="icon-remove icon-white"></i></a></span>
 | 
			
		||||
		           	<span class="label label-tags">Default<a href><i class="icon-remove icon-white"></i></a></span>
 | 
			
		||||
		           	<span class="label label-tags">Default<a href><i class="icon-remove icon-white"></i></a></span>
 | 
			
		||||
		           	<span class="label label-tags">Default<a href><i class="icon-remove icon-white"></i></a></span>
 | 
			
		||||
		            <hr>
 | 
			
		||||
					<input type="text" class="input-xlarge">
 | 
			
		||||
				</div>
 | 
			
		||||
		</div> 
 | 
			
		||||
  	<% if params[:action] != 'new' %>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@
 | 
			
		|||
		<span class="date"><%= @bulletin.postdate %></span>
 | 
			
		||||
		 | 
 | 
			
		||||
		<a href="" class="unit"><%= User.find(@bulletin.create_user_id).sub_roles.collect{|t| t.key}.join(" ") rescue '' %></a>
 | 
			
		||||
		<span><%= dislpay_view_count(@bulletin) %></span>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
<div class="news_image">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,7 @@ class Panel::News::FrontEnd::NewsBulletinsController < OrbitWidgetController
 | 
			
		|||
      preview_content
 | 
			
		||||
    else
 | 
			
		||||
      @news_bulletin = NewsBulletin.can_display.where(_id: params[:id]).first
 | 
			
		||||
      impressionist(@news_bulletin)
 | 
			
		||||
      get_categorys
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,10 @@
 | 
			
		|||
class NewsBulletin
 | 
			
		||||
  include Mongoid::Document
 | 
			
		||||
  include Mongoid::Timestamps
 | 
			
		||||
  include Mongoid::MultiParameterAttributes
 | 
			
		||||
  include Mongoid::MultiParameterAttributes  
 | 
			
		||||
  include Impressionist::Impressionable
 | 
			
		||||
 | 
			
		||||
  is_impressionable :counter_cache => { :column_name => :view_count }
 | 
			
		||||
 | 
			
		||||
  has_one :title, :class_name => "I18nVariable", :as => :language_value, :autosave => true, :dependent => :destroy
 | 
			
		||||
  has_one :subtitle, :class_name => "I18nVariable", :as => :language_value, :autosave => true, :dependent => :destroy
 | 
			
		||||
| 
						 | 
				
			
			@ -23,6 +26,7 @@ class NewsBulletin
 | 
			
		|||
  field :is_pending, :type => Boolean, :default => true 
 | 
			
		||||
  field :is_rejected, :type => Boolean, :default => false 
 | 
			
		||||
 | 
			
		||||
  field :view_count, :type => Integer, :default => 0
 | 
			
		||||
  
 | 
			
		||||
  field :not_checked_reason
 | 
			
		||||
  
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@
 | 
			
		|||
		<span class="date"><%= @news_bulletin.postdate %></span>
 | 
			
		||||
		 | 
 | 
			
		||||
		<a href="" class="unit"><%= @news_bulletin.unit_list_for_anc.title[I18n.locale] rescue '' %></a>
 | 
			
		||||
		<span><%= dislpay_view_count(@news_bulletin) %></span>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
<div class="news_image">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,10 +6,10 @@ class Panel::PageContent::FrontEnd::PageContextsController < OrbitWidgetControll
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def index
 | 
			
		||||
	
 | 
			
		||||
	# @page_context = PageContext.where("page_id" => params[:page_id], :archived => false)
 | 
			
		||||
	@page_context = PageContext.first(conditions: { page_id: params[:page_id], :archived => false })
 | 
			
		||||
 | 
			
		||||
    # @page_context = PageContext.where("page_id" => params[:page_id], :archived => false)
 | 
			
		||||
    @page_context = PageContext.first(conditions: { page_id: params[:page_id], :archived => false })
 | 
			
		||||
    impressionist(@page_context)
 | 
			
		||||
    
 | 
			
		||||
    respond_to do |format|
 | 
			
		||||
      format.html # index.html.erb
 | 
			
		||||
      format.xml  { render :xml => @page_contexts }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,15 +4,17 @@ class PageContext
 | 
			
		|||
  include Mongoid::Document
 | 
			
		||||
  include Mongoid::Timestamps
 | 
			
		||||
  include Mongoid::MultiParameterAttributes
 | 
			
		||||
 | 
			
		||||
  include Impressionist::Impressionable
 | 
			
		||||
  include OrbitCoreLib::ObjectAuthable
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  is_impressionable :counter_cache => { :column_name => :view_count }
 | 
			
		||||
 | 
			
		||||
  has_one :context, :class_name => "I18nVariable", :as => :language_value, :autosave => true, :dependent => :destroy
 | 
			
		||||
 | 
			
		||||
  field :create_user_id
 | 
			
		||||
  field :update_user_id
 | 
			
		||||
  field :version, :type => Integer , :default => 0
 | 
			
		||||
  field :view_count, :type => Integer, :default => 0
 | 
			
		||||
  
 | 
			
		||||
  field :archived, :type => Boolean, :default => false
 | 
			
		||||
  # field :current, :type => Boolean, :default => false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,23 +1,23 @@
 | 
			
		|||
 | 
			
		||||
			<tr id="<%= dom_id page_context %>" class="with_action">
 | 
			
		||||
				<td>
 | 
			
		||||
					<%= page_context.page.path %>
 | 
			
		||||
					<div class="quick-edit">
 | 
			
		||||
						<ul class="nav nav-pills hide">
 | 
			
		||||
							<%if is_manager? || is_admin? ||  page_context.authed_users(:edit).include?(current_user)%>
 | 
			
		||||
							<li><%= link_to t('admin.page_context.edit'), edit_panel_page_content_back_end_page_context_path(page_context) %></li>
 | 
			
		||||
							<%if (is_manager? || is_admin?) %>
 | 
			
		||||
								<li><%=show_page_context_edit_auth_link page_context%></li>
 | 
			
		||||
							<% end%>
 | 
			
		||||
							<% end -%>
 | 
			
		||||
						</ul>
 | 
			
		||||
					</div>
 | 
			
		||||
				</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<%if is_manager? || is_admin? ||  page_context.authed_users(:edit).include?(current_user)%>
 | 
			
		||||
						<%= link_to page_context.version, panel_page_content_back_end_view_path(page_context.page_id) %>
 | 
			
		||||
					<%end -%>
 | 
			
		||||
				</td>
 | 
			
		||||
				<td><%= page_context.updated_at.strftime("%Y-%m-%d %H:%I:%S") %></td>
 | 
			
		||||
				<td><%= User.find(page_context.create_user_id).name %></td>
 | 
			
		||||
			</tr>
 | 
			
		||||
<tr id="<%= dom_id page_context %>" class="with_action">
 | 
			
		||||
	<td>
 | 
			
		||||
		<%= page_context.page.path %></br>
 | 
			
		||||
		<%= page_context.page.i18n_variable[I18n.locale] %>
 | 
			
		||||
		<div class="quick-edit">
 | 
			
		||||
			<ul class="nav nav-pills hide">
 | 
			
		||||
				<%if is_manager? || is_admin? ||  page_context.authed_users(:edit).include?(current_user)%>
 | 
			
		||||
				<li><%= link_to t('admin.page_context.edit'), edit_panel_page_content_back_end_page_context_path(page_context) %></li>
 | 
			
		||||
				<%if (is_manager? || is_admin?) %>
 | 
			
		||||
					<li><%=show_page_context_edit_auth_link page_context%></li>
 | 
			
		||||
				<% end%>
 | 
			
		||||
				<% end -%>
 | 
			
		||||
			</ul>
 | 
			
		||||
		</div>
 | 
			
		||||
	</td>
 | 
			
		||||
	<td>
 | 
			
		||||
		<%if is_manager? || is_admin? ||  page_context.authed_users(:edit).include?(current_user)%>
 | 
			
		||||
			<%= link_to page_context.version, panel_page_content_back_end_view_path(page_context.page_id) %>
 | 
			
		||||
		<%end -%>
 | 
			
		||||
	</td>
 | 
			
		||||
	<td><%= page_context.updated_at.strftime("%Y-%m-%d %H:%I:%S") %></td>
 | 
			
		||||
	<td><%= User.find(page_context.create_user_id).name %></td>
 | 
			
		||||
</tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -6,3 +6,5 @@
 | 
			
		|||
<h1 class="h1"><%= @page_context.page.i18n_variable[I18n.locale] rescue nil %></h1>
 | 
			
		||||
 | 
			
		||||
<div class="page_content"><%= @page_context.context[I18n.locale].html_safe rescue nil %></div>
 | 
			
		||||
 | 
			
		||||
<div><%= dislpay_view_count(@page_context) %></div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
*~
 | 
			
		||||
/coverage
 | 
			
		||||
/pkg
 | 
			
		||||
/rdoc
 | 
			
		||||
/test_app/db/schema.rb
 | 
			
		||||
/test_app/db/migrate/*_create_impressions_table.rb
 | 
			
		||||
/test_app/doc
 | 
			
		||||
/test_app/test
 | 
			
		||||
/test_app/vendor
 | 
			
		||||
Gemfile.lock
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
--color
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
before_install: gem install bundler
 | 
			
		||||
before_script: "cd test_app && bundle install && ./script/rails generate impressionist && bundle exec rake db:migrate && cd .."
 | 
			
		||||
language: ruby
 | 
			
		||||
rvm:
 | 
			
		||||
  - rbx-18mode
 | 
			
		||||
  - rbx-19mode
 | 
			
		||||
  - jruby-18mode
 | 
			
		||||
  - 1.8.7
 | 
			
		||||
  - 1.9.2
 | 
			
		||||
  - 1.9.3
 | 
			
		||||
  - ruby-head
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
== 0.4.0 (2011-06-03)
 | 
			
		||||
* Fix postgres bug
 | 
			
		||||
* New impression count method that accepts options for filter, start_date and end_date
 | 
			
		||||
* Add referrer to Impression model.  YOU MUST RUN THE UPGRADE MIGRATION IF YOU ARE UPGRADING FROM 0.3.0
 | 
			
		||||
* UPGRADE MIGRATION = impressionist/upgrade_migrations/version_0_4_0.rb
 | 
			
		||||
* NOTE IF YOU ARE UPGRADING FROM 0.2.5 OR BELOW, YOU MUST RUN BOTH UPGRADE MIGRATIONS
 | 
			
		||||
 | 
			
		||||
== 0.3.0 (2011-03-06)
 | 
			
		||||
* added session_hash to impression model
 | 
			
		||||
* migration template updated to add session_hash
 | 
			
		||||
* new count instance method for impressionable model - unique_impression_count_session
 | 
			
		||||
* NOTE: if you are upgrading from 0.2.5, then run the migration in the 'upgrade_migrations' dir
 | 
			
		||||
 | 
			
		||||
== 0.2.5 (2011-02-17)
 | 
			
		||||
* New model method - @widget.unique_impression_count_ip  - This gives you unique impression account filtered by IP (and in turn request_hash since they have same IPs)
 | 
			
		||||
* @widget.unique_impression_count now uses request_hash.  This was incorrectly stated in the README, since it was using ip_address.  The README is correct as a result of the method change.
 | 
			
		||||
 | 
			
		||||
== 0.2.4 (2011-02-17)
 | 
			
		||||
* Fix issue #1 - action_name and controller_name were not being logged for impressionist method inside action
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
source 'https://rubygems.org'
 | 
			
		||||
 | 
			
		||||
platforms :jruby do
 | 
			
		||||
  gem 'activerecord-jdbcsqlite3-adapter'
 | 
			
		||||
  gem 'jdbc-sqlite3'
 | 
			
		||||
  gem 'jruby-openssl'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
platforms :ruby, :mswin, :mingw do
 | 
			
		||||
  # gem 'sqlite3'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
gemspec
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
Copyright (c) 2011 cowboycoded
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining
 | 
			
		||||
a copy of this software and associated documentation files (the
 | 
			
		||||
"Software"), to deal in the Software without restriction, including
 | 
			
		||||
without limitation the rights to use, copy, modify, merge, publish,
 | 
			
		||||
distribute, sublicense, and/or sell copies of the Software, and to
 | 
			
		||||
permit persons to whom the Software is furnished to do so, subject to
 | 
			
		||||
the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be
 | 
			
		||||
included in all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
			
		||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 | 
			
		||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 | 
			
		||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 | 
			
		||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,198 @@
 | 
			
		|||

 | 
			
		||||
 | 
			
		||||
[](http://travis-ci.org/charlotte-ruby/impressionist)
 | 
			
		||||
 | 
			
		||||
impressionist
 | 
			
		||||
=============
 | 
			
		||||
 | 
			
		||||
A lightweight plugin that logs impressions per action or manually per model
 | 
			
		||||
 | 
			
		||||
--------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
What does this thing do?
 | 
			
		||||
------------------------
 | 
			
		||||
Logs an impression... and I use that term loosely.  It can log page impressions
 | 
			
		||||
(technically action impressions), but it is not limited to that. You can log
 | 
			
		||||
impressions multiple times per request.  And you can also attach it to a model.
 | 
			
		||||
The goal of this project is to provide customizable stats that are immediately
 | 
			
		||||
accessible in your application as opposed to using Google Analytics and pulling
 | 
			
		||||
data using their API.  You can attach custom messages to impressions.  No
 | 
			
		||||
reporting yet.. this thingy just creates the data.
 | 
			
		||||
 | 
			
		||||
What about bots?
 | 
			
		||||
----------------
 | 
			
		||||
They are ignored.  1200 known bots have been added to the ignore list as of
 | 
			
		||||
February 1, 2011.  Impressionist uses this list:
 | 
			
		||||
http://www.user-agents.org/allagents.xml
 | 
			
		||||
 | 
			
		||||
Installation
 | 
			
		||||
------------
 | 
			
		||||
Add it to your Gemfile
 | 
			
		||||
 | 
			
		||||
    gem 'impressionist'
 | 
			
		||||
 | 
			
		||||
Install with Bundler
 | 
			
		||||
 | 
			
		||||
    bundle install
 | 
			
		||||
 | 
			
		||||
Generate the impressions table migration
 | 
			
		||||
 | 
			
		||||
    rails g impressionist
 | 
			
		||||
 | 
			
		||||
Run the migration
 | 
			
		||||
 | 
			
		||||
    rake db:migrate
 | 
			
		||||
 | 
			
		||||
The following fields are provided in the migration:
 | 
			
		||||
 | 
			
		||||
    t.string   "impressionable_type"  # model type: Widget
 | 
			
		||||
    t.integer  "impressionable_id"    # model instance ID: @widget.id
 | 
			
		||||
    t.integer  "user_id"              # automatically logs @current_user.id
 | 
			
		||||
    t.string   "controller_name"      # logs the controller name
 | 
			
		||||
    t.string   "action_name"          # logs the action_name
 | 
			
		||||
    t.string   "view_name"            # TODO: log individual views (as well as partials and nested partials)
 | 
			
		||||
    t.string   "request_hash"         # unique ID per request, in case you want to log multiple impressions and group them
 | 
			
		||||
    t.string   "session_hash"         # logs the rails session
 | 
			
		||||
    t.string   "ip_address"           # request.remote_ip
 | 
			
		||||
    t.string   "referrer"             # request.referer
 | 
			
		||||
    t.string   "message"              # custom message you can add
 | 
			
		||||
    t.datetime "created_at"           # I am not sure what this is.... Any clue?
 | 
			
		||||
    t.datetime "updated_at"           # never seen this one before either....  Your guess is as good as mine??
 | 
			
		||||
 | 
			
		||||
Usage
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
1. Log all actions in a controller
 | 
			
		||||
 | 
			
		||||
        WidgetsController < ApplicationController
 | 
			
		||||
          impressionist
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
2. Specify actions you want logged in a controller
 | 
			
		||||
 | 
			
		||||
        WidgetsController < ApplicationController
 | 
			
		||||
          impressionist :actions=>[:show,:index]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
3. Make your models impressionable.  This allows you to attach impressions to
 | 
			
		||||
   an AR model instance.  Impressionist will automatically log the Model name
 | 
			
		||||
   (based on action_name) and the id (based on params[:id]), but in order to
 | 
			
		||||
   get the count of impressions (example: @widget.impression_count), you will
 | 
			
		||||
   need to make your model impressionalble
 | 
			
		||||
 | 
			
		||||
        class Widget < ActiveRecord::Base
 | 
			
		||||
          is_impressionable
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
4. Log an impression per model instance in your controller.  Note that it is
 | 
			
		||||
   not necessary to specify "impressionist" (usage #1) in the top of you
 | 
			
		||||
   controller if you are using this method.  If you add "impressionist" to the
 | 
			
		||||
   top of your controller and also use this method in your action, it will
 | 
			
		||||
   result in 2 impressions being logged (but associated with one request_hash)
 | 
			
		||||
 | 
			
		||||
        def show
 | 
			
		||||
          @widget = Widget.find
 | 
			
		||||
          impressionist(@widget,message:"wtf is a widget?") #message is optional
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
5. Get unique impression count from a model.  This groups impressions by
 | 
			
		||||
   request_hash, so if you logged multiple impressions per request, it will
 | 
			
		||||
   only count them one time.  This unique impression count will not filter out
 | 
			
		||||
   unique users, only unique requests
 | 
			
		||||
 | 
			
		||||
        @widget.impressionist_count
 | 
			
		||||
        @widget.impressionist_count(:start_date=>"2011-01-01",:end_date=>"2011-01-05")
 | 
			
		||||
        @widget.impressionist_count(:start_date=>"2011-01-01")  #specify start date only, end date = now
 | 
			
		||||
 | 
			
		||||
6. Get the unique impression count from a model filtered by IP address.  This
 | 
			
		||||
   in turn will give you impressions with unique request_hash, since rows with
 | 
			
		||||
   the same request_hash will have the same IP address.
 | 
			
		||||
 | 
			
		||||
        @widget.impressionist_count(:filter=>:ip_address)
 | 
			
		||||
 | 
			
		||||
7. Get the unique impression count from a model filtered by session hash.  Same
 | 
			
		||||
   as #6 regarding request hash.  This may be more desirable than filtering by
 | 
			
		||||
   IP address depending on your situation, since filtering by IP may ignore
 | 
			
		||||
   visitors that use the same IP.  The downside to this filtering is that a
 | 
			
		||||
   user could clear session data in their browser and skew the results.
 | 
			
		||||
 | 
			
		||||
        @widget.impressionist_count(:filter=>:session_hash)
 | 
			
		||||
 | 
			
		||||
8. Get total impression count.  This may return more than 1 impression per http
 | 
			
		||||
   request, depending on how you are logging impressions
 | 
			
		||||
 | 
			
		||||
        @widget.impressionist_count(:filter=>:all)
 | 
			
		||||
 | 
			
		||||
Logging impressions for authenticated users happens automatically.  If you have
 | 
			
		||||
a current_user helper or use @current_user in your before_filter to set your
 | 
			
		||||
authenticated user, current_user.id will be written to the user_id field in the
 | 
			
		||||
impressions table.
 | 
			
		||||
 | 
			
		||||
Adding a counter cache
 | 
			
		||||
----------------------
 | 
			
		||||
Impressionist makes it easy to add a `counter_cache` column to your model. The
 | 
			
		||||
most basic configuration looks like:
 | 
			
		||||
 | 
			
		||||
    is_impressionable :counter_cache => true
 | 
			
		||||
 | 
			
		||||
This will automatically increment the `impressions_count` column in the
 | 
			
		||||
included model. Note: You'll need to add that column to your model. If you'd
 | 
			
		||||
like specific a different column name, you can:
 | 
			
		||||
 | 
			
		||||
    is_impressionable :counter_cache => { :column_name => :my_column }
 | 
			
		||||
 | 
			
		||||
If you'd like to include only unique impressions in your count:
 | 
			
		||||
 | 
			
		||||
    is_impressionable :counter_cache => { :column_name => :my_column, :unique => true }
 | 
			
		||||
 | 
			
		||||
What if I only want to record unique impressions?
 | 
			
		||||
-------------------------------------------------
 | 
			
		||||
Maybe you only care about unique impressions and would like to avoid
 | 
			
		||||
unnecessary database records. You can specify conditions for recording
 | 
			
		||||
impressions in your controller:
 | 
			
		||||
 | 
			
		||||
    # only record impression if the request has a unique combination of type, id, and session
 | 
			
		||||
    impressionist :unique => [:impressionable_type, :impressionable_id, :session_hash]
 | 
			
		||||
 | 
			
		||||
    # only record impression if the request has a unique combination of controller, action, and session
 | 
			
		||||
    impressionist :unique => [:controller_name, :action_name, :session_hash]
 | 
			
		||||
 | 
			
		||||
    # only record impression if session is unique
 | 
			
		||||
    impressionist :unique => [:session_hash]
 | 
			
		||||
 | 
			
		||||
Or you can use the `impressionist` method directly:
 | 
			
		||||
 | 
			
		||||
    impressionist(impressionable, "some message", :unique => [:session_hash])
 | 
			
		||||
 | 
			
		||||
Development Roadmap
 | 
			
		||||
-------------------
 | 
			
		||||
* Automatic impression logging in views.  For example, log initial view, and
 | 
			
		||||
  any partials called from initial view
 | 
			
		||||
* Customizable black list for user-agents or IP addresses.  Impressions will be
 | 
			
		||||
  ignored.  Web admin as part of the Engine.
 | 
			
		||||
* Reporting engine
 | 
			
		||||
* AB testing integration
 | 
			
		||||
 | 
			
		||||
Contributing to impressionist
 | 
			
		||||
-----------------------------
 | 
			
		||||
* Check out the latest master to make sure the feature hasn't been implemented
 | 
			
		||||
  or the bug hasn't been fixed yet
 | 
			
		||||
* Check out the issue tracker to make sure someone already hasn't requested it
 | 
			
		||||
  and/or contributed it
 | 
			
		||||
* Fork the project
 | 
			
		||||
* Start a feature/bugfix branch
 | 
			
		||||
* Commit and push until you are happy with your contribution
 | 
			
		||||
* Make sure to add rpsec tests for it. Patches or features without tests will
 | 
			
		||||
  be ignored.  Also, try to write better tests than I do ;-)
 | 
			
		||||
* If adding engine controller or view functionality, use HAML and Inherited
 | 
			
		||||
  Resources.
 | 
			
		||||
* All testing is done inside a small Rails app (test_app).  You will find specs
 | 
			
		||||
  within this app.
 | 
			
		||||
 | 
			
		||||
Contributors
 | 
			
		||||
------------
 | 
			
		||||
* [johnmcaliley](https://github.com/johnmcaliley)
 | 
			
		||||
* [coryschires](https://github.com/coryschires)
 | 
			
		||||
* [georgmittendorfer](https://github.com/georgmittendorfer)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2011 John McAliley. See LICENSE.txt for further details.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
require 'bundler/setup'
 | 
			
		||||
require 'rspec/core/rake_task'
 | 
			
		||||
 | 
			
		||||
Bundler::GemHelper.install_tasks
 | 
			
		||||
 | 
			
		||||
RSpec::Core::RakeTask.new do |task|
 | 
			
		||||
  task.rspec_opts = "-I ./test_app/spec"
 | 
			
		||||
  task.pattern = "./test_app/spec/**/*_spec.rb"
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
task :test => :spec
 | 
			
		||||
task :default => :spec
 | 
			
		||||
 | 
			
		||||
namespace :impressionist do
 | 
			
		||||
  require File.dirname(__FILE__) + "/lib/impressionist/bots"
 | 
			
		||||
 | 
			
		||||
  desc "output the list of bots from http://www.user-agents.org/"
 | 
			
		||||
  task :bots do
 | 
			
		||||
    p Impressionist::Bots.consume
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,103 @@
 | 
			
		|||
require 'digest/sha2'
 | 
			
		||||
 | 
			
		||||
module ImpressionistController
 | 
			
		||||
  module ClassMethods
 | 
			
		||||
    def impressionist(opts={})
 | 
			
		||||
      before_filter { |c| c.impressionist_subapp_filter(opts[:actions], opts[:unique])}
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  module InstanceMethods
 | 
			
		||||
    def self.included(base)
 | 
			
		||||
      base.before_filter :impressionist_app_filter
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def impressionist(obj,message=nil,opts={})
 | 
			
		||||
      unless bypass
 | 
			
		||||
        if obj.respond_to?("impressionable?")
 | 
			
		||||
          if unique_instance?(obj, opts[:unique])
 | 
			
		||||
            obj.impressions.create(associative_create_statement({:message => message}))
 | 
			
		||||
          end
 | 
			
		||||
        else
 | 
			
		||||
          # we could create an impression anyway. for classes, too. why not?
 | 
			
		||||
          raise "#{obj.class.to_s} is not impressionable!"
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def impressionist_app_filter
 | 
			
		||||
      @impressionist_hash = Digest::SHA2.hexdigest(Time.now.to_f.to_s+rand(10000).to_s)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def impressionist_subapp_filter(actions=nil,unique_opts=nil)
 | 
			
		||||
      unless bypass
 | 
			
		||||
        actions.collect!{|a|a.to_s} unless actions.blank?
 | 
			
		||||
        if (actions.blank? || actions.include?(action_name)) && unique?(unique_opts)
 | 
			
		||||
          Impression.create(direct_create_statement)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    private
 | 
			
		||||
 | 
			
		||||
    def bypass
 | 
			
		||||
      Impressionist::Bots.bot?(request.user_agent)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def unique_instance?(impressionable, unique_opts)
 | 
			
		||||
      return unique_opts.blank? || !impressionable.impressions.where(unique_query(unique_opts)).exists?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def unique?(unique_opts)
 | 
			
		||||
      return unique_opts.blank? || !Impression.where(unique_query(unique_opts)).exists?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # creates the query to check for uniqueness
 | 
			
		||||
    def unique_query(unique_opts)
 | 
			
		||||
      full_statement = direct_create_statement
 | 
			
		||||
      # reduce the full statement to the params we need for the specified unique options
 | 
			
		||||
      unique_opts.reduce({}) do |query, param|
 | 
			
		||||
        query[param] = full_statement[param]
 | 
			
		||||
        query
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # creates a statment hash that contains default values for creating an impression via an AR relation.
 | 
			
		||||
    def associative_create_statement(query_params={})
 | 
			
		||||
      query_params.reverse_merge!(
 | 
			
		||||
        :controller_name => controller_name,
 | 
			
		||||
        :action_name => action_name,
 | 
			
		||||
        :user_id => user_id,
 | 
			
		||||
        :request_hash => @impressionist_hash,
 | 
			
		||||
        :session_hash => session_hash,
 | 
			
		||||
        :ip_address => request.remote_ip,
 | 
			
		||||
        :referrer => request.referer
 | 
			
		||||
        )
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # creates a statment hash that contains default values for creating an impression.
 | 
			
		||||
    def direct_create_statement(query_params={})
 | 
			
		||||
      query_params.reverse_merge!(
 | 
			
		||||
        :impressionable_type => controller_name.singularize.camelize,
 | 
			
		||||
        :impressionable_id=> params[:id]
 | 
			
		||||
        )
 | 
			
		||||
      associative_create_statement(query_params)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def session_hash
 | 
			
		||||
      # # careful: request.session_options[:id] encoding in rspec test was ASCII-8BIT
 | 
			
		||||
      # # that broke the database query for uniqueness. not sure if this is a testing only issue.
 | 
			
		||||
      # str = request.session_options[:id]
 | 
			
		||||
      # logger.debug "Encoding: #{str.encoding.inspect}"
 | 
			
		||||
      # # request.session_options[:id].encode("ISO-8859-1")
 | 
			
		||||
      request.session_options[:id]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    #use both @current_user and current_user helper
 | 
			
		||||
    def user_id
 | 
			
		||||
      user_id = @current_user ? @current_user.id : nil rescue nil
 | 
			
		||||
      user_id = current_user ? current_user.id : nil rescue nil if user_id.blank?
 | 
			
		||||
      user_id
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
class Impression
 | 
			
		||||
  belongs_to :impressionable, :polymorphic=>true
 | 
			
		||||
end
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
module Impressionist
 | 
			
		||||
  module Impressionable
 | 
			
		||||
    extend ActiveSupport::Concern
 | 
			
		||||
 | 
			
		||||
    module ClassMethods
 | 
			
		||||
      attr_accessor :impressionist_cache_options
 | 
			
		||||
      @impressionist_cache_options = nil
 | 
			
		||||
 | 
			
		||||
      def impressionist_counter_cache_options
 | 
			
		||||
        if @impressionist_cache_options
 | 
			
		||||
          options = { :column_name => :impressions_count, :unique => false }
 | 
			
		||||
          options.merge!(@impressionist_cache_options) if @impressionist_cache_options.is_a?(Hash)
 | 
			
		||||
          options
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def impressionist_counter_caching?
 | 
			
		||||
        impressionist_counter_cache_options.present?
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def counter_caching?
 | 
			
		||||
        ::ActiveSupport::Deprecation.warn("#counter_caching? is deprecated; please use #impressionist_counter_caching? instead")
 | 
			
		||||
        impressionist_counter_caching?
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def impressionable?
 | 
			
		||||
      true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def impressionist_count(options={})
 | 
			
		||||
      # options.reverse_merge!(:filter=>:request_hash, :start_date=>nil, :end_date=>Time.now)
 | 
			
		||||
      # imps = options[:start_date].blank? ? impressions : impressions.where("created_at>=? and created_at<=?",options[:start_date],options[:end_date])
 | 
			
		||||
      # options[:filter] == :all ? imps.count : imps.count(options[:filter], :distinct => true)
 | 
			
		||||
      options.reverse_merge!(:filter => :request_hash, :start_date => nil, :end_date => Time.now)
 | 
			
		||||
      imps = options[:start_date].blank? ? impressions : impressions.where(:created_at.gte => options[:start_date], :created_at.lte => options[:end_date])
 | 
			
		||||
      options[:filter] == :all ? imps.count : imps.distinct(options[:filter]).count
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def update_impressionist_counter_cache
 | 
			
		||||
      cache_options = self.class.impressionist_counter_cache_options
 | 
			
		||||
      column_name = cache_options[:column_name].to_sym
 | 
			
		||||
      count = cache_options[:unique] ? impressionist_count(:filter => :ip_address) : impressionist_count
 | 
			
		||||
      update_attribute(column_name, count)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # OLD METHODS - DEPRECATE IN V0.5
 | 
			
		||||
    def impression_count(start_date=nil,end_date=Time.now)
 | 
			
		||||
      impressionist_count({:start_date=>start_date, :end_date=>end_date, :filter=>:all})
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def unique_impression_count(start_date=nil,end_date=Time.now)
 | 
			
		||||
      impressionist_count({:start_date=>start_date, :end_date=>end_date, :filter=> :request_hash})
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def unique_impression_count_ip(start_date=nil,end_date=Time.now)
 | 
			
		||||
      impressionist_count({:start_date=>start_date, :end_date=>end_date, :filter=> :ip_address})
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def unique_impression_count_session(start_date=nil,end_date=Time.now)
 | 
			
		||||
      impressionist_count({:start_date=>start_date, :end_date=>end_date, :filter=> :session_hash})
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
# encoding: utf-8
 | 
			
		||||
require File.expand_path('../lib/impressionist/version', __FILE__)
 | 
			
		||||
 | 
			
		||||
Gem::Specification.new do |s|
 | 
			
		||||
  s.add_dependency 'httpclient', '~> 2.2'
 | 
			
		||||
  s.add_dependency 'nokogiri', '~> 1.5'
 | 
			
		||||
  s.add_development_dependency 'capybara'
 | 
			
		||||
  s.add_development_dependency 'rake', '>= 0.9'
 | 
			
		||||
  s.add_development_dependency 'rails', '~>3.1'
 | 
			
		||||
  s.add_development_dependency 'rdoc', '>= 2.4.2'
 | 
			
		||||
  s.add_development_dependency 'rspec-rails'
 | 
			
		||||
  s.add_development_dependency 'simplecov'
 | 
			
		||||
  s.add_development_dependency 'sqlite3'
 | 
			
		||||
  s.add_development_dependency 'systemu'
 | 
			
		||||
  s.authors = ["johnmcaliley"]
 | 
			
		||||
  s.description = "Log impressions from controller actions or from a model"
 | 
			
		||||
  s.email = "john.mcaliley@gmail.com"
 | 
			
		||||
  s.files = `git ls-files`.split("\n")
 | 
			
		||||
  s.homepage = "https://github.com/charlotte-ruby/impressionist"
 | 
			
		||||
  s.licenses = ["MIT"]
 | 
			
		||||
  s.name = "impressionist"
 | 
			
		||||
  s.require_paths = ["lib"]
 | 
			
		||||
  s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if s.respond_to? :required_rubygems_version=
 | 
			
		||||
  s.summary = "Easy way to log impressions"
 | 
			
		||||
  s.test_files = `git ls-files -- test_app/*`.split("\n")
 | 
			
		||||
  s.version = Impressionist::VERSION
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										21
									
								
								vendor/impressionist/lib/generators/active_record/impressionist_generator.rb
								
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										21
									
								
								vendor/impressionist/lib/generators/active_record/impressionist_generator.rb
								
								
								
									vendored
								
								
									Normal file
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
module ActiveRecord
 | 
			
		||||
  module Generators
 | 
			
		||||
    class ImpressionistGenerator < Rails::Generators::Base
 | 
			
		||||
      include Rails::Generators::Migration
 | 
			
		||||
      source_root File.join(File.dirname(__FILE__), 'templates')
 | 
			
		||||
 | 
			
		||||
      def self.next_migration_number(dirname)
 | 
			
		||||
        sleep 1
 | 
			
		||||
        if ActiveRecord::Base.timestamped_migrations
 | 
			
		||||
          Time.now.utc.strftime("%Y%m%d%H%M%S")
 | 
			
		||||
        else
 | 
			
		||||
          "%.3d" % (current_migration_number(dirname) + 1)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def create_migration_file
 | 
			
		||||
        migration_template 'create_impressions_table.rb', 'db/migrate/create_impressions_table.rb'
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										30
									
								
								vendor/impressionist/lib/generators/active_record/templates/create_impressions_table.rb
								
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										30
									
								
								vendor/impressionist/lib/generators/active_record/templates/create_impressions_table.rb
								
								
								
									vendored
								
								
									Normal file
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
class CreateImpressionsTable < ActiveRecord::Migration
 | 
			
		||||
  def self.up
 | 
			
		||||
    create_table :impressions, :force => true do |t|
 | 
			
		||||
      t.string :impressionable_type
 | 
			
		||||
      t.integer :impressionable_id
 | 
			
		||||
      t.integer :user_id
 | 
			
		||||
      t.string :controller_name
 | 
			
		||||
      t.string :action_name
 | 
			
		||||
      t.string :view_name
 | 
			
		||||
      t.string :request_hash
 | 
			
		||||
      t.string :ip_address
 | 
			
		||||
      t.string :session_hash
 | 
			
		||||
      t.text :message
 | 
			
		||||
      t.text :referrer
 | 
			
		||||
      t.timestamps
 | 
			
		||||
    end
 | 
			
		||||
    add_index :impressions, [:impressionable_type, :message, :impressionable_id], :name => "impressionable_type_message_index", :unique => false
 | 
			
		||||
    add_index :impressions, [:impressionable_type, :impressionable_id, :request_hash], :name => "poly_request_index", :unique => false
 | 
			
		||||
    add_index :impressions, [:impressionable_type, :impressionable_id, :ip_address], :name => "poly_ip_index", :unique => false
 | 
			
		||||
    add_index :impressions, [:impressionable_type, :impressionable_id, :session_hash], :name => "poly_session_index", :unique => false
 | 
			
		||||
    add_index :impressions, [:controller_name,:action_name,:request_hash], :name => "controlleraction_request_index", :unique => false
 | 
			
		||||
    add_index :impressions, [:controller_name,:action_name,:ip_address], :name => "controlleraction_ip_index", :unique => false
 | 
			
		||||
    add_index :impressions, [:controller_name,:action_name,:session_hash], :name => "controlleraction_session_index", :unique => false
 | 
			
		||||
    add_index :impressions, :user_id
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.down
 | 
			
		||||
    drop_table :impressions
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
module Impressionist
 | 
			
		||||
  module Generators
 | 
			
		||||
    class ImpressionistGenerator < Rails::Generators::Base
 | 
			
		||||
      hook_for :orm
 | 
			
		||||
      source_root File.expand_path('../templates', __FILE__)
 | 
			
		||||
 | 
			
		||||
      def copy_config_file
 | 
			
		||||
        template 'impression.rb', 'config/initializers/impression.rb'
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
module MongoMapper
 | 
			
		||||
  module Generators
 | 
			
		||||
    class ImpressionistGenerator < Rails::Generators::Base
 | 
			
		||||
      # Empty for now, need it for generating the config file without
 | 
			
		||||
      # triggering other ORM's generators.
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
module Mongoid
 | 
			
		||||
  module Generators
 | 
			
		||||
    class ImpressionistGenerator < Rails::Generators::Base
 | 
			
		||||
      # Empty for now, need it for generating the config file without
 | 
			
		||||
      # triggering other ORM's generators.
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
# Use this hook to configure impressionist parameters
 | 
			
		||||
Impressionist.setup do |config|
 | 
			
		||||
  # Define ORM. Could be :active_record (default) and :mongo_mapper
 | 
			
		||||
  # config.orm = :active_record
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
require "impressionist/engine.rb"
 | 
			
		||||
 | 
			
		||||
module Impressionist
 | 
			
		||||
  # Define ORM
 | 
			
		||||
  mattr_accessor :orm
 | 
			
		||||
  @@orm = :active_record
 | 
			
		||||
 | 
			
		||||
  # Load configuration from initializer
 | 
			
		||||
  def self.setup
 | 
			
		||||
    yield self
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
require 'httpclient'
 | 
			
		||||
require 'nokogiri'
 | 
			
		||||
 | 
			
		||||
module Impressionist
 | 
			
		||||
  module Bots
 | 
			
		||||
    LIST_URL = "http://www.user-agents.org/allagents.xml"
 | 
			
		||||
    def self.consume
 | 
			
		||||
      response = HTTPClient.new.get_content(LIST_URL)
 | 
			
		||||
      doc = Nokogiri::XML(response)
 | 
			
		||||
      list = []
 | 
			
		||||
      doc.xpath('//user-agent').each do |agent|
 | 
			
		||||
        type = agent.xpath("Type").text
 | 
			
		||||
        list << agent.xpath("String").text.gsub("<","<") if ["R","S"].include?(type) #gsub hack for badly formatted data
 | 
			
		||||
      end
 | 
			
		||||
      list
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
require "impressionist"
 | 
			
		||||
require "rails"
 | 
			
		||||
 | 
			
		||||
module Impressionist
 | 
			
		||||
  class Engine < Rails::Engine
 | 
			
		||||
    initializer 'impressionist.model' do |app|
 | 
			
		||||
      require "#{root}/app/models/impressionist/impressionable.rb"
 | 
			
		||||
      if Impressionist.orm == :active_record
 | 
			
		||||
        require "impressionist/models/active_record/impression.rb"
 | 
			
		||||
        require "impressionist/models/active_record/impressionist/impressionable.rb"
 | 
			
		||||
        ActiveRecord::Base.send(:include, Impressionist::Impressionable)
 | 
			
		||||
      elsif Impressionist.orm == :mongo_mapper
 | 
			
		||||
        require "impressionist/models/mongo_mapper/impression.rb"
 | 
			
		||||
        require "impressionist/models/mongo_mapper/impressionist/impressionable.rb"
 | 
			
		||||
        MongoMapper::Document.plugin Impressionist::Impressionable
 | 
			
		||||
      elsif Impressionist.orm == :mongoid
 | 
			
		||||
        require "impressionist/models/mongoid/impression.rb"
 | 
			
		||||
        require "impressionist/models/mongoid/impressionist/impressionable.rb"
 | 
			
		||||
        # Mongoid::Document Impressionist::Impressionable
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    initializer 'impressionist.controller' do
 | 
			
		||||
      ActiveSupport.on_load(:action_controller) do
 | 
			
		||||
        include ImpressionistController::InstanceMethods
 | 
			
		||||
        extend ImpressionistController::ClassMethods
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
class Impression < ActiveRecord::Base
 | 
			
		||||
  attr_accessible :impressionable_type, :impressionable_id, :user_id,
 | 
			
		||||
  :controller_name, :action_name, :view_name, :request_hash, :ip_address,
 | 
			
		||||
  :session_hash, :message, :referrer
 | 
			
		||||
 | 
			
		||||
  after_save :update_impressions_counter_cache
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def update_impressions_counter_cache
 | 
			
		||||
    impressionable_class = self.impressionable_type.constantize
 | 
			
		||||
 | 
			
		||||
    if impressionable_class.impressionist_counter_cache_options
 | 
			
		||||
      resouce = impressionable_class.find(self.impressionable_id)
 | 
			
		||||
      resouce.try(:update_impressionist_counter_cache)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/impressionist/lib/impressionist/models/active_record/impressionist/impressionable.rb
								
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										12
									
								
								vendor/impressionist/lib/impressionist/models/active_record/impressionist/impressionable.rb
								
								
								
									vendored
								
								
									Normal file
								
							| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
module Impressionist
 | 
			
		||||
  module Impressionable
 | 
			
		||||
    extend ActiveSupport::Concern
 | 
			
		||||
 | 
			
		||||
    module ClassMethods
 | 
			
		||||
      def is_impressionable(options={})
 | 
			
		||||
        has_many :impressions, :as => :impressionable, :dependent => :destroy
 | 
			
		||||
        @impressionist_cache_options = options[:counter_cache]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
class Impression
 | 
			
		||||
  include MongoMapper::Document
 | 
			
		||||
 | 
			
		||||
  key :impressionable_type, String
 | 
			
		||||
  key :impressionable_id, String
 | 
			
		||||
  key :user_id, String
 | 
			
		||||
  key :controller_name, String
 | 
			
		||||
  key :action_name, String
 | 
			
		||||
  key :view_name, String
 | 
			
		||||
  key :request_hash, String
 | 
			
		||||
  key :ip_address, String
 | 
			
		||||
  key :session_hash, String
 | 
			
		||||
  key :message, String
 | 
			
		||||
  key :referrer, String
 | 
			
		||||
  timestamps!
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/impressionist/lib/impressionist/models/mongo_mapper/impressionist/impressionable.rb
								
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										12
									
								
								vendor/impressionist/lib/impressionist/models/mongo_mapper/impressionist/impressionable.rb
								
								
								
									vendored
								
								
									Normal file
								
							| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
module Impressionist
 | 
			
		||||
  module Impressionable
 | 
			
		||||
    extend ActiveSupport::Concern
 | 
			
		||||
 | 
			
		||||
    module ClassMethods
 | 
			
		||||
      def is_impressionable(options={})
 | 
			
		||||
        many :impressions, :as => :impressionable, :dependent => :destroy
 | 
			
		||||
        @cache_options = options[:counter_cache]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
class Impression
 | 
			
		||||
  include Mongoid::Document
 | 
			
		||||
  include Mongoid::Timestamps
 | 
			
		||||
 | 
			
		||||
  field :impressionable_type
 | 
			
		||||
  field :impressionable_id
 | 
			
		||||
  field :user_id
 | 
			
		||||
  field :controller_name
 | 
			
		||||
  field :action_name
 | 
			
		||||
  field :view_name
 | 
			
		||||
  field :request_hash
 | 
			
		||||
  field :ip_address
 | 
			
		||||
  field :session_hash
 | 
			
		||||
  field :message
 | 
			
		||||
  field :referrer
 | 
			
		||||
 | 
			
		||||
  belongs_to :impressionable, :polymorphic => true
 | 
			
		||||
 | 
			
		||||
  after_save :update_impressions_counter_cache
 | 
			
		||||
 | 
			
		||||
  def self.impressionist_count(options={})
 | 
			
		||||
    options.reverse_merge!(:filter => :request_hash, :start_date => nil, :end_date => Time.now)
 | 
			
		||||
    imps = options[:start_date].blank? ? impressions : impressions.where(:created_at.gte => options[:start_date], :created_at.lte => options[:end_date])
 | 
			
		||||
    options[:filter] == :all ? imps.count : imps.distinct(options[:filter]).count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def update_impressions_counter_cache
 | 
			
		||||
    impressionable_class = self.impressionable_type.constantize
 | 
			
		||||
 | 
			
		||||
    if impressionable_class.impressionist_counter_cache_options
 | 
			
		||||
      resouce = impressionable_class.find(self.impressionable_id)
 | 
			
		||||
      resouce.try(:update_impressionist_counter_cache)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/impressionist/lib/impressionist/models/mongoid/impressionist/impressionable.rb
								
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										12
									
								
								vendor/impressionist/lib/impressionist/models/mongoid/impressionist/impressionable.rb
								
								
								
									vendored
								
								
									Normal file
								
							| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
module Impressionist
 | 
			
		||||
  module Impressionable
 | 
			
		||||
    extend ActiveSupport::Concern
 | 
			
		||||
 | 
			
		||||
    module ClassMethods
 | 
			
		||||
      def is_impressionable(options={})
 | 
			
		||||
        has_many :impressions, :as => :impressionable, :dependent => :destroy
 | 
			
		||||
        @impressionist_cache_options = options[:counter_cache]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
module Impressionist
 | 
			
		||||
  VERSION = "1.1.1"
 | 
			
		||||
end
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 62 KiB  | 
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
# See http://help.github.com/ignore-files/ for more about ignoring files.
 | 
			
		||||
#
 | 
			
		||||
# If you find yourself ignoring temporary files generated by your text editor
 | 
			
		||||
# or operating system, you probably want to add a global ignore instead:
 | 
			
		||||
#   git config --global core.excludesfile ~/.gitignore_global
 | 
			
		||||
 | 
			
		||||
# Ignore bundler config
 | 
			
		||||
/.bundle
 | 
			
		||||
/Gemfile.lock
 | 
			
		||||
 | 
			
		||||
# Ignore the default SQLite database.
 | 
			
		||||
/db/*.sqlite3
 | 
			
		||||
 | 
			
		||||
# Ignore all logfiles and tempfiles.
 | 
			
		||||
/coverage
 | 
			
		||||
/log/*.log
 | 
			
		||||
/tmp
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
--color
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,59 @@
 | 
			
		|||
source 'https://rubygems.org'
 | 
			
		||||
 | 
			
		||||
gem 'rails', '3.2.2'
 | 
			
		||||
 | 
			
		||||
gem 'impressionist', :path => '../'
 | 
			
		||||
 | 
			
		||||
platforms :jruby do
 | 
			
		||||
  gem 'activerecord-jdbcsqlite3-adapter'
 | 
			
		||||
  gem 'jdbc-sqlite3'
 | 
			
		||||
  gem 'jruby-openssl'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
platforms :ruby, :mswin, :mingw do
 | 
			
		||||
  gem 'pg'
 | 
			
		||||
  gem 'sqlite3'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
gem 'json'
 | 
			
		||||
 | 
			
		||||
# Gems used only for assets and not required
 | 
			
		||||
# in production environments by default.
 | 
			
		||||
group :assets do
 | 
			
		||||
  gem 'sass-rails',   '~> 3.2.3'
 | 
			
		||||
  gem 'coffee-rails', '~> 3.2.1'
 | 
			
		||||
 | 
			
		||||
  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
 | 
			
		||||
  # gem 'therubyracer'
 | 
			
		||||
 | 
			
		||||
  gem 'uglifier', '>= 1.0.3'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
group :development, :test do
 | 
			
		||||
  gem 'autotest-notification'
 | 
			
		||||
  gem 'rspec-rails'
 | 
			
		||||
  gem 'spork'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
group :test do
 | 
			
		||||
  gem 'capybara'
 | 
			
		||||
  gem 'simplecov'
 | 
			
		||||
  gem 'systemu'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
gem 'jquery-rails'
 | 
			
		||||
 | 
			
		||||
# To use ActiveModel has_secure_password
 | 
			
		||||
# gem 'bcrypt-ruby', '~> 3.0.0'
 | 
			
		||||
 | 
			
		||||
# To use Jbuilder templates for JSON
 | 
			
		||||
# gem 'jbuilder'
 | 
			
		||||
 | 
			
		||||
# Use unicorn as the app server
 | 
			
		||||
# gem 'unicorn'
 | 
			
		||||
 | 
			
		||||
# Deploy with Capistrano
 | 
			
		||||
# gem 'capistrano'
 | 
			
		||||
 | 
			
		||||
# To use debugger
 | 
			
		||||
# gem 'ruby-debug'
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,256 @@
 | 
			
		|||
== Welcome to Rails
 | 
			
		||||
 | 
			
		||||
Rails is a web-application framework that includes everything needed to create
 | 
			
		||||
database-backed web applications according to the Model-View-Control pattern.
 | 
			
		||||
 | 
			
		||||
This pattern splits the view (also called the presentation) into "dumb"
 | 
			
		||||
templates that are primarily responsible for inserting pre-built data in between
 | 
			
		||||
HTML tags. The model contains the "smart" domain objects (such as Account,
 | 
			
		||||
Product, Person, Post) that holds all the business logic and knows how to
 | 
			
		||||
persist themselves to a database. The controller handles the incoming requests
 | 
			
		||||
(such as Save New Account, Update Product, Show Post) by manipulating the model
 | 
			
		||||
and directing data to the view.
 | 
			
		||||
 | 
			
		||||
In Rails, the model is handled by what's called an object-relational mapping
 | 
			
		||||
layer entitled Active Record. This layer allows you to present the data from
 | 
			
		||||
database rows as objects and embellish these data objects with business logic
 | 
			
		||||
methods. You can read more about Active Record in
 | 
			
		||||
link:files/vendor/rails/activerecord/README.html.
 | 
			
		||||
 | 
			
		||||
The controller and view are handled by the Action Pack, which handles both
 | 
			
		||||
layers by its two parts: Action View and Action Controller. These two layers
 | 
			
		||||
are bundled in a single package due to their heavy interdependence. This is
 | 
			
		||||
unlike the relationship between the Active Record and Action Pack that is much
 | 
			
		||||
more separate. Each of these packages can be used independently outside of
 | 
			
		||||
Rails. You can read more about Action Pack in
 | 
			
		||||
link:files/vendor/rails/actionpack/README.html.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== Getting Started
 | 
			
		||||
 | 
			
		||||
1. At the command prompt, create a new Rails application:
 | 
			
		||||
       <tt>rails new myapp</tt> (where <tt>myapp</tt> is the application name)
 | 
			
		||||
 | 
			
		||||
2. Change directory to <tt>myapp</tt> and start the web server:
 | 
			
		||||
       <tt>cd myapp; rails server</tt> (run with --help for options)
 | 
			
		||||
 | 
			
		||||
3. Go to http://localhost:3000/ and you'll see:
 | 
			
		||||
       "Welcome aboard: You're riding Ruby on Rails!"
 | 
			
		||||
 | 
			
		||||
4. Follow the guidelines to start developing your application. You can find
 | 
			
		||||
the following resources handy:
 | 
			
		||||
 | 
			
		||||
* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
 | 
			
		||||
* Ruby on Rails Tutorial Book: http://www.railstutorial.org/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== Debugging Rails
 | 
			
		||||
 | 
			
		||||
Sometimes your application goes wrong. Fortunately there are a lot of tools that
 | 
			
		||||
will help you debug it and get it back on the rails.
 | 
			
		||||
 | 
			
		||||
First area to check is the application log files. Have "tail -f" commands
 | 
			
		||||
running on the server.log and development.log. Rails will automatically display
 | 
			
		||||
debugging and runtime information to these files. Debugging info will also be
 | 
			
		||||
shown in the browser on requests from 127.0.0.1.
 | 
			
		||||
 | 
			
		||||
You can also log your own messages directly into the log file from your code
 | 
			
		||||
using the Ruby logger class from inside your controllers. Example:
 | 
			
		||||
 | 
			
		||||
  class WeblogController < ActionController::Base
 | 
			
		||||
    def destroy
 | 
			
		||||
      @weblog = Weblog.find(params[:id])
 | 
			
		||||
      @weblog.destroy
 | 
			
		||||
      logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
The result will be a message in your log file along the lines of:
 | 
			
		||||
 | 
			
		||||
  Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1!
 | 
			
		||||
 | 
			
		||||
More information on how to use the logger is at http://www.ruby-doc.org/core/
 | 
			
		||||
 | 
			
		||||
Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
 | 
			
		||||
several books available online as well:
 | 
			
		||||
 | 
			
		||||
* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe)
 | 
			
		||||
* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
 | 
			
		||||
 | 
			
		||||
These two books will bring you up to speed on the Ruby language and also on
 | 
			
		||||
programming in general.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== Debugger
 | 
			
		||||
 | 
			
		||||
Debugger support is available through the debugger command when you start your
 | 
			
		||||
Mongrel or WEBrick server with --debugger. This means that you can break out of
 | 
			
		||||
execution at any point in the code, investigate and change the model, and then,
 | 
			
		||||
resume execution! You need to install ruby-debug to run the server in debugging
 | 
			
		||||
mode. With gems, use <tt>sudo gem install ruby-debug</tt>. Example:
 | 
			
		||||
 | 
			
		||||
  class WeblogController < ActionController::Base
 | 
			
		||||
    def index
 | 
			
		||||
      @posts = Post.find(:all)
 | 
			
		||||
      debugger
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
So the controller will accept the action, run the first line, then present you
 | 
			
		||||
with a IRB prompt in the server window. Here you can do things like:
 | 
			
		||||
 | 
			
		||||
  >> @posts.inspect
 | 
			
		||||
  => "[#<Post:0x14a6be8
 | 
			
		||||
          @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>,
 | 
			
		||||
       #<Post:0x14a6620
 | 
			
		||||
          @attributes={"title"=>"Rails", "body"=>"Only ten..", "id"=>"2"}>]"
 | 
			
		||||
  >> @posts.first.title = "hello from a debugger"
 | 
			
		||||
  => "hello from a debugger"
 | 
			
		||||
 | 
			
		||||
...and even better, you can examine how your runtime objects actually work:
 | 
			
		||||
 | 
			
		||||
  >> f = @posts.first
 | 
			
		||||
  => #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
 | 
			
		||||
  >> f.
 | 
			
		||||
  Display all 152 possibilities? (y or n)
 | 
			
		||||
 | 
			
		||||
Finally, when you're ready to resume execution, you can enter "cont".
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== Console
 | 
			
		||||
 | 
			
		||||
The console is a Ruby shell, which allows you to interact with your
 | 
			
		||||
application's domain model. Here you'll have all parts of the application
 | 
			
		||||
configured, just like it is when the application is running. You can inspect
 | 
			
		||||
domain models, change values, and save to the database. Starting the script
 | 
			
		||||
without arguments will launch it in the development environment.
 | 
			
		||||
 | 
			
		||||
To start the console, run <tt>rails console</tt> from the application
 | 
			
		||||
directory.
 | 
			
		||||
 | 
			
		||||
Options:
 | 
			
		||||
 | 
			
		||||
* Passing the <tt>-s, --sandbox</tt> argument will rollback any modifications
 | 
			
		||||
  made to the database.
 | 
			
		||||
* Passing an environment name as an argument will load the corresponding
 | 
			
		||||
  environment. Example: <tt>rails console production</tt>.
 | 
			
		||||
 | 
			
		||||
To reload your controllers and models after launching the console run
 | 
			
		||||
<tt>reload!</tt>
 | 
			
		||||
 | 
			
		||||
More information about irb can be found at:
 | 
			
		||||
link:http://www.rubycentral.com/pickaxe/irb.html
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== dbconsole
 | 
			
		||||
 | 
			
		||||
You can go to the command line of your database directly through <tt>rails
 | 
			
		||||
dbconsole</tt>. You would be connected to the database with the credentials
 | 
			
		||||
defined in database.yml. Starting the script without arguments will connect you
 | 
			
		||||
to the development database. Passing an argument will connect you to a different
 | 
			
		||||
database, like <tt>rails dbconsole production</tt>. Currently works for MySQL,
 | 
			
		||||
PostgreSQL and SQLite 3.
 | 
			
		||||
 | 
			
		||||
== Description of Contents
 | 
			
		||||
 | 
			
		||||
The default directory structure of a generated Ruby on Rails application:
 | 
			
		||||
 | 
			
		||||
  |-- app
 | 
			
		||||
  |   |-- controllers
 | 
			
		||||
  |   |-- helpers
 | 
			
		||||
  |   |-- mailers
 | 
			
		||||
  |   |-- models
 | 
			
		||||
  |   `-- views
 | 
			
		||||
  |       `-- layouts
 | 
			
		||||
  |-- config
 | 
			
		||||
  |   |-- environments
 | 
			
		||||
  |   |-- initializers
 | 
			
		||||
  |   `-- locales
 | 
			
		||||
  |-- db
 | 
			
		||||
  |-- doc
 | 
			
		||||
  |-- lib
 | 
			
		||||
  |   `-- tasks
 | 
			
		||||
  |-- log
 | 
			
		||||
  |-- public
 | 
			
		||||
  |   |-- images
 | 
			
		||||
  |   |-- javascripts
 | 
			
		||||
  |   `-- stylesheets
 | 
			
		||||
  |-- script
 | 
			
		||||
  |-- test
 | 
			
		||||
  |   |-- fixtures
 | 
			
		||||
  |   |-- functional
 | 
			
		||||
  |   |-- integration
 | 
			
		||||
  |   |-- performance
 | 
			
		||||
  |   `-- unit
 | 
			
		||||
  |-- tmp
 | 
			
		||||
  |   |-- cache
 | 
			
		||||
  |   |-- pids
 | 
			
		||||
  |   |-- sessions
 | 
			
		||||
  |   `-- sockets
 | 
			
		||||
  `-- vendor
 | 
			
		||||
      `-- plugins
 | 
			
		||||
 | 
			
		||||
app
 | 
			
		||||
  Holds all the code that's specific to this particular application.
 | 
			
		||||
 | 
			
		||||
app/controllers
 | 
			
		||||
  Holds controllers that should be named like weblogs_controller.rb for
 | 
			
		||||
  automated URL mapping. All controllers should descend from
 | 
			
		||||
  ApplicationController which itself descends from ActionController::Base.
 | 
			
		||||
 | 
			
		||||
app/models
 | 
			
		||||
  Holds models that should be named like post.rb. Models descend from
 | 
			
		||||
  ActiveRecord::Base by default.
 | 
			
		||||
 | 
			
		||||
app/views
 | 
			
		||||
  Holds the template files for the view that should be named like
 | 
			
		||||
  weblogs/index.html.erb for the WeblogsController#index action. All views use
 | 
			
		||||
  eRuby syntax by default.
 | 
			
		||||
 | 
			
		||||
app/views/layouts
 | 
			
		||||
  Holds the template files for layouts to be used with views. This models the
 | 
			
		||||
  common header/footer method of wrapping views. In your views, define a layout
 | 
			
		||||
  using the <tt>layout :default</tt> and create a file named default.html.erb.
 | 
			
		||||
  Inside default.html.erb, call <% yield %> to render the view using this
 | 
			
		||||
  layout.
 | 
			
		||||
 | 
			
		||||
app/helpers
 | 
			
		||||
  Holds view helpers that should be named like weblogs_helper.rb. These are
 | 
			
		||||
  generated for you automatically when using generators for controllers.
 | 
			
		||||
  Helpers can be used to wrap functionality for your views into methods.
 | 
			
		||||
 | 
			
		||||
config
 | 
			
		||||
  Configuration files for the Rails environment, the routing map, the database,
 | 
			
		||||
  and other dependencies.
 | 
			
		||||
 | 
			
		||||
db
 | 
			
		||||
  Contains the database schema in schema.rb. db/migrate contains all the
 | 
			
		||||
  sequence of Migrations for your schema.
 | 
			
		||||
 | 
			
		||||
doc
 | 
			
		||||
  This directory is where your application documentation will be stored when
 | 
			
		||||
  generated using <tt>rake doc:app</tt>
 | 
			
		||||
 | 
			
		||||
lib
 | 
			
		||||
  Application specific libraries. Basically, any kind of custom code that
 | 
			
		||||
  doesn't belong under controllers, models, or helpers. This directory is in
 | 
			
		||||
  the load path.
 | 
			
		||||
 | 
			
		||||
public
 | 
			
		||||
  The directory available for the web server. Contains subdirectories for
 | 
			
		||||
  images, stylesheets, and javascripts. Also contains the dispatchers and the
 | 
			
		||||
  default HTML files. This should be set as the DOCUMENT_ROOT of your web
 | 
			
		||||
  server.
 | 
			
		||||
 | 
			
		||||
script
 | 
			
		||||
  Helper scripts for automation and generation.
 | 
			
		||||
 | 
			
		||||
test
 | 
			
		||||
  Unit and functional tests along with fixtures. When using the rails generate
 | 
			
		||||
  command, template test files will be generated for you and placed in this
 | 
			
		||||
  directory.
 | 
			
		||||
 | 
			
		||||
vendor
 | 
			
		||||
  External libraries that the application depends on. Also includes the plugins
 | 
			
		||||
  subdirectory. If the app has frozen rails, those gems also go here, under
 | 
			
		||||
  vendor/rails/. This directory is in the load path.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,261 @@
 | 
			
		|||
== Welcome to Rails
 | 
			
		||||
 | 
			
		||||
Rails is a web-application framework that includes everything needed to create
 | 
			
		||||
database-backed web applications according to the Model-View-Control pattern.
 | 
			
		||||
 | 
			
		||||
This pattern splits the view (also called the presentation) into "dumb"
 | 
			
		||||
templates that are primarily responsible for inserting pre-built data in between
 | 
			
		||||
HTML tags. The model contains the "smart" domain objects (such as Account,
 | 
			
		||||
Product, Person, Post) that holds all the business logic and knows how to
 | 
			
		||||
persist themselves to a database. The controller handles the incoming requests
 | 
			
		||||
(such as Save New Account, Update Product, Show Post) by manipulating the model
 | 
			
		||||
and directing data to the view.
 | 
			
		||||
 | 
			
		||||
In Rails, the model is handled by what's called an object-relational mapping
 | 
			
		||||
layer entitled Active Record. This layer allows you to present the data from
 | 
			
		||||
database rows as objects and embellish these data objects with business logic
 | 
			
		||||
methods. You can read more about Active Record in
 | 
			
		||||
link:files/vendor/rails/activerecord/README.html.
 | 
			
		||||
 | 
			
		||||
The controller and view are handled by the Action Pack, which handles both
 | 
			
		||||
layers by its two parts: Action View and Action Controller. These two layers
 | 
			
		||||
are bundled in a single package due to their heavy interdependence. This is
 | 
			
		||||
unlike the relationship between the Active Record and Action Pack that is much
 | 
			
		||||
more separate. Each of these packages can be used independently outside of
 | 
			
		||||
Rails. You can read more about Action Pack in
 | 
			
		||||
link:files/vendor/rails/actionpack/README.html.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== Getting Started
 | 
			
		||||
 | 
			
		||||
1. At the command prompt, create a new Rails application:
 | 
			
		||||
       <tt>rails new myapp</tt> (where <tt>myapp</tt> is the application name)
 | 
			
		||||
 | 
			
		||||
2. Change directory to <tt>myapp</tt> and start the web server:
 | 
			
		||||
       <tt>cd myapp; rails server</tt> (run with --help for options)
 | 
			
		||||
 | 
			
		||||
3. Go to http://localhost:3000/ and you'll see:
 | 
			
		||||
       "Welcome aboard: You're riding Ruby on Rails!"
 | 
			
		||||
 | 
			
		||||
4. Follow the guidelines to start developing your application. You can find
 | 
			
		||||
the following resources handy:
 | 
			
		||||
 | 
			
		||||
* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
 | 
			
		||||
* Ruby on Rails Tutorial Book: http://www.railstutorial.org/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== Debugging Rails
 | 
			
		||||
 | 
			
		||||
Sometimes your application goes wrong. Fortunately there are a lot of tools that
 | 
			
		||||
will help you debug it and get it back on the rails.
 | 
			
		||||
 | 
			
		||||
First area to check is the application log files. Have "tail -f" commands
 | 
			
		||||
running on the server.log and development.log. Rails will automatically display
 | 
			
		||||
debugging and runtime information to these files. Debugging info will also be
 | 
			
		||||
shown in the browser on requests from 127.0.0.1.
 | 
			
		||||
 | 
			
		||||
You can also log your own messages directly into the log file from your code
 | 
			
		||||
using the Ruby logger class from inside your controllers. Example:
 | 
			
		||||
 | 
			
		||||
  class WeblogController < ActionController::Base
 | 
			
		||||
    def destroy
 | 
			
		||||
      @weblog = Weblog.find(params[:id])
 | 
			
		||||
      @weblog.destroy
 | 
			
		||||
      logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
The result will be a message in your log file along the lines of:
 | 
			
		||||
 | 
			
		||||
  Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1!
 | 
			
		||||
 | 
			
		||||
More information on how to use the logger is at http://www.ruby-doc.org/core/
 | 
			
		||||
 | 
			
		||||
Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
 | 
			
		||||
several books available online as well:
 | 
			
		||||
 | 
			
		||||
* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe)
 | 
			
		||||
* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
 | 
			
		||||
 | 
			
		||||
These two books will bring you up to speed on the Ruby language and also on
 | 
			
		||||
programming in general.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== Debugger
 | 
			
		||||
 | 
			
		||||
Debugger support is available through the debugger command when you start your
 | 
			
		||||
Mongrel or WEBrick server with --debugger. This means that you can break out of
 | 
			
		||||
execution at any point in the code, investigate and change the model, and then,
 | 
			
		||||
resume execution! You need to install ruby-debug to run the server in debugging
 | 
			
		||||
mode. With gems, use <tt>sudo gem install ruby-debug</tt>. Example:
 | 
			
		||||
 | 
			
		||||
  class WeblogController < ActionController::Base
 | 
			
		||||
    def index
 | 
			
		||||
      @posts = Post.all
 | 
			
		||||
      debugger
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
So the controller will accept the action, run the first line, then present you
 | 
			
		||||
with a IRB prompt in the server window. Here you can do things like:
 | 
			
		||||
 | 
			
		||||
  >> @posts.inspect
 | 
			
		||||
  => "[#<Post:0x14a6be8
 | 
			
		||||
          @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>,
 | 
			
		||||
       #<Post:0x14a6620
 | 
			
		||||
          @attributes={"title"=>"Rails", "body"=>"Only ten..", "id"=>"2"}>]"
 | 
			
		||||
  >> @posts.first.title = "hello from a debugger"
 | 
			
		||||
  => "hello from a debugger"
 | 
			
		||||
 | 
			
		||||
...and even better, you can examine how your runtime objects actually work:
 | 
			
		||||
 | 
			
		||||
  >> f = @posts.first
 | 
			
		||||
  => #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
 | 
			
		||||
  >> f.
 | 
			
		||||
  Display all 152 possibilities? (y or n)
 | 
			
		||||
 | 
			
		||||
Finally, when you're ready to resume execution, you can enter "cont".
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== Console
 | 
			
		||||
 | 
			
		||||
The console is a Ruby shell, which allows you to interact with your
 | 
			
		||||
application's domain model. Here you'll have all parts of the application
 | 
			
		||||
configured, just like it is when the application is running. You can inspect
 | 
			
		||||
domain models, change values, and save to the database. Starting the script
 | 
			
		||||
without arguments will launch it in the development environment.
 | 
			
		||||
 | 
			
		||||
To start the console, run <tt>rails console</tt> from the application
 | 
			
		||||
directory.
 | 
			
		||||
 | 
			
		||||
Options:
 | 
			
		||||
 | 
			
		||||
* Passing the <tt>-s, --sandbox</tt> argument will rollback any modifications
 | 
			
		||||
  made to the database.
 | 
			
		||||
* Passing an environment name as an argument will load the corresponding
 | 
			
		||||
  environment. Example: <tt>rails console production</tt>.
 | 
			
		||||
 | 
			
		||||
To reload your controllers and models after launching the console run
 | 
			
		||||
<tt>reload!</tt>
 | 
			
		||||
 | 
			
		||||
More information about irb can be found at:
 | 
			
		||||
link:http://www.rubycentral.org/pickaxe/irb.html
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== dbconsole
 | 
			
		||||
 | 
			
		||||
You can go to the command line of your database directly through <tt>rails
 | 
			
		||||
dbconsole</tt>. You would be connected to the database with the credentials
 | 
			
		||||
defined in database.yml. Starting the script without arguments will connect you
 | 
			
		||||
to the development database. Passing an argument will connect you to a different
 | 
			
		||||
database, like <tt>rails dbconsole production</tt>. Currently works for MySQL,
 | 
			
		||||
PostgreSQL and SQLite 3.
 | 
			
		||||
 | 
			
		||||
== Description of Contents
 | 
			
		||||
 | 
			
		||||
The default directory structure of a generated Ruby on Rails application:
 | 
			
		||||
 | 
			
		||||
  |-- app
 | 
			
		||||
  |   |-- assets
 | 
			
		||||
  |       |-- images
 | 
			
		||||
  |       |-- javascripts
 | 
			
		||||
  |       `-- stylesheets
 | 
			
		||||
  |   |-- controllers
 | 
			
		||||
  |   |-- helpers
 | 
			
		||||
  |   |-- mailers
 | 
			
		||||
  |   |-- models
 | 
			
		||||
  |   `-- views
 | 
			
		||||
  |       `-- layouts
 | 
			
		||||
  |-- config
 | 
			
		||||
  |   |-- environments
 | 
			
		||||
  |   |-- initializers
 | 
			
		||||
  |   `-- locales
 | 
			
		||||
  |-- db
 | 
			
		||||
  |-- doc
 | 
			
		||||
  |-- lib
 | 
			
		||||
  |   `-- tasks
 | 
			
		||||
  |-- log
 | 
			
		||||
  |-- public
 | 
			
		||||
  |-- script
 | 
			
		||||
  |-- test
 | 
			
		||||
  |   |-- fixtures
 | 
			
		||||
  |   |-- functional
 | 
			
		||||
  |   |-- integration
 | 
			
		||||
  |   |-- performance
 | 
			
		||||
  |   `-- unit
 | 
			
		||||
  |-- tmp
 | 
			
		||||
  |   |-- cache
 | 
			
		||||
  |   |-- pids
 | 
			
		||||
  |   |-- sessions
 | 
			
		||||
  |   `-- sockets
 | 
			
		||||
  `-- vendor
 | 
			
		||||
      |-- assets
 | 
			
		||||
          `-- stylesheets
 | 
			
		||||
      `-- plugins
 | 
			
		||||
 | 
			
		||||
app
 | 
			
		||||
  Holds all the code that's specific to this particular application.
 | 
			
		||||
 | 
			
		||||
app/assets
 | 
			
		||||
  Contains subdirectories for images, stylesheets, and JavaScript files.
 | 
			
		||||
 | 
			
		||||
app/controllers
 | 
			
		||||
  Holds controllers that should be named like weblogs_controller.rb for
 | 
			
		||||
  automated URL mapping. All controllers should descend from
 | 
			
		||||
  ApplicationController which itself descends from ActionController::Base.
 | 
			
		||||
 | 
			
		||||
app/models
 | 
			
		||||
  Holds models that should be named like post.rb. Models descend from
 | 
			
		||||
  ActiveRecord::Base by default.
 | 
			
		||||
 | 
			
		||||
app/views
 | 
			
		||||
  Holds the template files for the view that should be named like
 | 
			
		||||
  weblogs/index.html.erb for the WeblogsController#index action. All views use
 | 
			
		||||
  eRuby syntax by default.
 | 
			
		||||
 | 
			
		||||
app/views/layouts
 | 
			
		||||
  Holds the template files for layouts to be used with views. This models the
 | 
			
		||||
  common header/footer method of wrapping views. In your views, define a layout
 | 
			
		||||
  using the <tt>layout :default</tt> and create a file named default.html.erb.
 | 
			
		||||
  Inside default.html.erb, call <% yield %> to render the view using this
 | 
			
		||||
  layout.
 | 
			
		||||
 | 
			
		||||
app/helpers
 | 
			
		||||
  Holds view helpers that should be named like weblogs_helper.rb. These are
 | 
			
		||||
  generated for you automatically when using generators for controllers.
 | 
			
		||||
  Helpers can be used to wrap functionality for your views into methods.
 | 
			
		||||
 | 
			
		||||
config
 | 
			
		||||
  Configuration files for the Rails environment, the routing map, the database,
 | 
			
		||||
  and other dependencies.
 | 
			
		||||
 | 
			
		||||
db
 | 
			
		||||
  Contains the database schema in schema.rb. db/migrate contains all the
 | 
			
		||||
  sequence of Migrations for your schema.
 | 
			
		||||
 | 
			
		||||
doc
 | 
			
		||||
  This directory is where your application documentation will be stored when
 | 
			
		||||
  generated using <tt>rake doc:app</tt>
 | 
			
		||||
 | 
			
		||||
lib
 | 
			
		||||
  Application specific libraries. Basically, any kind of custom code that
 | 
			
		||||
  doesn't belong under controllers, models, or helpers. This directory is in
 | 
			
		||||
  the load path.
 | 
			
		||||
 | 
			
		||||
public
 | 
			
		||||
  The directory available for the web server. Also contains the dispatchers and the
 | 
			
		||||
  default HTML files. This should be set as the DOCUMENT_ROOT of your web
 | 
			
		||||
  server.
 | 
			
		||||
 | 
			
		||||
script
 | 
			
		||||
  Helper scripts for automation and generation.
 | 
			
		||||
 | 
			
		||||
test
 | 
			
		||||
  Unit and functional tests along with fixtures. When using the rails generate
 | 
			
		||||
  command, template test files will be generated for you and placed in this
 | 
			
		||||
  directory.
 | 
			
		||||
 | 
			
		||||
vendor
 | 
			
		||||
  External libraries that the application depends on. Also includes the plugins
 | 
			
		||||
  subdirectory. If the app has frozen rails, those gems also go here, under
 | 
			
		||||
  vendor/rails/. This directory is in the load path.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
#!/usr/bin/env rake
 | 
			
		||||
# Add your own tasks in files placed in lib/tasks ending in .rake,
 | 
			
		||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
 | 
			
		||||
 | 
			
		||||
require File.expand_path('../config/application', __FILE__)
 | 
			
		||||
 | 
			
		||||
TestApp::Application.load_tasks
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 6.5 KiB  | 
| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
// This is a manifest file that'll be compiled into application.js, which will include all the files
 | 
			
		||||
// listed below.
 | 
			
		||||
//
 | 
			
		||||
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
 | 
			
		||||
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
 | 
			
		||||
//
 | 
			
		||||
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
 | 
			
		||||
// the compiled file.
 | 
			
		||||
//
 | 
			
		||||
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
 | 
			
		||||
// GO AFTER THE REQUIRES BELOW.
 | 
			
		||||
//
 | 
			
		||||
//= require jquery
 | 
			
		||||
//= require jquery_ujs
 | 
			
		||||
//= require_tree .
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
/*
 | 
			
		||||
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 | 
			
		||||
 * listed below.
 | 
			
		||||
 *
 | 
			
		||||
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
 | 
			
		||||
 * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
 | 
			
		||||
 *
 | 
			
		||||
 * You're free to add application-wide styles to this file and they'll appear at the top of the
 | 
			
		||||
 * compiled file, but it's generally better to create a new file per style scope.
 | 
			
		||||
 *
 | 
			
		||||
 *= require_self
 | 
			
		||||
 *= require_tree .
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
class ApplicationController < ActionController::Base
 | 
			
		||||
  protect_from_forgery
 | 
			
		||||
  before_filter :secondary_before_filter
 | 
			
		||||
 | 
			
		||||
  def secondary_before_filter
 | 
			
		||||
    @test_secondary_before_filter = "this is a test"
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
class ArticlesController < ApplicationController
 | 
			
		||||
  before_filter :test_current_user_var
 | 
			
		||||
 | 
			
		||||
  def test_current_user_var
 | 
			
		||||
    if session[:user_id]
 | 
			
		||||
      @current_user = User.new
 | 
			
		||||
      @current_user.id = session[:user_id]
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def index
 | 
			
		||||
    impressionist(Article.first,"this is a test article impression")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def show
 | 
			
		||||
    impressionist(Article.first)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
# This controller imports the impressionist module to make the modules methods available for testing
 | 
			
		||||
class DummyController < ActionController::Base
 | 
			
		||||
 | 
			
		||||
  impressionist
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
class PostsController < ApplicationController
 | 
			
		||||
  helper_method :current_user
 | 
			
		||||
  impressionist
 | 
			
		||||
  def index
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def show
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def edit
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def current_user
 | 
			
		||||
    if session[:user_id]
 | 
			
		||||
      user = User.new
 | 
			
		||||
      user.id = session[:user_id]
 | 
			
		||||
      @current_user ||= user
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
class WidgetsController < ApplicationController
 | 
			
		||||
  impressionist :actions=>[:show,:index], :unique => [:controller_name,:action_name,:impressionable_id]
 | 
			
		||||
 | 
			
		||||
  def show
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def index
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def new
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
module ApplicationHelper
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
class Article < ActiveRecord::Base
 | 
			
		||||
  is_impressionable
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
# We don't really care about this model. It's just being used to test the uniqueness controller
 | 
			
		||||
# specs. Nevertheless, we need a model because the counter caching functionality expects it.
 | 
			
		||||
#
 | 
			
		||||
class Dummy < ActiveRecord::Base
 | 
			
		||||
  self.abstract_class = true # doesn't need to be backed by an actual table
 | 
			
		||||
  is_impressionable
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
class Post < ActiveRecord::Base
 | 
			
		||||
  is_impressionable
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
class User
 | 
			
		||||
  attr_accessor :id
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
class Widget < ActiveRecord::Base
 | 
			
		||||
  is_impressionable :counter_cache => true
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
<%=@impressionist_hash==nil%>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
<%=link_to "Same Page", article_url(Article.first)%>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <title>TestApp</title>
 | 
			
		||||
  <%= stylesheet_link_tag    "application", :media => "all" %>
 | 
			
		||||
  <%= javascript_include_tag "application" %>
 | 
			
		||||
  <%= csrf_meta_tags %>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
<%= yield %>
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
# This file is used by Rack-based servers to start the application.
 | 
			
		||||
 | 
			
		||||
require ::File.expand_path('../config/environment',  __FILE__)
 | 
			
		||||
run TestApp::Application
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,59 @@
 | 
			
		|||
require File.expand_path('../boot', __FILE__)
 | 
			
		||||
 | 
			
		||||
require 'rails/all'
 | 
			
		||||
 | 
			
		||||
if defined?(Bundler)
 | 
			
		||||
  # If you precompile assets before deploying to production, use this line
 | 
			
		||||
  Bundler.require(*Rails.groups(:assets => %w(development test)))
 | 
			
		||||
  # If you want your assets lazily compiled in production, use this line
 | 
			
		||||
  # Bundler.require(:default, :assets, Rails.env)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
module TestApp
 | 
			
		||||
  class Application < Rails::Application
 | 
			
		||||
    # Settings in config/environments/* take precedence over those specified here.
 | 
			
		||||
    # Application configuration should go into files in config/initializers
 | 
			
		||||
    # -- all .rb files in that directory are automatically loaded.
 | 
			
		||||
 | 
			
		||||
    # Custom directories with classes and modules you want to be autoloadable.
 | 
			
		||||
    # config.autoload_paths += %W(#{config.root}/extras)
 | 
			
		||||
 | 
			
		||||
    # Only load the plugins named here, in the order given (default is alphabetical).
 | 
			
		||||
    # :all can be used as a placeholder for all plugins not explicitly named.
 | 
			
		||||
    # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
 | 
			
		||||
 | 
			
		||||
    # Activate observers that should always be running.
 | 
			
		||||
    # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
 | 
			
		||||
 | 
			
		||||
    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
 | 
			
		||||
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
 | 
			
		||||
    # config.time_zone = 'Central Time (US & Canada)'
 | 
			
		||||
 | 
			
		||||
    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
 | 
			
		||||
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
 | 
			
		||||
    # config.i18n.default_locale = :de
 | 
			
		||||
 | 
			
		||||
    # Configure the default encoding used in templates for Ruby 1.9.
 | 
			
		||||
    config.encoding = "utf-8"
 | 
			
		||||
 | 
			
		||||
    # Configure sensitive parameters which will be filtered from the log file.
 | 
			
		||||
    config.filter_parameters += [:password]
 | 
			
		||||
 | 
			
		||||
    # Use SQL instead of Active Record's schema dumper when creating the database.
 | 
			
		||||
    # This is necessary if your schema can't be completely dumped by the schema dumper,
 | 
			
		||||
    # like if you have constraints or database-specific column types
 | 
			
		||||
    # config.active_record.schema_format = :sql
 | 
			
		||||
 | 
			
		||||
    # Enforce whitelist mode for mass assignment.
 | 
			
		||||
    # This will create an empty whitelist of attributes available for mass-assignment for all models
 | 
			
		||||
    # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
 | 
			
		||||
    # parameters by using an attr_accessible or attr_protected declaration.
 | 
			
		||||
    # config.active_record.whitelist_attributes = true
 | 
			
		||||
 | 
			
		||||
    # Enable the asset pipeline
 | 
			
		||||
    config.assets.enabled = true
 | 
			
		||||
 | 
			
		||||
    # Version of your assets, change this if you want to expire all your assets
 | 
			
		||||
    config.assets.version = '1.0'
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
require 'rubygems'
 | 
			
		||||
 | 
			
		||||
# Set up gems listed in the Gemfile.
 | 
			
		||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
 | 
			
		||||
 | 
			
		||||
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
<%
 | 
			
		||||
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
 | 
			
		||||
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
 | 
			
		||||
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip"
 | 
			
		||||
%>
 | 
			
		||||
default: --drb <%= std_opts %> features
 | 
			
		||||
wip: --drb --tags @wip:3 --wip features
 | 
			
		||||
rerun: --drb <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
# SQLite version 3.x
 | 
			
		||||
#   gem install sqlite3-ruby (not necessary on OS X Leopard)
 | 
			
		||||
development:
 | 
			
		||||
  adapter: sqlite3
 | 
			
		||||
  database: db/development.sqlite3
 | 
			
		||||
  pool: 5
 | 
			
		||||
  timeout: 5000
 | 
			
		||||
 | 
			
		||||
test: &test
 | 
			
		||||
  adapter: sqlite3
 | 
			
		||||
  database: db/test.sqlite3
 | 
			
		||||
  pool: 5
 | 
			
		||||
  timeout: 5000
 | 
			
		||||
 | 
			
		||||
#pg_test:
 | 
			
		||||
#  adapter: postgresql
 | 
			
		||||
#  database: impressionist_test
 | 
			
		||||
#  username: johnmcaliley
 | 
			
		||||
# password:
 | 
			
		||||
#  host: localhost
 | 
			
		||||
#  encoding: UTF8
 | 
			
		||||
 | 
			
		||||
production:
 | 
			
		||||
  adapter: sqlite3
 | 
			
		||||
  database: db/production.sqlite3
 | 
			
		||||
  pool: 5
 | 
			
		||||
  timeout: 5000
 | 
			
		||||
 | 
			
		||||
cucumber:
 | 
			
		||||
  <<: *test
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
# Load the rails application
 | 
			
		||||
require File.expand_path('../application', __FILE__)
 | 
			
		||||
 | 
			
		||||
# Initialize the rails application
 | 
			
		||||
TestApp::Application.initialize!
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
TestApp::Application.configure do
 | 
			
		||||
  # Settings specified here will take precedence over those in config/application.rb
 | 
			
		||||
 | 
			
		||||
  # In the development environment your application's code is reloaded on
 | 
			
		||||
  # every request. This slows down response time but is perfect for development
 | 
			
		||||
  # since you don't have to restart the web server when you make code changes.
 | 
			
		||||
  config.cache_classes = false
 | 
			
		||||
 | 
			
		||||
  # Log error messages when you accidentally call methods on nil.
 | 
			
		||||
  config.whiny_nils = true
 | 
			
		||||
 | 
			
		||||
  # Show full error reports and disable caching
 | 
			
		||||
  config.consider_all_requests_local       = true
 | 
			
		||||
  config.action_controller.perform_caching = false
 | 
			
		||||
 | 
			
		||||
  # Don't care if the mailer can't send
 | 
			
		||||
  config.action_mailer.raise_delivery_errors = false
 | 
			
		||||
 | 
			
		||||
  # Print deprecation notices to the Rails logger
 | 
			
		||||
  config.active_support.deprecation = :log
 | 
			
		||||
 | 
			
		||||
  # Only use best-standards-support built into browsers
 | 
			
		||||
  config.action_dispatch.best_standards_support = :builtin
 | 
			
		||||
 | 
			
		||||
  # Raise exception on mass assignment protection for Active Record models
 | 
			
		||||
  config.active_record.mass_assignment_sanitizer = :strict
 | 
			
		||||
 | 
			
		||||
  # Log the query plan for queries taking more than this (works
 | 
			
		||||
  # with SQLite, MySQL, and PostgreSQL)
 | 
			
		||||
  config.active_record.auto_explain_threshold_in_seconds = 0.5
 | 
			
		||||
 | 
			
		||||
  # Do not compress assets
 | 
			
		||||
  config.assets.compress = false
 | 
			
		||||
 | 
			
		||||
  # Expands the lines which load the assets
 | 
			
		||||
  config.assets.debug = true
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,35 @@
 | 
			
		|||
TestApp::Application.configure do
 | 
			
		||||
  # Settings specified here will take precedence over those in config/application.rb
 | 
			
		||||
 | 
			
		||||
  # The test environment is used exclusively to run your application's
 | 
			
		||||
  # test suite.  You never need to work with it otherwise.  Remember that
 | 
			
		||||
  # your test database is "scratch space" for the test suite and is wiped
 | 
			
		||||
  # and recreated between test runs.  Don't rely on the data there!
 | 
			
		||||
  config.cache_classes = true
 | 
			
		||||
 | 
			
		||||
  # Log error messages when you accidentally call methods on nil.
 | 
			
		||||
  config.whiny_nils = true
 | 
			
		||||
 | 
			
		||||
  # Show full error reports and disable caching
 | 
			
		||||
  config.consider_all_requests_local       = true
 | 
			
		||||
  config.action_controller.perform_caching = false
 | 
			
		||||
 | 
			
		||||
  # Raise exceptions instead of rendering exception templates
 | 
			
		||||
  config.action_dispatch.show_exceptions = false
 | 
			
		||||
 | 
			
		||||
  # Disable request forgery protection in test environment
 | 
			
		||||
  config.action_controller.allow_forgery_protection    = false
 | 
			
		||||
 | 
			
		||||
  # Tell Action Mailer not to deliver emails to the real world.
 | 
			
		||||
  # The :test delivery method accumulates sent emails in the
 | 
			
		||||
  # ActionMailer::Base.deliveries array.
 | 
			
		||||
  config.action_mailer.delivery_method = :test
 | 
			
		||||
 | 
			
		||||
  # Use SQL instead of Active Record's schema dumper when creating the test database.
 | 
			
		||||
  # This is necessary if your schema can't be completely dumped by the schema dumper,
 | 
			
		||||
  # like if you have constraints or database-specific column types
 | 
			
		||||
  # config.active_record.schema_format = :sql
 | 
			
		||||
 | 
			
		||||
  # Print deprecation notices to the stderr
 | 
			
		||||
  config.active_support.deprecation = :stderr
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,67 @@
 | 
			
		|||
TestApp::Application.configure do
 | 
			
		||||
  # Settings specified here will take precedence over those in config/application.rb
 | 
			
		||||
 | 
			
		||||
  # Code is not reloaded between requests
 | 
			
		||||
  config.cache_classes = true
 | 
			
		||||
 | 
			
		||||
  # Full error reports are disabled and caching is turned on
 | 
			
		||||
  config.consider_all_requests_local       = false
 | 
			
		||||
  config.action_controller.perform_caching = true
 | 
			
		||||
 | 
			
		||||
  # Disable Rails's static asset server (Apache or nginx will already do this)
 | 
			
		||||
  config.serve_static_assets = false
 | 
			
		||||
 | 
			
		||||
  # Compress JavaScripts and CSS
 | 
			
		||||
  config.assets.compress = true
 | 
			
		||||
 | 
			
		||||
  # Don't fallback to assets pipeline if a precompiled asset is missed
 | 
			
		||||
  config.assets.compile = false
 | 
			
		||||
 | 
			
		||||
  # Generate digests for assets URLs
 | 
			
		||||
  config.assets.digest = true
 | 
			
		||||
 | 
			
		||||
  # Defaults to Rails.root.join("public/assets")
 | 
			
		||||
  # config.assets.manifest = YOUR_PATH
 | 
			
		||||
 | 
			
		||||
  # Specifies the header that your server uses for sending files
 | 
			
		||||
  # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
 | 
			
		||||
  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
 | 
			
		||||
 | 
			
		||||
  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
 | 
			
		||||
  # config.force_ssl = true
 | 
			
		||||
 | 
			
		||||
  # See everything in the log (default is :info)
 | 
			
		||||
  # config.log_level = :debug
 | 
			
		||||
 | 
			
		||||
  # Prepend all log lines with the following tags
 | 
			
		||||
  # config.log_tags = [ :subdomain, :uuid ]
 | 
			
		||||
 | 
			
		||||
  # Use a different logger for distributed setups
 | 
			
		||||
  # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
 | 
			
		||||
 | 
			
		||||
  # Use a different cache store in production
 | 
			
		||||
  # config.cache_store = :mem_cache_store
 | 
			
		||||
 | 
			
		||||
  # Enable serving of images, stylesheets, and JavaScripts from an asset server
 | 
			
		||||
  # config.action_controller.asset_host = "http://assets.example.com"
 | 
			
		||||
 | 
			
		||||
  # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
 | 
			
		||||
  # config.assets.precompile += %w( search.js )
 | 
			
		||||
 | 
			
		||||
  # Disable delivery errors, bad email addresses will be ignored
 | 
			
		||||
  # config.action_mailer.raise_delivery_errors = false
 | 
			
		||||
 | 
			
		||||
  # Enable threaded mode
 | 
			
		||||
  # config.threadsafe!
 | 
			
		||||
 | 
			
		||||
  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
 | 
			
		||||
  # the I18n.default_locale when a translation can not be found)
 | 
			
		||||
  config.i18n.fallbacks = true
 | 
			
		||||
 | 
			
		||||
  # Send deprecation notices to registered listeners
 | 
			
		||||
  config.active_support.deprecation = :notify
 | 
			
		||||
 | 
			
		||||
  # Log the query plan for queries taking more than this (works
 | 
			
		||||
  # with SQLite, MySQL, and PostgreSQL)
 | 
			
		||||
  # config.active_record.auto_explain_threshold_in_seconds = 0.5
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
TestApp::Application.configure do
 | 
			
		||||
  # Settings specified here will take precedence over those in config/application.rb
 | 
			
		||||
 | 
			
		||||
  # The test environment is used exclusively to run your application's
 | 
			
		||||
  # test suite. You never need to work with it otherwise. Remember that
 | 
			
		||||
  # your test database is "scratch space" for the test suite and is wiped
 | 
			
		||||
  # and recreated between test runs. Don't rely on the data there!
 | 
			
		||||
  config.cache_classes = true
 | 
			
		||||
 | 
			
		||||
  # Configure static asset server for tests with Cache-Control for performance
 | 
			
		||||
  config.serve_static_assets = true
 | 
			
		||||
  config.static_cache_control = "public, max-age=3600"
 | 
			
		||||
 | 
			
		||||
  # Log error messages when you accidentally call methods on nil
 | 
			
		||||
  config.whiny_nils = true
 | 
			
		||||
 | 
			
		||||
  # Show full error reports and disable caching
 | 
			
		||||
  config.consider_all_requests_local       = true
 | 
			
		||||
  config.action_controller.perform_caching = false
 | 
			
		||||
 | 
			
		||||
  # Raise exceptions instead of rendering exception templates
 | 
			
		||||
  config.action_dispatch.show_exceptions = false
 | 
			
		||||
 | 
			
		||||
  # Disable request forgery protection in test environment
 | 
			
		||||
  config.action_controller.allow_forgery_protection    = false
 | 
			
		||||
 | 
			
		||||
  # Tell Action Mailer not to deliver emails to the real world.
 | 
			
		||||
  # The :test delivery method accumulates sent emails in the
 | 
			
		||||
  # ActionMailer::Base.deliveries array.
 | 
			
		||||
  config.action_mailer.delivery_method = :test
 | 
			
		||||
 | 
			
		||||
  # Raise exception on mass assignment protection for Active Record models
 | 
			
		||||
  config.active_record.mass_assignment_sanitizer = :strict
 | 
			
		||||
 | 
			
		||||
  # Print deprecation notices to the stderr
 | 
			
		||||
  config.active_support.deprecation = :stderr
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
# Be sure to restart your server when you modify this file.
 | 
			
		||||
 | 
			
		||||
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
 | 
			
		||||
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
 | 
			
		||||
 | 
			
		||||
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
 | 
			
		||||
# Rails.backtrace_cleaner.remove_silencers!
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
# Use this hook to configure impressionist parameters
 | 
			
		||||
Impressionist.setup do |config|
 | 
			
		||||
  # Define ORM. Could be :active_record (default) and :mongo_mapper
 | 
			
		||||
  # config.orm = :active_record
 | 
			
		||||
end
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue