Class: ExCite::ExportCitationsController

Inherits:
ActionController::Base
  • Object
show all
Defined in:
app/controllers/ex_cite/export_citations_controller.rb

Overview

Logic behind the webservice. First it gathers all the resource keys and creates Citation objects out of them and then it gathers any and all from formats and data variables that were sent via post and creates an array out of them. If the array is still empty it uses the URL as an OpenURL. It then loops through the array and translates and caches (or fetches) each one using acts_as_citable. It then either downloads the data or redirects to another webservice.

Instance Method Summary collapse

Instance Method Details

#callbackObject

The callback url is defined here



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

def callback
  # Starts with current url minus the querystring..
  callback = "#{export_citations_url.gsub(/https?/, @push_to.callback_protocol.to_s)}?"
  resource_keys = []
  citations.each do |citation|
    if !citation.respond_to? :new_record || citation.new_record?
      resource_keys << citation.resource_key
    end
  end
  unless resource_keys.empty?
    resource_key = Digest::SHA1.hexdigest(resource_keys.sort.join)
    Rails.cache.write(resource_key,resource_keys)
    callback += "resource_key=#{resource_key}&"
  end
  citations.each do |citation|
    # then adds a resource key for each cached resource
    callback += (!citation.respond_to? :new_record || citation.new_record?) ? "" : "id[]=#{citation.id}&"
  end
  # and finally the to format
  callback += "to_format=#{@to_format.formatize}"
  # url encode and return
  ERB::Util.url_encode(callback)
end

#citationsObject

Constructs an array containing all the citations



26
27
28
29
30
31
32
33
34
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 26

def citations
 unless defined? @citations
  @citations = record_citation + resource_citation + format_citation
  if @citations.empty?
    @citations << open_url_citation
  end
 end
 @citations.compact
end

#delimitersObject



180
181
182
183
184
185
186
187
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 180

def delimiters
  case @to_format
  when "to_easybib", "to_csl"
    return [",\n","[","]"]
  else
    return ["\n\n"]
  end
end

#downloadObject

sends the data with utf-8 encoding



133
134
135
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 133

def download
  send_data @output.force_encoding('UTF-8'), :filename => filename, :type => @to_format.formatize.to_sym
end

#filenameObject

Creates the filename and extension. Few are application specific



163
164
165
166
167
168
169
170
171
172
173
174
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 163

def filename
  name = "export"
  case @to_format
  when "to_bibtex"
    name += ".bib"
  when "to_easybib"
    name += ".json"
  else
    name += "." + @to_format.formatize
  end
  name
end

#format_citationObject

Constructs new citation objects with data and source format set (the citation key is constructed automatically), returns an array



58
59
60
61
62
63
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 58

def format_citation
  (params[:from_format].nil? || params[:data].nil?) ? [] :
    params[:from_format].collect.with_index do |format, index|
      ExCite.acts_as_citable_class.new  ExCite.acts_as_citable_class.data_field.to_sym => params[:data].to_a[index],   ExCite.acts_as_citable_class.format_field.to_sym => (whitelist_formats :from, format)
    end
end

#handle_invalid_arguments(exc) ⇒ Object

For debugging purposes prints out the error. Also sends bad request header



113
114
115
116
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 113

def handle_invalid_arguments exc
  logger.debug exc
  head :bad_request
end

#indexObject

Maps then decides wether its a push request or a download, catches all bad argument errors



79
80
81
82
83
84
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 79

def index
  map
  serve
rescue ArgumentError => exc
  handle_invalid_arguments exc
end

#mapObject

Maps the output and caches it, alternatively it fetches the already cached result. Seperates each output with two new lines. Raises an argument error if any error is caught in mapping (usually the formats are messed up)



72
73
74
75
76
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 72

def map
  @output ||= citations.collect { |citation| Rails.cache.fetch(citation.resource_key+to_format) { citation.send(to_format) } }.join_and_enclose *delimiters
rescue Exception => exc
  raise ArgumentError, "#{exc}\n Data or source format not provided and/or mismatched. [citations => #{citations}, to_format => #{@to_format}]  "
end

#open_url_citationObject

Returns a single citation object with data and format set as the url and openurl respectively



66
67
68
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 66

def open_url_citation
  ExCite.acts_as_citable_class.new   ExCite.acts_as_citable_class.data_field.to_sym => CGI::unescape(request.protocol+request.host_with_port+request.fullpath),   ExCite.acts_as_citable_class.format_field.to_sym => (whitelist_formats :from, 'openurl')
end

#pushObject

Redirects or calls a predefined method depending on the webservice selected



119
120
121
122
123
124
125
126
127
128
129
130
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 119

def push
  # for redirects
  if @push_to.action.eql? :redirect
    # Openurl is data
    @data = "#{request.protocol}#{request.host_with_port}#{request.fullpath}"
    # and redirect to the url supplied by the webservice and the callback url
    redirect_to @push_to.url+callback, :status => 303
  elsif @push_to.action.eql? :render
    # call the method this service needs
    render_push
  end
end

#record_citationObject



36
37
38
39
40
41
42
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 36

def record_citation
  (params[:id].nil?) ? [] :
    params[:id].collect do |id|
      record = ExCite.acts_as_citable_class.find_by_id id if ExCite.acts_as_citable_class.respond_to? :find_by_id
      (record.nil?) ? (raise(ArgumentError, "This ID cannot be found.")) : record
    end
end

#render_pushObject



176
177
178
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 176

def render_push
  render :layout => false, :template => @push_to.template
end

#resource_citationObject

Constructs new citation objects with only the citation key set, returns an array



45
46
47
48
49
50
51
52
53
54
55
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 45

def resource_citation
  resources = []
  return resources if params[:resource_key].nil?
  resources << Rails.cache.fetch(params[:resource_key])
  resources.flatten!
  resources.collect do |key|
    citation = ExCite.acts_as_citable_class.new()
    citation.resource_key = key
    citation
  end
end

#serveObject

Pushes to a web service if that is what was requested else it downloads



87
88
89
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 87

def serve
  @push_to ? push : download
end

#valid_to_format?Boolean

Sends bad request if there is no destination format

Returns:

  • (Boolean)


15
16
17
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 15

def valid_to_format?
  head :bad_request unless to_format
end

#whitelist_formats(direction, format) ⇒ Object

Cleans the user input and finds the associated method for that format



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 92

def whitelist_formats direction, format
  # if the params are nil then it returns nil
  if direction.nil? || format.nil?
    return
  end
  # if the to format is found, it returns the method name for that to format
  if (direction == :to && (Citero.to_formats.include?(format.downcase) || Citero.citation_styles.include?(format.downcase)))
    return "#{:to.to_s}_#{format.downcase}"
  # if the from format is found, it returns just that because the object already knows what method to call
  elsif (direction == :from && Citero.from_formats.include?(format.downcase))
    return format.downcase
  end
  # if the format is still not found, it might be a push request, check if that is the case
  if ExCite.push_formats.include? format.to_sym
    @push_to = ExCite.push_formats[format.to_sym]
    @to_format = @push_to.to_format.downcase
    return "#{direction.to_s}_#{@to_format}"
  end
end