diff --git a/app/controllers/admin/research/hal/publications_controller.rb b/app/controllers/admin/research/hal/publications_controller.rb deleted file mode 100644 index 884b4efab..000000000 --- a/app/controllers/admin/research/hal/publications_controller.rb +++ /dev/null @@ -1,37 +0,0 @@ -class Admin::Research::Hal::PublicationsController < Admin::Research::Hal::ApplicationController - before_action :load_publication, except: :index - - def index - @publications = Research::Hal::Publication.ordered.page(params[:page]) - breadcrumb - end - - def show - breadcrumb - end - - def static - @about = @publication - @website = @publication.websites&.first || current_university.websites.first - render_as_plain_text - end - - def destroy - @publication.destroy - redirect_to admin_research_hal_publications_path - end - - protected - - def load_publication - @publication = Research::Hal::Publication.find params[:id] - end - - def breadcrumb - super - add_breadcrumb Research::Hal::Publication.model_name.human(count: 2), - admin_research_hal_publications_path - breadcrumb_for @publication - end - -end diff --git a/app/controllers/admin/research/publications_controller.rb b/app/controllers/admin/research/publications_controller.rb new file mode 100644 index 000000000..0c229a7db --- /dev/null +++ b/app/controllers/admin/research/publications_controller.rb @@ -0,0 +1,66 @@ +class Admin::Research::PublicationsController < Admin::Research::ApplicationController + load_and_authorize_resource class: Research::Publication + + has_scope :for_search_term + + def index + @publications = apply_scopes(@publications).ordered.page(params[:page]) + breadcrumb + end + + def show + breadcrumb + end + + def static + @about = @publication + @website = @publication.websites&.first || current_university.websites.first + render_as_plain_text + end + + def new + breadcrumb + end + + def edit + breadcrumb + add_breadcrumb t('edit') + end + + def create + if @publication.save + redirect_to [:admin, @publication], notice: t('admin.successfully_created_html', model: @publication.to_s) + else + breadcrumb + render :new, status: :unprocessable_entity + end + end + + def update + if @publication.update(publication_params) + redirect_to [:admin, @publication], notice: t('admin.successfully_updated_html', model: @publication.to_s) + else + breadcrumb + add_breadcrumb t('edit') + render :edit, status: :unprocessable_entity + end + end + + def destroy + @publication.destroy + redirect_to admin_research_publications_url, notice: t('admin.successfully_destroyed_html', model: @publication.to_s) + end + + protected + + def breadcrumb + super + add_breadcrumb Research::Publication.model_name.human(count: 2), admin_research_publications_path + breadcrumb_for @publication + end + + def publication_params + params.require(:research_publication) + .permit(:title, :publication_date, :abstract, :authors_list, :doi, :ref, :journal_title, :url, :open_access, :citation_full, researcher_ids: []) + end +end diff --git a/app/models/communication/website/page/research_hal_publication.rb b/app/models/communication/website/page/research_publication.rb similarity index 64% rename from app/models/communication/website/page/research_hal_publication.rb rename to app/models/communication/website/page/research_publication.rb index 9fc695c78..d64da7d63 100644 --- a/app/models/communication/website/page/research_hal_publication.rb +++ b/app/models/communication/website/page/research_publication.rb @@ -1,7 +1,7 @@ -class Communication::Website::Page::ResearchHalPublication < Communication::Website::Page +class Communication::Website::Page::ResearchPublication < Communication::Website::Page def is_necessary_for_website? - website.connected_hal_publications.any? + website.connected_publications.any? end def editable_width? @@ -15,7 +15,7 @@ def full_width_by_default? def dependencies super + [website.config_default_languages] + - website.connected_hal_publications + website.connected_publications end protected diff --git a/app/models/communication/website/page/with_type.rb b/app/models/communication/website/page/with_type.rb index 2f9a6a534..a668dd3a4 100644 --- a/app/models/communication/website/page/with_type.rb +++ b/app/models/communication/website/page/with_type.rb @@ -19,7 +19,7 @@ module Communication::Website::Page::WithType # Research Communication::Website::Page::ResearchVolume, Communication::Website::Page::ResearchPaper, - Communication::Website::Page::ResearchHalPublication, + Communication::Website::Page::ResearchPublication, # Administration Communication::Website::Page::AdministrationLocation, # People facets diff --git a/app/models/communication/website/permalink/publication.rb b/app/models/communication/website/permalink/publication.rb index 4b831579d..b4e4b193e 100644 --- a/app/models/communication/website/permalink/publication.rb +++ b/app/models/communication/website/permalink/publication.rb @@ -8,7 +8,7 @@ def self.static_config_key end def self.pattern_in_website(website, language) - "/#{website.special_page(Communication::Website::Page::ResearchHalPublication, language: language).slug_with_ancestors}/:year-:slug/" + "/#{website.special_page(Communication::Website::Page::ResearchPublication, language: language).slug_with_ancestors}/:year-:slug/" end protected diff --git a/app/models/communication/website/with_connected_objects.rb b/app/models/communication/website/with_connected_objects.rb index 497dc69b9..d04e87e18 100644 --- a/app/models/communication/website/with_connected_objects.rb +++ b/app/models/communication/website/with_connected_objects.rb @@ -88,9 +88,9 @@ def connected_organizations University::Organization.where(id: ids) end - def connected_hal_publications - ids = connections.where(indirect_object_type: 'Research::Hal::Publication').pluck(:indirect_object_id) - Research::Hal::Publication.where(id: ids) + def connected_publications + ids = connections.where(indirect_object_type: 'Research::Publication').pluck(:indirect_object_id) + Research::Publication.where(id: ids) end # ensure the object "website" respond to both is_direct_object? and is_indirect_object? as website doesn't include neither as_direct_object nor as_indirect_object diff --git a/app/models/research.rb b/app/models/research.rb index 633d16d2a..0c9050ee5 100644 --- a/app/models/research.rb +++ b/app/models/research.rb @@ -12,7 +12,7 @@ def self.parts [Research::Laboratory, :admin_research_laboratories_path], [Research::Thesis, :admin_research_theses_path], [Research::Journal, :admin_research_journals_path], - [Research::Hal, :admin_research_hal_root_path], + [Research::Publication, :admin_research_publications_path], ] end end diff --git a/app/models/research/hal.rb b/app/models/research/hal.rb index 21695429c..24a495024 100644 --- a/app/models/research/hal.rb +++ b/app/models/research/hal.rb @@ -18,11 +18,11 @@ def self.update_from_api! end def self.pause_git_sync - Research::Hal::Publication.skip_callback :save, :after, :connect_and_sync_direct_sources + Research::Publication.skip_callback :save, :after, :connect_and_sync_direct_sources end def self.unpause_git_sync - Research::Hal::Publication.set_callback :save, :after, :connect_and_sync_direct_sources + Research::Publication.set_callback :save, :after, :connect_and_sync_direct_sources end def self.clear_queue! @@ -30,7 +30,7 @@ def self.clear_queue! Delayed::Job.find_each do |job| next unless job.public_respond_to?(:payload_object) if job.payload_object.method_name == :sync_indirect_object_with_git_without_delay && - job.payload_object.args.first.is_a?(Research::Hal::Publication) + job.payload_object.args.first.is_a?(Research::Publication) ids << job.id end end @@ -39,7 +39,6 @@ def self.clear_queue! def self.parts [ - [Research::Hal::Publication, :admin_research_hal_publications_path], [Research::Hal::Author, :admin_research_hal_authors_path], ] end diff --git a/app/models/research/hal/author.rb b/app/models/research/hal/author.rb index 916467e97..5ed274912 100644 --- a/app/models/research/hal/author.rb +++ b/app/models/research/hal/author.rb @@ -20,7 +20,7 @@ class Research::Hal::Author < ApplicationRecord include Sanitizable has_and_belongs_to_many :publications, - foreign_key: 'research_hal_publication_id', + foreign_key: 'research_publication_id', association_foreign_key: :research_hal_author_id has_and_belongs_to_many :university_person_researchers, class_name: 'University::Person', @@ -68,7 +68,7 @@ def import_research_hal_publications! publications.clear # Do not overuse the API if no researcher is concerned return if researchers.none? - Research::Hal::Publication.import_from_hal_for_author(self).each do |publication| + Importers::Hal.import_publications_for_author(self).each do |publication| publications << publication end publications diff --git a/app/models/research/hal/publication.rb b/app/models/research/hal/publication.rb deleted file mode 100644 index 62e543fe8..000000000 --- a/app/models/research/hal/publication.rb +++ /dev/null @@ -1,147 +0,0 @@ -# == Schema Information -# -# Table name: research_hal_publications -# -# id :uuid not null, primary key -# abstract :text -# authors_citeproc :json -# authors_list :text -# citation_full :text -# data :jsonb -# docid :string indexed -# doi :string -# file :text -# hal_url :string -# journal_title :string -# open_access :boolean -# publication_date :date -# ref :string -# slug :string indexed -# title :string -# url :string -# created_at :datetime not null -# updated_at :datetime not null -# -# Indexes -# -# index_research_hal_publications_on_docid (docid) -# index_research_hal_publications_on_slug (slug) -# -class Research::Hal::Publication < ApplicationRecord - include AsIndirectObject - include Sanitizable - include Sluggable - include WithCitations - include WithGitFiles - include WithPermalink - - has_and_belongs_to_many :researchers, - class_name: 'University::Person', - foreign_key: :university_person_id, - association_foreign_key: :research_hal_publication_id - - has_and_belongs_to_many :authors, - foreign_key: :research_hal_author_id, - association_foreign_key: :research_hal_publication_id - - validates_presence_of :docid - - scope :ordered, -> { order(publication_date: :desc)} - - # https://api.archives-ouvertes.fr/search/?q=03713859&fl=* - def self.import_from_hal_for_author(author) - fields = [ - 'docid', - 'title_s', - 'citationRef_s', - 'citationFull_s', - 'uri_s', - 'doiId_s', - 'publicationDate_tdate', - 'linkExtUrl_s', - 'abstract_s', - 'openAccess_bool', - 'journalTitle_s', - 'authFullName_s', - 'authLastName_s', - 'authFirstName_s', - 'files_s' - # '*', - ] - publications = [] - response = HalOpenscience::Document.search "authIdFormPerson_s:#{author.docid}", fields: fields, limit: 1000 - response.results.each do |doc| - publication = create_from doc - publications << publication - end - publications - end - - def self.create_from(doc) - publication = where(docid: doc.docid).first_or_create - puts "HAL sync publication #{doc.docid}" - publication.title = Osuny::Sanitizer.sanitize doc.title_s.first, 'string' - publication.ref = doc.attributes['citationRef_s'] - publication.citation_full = doc.attributes['citationFull_s'] - publication.abstract = doc.attributes['abstract_s']&.first - publication.hal_url = doc.attributes['uri_s'] - publication.doi = doc.attributes['doiId_s'] - publication.publication_date = doc.attributes['publicationDate_tdate'] - publication.url = doc.attributes['linkExtUrl_s'] - publication.open_access = doc.attributes['openAccess_bool'] - publication.journal_title = doc.attributes['journalTitle_s'] - publication.file = doc.attributes['files_s']&.first - publication.authors_list = doc.attributes['authFullName_s'].join(', ') - publication.authors_citeproc = [] - doc.attributes['authLastName_s'].each_with_index do |last_name, index| - publication.authors_citeproc << { - "family" => last_name, - "given" => doc.attributes['authFirstName_s'][index] - } - end - publication.save - publication - end - - def template_static - "admin/research/hal/publications/static" - end - - def git_path(website) - "#{git_path_content_prefix(website)}publications/#{publication_date.year}/#{slug}.html" if for_website?(website) - end - - def doi_url - Doi.url doi - end - - def best_url - url || doi_url || hal_url - end - - def to_s - "#{title}" - end - - protected - - def to_citeproc(website: nil) - { - "title" => title, - "author" => authors_citeproc, - "URL" => hal_url, - "container-title" => journal_title, - "pdf" => file, - "month-numeric" => publication_date.present? ? publication_date.month.to_s : nil, - "issued" => publication_date.present? ? { "date-parts" => [[publication_date.year, publication_date.month]] } : nil, - "id" => docid - } - end - - def slug_unavailable?(slug) - self.class.unscoped - .where(slug: slug) - .where.not(id: self.id) - .exists? - end -end diff --git a/app/models/research/publication.rb b/app/models/research/publication.rb new file mode 100644 index 000000000..ce6064e3b --- /dev/null +++ b/app/models/research/publication.rb @@ -0,0 +1,115 @@ +# == Schema Information +# +# Table name: research_publications +# +# id :uuid not null, primary key +# abstract :text +# authors_citeproc :json +# authors_list :text +# citation_full :text +# data :jsonb +# doi :string +# file :text +# hal_docid :string indexed +# hal_url :string +# journal_title :string +# open_access :boolean +# publication_date :date +# ref :string +# slug :string indexed +# source :integer default("osuny") +# title :string +# url :string +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_research_publications_on_hal_docid (hal_docid) +# index_research_publications_on_slug (slug) +# +class Research::Publication < ApplicationRecord + include AsIndirectObject + include Sanitizable + include Sluggable + include WithCitations + include WithGitFiles + include WithPermalink + + has_and_belongs_to_many :researchers, + class_name: 'University::Person', + foreign_key: :university_person_id, + association_foreign_key: :research_publication_id + + has_and_belongs_to_many :authors, + class_name: 'Research::Hal::Author', + foreign_key: :research_hal_author_id, + association_foreign_key: :research_publication_id + + scope :ordered, -> { order(publication_date: :desc)} + + enum source: { + osuny: 0, + hal: 1 + } + + validates_presence_of :title, :publication_date + + before_validation :generate_authors_citeproc + + def editable? + source == 'osuny' + end + + def template_static + "admin/research/publications/static" + end + + def git_path(website) + "#{git_path_content_prefix(website)}publications/#{publication_date.year}/#{slug}.html" if for_website?(website) + end + + def doi_url + Doi.url doi + end + + def best_url + url || doi_url || hal_url + end + + def to_s + "#{title}" + end + + protected + + def to_citeproc(website: nil) + { + "title" => title, + "author" => authors_citeproc, + "URL" => best_url, + "container-title" => journal_title, + "pdf" => file, + "month-numeric" => publication_date.present? ? publication_date.month.to_s : nil, + "issued" => publication_date.present? ? { "date-parts" => [[publication_date.year, publication_date.month]] } : nil, + "id" => (hal_docid || id) + } + end + + def generate_authors_citeproc + return if hal? + self.authors_citeproc = researchers.map do |researcher| + { + "family" => researcher.last_name, + "given" => researcher.first_name + } + end + end + + def slug_unavailable?(slug) + self.class.unscoped + .where(slug: slug) + .where.not(id: self.id) + .exists? + end +end diff --git a/app/models/university/person/with_research.rb b/app/models/university/person/with_research.rb index e501d5543..29c0812a6 100644 --- a/app/models/university/person/with_research.rb +++ b/app/models/university/person/with_research.rb @@ -6,14 +6,7 @@ module University::Person::WithResearch class_name: 'Research::Hal::Author', foreign_key: :research_hal_author_id, association_foreign_key: :university_person_id - alias :hal_authors :research_hal_authors - - has_and_belongs_to_many :research_hal_publications, - class_name: 'Research::Hal::Publication', - foreign_key: :research_hal_publication_id, - association_foreign_key: :university_person_id - alias :hal_publications :research_hal_publications - alias :publications :research_hal_publications + alias :hal_authors :research_hal_authors has_many :authored_research_theses, class_name: 'Research::Thesis', @@ -25,11 +18,17 @@ module University::Person::WithResearch foreign_key: :director_id, dependent: :nullify + has_and_belongs_to_many :research_publications, + class_name: 'Research::Publication', + foreign_key: :research_publication_id, + association_foreign_key: :university_person_id + alias :publications :research_publications + has_and_belongs_to_many :research_laboratories, class_name: 'Research::Laboratory', foreign_key: :research_laboratory_id, association_foreign_key: :university_person_id - alias :laboratories :research_laboratories + alias :laboratories :research_laboratories scope :with_hal_identifier, -> { where.not(hal_form_identifier: [nil,'']) } end diff --git a/app/services/citations.rb b/app/services/citations.rb new file mode 100644 index 000000000..9b383c258 --- /dev/null +++ b/app/services/citations.rb @@ -0,0 +1,9 @@ +class Citations + FORMATS = [ + :apa, + :mla, + :chicago, + :harvard, + :iso690, + ] +end \ No newline at end of file diff --git a/app/services/importers/hal.rb b/app/services/importers/hal.rb new file mode 100644 index 000000000..1780d7fb4 --- /dev/null +++ b/app/services/importers/hal.rb @@ -0,0 +1,60 @@ +module Importers + class Hal + + # https://api.archives-ouvertes.fr/search/?q=03713859&fl=* + def self.import_publications_for_author(author) + fields = [ + 'docid', + 'title_s', + 'citationRef_s', + 'citationFull_s', + 'uri_s', + 'doiId_s', + 'publicationDate_tdate', + 'linkExtUrl_s', + 'abstract_s', + 'openAccess_bool', + 'journalTitle_s', + 'authFullName_s', + 'authLastName_s', + 'authFirstName_s', + 'files_s' + # '*', + ] + publications = [] + response = HalOpenscience::Document.search "authIdFormPerson_s:#{author.docid}", fields: fields, limit: 1000 + response.results.each do |doc| + publication = create_publication_from doc + publications << publication + end + publications + end + + def self.create_publication_from(doc) + publication = Research::Publication.where(hal_docid: doc.docid).first_or_create + puts "HAL sync publication #{doc.docid}" + publication.title = Osuny::Sanitizer.sanitize doc.title_s.first, 'string' + publication.ref = doc.attributes['citationRef_s'] + publication.citation_full = doc.attributes['citationFull_s'] + publication.abstract = doc.attributes['abstract_s']&.first + publication.hal_url = doc.attributes['uri_s'] + publication.doi = doc.attributes['doiId_s'] + publication.publication_date = doc.attributes['publicationDate_tdate'] + publication.url = doc.attributes['linkExtUrl_s'] + publication.open_access = doc.attributes['openAccess_bool'] + publication.journal_title = doc.attributes['journalTitle_s'] + publication.file = doc.attributes['files_s']&.first + publication.authors_list = doc.attributes['authFullName_s'].join(', ') + publication.authors_citeproc = [] + doc.attributes['authLastName_s'].each_with_index do |last_name, index| + publication.authors_citeproc << { + "family" => last_name, + "given" => doc.attributes['authFirstName_s'][index] + } + end + publication.save + publication + end + + end +end \ No newline at end of file diff --git a/app/views/admin/research/hal/authors/_list.html.erb b/app/views/admin/research/hal/authors/_list.html.erb index 00855e7f1..eed75e7b6 100644 --- a/app/views/admin/research/hal/authors/_list.html.erb +++ b/app/views/admin/research/hal/authors/_list.html.erb @@ -3,8 +3,8 @@ <%= Research::Hal::Author.human_attribute_name('full_name') %> - <%= Research::Hal::Publication.human_attribute_name('docid') %> - <%= Research::Hal::Publication.human_attribute_name('publications') %> + <%= Research::Hal::Author.human_attribute_name('docid') %> + <%= Research::Hal::Author.human_attribute_name('publications') %> diff --git a/app/views/admin/research/hal/authors/show.html.erb b/app/views/admin/research/hal/authors/show.html.erb index f3b2e9371..2649222ae 100644 --- a/app/views/admin/research/hal/authors/show.html.erb +++ b/app/views/admin/research/hal/authors/show.html.erb @@ -1,12 +1,12 @@ <% content_for :title, @author %> -
+
- <%= osuny_label Research::Hal::Author.human_attribute_name :docid %> + <%= osuny_label Research::Hal::Author.human_attribute_name(:docid) %>

<%= @author.docid %>

- <%= osuny_panel University::Person::Researcher.model_name.human do %> + <%= osuny_panel Research::Hal::Author.human_attribute_name(:researcher) do %> <% @author.researchers.in_university(current_university).each do |researcher| %> <%= render 'admin/university/people/researchers/researcher', researcher: researcher %> <% end %> @@ -14,8 +14,8 @@
-<%= osuny_panel Research::Hal::Publication.model_name.human(count: 2), subtitle: @author.publications.count do %> - <%= render 'admin/research/hal/publications/list', publications: @author.publications.ordered %> +<%= osuny_panel Research::Hal::Author.human_attribute_name(:publications), subtitle: @author.publications.count do %> + <%= render 'admin/research/publications/list', publications: @author.publications.ordered %> <% end %> <% content_for :action_bar_left do %> diff --git a/app/views/admin/research/hal/publications/_list.html.erb b/app/views/admin/research/hal/publications/_list.html.erb deleted file mode 100644 index 62de27ec4..000000000 --- a/app/views/admin/research/hal/publications/_list.html.erb +++ /dev/null @@ -1,26 +0,0 @@ -
- - - - - - - - - - <% publications.each do |publication| %> - - - - - - <% end %> - -
<%= Research::Hal::Publication.human_attribute_name('title') %><%= Research::Hal::Publication.human_attribute_name('publication_date') %><%= University::Person::Researcher.model_name.human(count: 2) %>
<%= link_to publication, admin_research_hal_publication_path(publication) %><%= l publication.publication_date %> - <% publication.researchers.in_university(current_university).each do |researcher| %> - <%= link_to_if researcher.university == current_university, - researcher, - admin_research_researcher_path(researcher) %> - <% end %> -
-
\ No newline at end of file diff --git a/app/views/admin/research/hal/publications/index.html.erb b/app/views/admin/research/hal/publications/index.html.erb deleted file mode 100644 index 5b34326d7..000000000 --- a/app/views/admin/research/hal/publications/index.html.erb +++ /dev/null @@ -1,4 +0,0 @@ -<% content_for :title, Research::Hal::Publication.model_name.human(count: 2) %> -<% content_for :title_right, "#{ @publications.total_count }" %> -<%= render 'admin/research/hal/publications/list', publications: @publications %> -<%= paginate @publications, theme: 'bootstrap-5' %> diff --git a/app/views/admin/research/hal/publications/show.html.erb b/app/views/admin/research/hal/publications/show.html.erb deleted file mode 100644 index 4f0a02251..000000000 --- a/app/views/admin/research/hal/publications/show.html.erb +++ /dev/null @@ -1,74 +0,0 @@ -<% content_for :title, @publication %> - -
-
- <% if @publication.abstract.present? %> -

- <%= sanitize @publication.abstract %> -

- <% end %> -
-
- <%= osuny_label Research::Hal::Publication.human_attribute_name('citation_full') %> -

<%= sanitize @publication.citation_full %>

-
-
- <%= osuny_label Research::Hal::Publication.human_attribute_name('ref') %> -

<%= sanitize @publication.ref %>

-
-
- <%= osuny_label Research::Hal::Publication.human_attribute_name('docid') %> -

<%= @publication.docid %>

-
-
- <%= osuny_label Research::Hal::Publication.human_attribute_name('publication_date') %> -

<%= l @publication.publication_date %>

-
-
- <%= osuny_label Research::Hal::Publication.human_attribute_name('open_access') %> -

<%= t @publication.open_access %>

-
-
-
-
- <%= osuny_panel Research::Hal::Publication.human_attribute_name('authors_list') do %> -

<%= @publication.authors_list %>

- <% end %> - <%= osuny_panel University::Person::Researcher.model_name.human(count: 2) do %> - <% @publication.researchers.in_university(current_university).each do |researcher| %> - <%= render 'admin/university/people/researchers/researcher', researcher: researcher %> - <% end %> - <% end %> - <%= osuny_panel Research::Hal::Author.model_name.human(count: 2) do %> -
    - <% @publication.authors.each do |author| %> -
  • - <%= link_to [:admin, author] do %> - <%= author %> - (<%= author.docid %>) - <% end %> -
  • - <% end %> -
- <% end %> -
-
- -<% [:url, :hal_url, :doi_url, :file].each do |key| %> - <% value = @publication.send key %> - <% next if value.blank? %> - <%= osuny_label Research::Hal::Publication.human_attribute_name(key) %> -

<%= link_to value, value, target: :_blank %>

-<% end %> - -<% content_for :action_bar_left do %> - <% if current_user.server_admin? %> - <%= link_to t('delete'), - admin_research_hal_publication_path(@publication), - method: :delete, - class: button_classes_danger %> - <%= link_to t('static'), - static_admin_research_hal_publication_path(@publication), - class: button_classes('btn-light') %> - <% end %> -<% end %> diff --git a/app/views/admin/research/hal/publications/static.html.erb b/app/views/admin/research/hal/publications/static.html.erb deleted file mode 100644 index 75fbeacb3..000000000 --- a/app/views/admin/research/hal/publications/static.html.erb +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: >- - <%= @about.title %> -date: "<%= @about.publication_date&.iso8601 %>" -<%= render 'admin/application/static/breadcrumbs', - pages: @website.special_page(Communication::Website::Page::ResearchHalPublication).ancestors_and_self, - current_title: @about.to_s %> -<%= render 'admin/application/static/permalink' %> -docid: "<%= @about.docid %>" -abstract: >- - <%= prepare_html_for_static @about.abstract, @website.university %> -citation_full: >- - <%= prepare_html_for_static @about.citation_full, @website.university %> -authors_list: >- - <%= @about.authors_list %> -ref: >- - <%= sanitize @about.ref %> -links: - - label: "HAL" - url: "<%= @about.hal_url %>" - - label: "DOI" - url: "<%= @about.doi_url %>" - - label: "URL" - url: "<%= @about.url %>" - - label: "PDF" - url: "<%= @about.file %>" -researchers: -<% @about.researchers.in_university(@website.university).each do |researcher| %> - - <%= researcher.slug %> -<% end %> -citations: - - label: "APA" - content: >- - <%= prepare_html_for_static @about.citation_apa, @website.university %> - - label: "MLA" - content: >- - <%= prepare_html_for_static @about.citation_mla, @website.university %> - - label: "Chicago" - content: >- - <%= prepare_html_for_static @about.citation_chicago, @website.university %> - - label: "Harvard" - content: >- - <%= prepare_html_for_static @about.citation_harvard, @website.university %> - <% if @website.default_language.iso_code == "fr" %> - - label: "ISO 690" - content: >- - <%= prepare_html_for_static @about.citation_iso690, @website.university %> - <% end %> ---- \ No newline at end of file diff --git a/app/views/admin/research/publications/_form.html.erb b/app/views/admin/research/publications/_form.html.erb new file mode 100644 index 000000000..fe564ffba --- /dev/null +++ b/app/views/admin/research/publications/_form.html.erb @@ -0,0 +1,27 @@ +<%= simple_form_for [:admin, publication] do |f| %> + <%= f.error_notification %> + <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %> +
+
+ <%= f.input :title %> + <%= f.input :abstract, input_html: { rows: 12 } %> + <%= f.input :citation_full, as: :summernote %> + <%= f.input :ref, as: :text %> + <%= f.input :authors_list, as: :string %> + <%= f.input :url %> +
+
+ <%= f.input :publication_date, html5: true %> + <%= f.input :doi %> + <%= f.input :journal_title %> + <%= f.input :open_access %> + <%= f.association :researchers, + as: :check_boxes, + collection: current_university.university_people.researchers.ordered %> +
+
+ + <% content_for :action_bar_right do %> + <%= submit f %> + <% end %> +<% end %> diff --git a/app/views/admin/research/publications/_list.html.erb b/app/views/admin/research/publications/_list.html.erb new file mode 100644 index 000000000..2f29e7bd5 --- /dev/null +++ b/app/views/admin/research/publications/_list.html.erb @@ -0,0 +1,23 @@ +
+ + + + + + + + + + <% publications.each do |publication| %> + + + + + + <% end %> + +
<%= Research::Publication.human_attribute_name('title') %><%= Research::Publication.human_attribute_name('source') %><%= Research::Publication.human_attribute_name('publication_date') %>
+ <%= link_to publication, [:admin, publication] %>
+ <%= publication.authors_list %> +
<%= publication.source_i18n %><%= l publication.publication_date %>
+
\ No newline at end of file diff --git a/app/views/admin/research/publications/edit.html.erb b/app/views/admin/research/publications/edit.html.erb new file mode 100644 index 000000000..02d475a3c --- /dev/null +++ b/app/views/admin/research/publications/edit.html.erb @@ -0,0 +1,3 @@ +<% content_for :title, @publication %> + +<%= render 'form', publication: @publication %> diff --git a/app/views/admin/research/publications/index.html.erb b/app/views/admin/research/publications/index.html.erb new file mode 100644 index 000000000..9791ccb5a --- /dev/null +++ b/app/views/admin/research/publications/index.html.erb @@ -0,0 +1,8 @@ +<% content_for :title, Research::Publication.model_name.human(count: 2) %> +<%= render 'filters', current_path: admin_research_publications_path, filters: @filters if @filters.any? %> +<%= render 'admin/research/publications/list', publications: @publications %> +<%= paginate @publications, theme: 'bootstrap-5' %> + +<% content_for :action_bar_right do %> + <%= create_link Research::Publication %> +<% end %> diff --git a/app/views/admin/research/publications/new.html.erb b/app/views/admin/research/publications/new.html.erb new file mode 100644 index 000000000..0ef29607a --- /dev/null +++ b/app/views/admin/research/publications/new.html.erb @@ -0,0 +1,3 @@ +<% content_for :title, Research::Publication.model_name.human %> + +<%= render 'form', publication: @publication %> diff --git a/app/views/admin/research/publications/show.html.erb b/app/views/admin/research/publications/show.html.erb new file mode 100644 index 000000000..8ea09134b --- /dev/null +++ b/app/views/admin/research/publications/show.html.erb @@ -0,0 +1,88 @@ +<% content_for :title, @publication %> + + +
+
+ <% if @publication.abstract.present? %> +

+ <%= sanitize @publication.abstract %> +

+ <% end %> +
+
+ <%= osuny_label Research::Publication.human_attribute_name('citation_full') %> +

<%= sanitize @publication.citation_full %>

+
+
+ <%= osuny_label Research::Publication.human_attribute_name('ref') %> +

<%= sanitize @publication.ref %>

+
+ <% if @publication.publication_date %> +
+ <%= osuny_label Research::Publication.human_attribute_name('publication_date') %> +

<%= l @publication.publication_date %>

+
+ <% end %> +
+ <%= osuny_label Research::Publication.human_attribute_name('open_access') %> +

<%= t @publication.open_access %>

+
+ <% if @publication.hal? %> +
+ <%= osuny_label Research::Publication.human_attribute_name('docid') %> +

<%= @publication.hal_docid %>

+
+ <% end %> +
+
+
+ <%= osuny_panel Research::Publication.human_attribute_name('authors_list') do %> +

<%= @publication.authors_list %>

+ <% end %> + <%= osuny_panel University::Person::Researcher.model_name.human(count: 2) do %> + <% @publication.researchers.in_university(current_university).each do |researcher| %> + <%= render 'admin/university/people/researchers/researcher', researcher: researcher %> + <% end %> + <% end %> + <%= osuny_panel Research::Hal::Author.model_name.human(count: 2) do %> +
    + <% @publication.authors.each do |author| %> +
  • + <%= link_to [:admin, author] do %> + <%= author %> + (<%= author.docid %>) + <% end %> +
  • + <% end %> +
+ <% end if @publication.hal? %> + <%= osuny_panel Research::Publication.human_attribute_name('urls') do %> + <% [:url, :hal_url, :doi_url, :file].each do |key| %> + <% value = @publication.send key %> + <% next if value.blank? %> + <%= osuny_label Research::Publication.human_attribute_name(key) %> +

<%= link_to value, value, target: :_blank %>

+ <% end %> + <% end %> +
+
+ +<%= osuny_panel Research::Publication.human_attribute_name('citations') do %> +
+ <% Citations::FORMATS.each do |format| %> +
+ <%= osuny_label t("research.citations.#{format}.label") %> +

<%= sanitize @publication.public_send("citation_#{format}") %>

+
+ <% end %> +
+<% end %> + +<% content_for :action_bar_left do %> + <%= destroy_link @publication if @publication.editable? %> + <%= static_link static_admin_research_publication_path(@publication) %> +<% end %> + +<% content_for :action_bar_right do %> + <%= edit_link @publication if @publication.editable? %> +<% end %> \ No newline at end of file diff --git a/app/views/admin/research/publications/static.html.erb b/app/views/admin/research/publications/static.html.erb new file mode 100644 index 000000000..e3e5a1d2b --- /dev/null +++ b/app/views/admin/research/publications/static.html.erb @@ -0,0 +1,48 @@ +<% +special_page = @website.special_page(Communication::Website::Page::ResearchPublication) +pages = special_page.ancestors_and_self if special_page +%> +--- +title: >- + <%= @about.title %> +date: "<%= @about.publication_date&.iso8601 %>" +<%= render 'admin/application/static/breadcrumbs', + pages: pages, + current_title: @about.to_s if pages %> +<%= render 'admin/application/static/permalink' %> +hal: + docid: "<%= @about.hal_docid %>" + url: "<%= @about.hal_url %>" +abstract: >- + <%= prepare_html_for_static @about.abstract, @website.university %> +citation_full: >- + <%= prepare_html_for_static @about.citation_full, @website.university %> +authors_list: >- + <%= @about.authors_list %> +ref: >- + <%= sanitize @about.ref %> +links: + - label: "HAL" + url: "<%= @about.hal_url %>" + - label: "DOI" + url: "<%= @about.doi_url %>" + - label: "URL" + url: "<%= @about.url %>" + - label: "PDF" + url: "<%= @about.file %>" +researchers: +<% @about.researchers.in_university(@website.university).each do |researcher| %> + - <%= researcher.slug %> +<% end %> +citations: +<% +Citations::FORMATS.each do |format| + citation = @about.public_send("citation_#{format}") + next if (@website.default_language.iso_code == "fr" && format == 'iso690') +%> + - label: "<%= t("research.citations.#{format}.label") %>" + format: "<%= format %>" + content: >- + <%= prepare_html_for_static citation, @website.university %> +<% end %> +--- \ No newline at end of file diff --git a/app/views/admin/research/researchers/show.html.erb b/app/views/admin/research/researchers/show.html.erb index d1f930ea0..cb50619b8 100644 --- a/app/views/admin/research/researchers/show.html.erb +++ b/app/views/admin/research/researchers/show.html.erb @@ -44,13 +44,13 @@
<% end %> -<%= osuny_panel Research::Hal::Publication.model_name.human(count: 2) do %> +<%= osuny_panel Research::Publication.model_name.human(count: 2) do %>

- <%= "#{@researcher.hal_publications.count} #{Research::Hal::Publication.model_name.human(count: @researcher.hal_publications.count).downcase}" %>. + <%= "#{@researcher.publications.count} #{Research::Publication.model_name.human(count: @researcher.publications.count).downcase}" %>. Les publications sont mises à jour automatiquement, chaque nuit.

- <%= render 'admin/research/hal/publications/list', publications: @researcher.hal_publications.ordered %> + <%= render 'admin/research/publications/list', publications: @researcher.publications.ordered %>
<% end %> diff --git a/config/locales/research/en.yml b/config/locales/research/en.yml index da5bce563..6ccfd688e 100644 --- a/config/locales/research/en.yml +++ b/config/locales/research/en.yml @@ -11,9 +11,6 @@ en: research/hal/author: one: HAL author other: HAL authors - research/hal/publication: - one: Publication - other: Publications research/journal: one: Journal other: Journals @@ -32,6 +29,9 @@ en: research/laboratory/axis: one: Axis other: Axes + research/publication: + one: Publication + other: Publications research/thesis: one: Thesis other: Theses @@ -41,14 +41,8 @@ en: first_name: First name full_name: Full name last_name: Last name - research/hal/publication: - authors_list: Authors list - docid: Identifier - doi_url: URL DOI - publication_date: Publication date - title: Title - url: URL - hal_url: URL HAL + publications: Publications imported from HAL + researcher: Researchers in Osuny research/journal: issn: ISSN title: Title @@ -88,6 +82,19 @@ en: name: Name short_name: Short name text: Text + research/publication: + abstract: Abstract + authors_list: Authors list + docid: Identifier + doi: DOI + doi_url: URL DOI + hal_url: URL HAL + journal_title: In... + open_access: Open access + publication_date: Publication date + title: Title + url: URL + urls: Web URLs research/thesis: abstract: Abstract author: Author @@ -97,11 +104,28 @@ en: laboratory: Laboratory started_at: Started at title: Title + enums: + research: + publication: + source: + hal: HAL + osuny: Osuny research/hal: description: text: "HAL signifie Hyper Article en Ligne. C’est une plateforme pluridisciplinaire nationale pour le dépôt et la consultation des écrits, travaux et résultats de recherches scientifiques des chercheur·e·s et enseignant·e·s-chercheur·e·s. HAL est un bien commun pour la recherche : Les plus grands organismes de recherche et la majorité des universités françaises ont choisi et soutiennent HAL, une infrastructure publique, pérenne et responsable." source: HAL.science research: + citations: + apa: + label: APA + mla: + label: MLA + chicago: + label: Chicago + harvard: + label: Harvard + iso690: + label: ISO 690 description: text: Scientific research is both an approach that creates knowledge motivated by pure curiosity and an activity that generates innovations that increase the means of action and diagnosis on nature, man and society. These two aspects of research, fundamental and applied, far from opposing each other, complement each other. Fundamental research creates the knowledge base from which applications are born and, conversely, technological advances provide the increasingly sophisticated investigative tools that lead to a deepening of our fundamental knowledge. source: Serge Haroche, Prix Nobel de physique 2012 @@ -112,6 +136,8 @@ en: description: Open access journals allowing researchers to contribute to research laboratory: description: Research structure hosting the work of researchers + publication: + description: Scientific publications produced by researchers researcher: description: Individual linked to a university, department, laboratory, etc. thesis: diff --git a/config/locales/research/fr.yml b/config/locales/research/fr.yml index bb29775ad..841f696bd 100644 --- a/config/locales/research/fr.yml +++ b/config/locales/research/fr.yml @@ -11,9 +11,6 @@ fr: research/hal/author: one: Auteur·e HAL other: Auteur·e·s HAL - research/hal/publication: - one: Publication - other: Publications research/journal: one: Revue scientifique other: Revues scientifiques @@ -32,6 +29,9 @@ fr: research/laboratory/axis: one: Axe other: Axes + research/publication: + one: Publication + other: Publications research/thesis: one: Thèse other: Thèses @@ -41,14 +41,8 @@ fr: first_name: Prénom full_name: Nom complet last_name: Nom - research/hal/publication: - authors_list: Liste des auteur·e·s - docid: Identifiant - doi_url: URL DOI - publication_date: Date de publication - title: Titre - url: URL - hal_url: URL HAL + publications: Publications importées de HAL + researcher: Chercheur·e dans Osuny research/journal: issn: ISSN title: Titre @@ -88,6 +82,19 @@ fr: name: Nom short_name: Nom court text: Texte + research/publication: + abstract: Résumé + authors_list: Liste des auteur·e·s + docid: Identifiant + doi: DOI + doi_url: URL DOI + hal_url: URL HAL + journal_title: Dans... + open_access: Accès ouvert (open access) + publication_date: Date de publication + title: Titre + url: URL + urls: Adresses Web research/thesis: abstract: Résumé author: Auteur·e @@ -97,11 +104,28 @@ fr: laboratory: Laboratoire started_at: Commencée le title: Titre + enums: + research: + publication: + source: + hal: HAL + osuny: Osuny research/hal: description: text: "HAL signifie Hyper Article en Ligne. C’est une plateforme pluridisciplinaire nationale pour le dépôt et la consultation des écrits, travaux et résultats de recherches scientifiques des chercheur·e·s et enseignant·e·s-chercheur·e·s. HAL est un bien commun pour la recherche : Les plus grands organismes de recherche et la majorité des universités françaises ont choisi et soutiennent HAL, une infrastructure publique, pérenne et responsable." source: HAL.science research: + citations: + apa: + label: APA + mla: + label: MLA + chicago: + label: Chicago + harvard: + label: Harvard + iso690: + label: ISO 690 description: text: La recherche scientifique est, à la fois, une démarche créatrice de connaissances motivée par la curiosité pure et une activité génératrice d’innovations qui augmentent les moyens d’action et de diagnostic sur la nature, l’homme et la société. Ces deux aspects de la recherche, le fondamental et l’appliqué, loin de s’opposer, sont complémentaires l’un de l’autre. La recherche fondamentale crée le socle de connaissances à partir duquel naissent les applications et, inversement, les avancées technologiques procurent les outils d’investigation de plus en plus perfectionnés qui conduisent à approfondir nos connaissances fondamentales. source: Serge Haroche, Prix Nobel de physique 2012 @@ -112,6 +136,8 @@ fr: description: Journaux en accès ouvert (open access) permettant aux chercheur·e·s de contribuer à la recherche laboratory: description: Structure de recherche hébergeant le travail des chercheur·e·s + publication: + description: Publications scientifiques produites par les chercheur·e·s researcher: description: Personne physique liée à une université, une composante, un laboratoire, etc. thesis: diff --git a/config/routes/admin/research.rb b/config/routes/admin/research.rb index 329a65705..7dbfd99d0 100644 --- a/config/routes/admin/research.rb +++ b/config/routes/admin/research.rb @@ -4,6 +4,11 @@ post 'sync-with-hal' => 'researchers#sync_with_hal', as: :sync_with_hal end end + resources :publications do + member do + get :static + end + end namespace :hal do resources :authors, only: [:index, :show, :destroy] do member do @@ -11,11 +16,6 @@ delete 'researchers/:researcher_id' => 'authors#disconnect_researcher' end end - resources :publications, only: [:index, :show, :destroy] do - member do - get :static - end - end root to: 'dashboard#index' end resources :journals do diff --git a/db/migrate/20240131081040_rename_hal_publications.rb b/db/migrate/20240131081040_rename_hal_publications.rb new file mode 100644 index 000000000..2ef098867 --- /dev/null +++ b/db/migrate/20240131081040_rename_hal_publications.rb @@ -0,0 +1,25 @@ +class RenameHalPublications < ActiveRecord::Migration[7.1] + def change + rename_column :research_hal_authors_publications, :research_hal_publication_id, :research_publication_id + + rename_table :research_hal_publications_university_people, :research_publications_university_people + rename_column :research_publications_university_people, :research_hal_publication_id, :research_publication_id + + reversible do |dir| + # Vieil index problématique + # Pas évident à intégrer dans une migration : + # 1. la première fois qu'on migre on répare l'index + # 2. mais on ne peut pas reverse la migration, d'où l'usage de reversible + # 3. et quand on remet après revert, il ne veut plus passer parce que l'index à réparer est déjà réparé + # 4. en ajoutant IF EXISTS, on peut le repasser + # Bingo ! + # https://stackoverflow.com/questions/32395126/rename-table-relation-table-pkey-does-not-exist + dir.up { execute "ALTER INDEX IF EXISTS research_documents_pkey RENAME TO research_hal_publications_pkey" } + end + rename_table :research_hal_publications, :research_publications + rename_column :research_publications, :docid, :hal_docid + add_column :research_publications, :source, :integer, default: 0 + # All existing publications are from HAL at this moment + Research::Publication.update_all source: 1 + end +end diff --git a/db/schema.rb b/db/schema.rb index 941f26db7..840cf18f3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_01_30_111440) do +ActiveRecord::Schema[7.1].define(version: 2024_01_31_081040) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -771,9 +771,9 @@ create_table "research_hal_authors_publications", id: false, force: :cascade do |t| t.uuid "research_hal_author_id", null: false - t.uuid "research_hal_publication_id", null: false - t.index ["research_hal_author_id", "research_hal_publication_id"], name: "hal_author_publication" - t.index ["research_hal_publication_id", "research_hal_author_id"], name: "hal_publication_author" + t.uuid "research_publication_id", null: false + t.index ["research_hal_author_id", "research_publication_id"], name: "hal_author_publication" + t.index ["research_publication_id", "research_hal_author_id"], name: "hal_publication_author" end create_table "research_hal_authors_university_people", id: false, force: :cascade do |t| @@ -783,36 +783,6 @@ t.index ["university_person_id", "research_hal_author_id"], name: "hal_person_author" end - create_table "research_hal_publications", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.string "docid" - t.jsonb "data" - t.string "title" - t.string "url" - t.string "ref" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "hal_url" - t.date "publication_date" - t.string "doi" - t.string "slug" - t.text "citation_full" - t.boolean "open_access" - t.text "abstract" - t.string "journal_title" - t.text "file" - t.text "authors_list" - t.json "authors_citeproc" - t.index ["docid"], name: "index_research_hal_publications_on_docid" - t.index ["slug"], name: "index_research_hal_publications_on_slug" - end - - create_table "research_hal_publications_university_people", id: false, force: :cascade do |t| - t.uuid "research_hal_publication_id", null: false - t.uuid "university_person_id", null: false - t.index ["research_hal_publication_id", "university_person_id"], name: "index_publication_person" - t.index ["university_person_id", "research_hal_publication_id"], name: "index_person_publication" - end - create_table "research_journal_paper_kinds", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "journal_id", null: false @@ -928,6 +898,37 @@ t.index ["university_id"], name: "index_research_laboratory_axes_on_university_id" end + create_table "research_publications", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "hal_docid" + t.jsonb "data" + t.string "title" + t.string "url" + t.string "ref" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "hal_url" + t.date "publication_date" + t.string "doi" + t.string "slug" + t.text "citation_full" + t.boolean "open_access" + t.text "abstract" + t.string "journal_title" + t.text "file" + t.text "authors_list" + t.json "authors_citeproc" + t.integer "source", default: 0 + t.index ["hal_docid"], name: "index_research_publications_on_hal_docid" + t.index ["slug"], name: "index_research_publications_on_slug" + end + + create_table "research_publications_university_people", id: false, force: :cascade do |t| + t.uuid "research_publication_id", null: false + t.uuid "university_person_id", null: false + t.index ["research_publication_id", "university_person_id"], name: "index_publication_person" + t.index ["university_person_id", "research_publication_id"], name: "index_person_publication" + end + create_table "research_theses", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "research_laboratory_id", null: false diff --git a/test/fixtures/research/hal/publications.yml b/test/fixtures/research/publications.yml similarity index 78% rename from test/fixtures/research/hal/publications.yml rename to test/fixtures/research/publications.yml index e7d35bb74..75e183820 100644 --- a/test/fixtures/research/hal/publications.yml +++ b/test/fixtures/research/publications.yml @@ -1,5 +1,5 @@ default_publication: - docid: MyString + hal_docid: MyString data: title: MyString url: MyString