annotate vendor/plugins/redmine_bibliography/app/controllers/publications_controller.rb @ 1052:6674e52e20bf bibplugin_bibtex

outputting error/success messages using the flash div; still not cleaning the messages correctly.
author luisf <luis.figueira@eecs.qmul.ac.uk>
date Mon, 19 Nov 2012 11:56:29 +0000
parents ef882e222003
children 80cf86be1611
rev   line source
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