update product for top-voted widget
[opensuse:openfate.git] / app / controllers / main_controller.rb
1 class MainController < ApplicationController
2
3   require 'feature.rb'
4
5   #skip_before_filter :verify_authenticity_token
6   skip_before_filter :set_client, :only => :logout
7   before_filter :set_products, :only => [:index]
8
9
10   def index
11     if isIdeas || ['/ideas', '/hackweek', '/hackweek/'].include?( request.env['REQUEST_URI'] )
12       set_top_features 'hackweek_5', 'Hackweek V'
13       render :template => 'ideas/main/index', :layout => 'layouts/application'
14     elsif isPartnerFate
15       # nothing
16     else
17       set_tag_cloud
18       set_top_features CONFIG['top_voted_prodid'], CONFIG['top_voted_prodname']
19     end
20     @top_features ||= []
21   end
22   
23   
24   def refresh_updated_features
25     begin
26       query = "let $hits:= (for $i in /feature[#{get_query_org()}] order by $i/k:versioningsummary/k:lastmodifydate descending return $i) return subsequence($hits, 1, 5)"
27       @features = Feature.queryFeatures(query, session[:user], @client)
28       @order = 'update_date'
29       @orderdirection = 'descending'
30       render :partial => "layouts/featurebox", :locals =>  {:headline => CGI::escapeHTML(params[:headline]), :action => :refresh_updated_features }
31     rescue Exception => e
32       @exception = e
33       logger.error "Error loading updated features: (#{e.message})"
34       @message = "Error loading updated features"
35       @status = 500
36       render :template => 'main/error', :layout => false
37     end
38   end
39
40
41   def refresh_my_features
42     begin
43       query = "/feature[#{get_query_org()} and actor[person/userid='#{session[:user].uid}'] and productcontext[not(status/done or status/rejected or status/duplicate)]]"
44       query = "let $hits:= (for $i in #{query} order by $i/k:versioningsummary/k:lastmodifydate descending return $i) return subsequence($hits, 1, 5)"
45       @features = Feature.queryFeatures(query, session[:user], @client)
46       @order = 'update_date'
47       @type = 'watchlist'
48       @orderdirection = 'descending'
49       render :partial => "layouts/featurebox", :locals =>  {:headline => CGI::escapeHTML(params[:headline]), :action => :refresh_my_features }
50     rescue Exception => e
51       @exception = e
52       logger.error "Error loading updated features: (#{e.message})"
53       @message = "Error loading updated features"
54       @status = 500
55       render :template => 'main/error', :layout => false
56     end
57   end
58
59
60   def refresh_top_features
61     prodid = CGI::escapeHTML(params[:prodid]).gsub("'", "").gsub("\\", "")
62     set_top_features prodid, CGI::escapeHTML(params[:prodname])
63     @top_features ||= []
64     render :partial => "layouts/top_features"
65   end
66   
67
68   def logout
69     reset_session if session[:user].uid
70     redirect_to("/cmd/ICSLogout")
71   end
72
73
74   def force_browser_type
75     session[:mobile_view] = params[:browser] == "mobile" ? true : false
76     redirect_to :action => :index
77   end
78
79
80   private
81
82   def set_tag_cloud
83     max, min = 0, 10000000
84     classes = %w(nube1 nube3 nube5 nube6 nube7)
85     tags = get_all_tags
86     
87     if !tags.nil? then
88       counts = tags.collect{|i| i.last.to_i}.sort
89       limit = counts.size > 25 ? counts[-25] : counts[0]
90       tags.each { |t|
91         if t.last.to_i < limit then next end
92         max = t.last.to_i if t.last.to_i > max
93         min = t.last.to_i if t.last.to_i < min
94       }
95
96       divisor = ((max - min) / classes.size) + 1
97       @cloud = Hash.new
98       tags.each { |t|
99         if t.last.to_i < limit then next end
100         @cloud[t.first] = classes[(t.last.to_i - min) / divisor]
101       }
102     end
103   end
104
105
106   def set_top_features prodid, prodname
107     cacheid = "#{@client}_top_#{prodid}"
108     @top_features = Rails.cache.fetch(cacheid, :expires_in => 10.minutes) do
109       logger.info( "Top features cache for prodid #{prodid} outdated, refreshing." )
110       features_list = nil
111       all_features = Feature.queryFeatures( "/feature[#{get_query_org()} and productcontext[(product/productid='#{prodid}')]]", session[:user], @client)
112       all_ids = all_features.map{|feature| feature.id}
113       logger.debug "Have #{all_ids.size} features in total for #{prodid}."
114       top = Feature.top_n_objects( 5, all_ids )
115       if !top.blank?
116         features_list = Array.new
117         idqueries = Array.new
118         top.each do |i|
119           idqueries << "@k:id='#{i.first}'"
120         end
121         query = "/feature[#{get_query_org()} and (#{idqueries.join(" or ")})]"
122         features = Feature.queryFeatures(query, session[:user], @client)
123         top.each do |t|
124           # Don't store the feature object, we cant marshall libxml objects atm :-(
125           if (feature = features.select{|f| f.id == t.first}).size > 0
126             feature = feature.first
127             product = feature.products.select{|p| p[:id] == "#{prodid}"}
128             product_state = !product.blank? ? product.first[:status] : nil
129             features_list << { :id => t.first, :score => t.last,
130               :title => feature.title, :rev => feature.revision.to_i, :product_state => product_state }
131           end
132         end
133       else
134         logger.info "Didn't find top features for #{prodid}"
135       end
136       features_list
137     end 
138     @top_product = prodname
139     @top_prodid = prodid
140   end
141
142   
143 end