luisf@613
|
1 # -*- coding: utf-8 -*-
|
luis@385
|
2 # vendor/plugins/redmine_bibliography/app/controllers/publications_controller.rb
|
luis@385
|
3
|
luis@947
|
4 class BibtexParsingError < Exception; end
|
luis@947
|
5
|
luis@328
|
6 class PublicationsController < ApplicationController
|
luis@425
|
7 unloadable
|
luis@946
|
8
|
luis@560
|
9 model_object Publication
|
luis@1051
|
10 before_filter :find_model_object, :except => [:parse_bibtex, :new, :create, :index, :get_bibtex_required_fields, :autocomplete_for_project, :add_author, :sort_author_order, :autocomplete_for_author, :get_user_info ]
|
luis@631
|
11 before_filter :find_project_by_project_id, :authorize, :only => [ :edit, :new, :update, :create ]
|
luis@946
|
12
|
luis@404
|
13 def new
|
luis@539
|
14 find_project_by_project_id
|
luis@539
|
15 @publication = Publication.new
|
luis@946
|
16
|
luis@445
|
17 # we'll always want a new publication to have its bibtex entry
|
luis@539
|
18 @publication.build_bibtex_entry
|
luis@946
|
19
|
luis@446
|
20 # and at least one author
|
luis@1051
|
21 # @publication.authorships.build.build_author
|
chris@647
|
22 @author_options = [["#{User.current.name} (@#{User.current.mail.partition('@')[2]})", "#{User.current.class.to_s}_#{User.current.id.to_s}"]]
|
luis@947
|
23 end
|
luis@614
|
24
|
luis@947
|
25 def parse_bibtex
|
luis@947
|
26 find_project_by_project_id
|
luis@1052
|
27 @bibtex_parse_success = true
|
luis@947
|
28
|
luis@1052
|
29 begin
|
luis@1052
|
30 bibtex_paste = params[:bibtex_paste]
|
luis@1052
|
31 bib = BibTeX.parse(bibtex_paste)
|
luis@1052
|
32 rescue
|
luis@1052
|
33 # todo: output errors to user
|
luis@1052
|
34 # bib.errors.present?
|
luis@1052
|
35 @bibtex_parse_success = false
|
luis@1052
|
36 # @bibtex_parsing_error = bib.errors[0].trace[4]
|
luis@1052
|
37 # logger.error { "BibTex Parsing Error: #{@bibtex_parsing_error}" }
|
luis@1052
|
38 logger.error { "BibTex Parsing Error" }
|
luis@1052
|
39 end
|
luis@947
|
40
|
luis@1051
|
41 respond_to do |format|
|
luis@1051
|
42 # todo: response for HTML
|
luis@1051
|
43 format.html{}
|
luis@1051
|
44
|
luis@1052
|
45 if @bibtex_parse_success
|
luis@1052
|
46 @ieee_prev = CiteProc.process bib.to_citeproc, :style => :ieee, :format => :html
|
luis@1052
|
47 end
|
luis@1052
|
48
|
luis@1051
|
49 format.js
|
luis@1052
|
50
|
luis@1052
|
51
|
luis@1051
|
52 end
|
luis@1051
|
53 end
|
luis@947
|
54
|
luis@947
|
55
|
luis@1051
|
56 # respond_to do |format|
|
luis@1051
|
57 # format.js {
|
luis@1051
|
58 # render(:update) {|page|
|
luis@1051
|
59 # flash.now[:notice] = "Correctly parsed BibTeX entry"
|
luis@1051
|
60 #
|
luis@1051
|
61 # bibtex_entry_no = BibtexEntryType.find_by_name(bib[0].type.to_s).id
|
luis@1051
|
62 # page["publication_title"].value = bib[0][:title]
|
luis@1051
|
63 # page["publication_bibtex_entry_attributes_entry_type"].value = #bibtex_entry_no
|
luis@1051
|
64 #
|
luis@1051
|
65 # BibtexEntryType.fields(bibtex_entry_no).each do |field|
|
luis@1051
|
66 # page["publication_bibtex_entry_attributes_#{field}"].value = bib[0][field#]
|
luis@1051
|
67 # end
|
luis@1051
|
68 #
|
luis@1051
|
69 # # for each author simulates a click and fills the author info
|
luis@1051
|
70 ## bib[0].authors.each do |author|
|
luis@1051
|
71 ## page["add_another_author"].click
|
luis@1051
|
72 ## page.alert(bib[0].authors.length)
|
luis@1051
|
73 ## page.alert(page["authors"].first.id)
|
luis@1051
|
74 ## end
|
luis@1051
|
75 #
|
luis@1051
|
76 #
|
luis@1051
|
77 #
|
luis@1051
|
78 # }
|
luis@1051
|
79 # }
|
luis@1051
|
80 # end
|
luis@951
|
81
|
luis@1051
|
82 # rescue BibtexParsingError => e
|
luis@1051
|
83 # logger.error { "Bibtex Parsing Error #{bib.errors}" }
|
luis@947
|
84
|
luis@947
|
85 # todo: not showing... should be inside render?
|
luis@1051
|
86 # flash[:error] = e.message
|
luis@947
|
87
|
luis@1051
|
88 # respond_to do |format|
|
luis@1051
|
89 # format.js{
|
luis@1051
|
90 # render(:update) {|page|
|
luis@1051
|
91 # }
|
luis@1051
|
92 # }
|
luis@1051
|
93 # end
|
luis@947
|
94
|
luis@1051
|
95 # end
|
luis@409
|
96
|
luis@947
|
97
|
luis@1051
|
98
|
luis@1051
|
99 def create
|
luisf@613
|
100 @project = Project.find(params[:project_id])
|
luisf@613
|
101
|
chris@661
|
102 @author_options = []
|
luis@614
|
103
|
luis@390
|
104 @publication = Publication.new(params[:publication])
|
luis@553
|
105 @publication.projects << @project unless @project.nil?
|
luis@946
|
106
|
luis@1051
|
107 if @publication.save
|
luis@666
|
108 @publication.notify_authors_publication_added(@project)
|
luis@946
|
109
|
luis@445
|
110 flash[:notice] = "Successfully created publication."
|
luisf@613
|
111 redirect_to :action => :show, :id => @publication, :project_id => @project
|
luis@445
|
112 else
|
luisf@613
|
113 render :action => 'new', :project_id => @project
|
luis@445
|
114 end
|
luis@445
|
115 end
|
luis@445
|
116
|
luis@445
|
117 def index
|
luis@538
|
118 if !params[:project_id].nil?
|
luis@538
|
119 find_project_by_project_id
|
luis@538
|
120 @project = Project.find(params[:project_id])
|
luis@538
|
121 @publications = Publication.find :all, :joins => :projects, :conditions => ["project_id = ?", @project.id]
|
luis@538
|
122 else
|
luis@538
|
123 @publications = Publication.find :all
|
luis@538
|
124 end
|
luis@445
|
125 end
|
luis@445
|
126
|
luis@445
|
127 def new_from_bibfile
|
luis@391
|
128 @publication.current_step = session[:publication_step]
|
luis@946
|
129
|
luis@404
|
130 # contents of the paste text area
|
luis@404
|
131 bibtex_entry = params[:bibtex_entry]
|
luis@384
|
132
|
luis@404
|
133 # method for creating "pasted" bibtex entries
|
luis@424
|
134 if bibtex_entry
|
luis@1051
|
135 parse_bibtex_list bibtex_entry
|
luis@404
|
136 end
|
luis@329
|
137 end
|
luis@329
|
138
|
luis@675
|
139 def get_bibtex_required_fields
|
luis@675
|
140
|
luis@1051
|
141 fields = BibtexEntryType.fields(params[:q])
|
luis@675
|
142
|
luis@675
|
143 respond_to do |format|
|
luis@675
|
144 format.js {
|
luis@1051
|
145 render(:update) {|page|
|
luis@947
|
146 if params[:q].empty?
|
luis@699
|
147 page << "hideOnLoad();"
|
luis@699
|
148 else
|
luis@699
|
149 page << "show_required_bibtex_fields(#{fields.to_json()});"
|
luis@675
|
150 end
|
luis@675
|
151 }
|
luis@675
|
152 }
|
luis@946
|
153
|
luis@675
|
154 end
|
luis@675
|
155 end
|
luis@675
|
156
|
luis@467
|
157 def add_author
|
luis@467
|
158 if (request.xhr?)
|
luis@467
|
159 render :text => User.find(params[:user_id]).name
|
luis@467
|
160 else
|
luis@467
|
161 # No? Then render an action.
|
luis@467
|
162 #render :action => 'view_attribute', :attr => @name
|
luis@675
|
163 logger.error { "Error while adding Author to publication." }
|
luis@467
|
164 end
|
luis@467
|
165 end
|
luis@467
|
166
|
luis@1051
|
167 def edit
|
luis@547
|
168 find_project_by_project_id unless params[:project_id].nil?
|
luis@946
|
169
|
luis@609
|
170 @edit_view = true;
|
luis@428
|
171 @publication = Publication.find(params[:id])
|
luis@626
|
172 @selected_bibtex_entry_type_id = @publication.bibtex_entry.entry_type
|
luis@626
|
173
|
luis@1051
|
174 @author_options = []
|
luis@946
|
175
|
luis@1051
|
176 @bibtype_fields = BibtexEntryType.fields(@selected_bibtex_entry_type_id)
|
luis@430
|
177 end
|
luis@430
|
178
|
luis@1051
|
179 def update
|
luis@1051
|
180 @publication = Publication.find(params[:id])
|
luis@538
|
181
|
chris@661
|
182 @author_options = []
|
luis@626
|
183
|
luis@430
|
184 if @publication.update_attributes(params[:publication])
|
luis@947
|
185 flash[:notice] = "Successfully Updated Publication."
|
luis@538
|
186
|
luis@538
|
187 if !params[:project_id].nil?
|
luis@538
|
188 redirect_to :action => :show, :id => @publication, :project_id => params[:project_id]
|
luis@538
|
189 else
|
luis@538
|
190 redirect_to :action => :show, :id => @publication
|
luis@538
|
191 end
|
luis@430
|
192 else
|
luis@448
|
193 render :action => 'edit'
|
luis@1051
|
194 end
|
luis@328
|
195 end
|
luis@328
|
196
|
luis@946
|
197
|
luis@425
|
198 def show
|
luis@535
|
199 find_project_by_project_id unless params[:project_id].nil?
|
luis@946
|
200
|
luis@425
|
201 if @publication.nil?
|
luis@579
|
202 @publications = Publication.all
|
luis@579
|
203 render "index", :alert => 'The publication was not found!'
|
luis@425
|
204 else
|
luis@425
|
205 @authors = @publication.authors
|
luis@425
|
206 @bibtext_entry = @publication.bibtex_entry
|
luis@425
|
207 end
|
luis@329
|
208 end
|
luis@329
|
209
|
luis@406
|
210 # parse string with bibtex authors
|
luis@406
|
211 def parse_authors(authors_entry)
|
luis@406
|
212 # in bibtex the authors are always seperated by "and"
|
luis@407
|
213 return authors_entry.split(" and ")
|
luis@406
|
214 end
|
luis@406
|
215
|
luis@1051
|
216 # parses a list of bibtex
|
luis@406
|
217 def parse_bibtex_list(bibtex_list)
|
luis@406
|
218 bibliography = BibTeX.parse bibtex_list
|
luis@406
|
219
|
luis@406
|
220 no_entries = bibliography.data.length
|
luis@406
|
221
|
luis@406
|
222 # parses the bibtex entries
|
luis@406
|
223 bibliography.data.map do |d|
|
luis@407
|
224
|
luis@407
|
225 if d.class == BibTeX::Entry
|
luis@407
|
226 create_bibtex_entry d
|
luis@407
|
227 end
|
luis@406
|
228 end
|
luis@1051
|
229 end
|
luis@407
|
230
|
luis@1051
|
231 def create_bibtex_entry(d)
|
luis@407
|
232 @publication = Publication.new
|
luis@1051
|
233 @bentry = BibtexEntry.new
|
luis@407
|
234 authors = []
|
luis@407
|
235 institution = ""
|
luis@407
|
236 email = ""
|
luis@409
|
237
|
luis@407
|
238 d.fields.keys.map do |field|
|
luis@407
|
239 case field.to_s
|
luis@407
|
240 when "author"
|
luis@407
|
241 authors = parse_authors d[field]
|
luis@407
|
242 when "title"
|
luis@407
|
243 @publication.title = d[field]
|
luis@407
|
244 when "institution"
|
luis@407
|
245 institution = d[field]
|
luis@407
|
246 when "email"
|
luis@407
|
247 email = d[field]
|
luis@407
|
248 else
|
luis@407
|
249 @bentry[field] = d[field]
|
luis@407
|
250 end
|
luis@1051
|
251 end
|
luis@406
|
252
|
luis@406
|
253 @publication.bibtex_entry = @bentry
|
luis@407
|
254 @publication.save
|
luis@409
|
255
|
luis@1051
|
256 # what is this for???
|
luis@424
|
257 # @created_publications << @publication.id
|
luis@409
|
258
|
luis@407
|
259 # need to save all authors
|
luis@1051
|
260 # and establish the author-publication association
|
luis@1051
|
261 # via the authorships table
|
luis@407
|
262 authors.each_with_index.map do |authorname, idx|
|
luis@407
|
263 author = Author.new(:name => authorname)
|
luis@407
|
264 if author.save!
|
luis@946
|
265 # todo: catch the errors...
|
luis@407
|
266 puts "SAVED"
|
luis@407
|
267 else
|
luis@407
|
268 puts "NOT SAVED"
|
luis@406
|
269 end
|
luis@406
|
270
|
luis@407
|
271 author.authorships.create!(
|
luis@946
|
272 :publication => @publication,
|
luis@946
|
273 :institution => institution,
|
luis@946
|
274 :email => email,
|
luis@946
|
275 :order => idx)
|
luis@407
|
276 end
|
luis@407
|
277 end
|
luis@409
|
278
|
luis@407
|
279 # parses the bibtex file
|
luis@407
|
280 def parse_bibtex_file
|
luis@407
|
281
|
luis@406
|
282 end
|
luis@406
|
283
|
luis@444
|
284 def import
|
luis@444
|
285 @publication = Publication.new
|
luis@946
|
286
|
luis@946
|
287
|
luis@444
|
288 end
|
luis@946
|
289
|
luis@461
|
290 def autocomplete_for_project
|
luis@461
|
291 @publication = Publication.find(params[:id])
|
luis@946
|
292
|
luis@1051
|
293 @projects = Project.active.like(params[:q]).find(:all, :limit => 100) - @publication.projects
|
luis@461
|
294 logger.debug "Query for \"#{params[:q]}\" returned \"#{@projects.size}\" results"
|
luis@461
|
295 render :layout => false
|
luis@409
|
296 end
|
luis@471
|
297
|
luis@1051
|
298
|
luis@1051
|
299 def autocomplete_for_author
|
luis@519
|
300 @results = []
|
luis@946
|
301
|
luis@596
|
302 object_id = params[:object_id]
|
luis@598
|
303 @object_name = "publications[authorships_attributes][#{object_id}][search_results]"
|
luis@946
|
304
|
Chris@674
|
305 # cc 20110909 -- revert to like instead of like_unique -- see #289
|
Chris@674
|
306 authorships_list = Authorship.like(params[:q]).find(:all, :limit => 100)
|
luis@480
|
307 users_list = User.active.like(params[:q]).find(:all, :limit => 100)
|
luis@480
|
308
|
luis@591
|
309 logger.debug "Query for \"#{params[:q]}\" returned \"#{authorships_list.size}\" authorships and \"#{users_list.size}\" users"
|
luis@946
|
310
|
luis@601
|
311 @results = users_list
|
luis@601
|
312
|
luis@1051
|
313 # TODO: can be optimized…
|
luis@1051
|
314 authorships_list.each do |authorship|
|
luis@601
|
315 flag = true
|
luis@946
|
316
|
luis@601
|
317 users_list.each do |user|
|
luis@601
|
318 if authorship.name == user.name && authorship.email == user.mail && authorship.institution == user.institution
|
luis@601
|
319 Rails.logger.debug { "Rejecting Authorship #{authorship.id}" }
|
luis@601
|
320 flag = false
|
luis@601
|
321 break
|
luis@601
|
322 end
|
luis@601
|
323 end
|
luis@601
|
324
|
luis@601
|
325 @results << authorship if flag
|
luis@592
|
326 end
|
luis@592
|
327
|
luis@1051
|
328 render :layout => false
|
luis@598
|
329 end
|
luis@946
|
330
|
luis@598
|
331 def get_user_info
|
luis@598
|
332 object_id = params[:object_id]
|
luis@598
|
333 value = params[:value]
|
luis@598
|
334 classname = Kernel.const_get(value.split('_')[0])
|
luis@592
|
335
|
luis@598
|
336 item = classname.find(value.split('_')[1])
|
luis@598
|
337
|
luis@598
|
338 name_field = "publication_authorships_attributes_#{object_id}_name_on_paper".to_sym
|
luis@598
|
339 email_field = "publication_authorships_attributes_#{object_id}_email".to_sym
|
luis@600
|
340 institution_field = "publication_authorships_attributes_#{object_id}_institution".to_sym
|
luis@946
|
341
|
luis@600
|
342 yes_radio = "publication_authorships_attributes_#{object_id}_identify_author_yes".to_sym
|
luis@946
|
343
|
luis@598
|
344 respond_to do |format|
|
luis@675
|
345 format.js {
|
luis@1051
|
346 render(:update) {|page|
|
luis@598
|
347 page[name_field].value = item.name
|
luis@598
|
348 page[email_field].value = item.mail
|
luis@600
|
349 page[institution_field].value = item.institution
|
luis@600
|
350
|
luis@600
|
351 page[yes_radio].checked = true
|
luis@601
|
352 page[name_field].readOnly = true
|
luis@601
|
353 page[email_field].readOnly = true
|
luis@601
|
354 page[institution_field].readOnly = true
|
luis@598
|
355 }
|
luis@598
|
356 }
|
luis@598
|
357 end
|
luis@477
|
358 end
|
luis@471
|
359
|
luis@557
|
360 def sort_author_order
|
luis@557
|
361 params[:authorships].each_with_index do |id, index|
|
luis@557
|
362 Authorship.update_all(['auth_order=?', index+1], ['id=?', id])
|
luis@471
|
363 end
|
luis@471
|
364 render :nothing => true
|
luis@471
|
365 end
|
luis@574
|
366
|
luis@574
|
367 def add_project
|
luis@1051
|
368 @projects = Project.find(params[:publication][:project_ids])
|
luis@574
|
369 @publication.projects << @projects
|
luis@1051
|
370 @project = Project.find(params[:project_id])
|
luis@946
|
371
|
luis@1051
|
372 # TODO luisf should also respond to HTML???
|
luis@574
|
373 respond_to do |format|
|
luis@574
|
374 format.html { redirect_to :back }
|
luis@1051
|
375 format.js {
|
luis@1051
|
376 render(:update) {|page|
|
luis@1051
|
377 page[:add_project_form].reset
|
luis@574
|
378 page.replace_html :list_projects, :partial => 'list_projects'
|
luis@574
|
379 }
|
luis@574
|
380 }
|
luis@574
|
381 end
|
luis@574
|
382 end
|
luis@946
|
383
|
luis@946
|
384
|
luis@574
|
385 def remove_project
|
luis@579
|
386 @project = Project.find(params[:project_id])
|
luis@579
|
387 proj = Project.find(params[:remove_project_id])
|
luis@554
|
388
|
luis@574
|
389 if @publication.projects.length > 1
|
luis@579
|
390 if @publication.projects.exists? proj
|
luis@579
|
391 @publication.projects.delete proj if request.post?
|
luis@554
|
392 end
|
luis@554
|
393 else
|
luis@1051
|
394 logger.error { "Cannot remove project from publication list" }
|
luis@554
|
395 end
|
luis@946
|
396
|
luis@591
|
397 logger.error { "CURRENT project name#{proj.name} and wanna delete #{@project.name}" }
|
luis@946
|
398
|
luis@1051
|
399 render(:update) {|page|
|
luis@579
|
400 page.replace_html "list_projects", :partial => 'list_projects', :id => @publication
|
luis@1051
|
401 }
|
luis@554
|
402 end
|
luis@946
|
403
|
luis@560
|
404 def destroy
|
luis@560
|
405 find_project_by_project_id
|
luis@946
|
406
|
luis@560
|
407 @publication.destroy
|
luis@946
|
408
|
luis@560
|
409 flash[:notice] = "Successfully deleted Publication."
|
luis@560
|
410 redirect_to :controller => :publications, :action => 'index', :project_id => @project
|
luis@560
|
411 end
|
luis@471
|
412
|
luis@538
|
413 private
|
luis@478
|
414
|
luis@328
|
415 end
|