Class: PrintController

Inherits:
ApplicationController show all
Defined in:
app/controllers/print_controller.rb

Overview

Mapfish print controller with access control and servlet call

Defined Under Namespace

Classes: JavaError

Constant Summary collapse

TMP_PREFIX =

WARNING: use NFS for multi-node setups! TODO: external config

"/opt/geodata/tmp/mfPrintTempFile"
TMP_SUFFIX =
".pdf"
TMP_PURGE_SECONDS =
600
OUTPUT_FORMATS =
["pdf", "png", "jpg", "tif", "gif"]

Instance Method Summary collapse

Constructor Details

#initialize ⇒ PrintController

Returns a new instance of PrintController.



21
22
23
# File 'app/controllers/print_controller.rb', line 21

def initialize
  @configFile = "#{Rails.root}/config/print.yml"
end

Instance Method Details

#create ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'app/controllers/print_controller.rb', line 65

def create
  cleanupTempFiles

  accessible_topics = Topic.accessible_by(current_ability).collect{ |topic| topic.name }
  layers_to_delete = []
  request.parameters["layers"].each do |layer|
    if layer["baseURL"] # WMS layers
      topic = File.basename(URI.parse(layer["baseURL"]).path)
      if accessible_topics.include?(topic)
        # rewrite URL for local WMS, use CGI if layer filter is used
        use_cgi = !layer["customParams"].nil? && layer["customParams"].any? { |param, value| param =~ LAYER_FILTER_REGEX }
        layer["baseURL"] = rewrite_wms_uri(layer["baseURL"], use_cgi)
        if layer["customParams"] #Set map_resolution for mapserver (MapFish print bug?)
          layer["customParams"].delete("DPI")
          layer["customParams"]["map_resolution"] = request.parameters["dpi"]
        end
        # For permission check in WMS controller: pass session as WMS request parameter
        #layer["customParams"]["session"] =
      else
        # collect inaccessible layers for later removal
        layers_to_delete << layer
      end
    end

    if layer["baseURL"].nil? && layer["styles"] #Vector layers
      layer["styles"].each_value do |style| #NoMethodError (undefined method `each_value' for [""]:Array):
        if style["externalGraphic"]
          style["externalGraphic"].gsub!(LOCAL_GRAPHICS_HOST, '127.0.0.1')
          style["externalGraphic"].gsub!(/^https:/, 'http:')
        end
      end
    end
  end
  # remove inaccessible layers
  request.parameters["layers"] -= layers_to_delete

  request.parameters["pages"].each do |page|
    # round center coordinates
    page["center"].collect! {|coord| (coord * 100.0).round / 100.0  }
    # add blank user strings if missing
    page["user_title"] = " " if page["user_title"].blank?
    page["user_comment"] = " " if page["user_comment"].blank?
    # base url
    page["base_url"] = "#{request.protocol}#{request.host}"
    # disclaimer
    topic = Topic.accessible_by(current_ability).where(:name => page["topic"]).first
    page["disclaimer"] = topic.nil? ? Topic.default_print_disclaimer : topic.print_disclaimer
  end

  logger.info request.parameters.to_yaml

  if PRINT_URL.present?
    call_servlet(request)
  else
    #print-standalone
    tempId = SecureRandom.random_number(2**31)
    temp = TMP_PREFIX + tempId.to_s + TMP_SUFFIX
    cmd = baseCmd + " --output=" + temp
    result = ""
    errors = ""
    status = POpen4::popen4(cmd) do |stdout, stderr, stdin, pid|
      stdin.puts request.parameters.to_json
      #body = request.body
      #FileUtils.copy_stream(body, stdin)
      #body.close
      stdin.close
      result = stdout.readlines.join("\n")
      errors = stderr.readlines.join("\n")
    end
    if status.nil? || status.exitstatus != 0
      raise JavaError.new(cmd, errors)
    else
      convert_and_send_link(temp, tempId, request.parameters["dpi"], request.parameters["outputFormat"])
    end
  end
end

#info ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'app/controllers/print_controller.rb', line 31

def info
  #if PRINT_URL.present?
  #TODO:  call_servlet(request)
  cmd = baseCmd + " --clientConfig"
  result = ""
  errors = ""
  status = POpen4::popen4(cmd) do |stdout, stderr, stdin, pid|

    result = stdout.readlines.join("\n")
    errors = stderr.readlines.join("\n")
  end
  if status.nil? || status.exitstatus != 0
    raise JavaError.new(cmd, errors)
  else
    info = ActiveSupport::JSON.decode(result)
    info['createURL'] = url_for(:protocol => request.protocol, :action=>'create') + '.json'
    # add output formats
    info['outputFormats'] = []
    OUTPUT_FORMATS.each do |output_format|
      info['outputFormats'] << {:name => output_format}
    end

    respond_to do |format|
      format.json do
        if params[:var]
          render :text=>"var "+params[:var]+"="+result+";"
        else
          render :json=>info
        end
      end
    end
  end
end

#show ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'app/controllers/print_controller.rb', line 142

def show
  output_format = params[:format]
  if OUTPUT_FORMATS.include?(output_format)
    temp = TMP_PREFIX + params[:id] + ".#{output_format}"
    case output_format
    when "pdf"
      type = 'application/x-pdf'
    when "png"
      type = 'image/png'
    when "jpg"
      type = 'image/jpeg'
    when "tif"
      type = 'image/tiff'
    when "gif"
      type = 'image/gif'
    end
    send_file temp, :type => type, :disposition => 'attachment', :filename => params[:id] + ".#{output_format}"
  end
end