apply workaround for pattern search
[opensuse:software-o-o.git] / app / controllers / application_controller.rb
1 # Filters added to this controller apply to all controllers in the application.
2 # Likewise, all the methods added will be available for all controllers.
3
4 require 'net/https'
5
6 class ApplicationController < ActionController::Base
7
8   before_filter :set_language
9   before_filter :set_distributions
10   
11   helper :all # include all helpers, all the time
12   require "rexml/document"
13
14   init_gettext('software')
15
16   class MissingParameterError < Exception; end
17
18   protected
19
20   def rescue_action_locally( exception )
21     rescue_action_in_public( exception )
22   end
23
24   def rescue_action_in_public(exception)
25     @message = exception.message
26     if request.xhr?
27       render :template => "error", :layout => false, :status => 400
28     else
29       render :template => 'error', :layout => "application", :status => 400
30     end
31   end
32
33   def set_language
34     if cookies[:lang]
35       @lang = cookies[:lang]
36     elsif params[:lang]
37       @lang = params[:lang][0]
38     end
39     @lang.gsub!(/_/, '-') if @lang
40     if !@lang || !LANGUAGES.include?( @lang )
41       if !request.compatible_language_from(LANGUAGES).blank?
42         @lang = request.compatible_language_from(LANGUAGES).dup
43       else
44         @lang = "en"
45       end
46     end
47     @lang.gsub!(/-/, '_')
48     GetText.locale = @lang
49   end
50
51
52   def set_distributions
53     @distributions = Rails.cache.fetch('distributions', :expires_in => 120.minutes) do
54       load_distributions
55     end
56   end
57
58
59   # load available distributions
60   def load_distributions
61     @distributions = Array.new
62     begin
63       response = get_from_api("distributions")
64       doc = REXML::Document.new response.body
65       doc.elements.each("distributions/distribution") { |element|
66         dist = [element.elements['name'].text, element.elements['project'].text]
67         @distributions << dist
68       }
69       @distributions << ["ALL Distributions", 'ALL']
70     rescue Exception => e
71       logger.error "Error while loading distributions: " + e.to_s
72       @distributions = nil
73     end
74     return @distributions
75   end
76
77   # special version of render json with JSONP capabilities (only needed for rails < 3.0)
78   def render_json(json, options = {})
79     callback, variable = params[:callback], params[:variable]
80     response = begin
81       if callback && variable
82         "var #{variable} = #{json};\n#{callback}(#{variable});"
83       elsif variable
84         "var #{variable} = #{json};"
85       elsif callback
86         "#{callback}(#{json});"
87       else
88         json
89       end
90     end
91     render({:content_type => :js, :text => response}.merge(options))
92   end
93
94   def required_parameters(*parameters)
95     parameters.each do |parameter|
96       unless params.include? parameter.to_s
97         raise MissingParameterError, "Required Parameter #{parameter} missing"
98       end
99     end
100   end
101   
102
103   def valid_package_name? name
104     name =~ /^[[:alnum:]][-_+\w\.:]*$/
105   end
106
107   def valid_pattern_name? name
108     name =~ /^[[:alnum:]][-_+\w\.:]*$/
109   end
110
111   def valid_project_name? name
112     name =~ /^[[:alnum:]][-+\w.:]+$/
113   end
114
115
116   private
117
118   def get_from_api(path)
119     uri_str = "#{API_HOST}/#{path}".gsub(' ', '%20')
120     uri = URI.parse(uri_str)
121     logger.debug "Loading from api: #{uri_str}"
122     begin
123       http = Net::HTTP.new(uri.host, uri.port)
124       if  uri.scheme == 'https'
125         http.use_ssl = true
126         http.verify_mode = OpenSSL::SSL::VERIFY_NONE
127       end
128       request = Net::HTTP::Get.new("#{uri.path}?#{uri.query}")
129       api_user = API_USERNAME if defined? API_USERNAME
130       api_pass = API_PASSWORD if defined? API_PASSWORD
131       request['x-username'] = api_user
132       request.basic_auth  api_user, api_pass unless (api_user.blank? || api_pass.blank?)
133       http.read_timeout = 15
134       response = http.request(request)
135       case response
136       when Net::HTTPSuccess then response;
137       else
138         raise "Response was: #{response} #{response.body}"
139       end
140     rescue Exception => e
141       logger.error "Error connecting to #{uri_str}: #{e.to_s}"
142       raise "Error connecting to OBS API: #{e.to_s}"
143       return nil
144     end
145   end
146
147 end