comparison vendor/plugins/redmine_bibliography/app/controllers/publications_controller.rb @ 1051:ef882e222003 bibplugin_bibtex

Changing the way the bibtex is parsed: uses link_to_remote instead of remote_form_for; using RJS; created tab helper (still not implemented correctly in terms of views
author luisf <luis.figueira@eecs.qmul.ac.uk>
date Fri, 16 Nov 2012 19:05:01 +0000
parents 010291c90b0b
children 6674e52e20bf
comparison
equal deleted inserted replaced
1043:8cfa9b743559 1051:ef882e222003
5 5
6 class PublicationsController < ApplicationController 6 class PublicationsController < ApplicationController
7 unloadable 7 unloadable
8 8
9 model_object Publication 9 model_object Publication
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 ] 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 ]
11 before_filter :find_project_by_project_id, :authorize, :only => [ :edit, :new, :update, :create ] 11 before_filter :find_project_by_project_id, :authorize, :only => [ :edit, :new, :update, :create ]
12 12
13 def new 13 def new
14 find_project_by_project_id 14 find_project_by_project_id
15 @publication = Publication.new 15 @publication = Publication.new
16 16
17 # we'll always want a new publication to have its bibtex entry 17 # we'll always want a new publication to have its bibtex entry
18 @publication.build_bibtex_entry 18 @publication.build_bibtex_entry
19 19
20 # and at least one author 20 # and at least one author
21 # @publication.authorships.build.build_author 21 # @publication.authorships.build.build_author
22 @author_options = [["#{User.current.name} (@#{User.current.mail.partition('@')[2]})", "#{User.current.class.to_s}_#{User.current.id.to_s}"]] 22 @author_options = [["#{User.current.name} (@#{User.current.mail.partition('@')[2]})", "#{User.current.class.to_s}_#{User.current.id.to_s}"]]
23 end 23 end
24
25 24
26 def parse_bibtex 25 def parse_bibtex
27 find_project_by_project_id 26 find_project_by_project_id
28 27
29 @bibtex_paste = params[:bibtex_paste] 28 bibtex_paste = params[:bibtex_paste]
30 29 bib = BibTeX.parse(bibtex_paste)
31 begin 30
32 bib = BibTeX.parse(@bibtex_paste) 31 respond_to do |format|
33
34 if bib.errors.present? or bib[0].class == NilClass 32 if bib.errors.present? or bib[0].class == NilClass
35 raise BibtexParsingError, "Bibtex Parsing Error" 33
36 end 34 # todo: response for HTML
37 35 format.html{}
38 respond_to do |format| 36
39 format.js { 37 # todo: better error handling
40 render(:update) {|page| 38 biberror = bib.errors[0].trace[4]
41 flash[:notice] = "Correctly parsed BibTeX entry" 39 logger.error { "BibTex Parsing Error: #{biberror}" }
42 40 flash[:error] = "BibTex Parsing Error: #{biberror}"
43 bibtex_entry_no = BibtexEntryType.find_by_name(bib[0].type.to_s).id 41 #raise BibtexParsingError, "Bibtex Parsing Error: biberror}"
44 page["publication_title"].value = bib[0][:title] 42 format.js
45 page["publication_bibtex_entry_attributes_entry_type"].value = bibtex_entry_no 43 else
46 44 @ieee_prev = CiteProc.process bib.to_citeproc, :style => :ieee, :format => :html
47 BibtexEntryType.fields(bibtex_entry_no).each do |field| 45 flash['notice'] = "OK!"
48 page["publication_bibtex_entry_attributes_#{field}"].value = bib[0][field] 46 format.js
49 end 47 end
50 48 end
51 # for each author simulates a click and fills the author info 49 end
52 bib[0].authors.each do |author| 50
53 page["add_another_author"].click 51
54 # page.alert(bib[0].authors.length) 52 # respond_to do |format|
55 # page.alert(page["authors"].first.id) 53 # format.js {
56 54 # render(:update) {|page|
57 end 55 # flash.now[:notice] = "Correctly parsed BibTeX entry"
58 56 #
59 57 # bibtex_entry_no = BibtexEntryType.find_by_name(bib[0].type.to_s).id
60 58 # page["publication_title"].value = bib[0][:title]
61 } 59 # page["publication_bibtex_entry_attributes_entry_type"].value = #bibtex_entry_no
62 } 60 #
63 end 61 # BibtexEntryType.fields(bibtex_entry_no).each do |field|
64 62 # page["publication_bibtex_entry_attributes_#{field}"].value = bib[0][field#]
65 rescue BibtexParsingError => e 63 # end
66 logger.error { "Bibtex Parsing Error #{bib.errors}" } 64 #
65 # # for each author simulates a click and fills the author info
66 ## bib[0].authors.each do |author|
67 ## page["add_another_author"].click
68 ## page.alert(bib[0].authors.length)
69 ## page.alert(page["authors"].first.id)
70 ## end
71 #
72 #
73 #
74 # }
75 # }
76 # end
77
78 # rescue BibtexParsingError => e
79 # logger.error { "Bibtex Parsing Error #{bib.errors}" }
67 80
68 # todo: not showing... should be inside render? 81 # todo: not showing... should be inside render?
69 flash[:error] = e.message 82 # flash[:error] = e.message
70 83
71 respond_to do |format| 84 # respond_to do |format|
72 format.js{ 85 # format.js{
73 render(:update) {|page| 86 # render(:update) {|page|
74 } 87 # }
75 } 88 # }
76 end 89 # end
77 90
78 end 91 # end
79 92
80 end 93
81 94
82 95 def create
83 def create
84 @project = Project.find(params[:project_id]) 96 @project = Project.find(params[:project_id])
85 97
86 @author_options = [] 98 @author_options = []
87 99
88 @publication = Publication.new(params[:publication]) 100 @publication = Publication.new(params[:publication])
89 @publication.projects << @project unless @project.nil? 101 @publication.projects << @project unless @project.nil?
90 102
91 if @publication.save 103 if @publication.save
92 @publication.notify_authors_publication_added(@project) 104 @publication.notify_authors_publication_added(@project)
93 105
94 flash[:notice] = "Successfully created publication." 106 flash[:notice] = "Successfully created publication."
95 redirect_to :action => :show, :id => @publication, :project_id => @project 107 redirect_to :action => :show, :id => @publication, :project_id => @project
96 else 108 else
114 # contents of the paste text area 126 # contents of the paste text area
115 bibtex_entry = params[:bibtex_entry] 127 bibtex_entry = params[:bibtex_entry]
116 128
117 # method for creating "pasted" bibtex entries 129 # method for creating "pasted" bibtex entries
118 if bibtex_entry 130 if bibtex_entry
119 parse_bibtex_list bibtex_entry 131 parse_bibtex_list bibtex_entry
120 end 132 end
121 end 133 end
122 134
123 def get_bibtex_required_fields 135 def get_bibtex_required_fields
124 136
125 fields = BibtexEntryType.fields(params[:q]) 137 fields = BibtexEntryType.fields(params[:q])
126 138
127 respond_to do |format| 139 respond_to do |format|
128 format.js { 140 format.js {
129 render(:update) {|page| 141 render(:update) {|page|
130 if params[:q].empty? 142 if params[:q].empty?
131 page << "hideOnLoad();" 143 page << "hideOnLoad();"
132 else 144 else
133 page << "show_required_bibtex_fields(#{fields.to_json()});" 145 page << "show_required_bibtex_fields(#{fields.to_json()});"
134 end 146 end
146 #render :action => 'view_attribute', :attr => @name 158 #render :action => 'view_attribute', :attr => @name
147 logger.error { "Error while adding Author to publication." } 159 logger.error { "Error while adding Author to publication." }
148 end 160 end
149 end 161 end
150 162
151 def edit 163 def edit
152 find_project_by_project_id unless params[:project_id].nil? 164 find_project_by_project_id unless params[:project_id].nil?
153 165
154 @edit_view = true; 166 @edit_view = true;
155 @publication = Publication.find(params[:id]) 167 @publication = Publication.find(params[:id])
156 @selected_bibtex_entry_type_id = @publication.bibtex_entry.entry_type 168 @selected_bibtex_entry_type_id = @publication.bibtex_entry.entry_type
157 169
158 @author_options = [] 170 @author_options = []
159 171
160 @bibtype_fields = BibtexEntryType.fields(@selected_bibtex_entry_type_id) 172 @bibtype_fields = BibtexEntryType.fields(@selected_bibtex_entry_type_id)
161 end 173 end
162 174
163 def update 175 def update
164 @publication = Publication.find(params[:id]) 176 @publication = Publication.find(params[:id])
165 177
166 @author_options = [] 178 @author_options = []
167 179
168 if @publication.update_attributes(params[:publication]) 180 if @publication.update_attributes(params[:publication])
169 flash[:notice] = "Successfully Updated Publication." 181 flash[:notice] = "Successfully Updated Publication."
173 else 185 else
174 redirect_to :action => :show, :id => @publication 186 redirect_to :action => :show, :id => @publication
175 end 187 end
176 else 188 else
177 render :action => 'edit' 189 render :action => 'edit'
178 end 190 end
179 end 191 end
180 192
181 193
182 def show 194 def show
183 find_project_by_project_id unless params[:project_id].nil? 195 find_project_by_project_id unless params[:project_id].nil?
195 def parse_authors(authors_entry) 207 def parse_authors(authors_entry)
196 # in bibtex the authors are always seperated by "and" 208 # in bibtex the authors are always seperated by "and"
197 return authors_entry.split(" and ") 209 return authors_entry.split(" and ")
198 end 210 end
199 211
200 # parses a list of bibtex 212 # parses a list of bibtex
201 def parse_bibtex_list(bibtex_list) 213 def parse_bibtex_list(bibtex_list)
202 bibliography = BibTeX.parse bibtex_list 214 bibliography = BibTeX.parse bibtex_list
203 215
204 no_entries = bibliography.data.length 216 no_entries = bibliography.data.length
205 217
208 220
209 if d.class == BibTeX::Entry 221 if d.class == BibTeX::Entry
210 create_bibtex_entry d 222 create_bibtex_entry d
211 end 223 end
212 end 224 end
213 end 225 end
214 226
215 def create_bibtex_entry(d) 227 def create_bibtex_entry(d)
216 @publication = Publication.new 228 @publication = Publication.new
217 @bentry = BibtexEntry.new 229 @bentry = BibtexEntry.new
218 authors = [] 230 authors = []
219 institution = "" 231 institution = ""
220 email = "" 232 email = ""
221 233
222 d.fields.keys.map do |field| 234 d.fields.keys.map do |field|
230 when "email" 242 when "email"
231 email = d[field] 243 email = d[field]
232 else 244 else
233 @bentry[field] = d[field] 245 @bentry[field] = d[field]
234 end 246 end
235 end 247 end
236 248
237 @publication.bibtex_entry = @bentry 249 @publication.bibtex_entry = @bentry
238 @publication.save 250 @publication.save
239 251
240 # what is this for??? 252 # what is this for???
241 # @created_publications << @publication.id 253 # @created_publications << @publication.id
242 254
243 # need to save all authors 255 # need to save all authors
244 # and establish the author-publication association 256 # and establish the author-publication association
245 # via the authorships table 257 # via the authorships table
246 authors.each_with_index.map do |authorname, idx| 258 authors.each_with_index.map do |authorname, idx|
247 author = Author.new(:name => authorname) 259 author = Author.new(:name => authorname)
248 if author.save! 260 if author.save!
249 # todo: catch the errors... 261 # todo: catch the errors...
250 puts "SAVED" 262 puts "SAVED"
272 end 284 end
273 285
274 def autocomplete_for_project 286 def autocomplete_for_project
275 @publication = Publication.find(params[:id]) 287 @publication = Publication.find(params[:id])
276 288
277 @projects = Project.active.like(params[:q]).find(:all, :limit => 100) - @publication.projects 289 @projects = Project.active.like(params[:q]).find(:all, :limit => 100) - @publication.projects
278 logger.debug "Query for \"#{params[:q]}\" returned \"#{@projects.size}\" results" 290 logger.debug "Query for \"#{params[:q]}\" returned \"#{@projects.size}\" results"
279 render :layout => false 291 render :layout => false
280 end 292 end
281 293
282 294
283 def autocomplete_for_author 295 def autocomplete_for_author
284 @results = [] 296 @results = []
285 297
286 object_id = params[:object_id] 298 object_id = params[:object_id]
287 @object_name = "publications[authorships_attributes][#{object_id}][search_results]" 299 @object_name = "publications[authorships_attributes][#{object_id}][search_results]"
288 300
292 304
293 logger.debug "Query for \"#{params[:q]}\" returned \"#{authorships_list.size}\" authorships and \"#{users_list.size}\" users" 305 logger.debug "Query for \"#{params[:q]}\" returned \"#{authorships_list.size}\" authorships and \"#{users_list.size}\" users"
294 306
295 @results = users_list 307 @results = users_list
296 308
297 # TODO: can be optimized… 309 # TODO: can be optimized…
298 authorships_list.each do |authorship| 310 authorships_list.each do |authorship|
299 flag = true 311 flag = true
300 312
301 users_list.each do |user| 313 users_list.each do |user|
302 if authorship.name == user.name && authorship.email == user.mail && authorship.institution == user.institution 314 if authorship.name == user.name && authorship.email == user.mail && authorship.institution == user.institution
303 Rails.logger.debug { "Rejecting Authorship #{authorship.id}" } 315 Rails.logger.debug { "Rejecting Authorship #{authorship.id}" }
307 end 319 end
308 320
309 @results << authorship if flag 321 @results << authorship if flag
310 end 322 end
311 323
312 render :layout => false 324 render :layout => false
313 end 325 end
314 326
315 def get_user_info 327 def get_user_info
316 object_id = params[:object_id] 328 object_id = params[:object_id]
317 value = params[:value] 329 value = params[:value]
325 337
326 yes_radio = "publication_authorships_attributes_#{object_id}_identify_author_yes".to_sym 338 yes_radio = "publication_authorships_attributes_#{object_id}_identify_author_yes".to_sym
327 339
328 respond_to do |format| 340 respond_to do |format|
329 format.js { 341 format.js {
330 render(:update) {|page| 342 render(:update) {|page|
331 page[name_field].value = item.name 343 page[name_field].value = item.name
332 page[email_field].value = item.mail 344 page[email_field].value = item.mail
333 page[institution_field].value = item.institution 345 page[institution_field].value = item.institution
334 346
335 page[yes_radio].checked = true 347 page[yes_radio].checked = true
347 end 359 end
348 render :nothing => true 360 render :nothing => true
349 end 361 end
350 362
351 def add_project 363 def add_project
352 @projects = Project.find(params[:publication][:project_ids]) 364 @projects = Project.find(params[:publication][:project_ids])
353 @publication.projects << @projects 365 @publication.projects << @projects
354 @project = Project.find(params[:project_id]) 366 @project = Project.find(params[:project_id])
355 367
356 # TODO luisf should also respond to HTML??? 368 # TODO luisf should also respond to HTML???
357 respond_to do |format| 369 respond_to do |format|
358 format.html { redirect_to :back } 370 format.html { redirect_to :back }
359 format.js { 371 format.js {
360 render(:update) {|page| 372 render(:update) {|page|
361 page[:add_project_form].reset 373 page[:add_project_form].reset
362 page.replace_html :list_projects, :partial => 'list_projects' 374 page.replace_html :list_projects, :partial => 'list_projects'
363 } 375 }
364 } 376 }
365 end 377 end
366 end 378 end
373 if @publication.projects.length > 1 385 if @publication.projects.length > 1
374 if @publication.projects.exists? proj 386 if @publication.projects.exists? proj
375 @publication.projects.delete proj if request.post? 387 @publication.projects.delete proj if request.post?
376 end 388 end
377 else 389 else
378 logger.error { "Cannot remove project from publication list" } 390 logger.error { "Cannot remove project from publication list" }
379 end 391 end
380 392
381 logger.error { "CURRENT project name#{proj.name} and wanna delete #{@project.name}" } 393 logger.error { "CURRENT project name#{proj.name} and wanna delete #{@project.name}" }
382 394
383 render(:update) {|page| 395 render(:update) {|page|
384 page.replace_html "list_projects", :partial => 'list_projects', :id => @publication 396 page.replace_html "list_projects", :partial => 'list_projects', :id => @publication
385 } 397 }
386 end 398 end
387 399
388 def destroy 400 def destroy
389 find_project_by_project_id 401 find_project_by_project_id
390 402