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



135
136
137
138
139
140
141
142
143
144
145
146
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 135

def callback
  # Starts with current url minus the querystring..
  callback = "#{export_citations_url.gsub(/https?/, @push_to.callback_protocol.to_s)}?"
  citations.collect do |citation|
    # then adds a resource key for each cached resource
    callback += (!citation.respond_to? :new_record || citation.new_record?) ? "resource_key[]=#{citation.resource_key}&" : "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



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

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



130
131
132
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 130

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



149
150
151
152
153
154
155
156
157
158
159
160
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 149

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



55
56
57
58
59
60
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 55

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



110
111
112
113
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 110

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



76
77
78
79
80
81
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 76

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)



69
70
71
72
73
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 69

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



63
64
65
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 63

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



116
117
118
119
120
121
122
123
124
125
126
127
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 116

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



162
163
164
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 162

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
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 45

def resource_citation
  (params[:resource_key].nil?) ? [] :
    params[:resource_key].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



84
85
86
# File 'app/controllers/ex_cite/export_citations_controller.rb', line 84

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



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

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