[PATCH] RM3311 added date select, ordering options, and csv export to log history

Scott Seago sseago at redhat.com
Tue Jun 5 13:00:11 UTC 2012


On 06/04/2012 12:25 AM, Tzu-Mainn Chen wrote:
> ---
>   src/app/controllers/logs_controller.rb |   80 ++++++++++++++++++++++++++++++--
>   src/app/views/logs/index.html.haml     |   12 +++++
>   src/config/locales/en.yml              |   10 ++++
>   src/config/routes.rb                   |    5 ++-
>   src/features/logs.feature              |    3 +-
>   5 files changed, 103 insertions(+), 7 deletions(-)
>
> diff --git a/src/app/controllers/logs_controller.rb b/src/app/controllers/logs_controller.rb
> index 8b9e5c4..2441fd5 100644
> --- a/src/app/controllers/logs_controller.rb
> +++ b/src/app/controllers/logs_controller.rb
> @@ -30,11 +30,42 @@ class LogsController<  ApplicationController
>     end
>
>     def filter
> -    redirect_to_original({"source_type" =>  params[:source_type],
> +    redirect_to_original({ "source_type" =>  params[:source_type],
>                              "pool_select" =>  params[:pool_select],
>                              "provider_select" =>  params[:provider_select],
>                              "owner_id" =>  params[:owner_id],
> -                           "state" =>  params[:state]})
> +                           "state" =>  params[:state],
> +                           "from_date" =>  params[:from_date],
> +                           "to_date" =>  params[:to_date],
> +                           "order" =>  params[:order] })
> +  end
> +
> +  def export_logs
> +    load_logs
> +    load_headers
> +
> +    csvm = Object.const_defined?(:FasterCSV) ? FasterCSV : CSV
> +    csv_string = csvm.generate(:col_sep =>  ";", :row_sep =>  "\r\n") do |csv|
> +      csv<<  @header.map {|header| header[:name].capitalize }
> +
> +      unless @events.nil?
> +        @events.each do |event|
> +          source = event.source
> +          provider_account = source.nil? ? nil : source.provider_account
> +          csv<<  [ event.event_time.strftime("%d-%b-%Y %H:%M:%S"),
> +                   source.nil? ? t('logs.index.not_available') : source.name,
> +                   source.nil? ? t('logs.index.not_available') : source.state,
> +                   source.nil? ? t('logs.index.not_available') : source.pool_family.name + "/" + source.pool.name,
> +                   provider_account.nil? ? t('logs.index.not_available') : provider_account.provider.name + "/" + provider_account.name,
> +                   source.nil? ? t('logs.index.not_available') : source.owner.login,
> +                   event.summary ]
> +        end
> +      end
> +    end
> +
> +    send_data(csv_string,
> +              :type =>  'text/csv; charset=utf-8; header=present',
> +              :filename =>  "export.csv")
>     end
>
>     protected
> @@ -46,16 +77,29 @@ class LogsController<  ApplicationController
>         params[:provider_select].nil? ? "" : params[:provider_select]
>       @owner_id = params[:owner_id].nil? ? "" : params[:owner_id]
>       @state = params[:state].nil? ? "" : params[:state]
> +    @order = params[:order].nil? ? t('logs.options.time_order') : params[:order]
> +    @from_date = params[:from_date].nil? ? Date.today - 7.days :
> +      Date.civil(params[:from_date][:year].to_i,
> +                 params[:from_date][:month].to_i,
> +                 params[:from_date][:day].to_i)
> +    @to_date = params[:to_date].nil? ? Date.today + 1.days :
> +      Date.civil(params[:to_date][:year].to_i,
> +                 params[:to_date][:month].to_i,
> +                 params[:to_date][:day].to_i)
>
> -    conditions = []
>       if @source_type.present?
> -      conditions += ["source_type = ?", @source_type]
> +      conditions = ["event_time between ? and ? and source_type = ?",
> +                    @from_date, @to_date, @source_type]
> +    else
> +      conditions = ["event_time between ? and ?",
> +                    @from_date, @to_date]
>       end
>
>       @events = Event.unscoped.find(:all,
>                                     :include =>
>                                     {:source =>  [:pool_family, :pool, :owner]},
> -                                  :conditions =>  conditions
> +                                  :conditions =>  conditions,
> +                                  :order =>  "event_time asc"
>                                     )
>       deployments = Deployment.unscoped.list_for_user(current_user,
>                                                       Privilege::VIEW)
> @@ -100,6 +144,25 @@ class LogsController<  ApplicationController
>         true
>       }
>
> +    case @order
> +    when t('logs.options.deployment_instance_order')
> +      @events = @events.sort_by {|event|
> +        (event.source.nil? ? "" : event.source.name)}
> +    when t('logs.options.state_order')
> +      @events = @events.sort_by {|event|
> +        (event.source.nil? ? "" :
> +         (event.source.state.nil? ? "" : event.source.state))}
> +    when t('logs.options.pool_order')
> +      @events = @events.sort_by {|event|
> +        (event.source.nil? ? "" : event.source.pool_family.name)}
> +    when t('logs.options.provider_order')
> +      @events = @events.sort_by {|event|
> +        (event.source.nil? ? "" : event.source.provider_account.name)}
> +    when t('logs.options.owner_order')
> +      @events = @events.sort_by {|event|
> +        (event.source.nil? ? "" : event.source.owner.login)}
> +    end
> +
>       @paginated_events = paginate_collection(@events, params[:page], PER_PAGE)
>     end
>
> @@ -128,6 +191,12 @@ class LogsController<  ApplicationController
>       @owner_options = [[t('logs.options.default_users'), ""]] +
>         User.find(:all, :order =>  "login",
>                   :select =>  ["id", "login"]).map{|x| [x.login, x.id]}
> +    @order_options = [t('logs.options.time_order'),
> +                      t('logs.options.deployment_instance_order'),
> +                      t('logs.options.state_order'),
> +                      t('logs.options.pool_order'),
> +                      t('logs.options.provider_order'),
> +                      t('logs.options.owner_order')]
>     end
>
>     def load_headers
> @@ -142,4 +211,5 @@ class LogsController<  ApplicationController
>         { :name =>  "", :sortable =>  false },
>       ]
>     end
> +
>   end
> diff --git a/src/app/views/logs/index.html.haml b/src/app/views/logs/index.html.haml
> index b76d620..36cd965 100644
> --- a/src/app/views/logs/index.html.haml
> +++ b/src/app/views/logs/index.html.haml
> @@ -16,6 +16,18 @@
>           = select_tag "owner_id", options_for_select(@owner_options, @owner_id)
>           = restful_submit_tag t("filter_table.apply_filters"), "index", filter_logs_path, 'POST', :class =>  'button', :id =>  'apply_logs_filter'
>           %span.label.badge.dark= @events.count
> +      %br
> +        = t('filter_table.from')
> +        = select_date @from_date, :prefix =>  :from_date
> +        = t('filter_table.to')
> +        = select_date @to_date, :prefix =>  :to_date
> +        = t('filter_table.order_by')
> +        = select_tag "order", options_for_select(@order_options, @order)
> +        %li.more_actions
> +          %span
> +            = image_tag "more_actions_drop.png"
> +          %ul
> +            %li= link_to "#{t'logs.index.export_logs'}", export_logs_logs_path(:source_type =>  @source_type, :state =>  @state, :pool_select =>  @pool_select, :provider_select =>  @provider_select, :owner_id =>  @owner_id, :from_date =>  {:day =>  @from_date.day, :month =>  @from_date.month, :year =>  @from_date.year}, :to_date =>  {:day =>  @to_date.day, :month =>  @to_date.month, :year =>  @to_date.year}, :order =>  @order)
>
>       = filter_table(@header, @paginated_events) do |event|
>         - source = event.source
> diff --git a/src/config/locales/en.yml b/src/config/locales/en.yml
> index b198935..a4a2ddd 100644
> --- a/src/config/locales/en.yml
> +++ b/src/config/locales/en.yml
> @@ -19,6 +19,12 @@ en:
>         instance_event_type: Instance
>         default_pools: All Pools
>         default_providers: All Providers
> +      time_order: Time
> +      deployment_instance_order: Deployment/Instance
> +      state_order: State
> +      pool_order: Pool
> +      provider_order: Provider
> +      owner_order: Owner
>       index:
>         title: Logs
>         not_available: N/A
> @@ -35,6 +41,7 @@ en:
>         frontend_realm: Frontend Realm
>         image: Image
>         hwp: Hardware Profile
> +      export_logs: Export logs
>     users:
>       users: "Users"
>       return_to: "Return to:"
> @@ -1235,6 +1242,9 @@ en:
>       none: None
>     filter_table:
>       viewing: Viewing
> +    from: From
> +    to: To
> +    order_by: Order By
>       results: Results
>       search: Search
>       apply_filters: "Apply filters"
> diff --git a/src/config/routes.rb b/src/config/routes.rb
> index 265f752..fe72be1 100644
> --- a/src/config/routes.rb
> +++ b/src/config/routes.rb
> @@ -157,7 +157,10 @@ Conductor::Application.routes.draw do
>     end
>
>     resources :logs do
> -    post :filter, :on =>  :collection
> +    collection do
> +      post 'filter'
> +      get 'export_logs'
> +    end
>     end
>
>     resources :config_servers do
> diff --git a/src/features/logs.feature b/src/features/logs.feature
> index 98bbe34..3ebe42b 100644
> --- a/src/features/logs.feature
> +++ b/src/features/logs.feature
> @@ -8,7 +8,8 @@ Feature: View Logs
>       And I am logged in
>
>     Scenario: View logs
> -    Given there is a deployment named "MySQL Cluster" belonging to "Databases" owned by "bob"
> +    Given there is a deployment named "Test-Deployment" belonging to "Databases" owned by "bob"
> +    And deployement "Test-Deployment" has associated event "testevent"
>       And I am on the logs page
>       Then I should see "created"
>       When I select "stopped" from "state"
ACK and pushed. I had to make a couple minor changes so the patch would 
apply after pushing the user groups patch, but it's all pushed now, 
since there's no need in you having to make the same changes on your 
side prior to pushing later.

One suggestion is that we should integrate this with the other filtered 
list design -- and, in particular, sorting columns should be accessed by 
clicking the column header, but that shouldn't hold up the functionality 
here.

The other thing I noticed was that the "csv" file wasn't comma-delimited 
but rather it was semicolon-delimited. From the code it looks like this 
was deliberate, so I pushed it anyway. If you really wanted 
comma-separated values then you should fix it in a (trivial) follow-on 
patch.

Scott





More information about the aeolus-devel mailing list