incubator-alois-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fla...@apache.org
Subject svn commit: r1031127 [8/22] - in /incubator/alois/trunk: ./ bin/ debian/ doc/ etc/ etc/alois/ etc/alois/apache2/ etc/alois/environments/ etc/alois/prisma/ etc/cron.d/ etc/default/ etc/logrotate.d/ prisma/ prisma/bin/ prisma/conf/ prisma/conf/prisma/ pr...
Date Thu, 04 Nov 2010 18:27:42 GMT
Added: incubator/alois/trunk/rails/app/helpers/application_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/application_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/application_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/application_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,854 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Methods added to this helper will be available to all templates in the application.
+require 'webrick/utils'
+
+module ApplicationHelper
+  include ViewsHelper
+
+  def user
+    request.env["REMOTE_USER"] or "nobody"
+  end
+  
+  def group
+    $group_map[user] if $group_map
+  end
+
+  # Help helpers
+
+  def t_exists?(name)
+    begin
+      self.view_paths.find_template(name)
+      return true
+    rescue ActionView::MissingTemplate
+      return false
+    end
+  end
+  
+  def help_exists?(context = nil, page=nil)
+    return nil if context =~ /\</
+    get_help_view(context,page) != nil
+  end
+  
+  def get_all_help_pages
+    Dir.glob(RAILS_ROOT + "/app/views/*/*_help*").sort.map {|name|
+      if name =~ /app\/views\/([^\/]*)\/_(.*)_help\..*$/
+	[$1,$2]
+      else
+	nil
+      end
+    }.compact.uniq.map {|context,page|
+      category = context.humanize
+      category = "General Topics" if context == "help"
+      name = page.humanize
+      if help_exists?(context,page)
+	[category,name,context,page]
+      else
+	nil
+      end
+    }.compact.sort {|a,b|
+      r = a[0] <=> b[0]
+      if r != 0
+	r
+      else
+	a[1] <=> b[1]
+      end
+    }
+  end
+
+  def get_help_view(cont,page)
+    cont = nil if cont == ""
+    page = nil if page == ""
+
+    cont = cont.downcase if cont
+    page = page.downcase if page
+
+    cont ||= "index"
+
+    return "#{cont}/help" if page.nil? and t_exists?("#{cont}/_help")
+
+    return "#{cont}/#{page}_help" if page and t_exists?("#{cont}/_#{page}_help")
+
+    return "#{cont.pluralize}/#{page}_help" if 
+      page and t_exists?("#{cont.pluralize}/_#{page}_help")
+
+    return "#{cont.singularize}/#{page}_help" if 
+      page and t_exists?("#{cont.singularize}/_#{page}_help")
+
+    return "help/#{cont}_help" if t_exists?("help/_#{cont}_help")
+
+    return "help/#{cont.singularize}_help" if t_exists?("help/_#{cont.singularize}_help")
+
+    return "help/#{cont.pluralize}_help" if t_exists?("help/_#{cont.pluralize}_help")
+
+    return nil
+  end
+
+
+  
+  def main_help_link(name, options = {}, html_options = {})
+    name ||= image_tag("help.png")
+    options[:after] = "document.getElementsByClassName('help_button').each(function(val) {val.show();})"
+    options[:ignore_missing] = true
+    html_options[:class] ||= "main_help_link"
+    help_link name, nil, nil, options, html_options
+  end
+  
+  def help_link(name, context = nil, page = nil, options = {}, html_options = {})
+    #    link_to("help", :action => 'help')
+    html_options[:class] ||= "help_button"    
+
+    if options[:title] and options[:text]
+      new_params = {:title => options[:title],
+	:text =>options[:text]}
+    else
+      c = context
+      p = page 
+
+      c,p = name,nil if c.nil? and p.nil? and help_exists?(name,nil) 
+
+      if not help_exists?(c,p) or (c.nil? and p.nil?)
+	c ||= @controller.controller_name 
+	p ||= @controller.action_name
+      end           
+    
+      c,p = @controller.controller_name,context if not help_exists?(c,p) and not p
+      
+      exists = help_exists?(c,p)
+      return nil if not
+	exists and 
+	options[:only_if_exists]
+      
+      if !options.delete(:ignore_missing) and !exists
+	return "#{name}?!"
+      end
+
+      new_params = {:context => c,
+	:page =>p}
+    end
+
+    if inline_help? or not help_page?
+      options[:url] = {:controller => 'help', :action => 'inline'}.update(new_params)
+      options[:update] = 'help'
+      link_to_remote name, options, html_options
+    else
+      options[:url] = {:controller => 'help'}.update(new_params)
+      options[:after] = nil
+      link_to name, options, html_options
+    end
+
+
+  end
+  
+  def inline_help?
+    help_page? and @controller.action_name == "inline"
+  end
+
+  def help_page?
+    @controller.controller_name == "help"
+  end
+
+  def help_button(context = nil, page = nil, options = {}, html_options = {})
+    if not help_page?
+      html_options[:style] ||= "" 
+      html_options[:style] += "display:none;" 
+    end
+    help_link image_tag('help.png'), context, page, options, html_options
+  end
+
+  def short_help(title, text)
+    help_button(nil,nil,{:title => title, :text => text})
+  end
+
+  def help_goto(context = nil, page = nil, options = {}, html_options = {})
+    help_link image_tag('goto.png'), context, page, options, html_options
+  end
+
+  def help_close_button
+    if inline_help?
+      help_link(image_tag('close.png'), "hidden", nil, 
+		{:after => "document.getElementsByClassName('help_button').each(function(val) {val.hide();})"})
+    else
+      ""
+    end
+  end
+
+  def help_title(text)
+    "<h1 class='help'>#{h text} #{help_close_button}</h1>"
+  end
+
+  def help_subtitle(text)
+    "<h2 class='help'>#{h text}</h2>"
+  end
+
+  def help_subsubtitle(text)
+    "<h3 class='help'>#{h text}</h3>"
+  end
+
+  def help_notice(text)
+    "<i class='help'>#{h text}</i>"
+  end
+
+  def title(title)
+    return "<div class='homepageTitle'>#{h(title)} #{help_button nil,nil,{:only_if_exists => true} }</div>"
+  end
+  
+#  def help_link(text)
+#    link_to text, :controller => 'help', :context => text.downcase
+#  end
+
+  
+  def hostname
+    Socket.gethostname
+  end
+
+  def initialize_parameters
+    Timeout.timeout(2) {
+      load_session
+      @chart = Chart.new(:time_range => nil) if params[:reset_chart] or @chart.nil?
+      load_params
+
+      @filters = [] unless @filters
+      @conditions = @current_filter.conditions() if @current_filter
+      @conditions = [] unless @conditions
+      @conditions << @filters.map{|f| f.conditions}.flatten
+      @paging_size = 10 unless @paging_size
+      @page_number = 1 unless @page_number
+      
+      unless @current_filter
+	@current_filter = Filter.new(:name => "Current Filter #{Time.now.strftime("%F %T")}") 
+	unless params[:no_default_filter]
+	  if params[:default_filter]
+	    cond = Condition.create(nil, "SQL",params[:default_filter])
+	  else
+	    cond = Condition.create("date","DATE","today")
+	  end
+	  @current_filter.conditions = @current_filter.conditions.push(cond)
+	end
+      end
+
+      save_session
+    }
+
+    if @current_filter 
+      @current_filter.datasource = current_datasource
+    end
+#    if @filters
+#      @filters.each {|filter| filter.datasource = datasource }
+#    end
+
+    if @chart and not @chart.mode == :view_only
+      @chart.datasource = current_datasource
+      @chart.conditions = get_condition_string if current_datasource
+    end
+    
+  end
+
+  # ----------- session -------------- #
+  def state_id
+    @state_id
+  end
+  TEST_STATE_ID = "random_id_used_for_testing"
+  def current_session
+    return session[@state_id] if @state_id
+    @state_id = params[:state_id]
+    if RAILS_ENV=="test"
+      @state_id = TEST_STATE_ID
+    else
+      @state_id = WEBrick::Utils.random_string(20) unless @state_id
+    end
+    session[@state_id] = {} unless session[@state_id]
+    return session[@state_id]
+  end
+  def clear_session
+    session[@state_id] = nil
+  end
+  def save_session_value(key, value)    
+    begin
+      return current_session[key] = value.full_clone if value.respond_to?(:full_clone)
+      return current_session[key] = value.clone if value.respond_to?(:clone)
+    rescue TypeError
+      current_session[key] = value
+    end
+  end
+  def load_session_value(key)
+    # fix, otherwise attributes_methods:160 will complain nil.[] on cached methods
+    v = current_session[key]
+    v.instance_eval("@attributes_cache ||= {}")
+
+    if v and subclasses_of(ActiveRecord::Base).include?(v.class) and v.id
+      begin
+	new_val = v.class.find(v.id)
+	new_val.attributes = v.attributes
+	v = new_val
+      rescue ActiveRecord::RecordNotFound
+	flash[:error] = "Could not find '#{v.class}.#{v.id}'"
+      end
+    end
+    v
+  end
+  SESSION_VALUES = [:filters,:chart,:current_filter,:zoom,:order,
+    :page_number,:page_offset,:paging_size,:table_name]
+  def save_session
+    @zoom = @chart.zoom if @chart
+    SESSION_VALUES.each {|name|
+      save_session_value(name,instance_variable_get("@#{name}"))
+    }
+  end
+  def load_session
+    SESSION_VALUES.each {|name|
+      instance_variable_set("@#{name}",load_session_value(name))
+    }
+    @chart.zoom = @zoom if @zoom
+  end
+  def clone_session
+    old_session = current_session
+    @state_id = nil
+    params[:state_id] = nil
+    
+    old_session.each {|key,val|
+      save_session_value(key,val)
+    }
+
+    load_session
+    save_session
+  end
+
+  # ----------- datasource -------------- #
+
+  def current_datasource
+    return @table_class if @table_class and @table_class.table.table_name == @table_name
+    if @table_name     
+      @table_class = Prisma::Database.get_class_from_tablename(@table_name) if defined?(Prisma::Database)
+      @table_class = View.get_class_from_tablename(@table_name) unless @table_class
+      @table_class = GenericRecord.get_class_from_tablename(@table_name) unless @table_class
+      @table_name = nil unless @table_class
+    end
+    @table_class
+  end
+
+  def current_table
+    begin
+      current_datasource.table
+    rescue
+      nil
+    end
+  end
+
+  def get_condition_string(real = false, withoutrule = -1)
+    #    return nil if not @current_filter
+    #    return @current_filter.get_condition_string(real,withoutrule,{:banished_set => @banished_set,
+    #                                           :negative_set => @negative_set,
+    #
+    #:global_rule_number => @global_rule_number})
+    throw "No current filter defined." unless @current_filter
+    throw "No datasource for current filter defined." unless @current_filter.datasource
+
+    @current_filter.valid?
+    table = current_table
+    table = nil if (view = View.get_class_from_tablename(table.table_name)) and view.do_not_use_view_for_query
+
+    @filters = [] unless @filters
+    sql = (@filters.clone << @current_filter).compact.map {
+      |f| f.get_condition_string(table,false,-1,{:flash => flash})
+    }.compact.join(" AND ")
+    return nil if sql == ""
+    sql
+  end
+
+  # ----------- params -------------- #
+  
+  def load_params
+    begin
+      @filters = params[:filters].map { |id| Filter.find(id) } if params[:filters] 
+      @order = params[:order] if params[:order]
+      @table_name = params[:table] if params[:table] and !(params[:table].class.to_s =~ /Hash/)
+      @table_name = params[:table_name] if params[:table_name]
+      @paging_size = params[:paging_size].to_i if params[:paging_size]
+      @paging_size = 10 if @paging_size == 0       
+      
+      if params[:page_number] and @page_number != params[:page_number].to_i
+ 	if @page_offset and @page_number 
+	  @page_offset = @page_offset + @paging_size * (params[:page_number].to_i - @page_number)	  
+	  @page_number = (@page_offset / @paging_size) + 1 # pagenumbers starts at 1
+	else
+	  @page_number = params[:page_number].to_i 
+	  @page_offset = @page_number * @paging_size
+	end	  
+      else
+	if params[:page_offset] and @page_offset != params[:page_offset].to_i
+	  @page_offset = params[:page_offset].to_i  
+	  @page_number = (@page_offset / @paging_size) + 1 #page_number starts at 1
+	end
+	@page_offset = 0 unless @page_offset
+	@page_number = 1 unless @page_number
+	if @page_offset < 0 or @page_number < 1 
+	  @page_offset = 0
+	  @page_number = 1
+	end
+      end 
+            
+      
+      @chart = Chart.load_yaml(params[:chart_tmpdir_hash], params[:chart_yaml_hash]) if 
+	params[:chart_tmpdir_hash]
+      @chart = Chart.load_yaml(params[:chart_data_dir], params[:chart_yaml_hash]) if
+	params[:chart_data_dir]
+      @chart = Chart.find(params[:chart_id]) if params[:chart_id]
+
+      if @chart and not @chart.mode == :view_only
+	@chart.column1 = params[:chart_column1] if params[:chart_column1]
+	@chart.column2 = params[:chart_column2] if params[:chart_column2]
+	@chart.aggregation_column = params[:chart_aggregation_column] if params[:chart_aggregatino_column]
+	@chart.aggregation_function = params[:chart_aggregation_function] if params[:chart_aggregation_function]
+	@chart.chart_type = params[:chart_type] if params[:chart_type]
+	@chart.order_by = params[:chart_order_by] if params[:chart_order_by]
+	@chart.set_data_directory_from_hash = params[:chart_hash] if params[:chart_hash]
+	@chart.attributes = (params[:chart]) if params[:chart] and params[:chart].class.name != "String"
+      end
+      
+      load_current_object
+
+#    rescue
+#      flash[:warning] = "Error loading parameters. (#{$!})"
+    end
+  end
+  
+  # ------------- default object for CRUD ------------ #
+
+  def load_current_object
+    # first access the class that yaml can find it.
+    # otherwise return
+    return unless (obj_class rescue nil)
+    if params[:current_object_zip]
+      begin
+	self.current_object = Object.from_zip(params[:current_object_zip]).clone
+	flash[:info] = "Loaded zip of type #{current_object.class} to #{obj_instance_variable_name}"
+	return self.current_object
+      rescue
+	flash[:error] = "Could not load zip '#{$!}'."
+      end      
+    end
+    if params[:id]
+      self.current_object = obj_class.find(params[:id])
+      return self.current_object
+    end
+  end
+
+  def obj_instance_variable_name
+    "#{params[:controller].singularize}"
+  end
+
+  def obj_class_name
+    params[:controller].singularize.camelize
+  end
+
+  def obj_class
+    Object.const_get(obj_class_name) if Object.const_defined?(obj_class_name)    
+  end
+  
+  def current_object
+    instance_variable_get("@#{obj_instance_variable_name}")    
+  end
+  def current_object=(val)
+    raise "Yaml object '#{val}' has type '#{val.class.name}' expected was '#{obj_class_name}'." unless val.class.name == obj_class_name
+    instance_variable_set("@#{obj_instance_variable_name}",val)    
+  end
+
+  # ----------- paging -------------- #
+
+  def reset_paging
+    @page_offset = 0
+    @page_number = 1
+  end
+
+  def get_params
+    throw "To overwork"
+    return nil unless @state_id
+    { :filters => @filters.map { |f| f.id}.uniq,
+      :order => @order,
+      :table => @table_name,
+      :page_number => @page_number,
+      :page_offset => @page_offset,
+      :paging_size => @paging_size}
+  end
+  
+
+  # ----------- stuff -------------- #
+  def safe_filename(name,type, date = DateTime.now)
+    "#{(name or "UNKNOWN").gsub(/[^[:alnum:]\-\_]/, '_')}-#{date.strftime("%F%t")}.#{type}"
+  end
+  
+  def create_links_in_query(query)
+    return "" unless query
+    query = h query
+    query.gsub!(/(FROM[^[:alnum:]]*)(\`?[^ ]*\`?)|(\`?view_\d+\`?)|(\`?[[:alnum:]]*_metas\`?)/i) { |s|
+      begin
+	#	throw [query,$1,$2,$3,$4]
+	prefix,table = $1,$2 if $1
+	prefix,table = "",$3 if $3
+	prefix,table = "",$4 if $4
+
+	table_name = table
+	table_name = table_name[1..-1] if table_name.starts_with?("`")
+	table_name = table_name[0..-2] if table_name.ends_with?("`")
+
+      	if GenericRecord.connection.tables.include?(table_name)
+	  prefix + link_to(table,:controller => 'survey',
+			   :action => 'show',
+			   :table => table_name) 
+	else
+	  prefix + table
+	end
+#      rescue
+#	s
+      end
+    }
+
+    query.gsub!(/\*|\sWHERE\s|\sLIKE\s|\sAND\s|SELECT\s|\sFROM\s|\sAS\s|\sIN\s|\sCOUNT\s|\sSUM\s|\sJOIN\s|\sLEFT\s|\sRIGHT\s|\sINNER\s|\sOUTER\s|\sDISTINCT\s|\sGROUP\sBY\s|\sORDER\sBY\s|\sDESC\s|\sOR\s|\sLIMIT\s|\sLIMIT\s|OFFSET\s|UNION\s|ALL\s/i) { |s|
+      "<b><i>#{s}</i></b>"
+    }
+  end
+
+  # Common
+  def page_title
+    "#{controller.controller_name.humanize}: #{controller.action_name.humanize}"
+  end
+
+  def object_submenu(obj, actions = ["edit"])
+    ret = []
+    actions.each {|action|
+      ret.push({:title => action, :link => url_for( :controller => obj.class.name.tableize, 
+						   :action => action, 
+						   :id => obj)})
+    }
+#    ret.push({:title => "<hr>"})
+    ret.push({:title => "Number&nbsp;#{obj.id}"})
+    ret.push({:title => obj.description}) if obj.respond_to?("description") and obj.description and obj.description.strip != ""
+  end
+
+  def auto_submenu(klass)
+    [{:title => "New ...", :link => url_for(:controller => klass.name.tableize, :action => "new")}] +
+      klass.find(:all,:order => "name").map {|obj|
+      { :title => obj.name, :link => url_for( :controller => klass.name.tableize, 
+					     :action => 'show', 
+					     :id => obj),
+	:submenu => object_submenu(obj)
+      }
+    }
+  end
+
+  def common_menu(main_name = "Alois", unfolded = true)
+    views=[]
+    views.push({ :title => "New ...", :link => url_for( :controller => 'views', :action => 'new') })
+    
+    all_views = View.find(:all).select {|view| view.exclusive_for_group.nil? or view.exclusive_for_group == ""  or view.exclusive_for_group == group}
+    
+    make_groups(all_views).each{|name,views_coll|
+      
+      sub_sub_entries = []
+      
+      if name == ""
+	for view in views_coll
+	  views.push({ :title => view.name, :link => url_for( :controller => 'survey', :table => view.table_name), :submenu => object_submenu(view, ["show","edit"])
+		     })
+	end
+      else
+	for view in views_coll
+	  sub_sub_entries.push({ :title => view.name, :link => url_for( :controller => 'survey', :table => view.table_name),
+				 :submenu => [
+				   { :title => "show", :link => url_for( :controller => 'views', :action => "show", :id => view)},
+				   { :title => "edit", :link => url_for( :controller => 'views', :action => "edit", :id => view)}
+				 ]
+			       })
+	end
+	
+	views.push({ :title => (name or "Rest"), :submenu => sub_sub_entries})
+      end
+    }
+             
+    
+    m = [
+      {
+	:title => main_name,
+	:link => url_for(:controller => 'prisma'),
+	:submenu => [
+	  { :title => "Overview", :link => url_for( :controller => 'prisma')},
+	  { :title => "Statistics", :link => url_for( :controller => 'prisma', :action => 'statistics')},
+#	  { :title => "Bookmarks", :link => url_for( :controller => 'bookmarks')},
+	  { :title => "Reports", :link => url_for( :controller => 'reports')},
+	  { :title => "Alarms", :link => url_for( :controller => 'alarms')},
+	  { :title => "Help", :link => url_for( :controller => 'help')},
+	]
+      },
+      {
+	:title => "Database",
+	:link => url_for( :controller => 'prisma', :action => "databases"),
+	:submenu => [
+	  { :title => "Status", :link => url_for( :controller => 'prisma', :action => "databases")},
+	  { :title => "Views",  :link => url_for( :controller => 'views'), :submenu => views},
+	  { :title => "Ip Ranges", :link => url_for( :controller => 'ip_ranges')},
+	  { :title => "Tables", :link => url_for( :controller => 'tablelist')},
+	  { :title => "Schema", :link => url_for( :controller => 'tablelist',:action => 'schema')}
+	]
+      },
+      {
+	:title => "Reporting",
+	:link => url_for( :controller => 'sentinels'),
+	:submenu => [
+	  { :title => "Sentinels", :link => url_for( :controller => 'sentinels'), :submenu => auto_submenu(Sentinel)},
+	  { :title => "Report Templates", :link => url_for( :controller => 'report_templates'), :submenu => auto_submenu(ReportTemplate)},
+	  { :title => "Charts", :link => url_for( :controller => 'charts'), :submenu => auto_submenu(Chart)},
+	  { :title => "Filters", :link => url_for( :controller => 'filters'), :submenu => auto_submenu(Filter)}
+	]
+      }
+    ]
+
+
+=begin
+    if @controller.class == FiltersController or unfolded 
+      sub_entries=[]
+      sub_entries.push({ :title => "Create new filter", :link => url_for( :controller => 'filters', :action => 'new') })
+      for filter in Filter.find(:all)
+	sub_entries.push({ :title => filter.name, :link => url_for( :controller => 'filters', :action => 'show', :id => filter ) })
+      end
+      m.push({ :title => 'Filters', :link => url_for( :controller => 'filters' ), :submenu => sub_entries })
+    end
+=end
+    
+    m.push({ :title => 'Views', :link => url_for( :controller => 'views' ), :submenu => views })
+    
+    m
+  end
+
+  def place_holder(width, height, options = {})
+    options[:width] = width
+    options[:height] = height
+    options[:border] = '0'
+    
+    return image_tag("dot.gif", options)
+  end
+
+  def main_menu(menu)
+    result = '<div id="menu" >' + "\n" 
+    for entry in menu
+      result += '<ul>' + "\n"
+      result += '<li><h2>' + "\n"
+      result += link_to(entry[:title], entry[:link])  + "\n"
+      result += '</h2>' + "\n"
+      result += sub_menues(entry)
+      result += '    </li>' + "\n"
+      result += '</ul>' + "\n"
+    end 
+    
+    result += '</div>' + "\n"
+  end
+
+  def sub_menues(entry)
+    return "" unless entry
+    result = ""
+    if entry[:submenu] and entry[:submenu].length > 0
+      result += '        <ul>' + "\n"
+      for sub_entry in entry[:submenu] 
+	if sub_entry[:link]
+	  result += '          <li>' + link_to(sub_entry[:title], sub_entry[:link]) + sub_menues(sub_entry) + '</li>' + "\n"
+	else
+	  result += '          <li>' + sub_entry[:title].to_s + sub_menues(sub_entry) + '</li>' + "\n"
+	end
+      end 
+      result += '        </ul>' + "\n"
+    end 
+    return result
+  end
+
+  # error messages
+  def error_messages_for_depr(*params)
+    return ActionView::Helpers::ActiveRecordHelper.error_messages_for(*params)
+    options = params.last.is_a?(Hash) ? params.pop.symbolize_keys : {}
+    objects = params.collect { |object_name| instance_variable_get("@#{object_name}") }.compact
+    
+    errors = []
+#    errors.push(flash[:error]) unless flash[:error].nil?
+#    error_messages = objects.map { |object| errors.concat(object.errors.full_messages) unless object.errors.full_messages.empty? }
+    
+    warnings = []
+#    warnings.push(flash[:warning]) unless flash[:warning].nil?
+
+    notices = []
+#    notices.push(flash[:notice]) unless flash[:notice].nil?
+
+    render :partial => '/messages', :locals => { :errors => errors.flatten, :warnings => warnings.flatten, :notices => notices.flatten }
+  end
+
+  def error_messages
+    return nil
+    error_messages_for nil
+  end
+
+
+  def render_remote(url, options = {})
+    options[:update_color] ||= "red"
+    options[:container] ||= "div"
+    options[:text] ||= "Bitte warten, der Inhalt wird geladen..."
+    url[:layout] ||= "false"
+
+    div_id = "auto_refresh_#{WEBrick::Utils.random_string(10)}"
+    ret = ""
+    if options[:frequency]
+      ret += periodically_call_remote(:frequency => options[:frequency],
+				      :before => "Element.setStyle('#{div_id}', {'background-color' : '#{options[:update_color]}'});",
+				      :loaded => "Element.setStyle('#{div_id}', {'background-color' : 'transparent'});",
+				      :update => div_id, 
+				      :url => url)      
+      ret += "<div>Auto reload after #{pluralize(options[:frequency],"second")}</div>"
+    end
+    ret += "<#{options[:container]} id=\"#{div_id}\">"
+    ret += javascript_tag remote_function(:update => div_id, :url => url)
+    ret += options[:text]
+    ret += "</#{options[:container]}>"   
+    ret
+  end
+
+
+  def bookmark_add_link(text = nil)
+    text ||= image_tag "bookmark_add.png"
+    link_to text, :controller => "bookmarks", :action => "new",
+      "bookmark[title]" => "Neuer Bookmark",
+      "bookmark[controller]" => params[:controller],
+      "bookmark[action]" => params[:action],
+      "bookmark[table_name]" => @table_name,
+      "bookmark[identifier]" => params[:id]
+
+     
+  end
+
+  def fobj(obj, action = "show", text = nil)
+    return "NONE" unless obj
+
+    if obj.respond_to?(:name)
+      txt = (text or (h(obj.name) or "NONAME"))
+      txt = "NONAME" if txt == ""
+    else
+      txt = (text or h("#{obj.class.name}.#{obj.id}"))
+    end
+    
+    link_to(txt, :controller => obj.class.name.tableize, :action => action, :id => obj)
+  end
+
+  def post_attributes_show
+    if current_object
+      "<tr><th>Serialized</th>" + 
+	"<td><pre>#{current_object.to_zip rescue $!}</pre></td>" + 
+	"</tr>"    
+    end
+  end
+  
+  def post_attribute_new
+    _erbout = ''
+    form_tag(:action=>'new', :state_id => @state_id) do
+      _erbout.concat("<tr><th class='form_header' colspan='2'>Upload</th></tr>"+
+      "<tr><th>ZIP</th><td>" + text_area_tag('current_object_zip', '', :rows => 4) + "</td></tr>" +
+      "<tr><td class='button-bar' colspan='2'>" + submit_tag("Load") + submit_tag("Cancel") + "</td></tr>")
+    end
+  end
+
+  def datasource_fields
+    remote_function = remote_function(:update => "filters_list",
+				      :before => 'document.getElementById("filters_list").innerHTML = "Loading...";',
+				      :with => "'table=' + document.getElementById('table_name').options[document.getElementById('table_name').selectedIndex].value",
+				      :url => { :controller => "filters", :action => "list_possible_filters" })
+    
+
+
+    sources = Prisma::Database.data_sources
+    if block_given?
+      sources = sources.select {|s| (yield s) rescue false}
+    end
+    sources = sources.map {|s| ["#{s.name} (#{s.table_name})",s.table_name]}
+    sources = sources.sort_by{|x| (x[0] or "")}
+    
+    "Datasource: #{select_tag('table_name', options_for_select(sources),:onChange => remote_function)}<br>" +
+      "Time Range: #{text_field_tag "time_span","today"}<br>" +
+      "Filters: #{text_field_tag "filters"} (id, id, id)<br><div id='filters_list'><br></div>"
+  end
+
+  def parse_datasource_parameters
+    d = current_datasource
+    
+    c = Condition.create("date","DATE",params[:time_span]) if
+      params[:time_span] and params[:time_span] != ""      
+    c = ([c] + Filter.parse_text_field(params["filters"])).compact.map {|f| f.sql(:table_class => @datasource)}.join(" AND ")
+    [d,c]
+  end
+
+
+  # show hide
+  def show_hide(id, css_class = "show_hide")
+    if css_class
+      "class='show_hide' "
+    else
+      ""
+    end + "onmouseover=\"showElement(this,'sh_#{id}')\" onmouseout=\"hideElement(this,'sh_#{id}')\""
+  end
+
+  def show_hide_element(id)
+    "id='sh_#{id}' class='show_hide_element' onmouseover=\"showElement(this,'sh_#{id}')\" onmouseout=\"hideElement(this,'sh_#{id}')\""
+  end
+  
+  def show_hide_script
+    <<eof
+<script>
+function log(text) {
+/* document.getElementById("log").innerHTML += text.toString() + "<br>";  */
+}
+
+var shownElements = new Array();
+function showElement(caller,id) {
+  log("showElement(" + caller + "," + id + ")");
+  var element = document.getElementById(id);
+  element.style.display = 'block';
+  shownElements.push(id);
+}
+
+function hideElement(caller,id) {
+  log("hideElement(" + caller + ","  + id + ")");
+  var element = document.getElementById(id);
+
+  // remove from shown elements
+  for (i = 0; i < shownElements.length; i++) {
+    if (shownElements[i] == id) {
+      shownElements.splice(i,1);
+    }
+  }
+
+  setTimeout("finallyHideElement('" + id + "')", 100);
+}
+
+function finallyHideElement(id) {
+  log("finallyHideElement(" + id + ")");
+  var hide = true;
+  for (i = 0; i < shownElements.length; i++) {
+    if (shownElements[i] == id) {
+      hide = false;
+    }
+  }
+  if (hide) {
+    document.getElementById(id).style.display = 'none';
+  }
+}
+
+</script>
+eof
+end
+end

Added: incubator/alois/trunk/rails/app/helpers/bookmarks_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/bookmarks_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/bookmarks_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/bookmarks_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,16 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module BookmarksHelper
+end

Added: incubator/alois/trunk/rails/app/helpers/charts_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/charts_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/charts_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/charts_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,25 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module ChartsHelper
+  
+  def column_control(field_name)
+    if @table
+      select "chart", field_name, @table.columns.collect{|col| [col.human_name, col.human_name]}
+    else
+      text_field "chart", field_name
+    end
+  end
+  
+end

Added: incubator/alois/trunk/rails/app/helpers/exception_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/exception_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/exception_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/exception_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,16 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module ExceptionHelper
+end

Added: incubator/alois/trunk/rails/app/helpers/filters_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/filters_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/filters_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/filters_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,16 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module FiltersHelper
+end

Added: incubator/alois/trunk/rails/app/helpers/help_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/help_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/help_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/help_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,23 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module HelpHelper
+
+  def get_page    
+    get_help_view(params[:context],params[:page]) or 
+      "help/help_not_found"
+  end
+
+end
+

Added: incubator/alois/trunk/rails/app/helpers/ip_ranges_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/ip_ranges_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/ip_ranges_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/ip_ranges_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,16 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module IpRangesHelper
+end

Added: incubator/alois/trunk/rails/app/helpers/prisma_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/prisma_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/prisma_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/prisma_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,60 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module PrismaHelper
+
+  def start_painting_div(x,y)
+    
+  end
+  
+  def query_background_color(hash)
+    case hash["Command"]
+    when "Query"
+      "FF" + (if (t = hash["Time"].to_i) > 255 then 
+	"00" 
+      else 
+	(255 - t).to_s(16)
+      end) * 2
+    when "Statistics"
+      "transparent"
+    when "Sleep"
+      "AAFFAA"
+    else
+      "transparent"
+    end
+  end
+
+  def host_name_div(name, x, y, help_context = nil)
+    help = help_button help_context if help_context
+    if name =~ /([^\.]*).*/ then
+      short_name = $1 
+    else
+      short_name = name
+    end
+    "<div class='paint_host' style='left:#{x}px;top:#{y}px;'>" +
+      "<a href='/munin/localdomain/#{name}.html'>#{short_name}</a> #{help}" +
+      "</div>"
+  end
+
+  def arrow_div(name, x, y)
+    "<div class='paint_arrow' style='left:#{x}px;top:#{y}px;'>" +
+      "<span id='#{name}'>#{@controller.measure(name)}</span> #{help_button name}" +
+      "</div>"
+  end
+
+  def updating_value(name)
+    "<span id='#{name}'>#{@controller.measure(name)}</span>"
+  end
+  
+end

Added: incubator/alois/trunk/rails/app/helpers/report_templates_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/report_templates_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/report_templates_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/report_templates_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,16 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module ReportTemplatesHelper
+end

Added: incubator/alois/trunk/rails/app/helpers/reports_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/reports_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/reports_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/reports_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,16 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module ReportsHelper
+end

Added: incubator/alois/trunk/rails/app/helpers/sentinels_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/sentinels_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/sentinels_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/sentinels_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,16 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module SentinelsHelper
+end

Added: incubator/alois/trunk/rails/app/helpers/survey_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/survey_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/survey_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/survey_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,276 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module SurveyHelper
+
+  def children_table(record, processed = [])
+    return "" if record.class.name =~ /.*Raw$/
+    return "" if record.class.name =~ /^Message$/   
+    while record.is_a?(GenericRecord)
+      record = record.parent
+    end
+    return "" unless record
+
+    ret = ""
+
+    for klass in Prisma::Database.get_classes(:meta)
+      for column in klass.columns
+	f_column = record.class.foreign_column_name
+	if column.name == f_column then
+	  # count how many record there are
+	  ret += (children_line(klass, f_column, record, processed) or "NO CHILDREN")
+	end
+      end
+    end
+    ret += (children_line(Message, nil, record, processed) or "NO CHILDREN")
+    for view in View.find(:all,:conditions => ["id_source_table = ?",record.class.table_name])
+      ret += children_line(view, "id", record, processed)
+    end
+    
+    return nil if ret == "" 
+    return "All children of #{record.class.name}.#{record.id}:<br>#{ret}"
+  end
+
+  def children_line(klass, col, parent, processed)
+    n = nil
+    if klass == Message
+      n = klass.count(:conditions => "meta_type_name = 'Prisma::#{parent.class.to_s}' AND meta_id = #{parent.id}")
+    else
+      if klass.is_a?(View)
+	n = nil
+      else
+	n = klass.table.count(:conditions => "#{col} = #{parent.id}")
+      end
+    end
+
+    link = nil
+    ret = "<ul>"
+    case n
+    when 0
+      ret += "No children in #{klass.name}"
+    when 1
+      if klass == Message
+	child = klass.table.find(:all,:conditions => "meta_type_name = 'Prisma::#{parent.class.to_s}' AND meta_id = #{parent.id}")[0]
+      else
+	child = klass.table.find(:all,:conditions => "#{col} = #{parent.id}")[0]
+      end
+      
+      link = link_to("#{klass.name}.#{parent.id}",:action =>'show',
+		     :table => klass.table.table_name, :id => child.id
+		     )
+      if processed.include?(child)
+	ret += "<li>#{link} (...recursive...)</li>"
+      else
+	if processed.length > 10
+	  ret += "<li>#{link} (...too deep...)</li>"
+	else
+	  if child.class == GenericRecord
+	    ret += "<li>#{link}</li>"
+	  else
+	    processed.push(child)
+	    ret += "<li>#{link}<br> #{children_table(child,processed)}</li>"
+	  end
+	end
+      end
+    else
+      # n is nil or > 1
+      if klass == Message
+	link = link_to("#{n or "?"} x #{klass.name}",:action =>'add_condition',
+		       :table => Message.table_name, 
+		       :column => "meta_type_name", 
+		       :operator => '=', 
+		       :value => "#{parent.class}",
+		       :column2 => "meta_id", 
+		       :operator2 => '=',
+		       :value2 => "#{parent.id}",
+		       :no_default_filter => true)
+      else
+	link = link_to("#{n or "?"} x #{klass.name}",:action =>'add_condition',
+		       :table => klass.table.table_name, 
+		       :column => col, 
+		       :operator => '=', 
+		       :value => parent.id,
+		       :no_default_filter => true)
+      end
+      ret += "<li>#{link}</li>"
+    end
+
+    ret += "</ul>"
+    ret
+  end
+
+  COUNT_LIMIT = 10000
+
+  def count_cache
+    session[@state_id][:count_cache] = {} unless session[@state_id][:count_cache]
+    return session[@state_id][:count_cache] 
+  end
+
+  def save_value_in_cache(name, value)
+    c = count_cache
+    c[name] = value
+    session[@state_id][:count_cache] = c
+  end
+
+  def count_fast(conditions = nil)
+    return count_cache[conditions] if count_cache[conditions]
+
+    unless conditions
+      if @table_class.respond_to?(:approx_count)
+	approx = @table_class.approx_count || 0
+	if approx > COUNT_LIMIT
+	  return approx
+	else
+	  return @table_class.count
+	end
+      end
+    end    
+    return nil
+  end
+  
+  def count_slow(conditions = nil)
+    fast = count_fast(conditions)
+    return fast if fast
+    value = current_table.count(:conditions => conditions)
+    save_value_in_cache(conditions,value)
+    return value
+  end
+ 
+  ## OLD CODE
+  #  def compute_percentage(pos_condition, neg_condition, divisor_condition, default_value)
+  #    return [ default_value] unless
+  #      pos_condition or neg_condition or divisor_condition
+  #    pos_count = get_count_from_cache_or_compute(pos_condition)
+  #    neg_count = get_count_from_cache_or_compute(neg_condition)
+  #    divisor = get_count_from_cache_or_compute(divisor_condition)
+  #    
+  #    ret = 0
+  #    ret += pos_count unless pos_count == nil
+  #    ret -= neg_count unless neg_count == nil
+  #    if divisor then
+  #      if divisor == 0
+  #	ret = "INF"
+  #      else
+  #	ret = ret.to_f / divisor.to_f
+  #	ret = (ret * 1000).round.to_f / 10
+  #      end
+  #    end
+  #    
+  #    return [ret, pos_count, neg_count, divisor]
+  #  end
+    
+#  def count
+#    if params[:fast] 
+#      count_fast()
+#    else
+#      count_slow() 
+#    end
+#  end 
+
+  def get_count_text
+    cs = get_condition_string
+    approx_text = ""
+    unless params[:slow_count] 
+      approx_text = "Approximate/cached values! "
+      total_count = count_fast()
+      now_count = count_fast(cs)
+    else
+      total_count = count_fast()
+      now_count = count_slow(cs)
+    end    
+
+    ret = ""
+    if total_count
+      ret += approx_text + "There are total #{pluralize(total_count,'record')}."
+    end      
+    if now_count
+      ret += " You have selected #{pluralize(now_count,'record')}"
+    end
+    if total_count and total_count > 0 and now_count
+      ret += " (#{((now_count.to_f / total_count.to_f * 1000).round().to_f/10)}%)" 
+    end
+    return ret
+  end
+
+  #    # Code for pagination with a query
+  #    if @all_count != @count_limit then
+  #      @display_count = "#{@current_count} records of #{@all_count.to_i} (#{if @all_count > 0 then ((@current_count.to_f / @all_count.to_f * 1000).round().to_f/10) else 0 end})"
+  #    else
+  #      @display_count = "More than #{@count_limit} records..."
+  #    end    
+
+  
+  ## OLD CODE
+  ## for c_num in 0...@conditions.length
+  ## @raw_descriptions = get_desc(c_num)
+  ## @descriptions[c_num] = []
+  ## #for d_num in 0...@raw_descriptions.length
+  ## #  desc = @raw_descriptions[d_num]
+  ## 
+  ## #  @descriptions[c_num][d_num] = [desc ] +
+  ##     compute_percentage(desc[2],desc[3],desc[4], desc[5])
+  ## #end
+
+  def format_column(record,column, index)
+    ret = ""
+    val = record.send(column.name)
+    hash = "#{val}_#{column.name}_#{index}".hash.abs
+    if !val.nil? and val.class == String
+      sub_num = 0
+      val.gsub(/\d+\.\d+\.\d+\.\d+/) {|v|
+	sub_num += 1
+	table_id = "ip_#{hash}_#{sub_num}"
+	ranges = IpRange.find_including_range(v)	
+	ip = v.to_ip
+	
+	if ranges.length > 0
+	  ret += fobj(ranges[0],"show","<span #{show_hide(table_id)}>#{v}</span>")
+	else
+	  ret += "<span #{show_hide(table_id)}>#{v}</span>"
+	end
+	ret += "<div style='position:absolute;'><div #{show_hide_element(table_id)}'> <table>"
+	ret += "<tr>"
+	ret += "<td rowspan='#{ranges.length * 5 + 1}'>"
+	ret += "A:&nbsp;#{h(v)}<br/>"
+	ret += "I:&nbsp;#{ip.to_i.to_s }<br>"
+	ret += "DIG:#{ip.dig}<br/>"
+	ret += "</td>"
+	ret += "</tr>"
+	ranges.each {|ipr|
+	  ret += "<tr><th>#{fobj(ipr)}</th></tr>"
+	  
+	  if ipr.single_ip?
+	    ret += "<tr><td>#{ipr.description}</td></tr>"	  
+	  else
+	    ret += "<tr><td>#{ipr.description}</td></tr>"	  
+	    ret += "<tr><td>#{ipr.from_ip} - #{ipr.to_ip}</td></tr>"
+	    ret += "<tr><td>range contains #{ipr.to_ip.to_i - ipr.from_ip.to_i} ips</td></tr>"
+	    ret += "<tr><td>the ip is number #{ip.to_i- ipr.from_ip.to_i + 1} in range</td></tr>"
+	  end
+	}
+	ret += "</table></div></div>"
+	ret
+      }
+    else
+      h(record.send(column.name)) 
+    end
+  rescue
+    if RAILS_ENV == "development"
+      "#{h(record[column.name])} <span class='error'>#{$!}</span>" 
+    else
+      "<span class='error'>#{h(record[column.name])}</span>" 
+    end
+  end
+
+end

Added: incubator/alois/trunk/rails/app/helpers/tablelist_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/tablelist_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/tablelist_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/tablelist_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,16 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module TablelistHelper
+end

Added: incubator/alois/trunk/rails/app/helpers/tables_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/tables_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/tables_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/tables_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,16 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module TablesHelper
+end

Added: incubator/alois/trunk/rails/app/helpers/views_helper.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/helpers/views_helper.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/helpers/views_helper.rb (added)
+++ incubator/alois/trunk/rails/app/helpers/views_helper.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,42 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module ViewsHelper
+  UNGROUPED_NAME = ""
+  
+  def make_groups(views)
+    groups = {}
+    
+    views.each {|v|
+      names = (v.name or "").split(" ") 
+
+      groups[names[0]] = [] unless groups[names[0]]
+      groups[names[0]].push(v)
+
+    }
+
+    groups.each {|key,views|
+      if views.length == 1
+	groups[UNGROUPED_NAME] = [] unless groups[UNGROUPED_NAME]
+	groups[UNGROUPED_NAME].push(views[0])
+	groups.delete(key)
+      end
+      views.sort! {|a,b| (a.name or "") <=> (b.name or "") }
+    }
+        
+    groups[UNGROUPED_NAME].sort! {|a,b| (a.name or "") <=> (b.name or "") } if groups[UNGROUPED_NAME]
+    groups
+  end
+
+end

Added: incubator/alois/trunk/rails/app/models/alarm.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/models/alarm.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/models/alarm.rb (added)
+++ incubator/alois/trunk/rails/app/models/alarm.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,251 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+class Alarm < ActiveRecord::Base
+  belongs_to :sentinel
+  has_one :report
+
+  # Levels from syslog:
+  #  0 Emergency : system is unusable 
+  #  1 Alert: action must be taken immediately 
+  #  2 Critical: critical conditions 
+  #  3 Error: error conditions 
+  #  4 Warning: warning conditions 
+  #  5 Notice: normal but significant condition 
+  #  6 Informational: informational messages 
+  #  7 Debug: debug-level messages
+  ALARM_LEVELS = {
+    0 => :emergency, 
+    1 => :alert, 
+    2 => :critical,
+    3 => :error,
+    4 => :warning,
+    5 => :notice,
+    6 => :informational,
+    7 => :debug }
+
+  # Define a color for every alarm level
+  ALARM_COLORS = {
+    0 => "red",
+    1 => "red", 
+    2 => "red",
+    3 => "orange",
+    4 => "yellow",
+    5 => "grey",
+    6 => "green",
+    7 => "transparent" }  
+  
+  # Alarm states for alarm workflow
+  PROCESS_STATES = {
+    0 => :new,
+    1 => :assigned,
+    2 => :in_progress,
+    10 => :closed
+  }
+
+  # SQL Array of Alarm levels to use in SQL queries
+  def self.sql_array(levels)
+    inv = Alarm::ALARM_LEVELS.invert	
+    "(" + levels.map{|l| inv[l]}.join(",") + ")"
+  end
+
+  # SQL Condition for alarms that are not acknowledget yet
+  NOT_ACKNOWLEDGE_CONDITION = "(process_state < 10 or process_state IS NULL)"
+  # SQL Condition for alarms that has already been acknowledged
+  ACKNOWLEDGE_CONDITION = "process_state = 10"
+
+  # Levels that need immediate attention
+  RED_LEVELS = [:emergency, :alert, :critical]
+  # SQL Condition for alamrs that need immediate attention
+  ACTIVE_RED_CONDITION = "#{NOT_ACKNOWLEDGE_CONDITION} AND alarm_level IN #{sql_array(RED_LEVELS)}"
+
+  # Levels that need attention, but not immediately
+  YELLOW_LEVELS = [:error, :warning]
+  # SQL Condition for alamrs that need attention but not immediately
+  ACTIVE_YELLOW_CONDITION =  "#{NOT_ACKNOWLEDGE_CONDITION} AND alarm_level IN #{sql_array(YELLOW_LEVELS)}"
+
+  # SQL Condition for alarms that need acknowledge
+  ACTIVE_YELLOW_RED_CONDITION = "#{NOT_ACKNOWLEDGE_CONDITION} AND alarm_level IN #{sql_array(YELLOW_LEVELS + RED_LEVELS)}"
+
+  # Levels for informational usage
+  WHITE_LEVELS = ALARM_LEVELS.values.reject {|l| RED_LEVELS.include?(l) or YELLOW_LEVELS.include?(l)}
+  # SQL Condition for informational alamrs
+  ACTIVE_WHITE_CONDITION = "#{NOT_ACKNOWLEDGE_CONDITION} AND (alarm_level IN #{sql_array(WHITE_LEVELS)} OR alarm_level IS NULL)"
+
+  # true if alarm has been acknowledgetd already
+  def acknowledge; process_state == :closed; end
+
+  # Returns the color of the current system state,
+  # if there exist a red alarm, the stat is red,
+  # if there exist no red alarm but a yellow alarm
+  # yellow, green otherwise.
+  def self.status_color
+    a = Alarm.find(:first, :conditions => ACTIVE_YELLOW_RED_CONDITION, :order => "alarm_level")
+    if a then a.color else "green" end
+  end
+
+  # Returns the symbol of alarm state: :new, :assigned, ...
+  def process_state
+    PROCESS_STATES[super] or :unknown
+  end
+
+  # Returns the symbol of the alarm_level. See ALARM_LEVELS
+  def alarm_level_name
+    Alarm::ALARM_LEVELS[self.alarm_level]
+  end
+  
+  # Returns the color name of the alarm based on the alarm_level
+  def color
+    Alarm::ALARM_COLORS[self.alarm_level]
+  end
+
+  # Sets a new alarm_level. Can either be a symbol (see ALARM_LEVELS) or
+  # the integer that representes the level in the DB.
+  def alarm_level=(val)
+    if val.is_a?(Symbol)
+      "Alarm '#{val}' not found." unless Alarm::ALARM_LEVELS.value?(val)
+	val = Alarm::ALARM_LEVELS.invert[val]	
+    end
+    super(val)
+  end 
+
+  # Appends a message to the alarm log, the message should
+  # not include datetime since the function prepends this
+  # information.
+  def log_message(msg, sender = nil)
+    self.log ||= ""
+    if sender
+      self.log += "#{DateTime.now.strftime("%F %T")} #{sender.class.name}.#{sender.id}: #{msg.inspect}\n"
+    else
+      self.log += "#{DateTime.now.strftime("%F %T")}: #{msg.inspect}\n"
+    end
+    self.save
+  end
+  
+  # Generate/Create a new alarm out of a sentinel
+  def self.generate(sentinel, report,options = {})
+    a = Alarm.new
+    begin
+      a.sentinel = sentinel
+      datasource = options[:datasource]
+      a.log_message("Alarm created with sentinel threashold #{sentinel.threshold}" +
+		    " and count of table #{datasource.table.table_name} is #{sentinel.count}.")
+      a.log_message("Saving table data.")
+      
+      # this does not work with big datarecords, disabled
+      a.save_data(datasource,options)
+      
+      a.report = report
+
+      a.alarm_level = sentinel.alarm_level
+      a.save
+    rescue
+      a.log_message("ERROR Generating alarm: '#{$!}').")
+      a.log_message($!.backtrace)
+    end
+    return a
+  end
+
+  # Return conditions of sentinel with the current time of the alarm
+  def conditions
+    self.sentinel.dup.conditions({:now => self.created_at})
+  end
+
+  # Other name for data function, see data
+  def datasource; data;  end
+  
+  # Returns the data of that alarm
+  def data
+    return @data if defined?(@data)
+    @data = YAML.parse(open(data_file,"r") {|f| f.readlines.reject{|r| r =~ /BigDecimal/}.join}).transform    
+  end
+  
+  # Return the data as readable text
+  def text
+    if data.class == String
+      return data
+    else
+      return data.as(:text, :ignore_table_width => true)      
+    end
+  end
+
+  ##### Things for archivating ####
+
+  # Limit of source records (query result of the sentinel that
+  # causes the alarm) that will be saved in a alarm.
+  RECORD_LIMIT = 1000
+
+  # Substitutes archive path patterns
+  def self.archive_path(path, conditions)
+    if conditions[:id]
+      path = path.gsub(/\%i/, conditions[:id].to_s)
+    end
+    if conditions[:date]
+      path = path.gsub(/\%d/, conditions[:date].to_s)
+    end
+    if conditions[:time]
+      path = path.gsub(/\%t/, conditions[:time].to_s)
+    end
+    if conditions[:name]
+      path = path.gsub(/\%n/, conditions[:name].to_s)
+    end
+    path
+  end
+
+  # Get the path where the alarm will be archivated to.
+  def path
+    unless super
+      # to get an id
+      save if new_record?
+      self.path = Pathname.new(Alarm.archive_path($alarm_archive_pattern, {
+					       :date => (self.created_at.strftime("%F") rescue DateTime.now.strftime("%F")),
+					       :time => (self.created_at.strfiime("%T") rescue ""),
+					       :id => self.id})).to_s
+
+      save
+    end
+    super
+  end
+
+  # Returns the path of the data file in the archive
+  def data_file
+    (Pathname.new(path) + "alarm.data").to_s
+  end
+
+  # Save data from the datasource to the correct plcae
+  # in the archive
+  def save_data(datasource,options = {})
+    @data = datasource
+    
+    if @data.respond_to?(:table) and @data.table.respond_to?(:report_table)
+      my_data = @data.table.report_table(:all, 
+					 :limit => RECORD_LIMIT, 
+					 :conditions => options[:conditions],
+					 :methods => "original_text"
+					 )
+      log_message("WARNING: Record limit of #{RECORD_LIMIT} reached small for count. " +
+		  "Not all data will be saved!",self) if
+	my_data.length >= RECORD_LIMIT
+    else
+      my_data = @data
+    end
+
+    p = Pathname.new(path)
+    p.mkpath unless p.exist?
+    open(data_file,"w") {|f| f.write(my_data.to_yaml) }
+
+    self.save
+  end
+  
+end

Added: incubator/alois/trunk/rails/app/models/alarm_mailer.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/models/alarm_mailer.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/models/alarm_mailer.rb (added)
+++ incubator/alois/trunk/rails/app/models/alarm_mailer.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,24 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Mailer for alarms
+class AlarmMailer < BaseMailer
+
+  def simple(recipients, alarm,options = {})
+    options[:title] ||= "Alarm #{alarm.sentinel ? alarm.sentinel.name : "\##{alarm.id}"} (#{alarm.alarm_level_name})"
+    text(recipients, alarm, options)
+    html(recipients, alarm, options)
+  end
+
+end

Added: incubator/alois/trunk/rails/app/models/any_condition.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/models/any_condition.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/models/any_condition.rb (added)
+++ incubator/alois/trunk/rails/app/models/any_condition.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,46 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+  # Condition Class for matching a operator agains any column in the datasource
+  class AnyCondition < Condition
+    attr_reader :operator, :value
+    # Create a new any condition
+    def initialize(operator, value, options = {})      
+      @operator = operator
+      @value = value
+      @options = options
+    end
+
+    # This is only for display to user. Column field is not used because
+    # it anyway should match any column.
+    def column 
+      "ANY"
+    end
+    
+    # Sql statement
+    def sql(options = {})
+      options = normalize_options(options)
+      return "ANY #{operator} #{value}" unless (table_class = options[:table_class])
+      "( " + table_class.table.columns.map { |c|
+	Condition.new(c.name, operator, value,@options)
+      }.map { |c| c.sql(table_class) }.compact.join(' OR ') + " )"
+    end
+
+    # This condition is applyable to any source. (always true)
+    def applyable(options = {})
+      true
+    end
+    
+  end
+

Added: incubator/alois/trunk/rails/app/models/application_log.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/models/application_log.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/models/application_log.rb (added)
+++ incubator/alois/trunk/rails/app/models/application_log.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,16 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+class ApplicationLog < ActiveRecord::Base
+end

Added: incubator/alois/trunk/rails/app/models/base_mailer.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/models/base_mailer.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/models/base_mailer.rb (added)
+++ incubator/alois/trunk/rails/app/models/base_mailer.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,258 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+class BaseMailer < ActionMailer::Base
+  
+  # function from old mail class
+  def self.expecting_mail(count = 1)
+    raise "Not expecing to use this when not in testing mode." unless RAILS_ENV=="test"
+    @expected_mail_count ||= 0
+    @expected_mail_count += count
+  end
+  def self.not_delivered_mails_count
+    raise "Not expecing to use this when not in testing mode." unless RAILS_ENV=="test"
+    @expected_mail_count or 0
+  end
+  def self.mail_delivered(mail)
+    # decrement expected mails
+    if RAILS_ENV == "test"
+      raise "No email expected.\n #{mail.to_s}" unless not_delivered_mails_count > 0
+      @expected_mail_count -= 1  
+    end  
+  end
+  def self.latest_mail
+    deliveries[-1]
+  end
+  def deliver!(mail = @mail)
+    r = super
+    BaseMailer.mail_delivered(mail)
+    r
+  end
+  def self.mails
+    print "DEPRECATED WARNING: use BaseMailer.deliveries instead of mails.\n"
+    deliveries
+  end
+  def self.smtp_server
+    $email_smtp_server or "localhost"
+  end
+  def self.sender
+    $email_sender_address or "alois@logintas.com"
+  end
+  
+  # exception delivering
+  def self.send_exception(exceptions)
+    exceptions = [exceptions] unless exceptions.class == Array
+
+    ret = "#{exceptions.length} exception ocurred:\n\n\n"
+
+    if $log
+      $log.error("Sending #{exceptions.length} execptions to '#{$developper_email}'.")
+    end
+
+    exceptions.each {|ex|
+      ret += "Message:\n#{ex.to_s}\n\nBacktrace:\n" +
+	ex.backtrace.join("\n")
+
+      if $log
+	$log.error(ex.to_s)
+	ex.backtrace.each {|m| $log.error(m)}
+      end
+
+    }
+
+    
+    BaseMailer.send_email(:text, $developper_email, "Exception Alert", ret)
+  end
+  
+  # simple send function
+  def BaseMailer.send_email(type, addresses, title, content, attachments = [])
+    BaseMailer.deliver_oldfashioned(type,addresses,title,content,attachments)
+  end
+
+  def oldfashioned(type, addresses, title, content, attachments = [])
+    opt = {:title => title, :body => content, :attachments => attachments, :without_object => true }
+    case type
+    when :html
+      html(addresses, nil, opt)
+    when :text
+      text(addresses, nil, opt)
+    else
+      raise "Unknown type #{type}"
+    end
+  end
+
+  # base mailer functions
+
+  def object_name
+    if mailer_name =~ /^(.*)\_mailer$/
+      return $1
+    else
+      raise "Cannot compute object name of mailer '#{mailer_name}'."
+    end
+  end
+
+  def text(recipients, obj, options = {})
+    if options[:without_object]
+      title = (options[:title] or "Message")
+    else
+      raise "No #{object_name} given." unless obj
+      
+      title = nil
+      unless title = options[:title]
+	if obj.respond_to?(:name)
+	  title = "#{object_name.camelize} #{obj.name}"
+	else
+	  title = "#{object_name.camlize} #{obj.id}"
+	end
+      end
+    end
+
+    # Always prepend installation name
+    prefix = ($installation_name or "Alois")
+    title = "#{prefix} - #{title}"
+    
+    recipients recipients
+    from       BaseMailer.sender
+    subject    title   
+    content_type "multipart/alternative"
+
+    layout get_layout("plain")
+
+    part "text/plain" do |p|
+      p.charset = "utf-8"
+      p.body = (options[:body] or render_message("#{template}.plain.erb", {object_name.to_sym => obj}))
+      p.content_disposition = ""
+    end
+
+    css get_css
+    layout get_layout("html")
+  end
+
+  def html(recipients, obj, options = {})   
+    p = nil
+    if !options[:without_images]
+      part "multipart/related" do |p|	
+	# not necessary but otherwice a exception is thrown
+	p.charset = "uft-8"
+
+	new_part = ActionMailer::Part.new(
+					  :content_type => "text/html",
+					  :body => (options[:body] or render_message("#{template}.html.erb", 
+										     :part_container => p, 
+										     object_name => obj)),
+					  :disposition => ""
+					  )
+	# correct buggy implementation. but now you only can use png images.
+	# currently the image type is 'image/FILENAME'
+	p.parts.each {|mp|
+	  mp.content_type = "image/png" if mp.content_type =~ /image/
+	}
+	
+	# The message must be first for thunderbird.
+	# Image tag inserts image tags to the beginning of the parts.
+	p.parts.insert(0,new_part)
+	
+	# attach files    
+	(options[:attachments] or []).each {|f|
+	  attach_file(p,f)
+	}
+      end      
+    else
+      part "text/html" do |p|
+	p.body = render_message("#{template}.html.erb", {object_name.to_sym => obj})
+	p.charset = "utf-8"
+	p.content_disposition = ""
+      end
+    end
+    p
+  end
+
+  def self.compute_cid(filename)
+    filename = Pathname.new(filename).realpath.to_s
+    if BaseMailer.sender =~ /\@([\w\d\.]*)/
+      domain = $1
+    else
+      domain = BaseMailer.sender
+    end
+    
+    res = ERB::Util.url_encode(Pathname.new(filename).to_s).hash.abs.to_s + "@" + domain 
+    $debug ||= []
+    $debug.push([filename,res])
+    res
+  end
+
+  def self.translate_image_links(text)
+    text.gsub(/(src|SRC)=\"([^\"]*)\"/) {|match|
+      "#{$1}=\"cid:#{compute_cid($2)}\""
+    }
+  end
+
+  def layout_name
+    ($selected_theme and $selected_theme.layout) or "alois"
+  end
+  
+  def get_layout(type)
+    return "#{layout_name}.#{type}" if File.exist?("#{RAILS_ROOT}/app/views/layouts/mailers/#{layout_name}.#{type}.erb")
+    return "alois.#{type}" if File.exist?("#{RAILS_ROOT}/app/views/layout/mailers/alois.#{type}.erb")
+    return nil
+  end
+
+  def get_css    
+    ret = ["common","alois-common","alois","alois-screen", layout_name, "#{layout_name}-common","#{layout_name}-screen"]
+    ret = ret.select {|f|
+      File.exist?("#{RAILS_ROOT}/public/stylesheets/#{f}.css")
+    }
+    return [] if ret.length == 0
+    ret
+  end
+
+  def initialize(method_name=nil, *parameters)
+    ActionMailer::Base.smtp_settings[:address] = BaseMailer.smtp_server
+
+    if $root_url =~ /^(.*):\/\/(.*[^\/])\/?$/
+      ActionMailer::Base.default_url_options[:protocol] = $1
+      ActionMailer::Base.default_url_options[:host] = $2
+    else
+      raise "Cannot parse \$root_url '#{$root_url}'. Need something like https://example.com/alois/"
+    end
+    super
+  end
+
+  def attach_file(part, filename)
+    cid = BaseMailer.compute_cid(filename)
+    raise "Can only attach pngs" unless filename =~ /.png$/
+    part.inline_attachment :content_type => "image/png",
+      :body => File.read(filename),
+      :filename => Pathname.new(filename).split[1].to_s,
+      :cid => "<#{cid}>"    
+  end
+
+
+  def self.preview_html(part)
+    ret = ""
+    part.parts.each {|p|
+      case p.content_type
+      when "text/html"
+	ret += "<hr>#{p.content_type}<br>"
+	ret += p.body
+      when "text/plain"
+	ret += "<hr>#{p.content_type}<br>"
+	ret += "<pre>#{p.body}</pre>"
+      end
+      ret += preview_html(p)
+    }
+    ret
+  end
+
+end

Added: incubator/alois/trunk/rails/app/models/bookmark.rb
URL: http://svn.apache.org/viewvc/incubator/alois/trunk/rails/app/models/bookmark.rb?rev=1031127&view=auto
==============================================================================
--- incubator/alois/trunk/rails/app/models/bookmark.rb (added)
+++ incubator/alois/trunk/rails/app/models/bookmark.rb Thu Nov  4 18:27:22 2010
@@ -0,0 +1,29 @@
+# Copyright 2010 The Apache Software Foundation.
+# 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Model for saving bookmarks (links to pages within alois) in the database
+class Bookmark < ActiveRecord::Base
+  validates_presence_of :controller, :action, :title
+
+  # Get the hash for url_for representing the bookmark
+  def url
+    { :controller => self.controller,
+      :action => self.action,
+      :mode => self.mode,
+      :table_name => self.table_name,
+      :table => self.table_name,
+      :id => self.identifier }
+  end
+
+end



Mime
View raw message