From 06c22824b160d478963c630f62b3e576609afbea Mon Sep 17 00:00:00 2001 From: Martin Fenner Date: Sat, 11 Apr 2020 08:10:45 +0200 Subject: [PATCH] added field for doi metadata in bibtex format --- app/graphql/schema.graphql | 100 +++++++++++++++++++++++++++ app/graphql/types/doi_item.rb | 23 ++++++ spec/graphql/types/doi_item_spec.rb | 1 + spec/graphql/types/work_type_spec.rb | 30 ++++++++ 4 files changed, 154 insertions(+) diff --git a/app/graphql/schema.graphql b/app/graphql/schema.graphql index 4d97a2585..70b2e5f33 100644 --- a/app/graphql/schema.graphql +++ b/app/graphql/schema.graphql @@ -49,6 +49,11 @@ type Affiliation { } type Audiovisual implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -480,6 +485,11 @@ type AudiovisualEdge { } type Collection implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -1135,6 +1145,11 @@ type DataCatalogEdge { } type DataPaper implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -1566,6 +1581,11 @@ type DataPaperEdge { } type Dataset implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -2111,6 +2131,11 @@ type Description { Information about DOIs """ interface DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -2505,6 +2530,11 @@ interface DoiItem { } type Event implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -2921,6 +2951,11 @@ type EventConnection { } type EventData implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -3670,6 +3705,11 @@ type Identifier { } type Image implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -4101,6 +4141,11 @@ type ImageEdge { } type Instrument implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -4532,6 +4577,11 @@ type InstrumentEdge { } type InteractiveResource implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -5358,6 +5408,11 @@ type MemberPrefixEdge { } type Model implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -6009,6 +6064,11 @@ type OrganizationEdge { } type Other implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -6691,6 +6751,11 @@ type PersonEdge { } type PhysicalObject implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -7175,6 +7240,11 @@ type PrefixEdge { } type Publication implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -8778,6 +8848,11 @@ type Rights { } type Service implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -9209,6 +9284,11 @@ type ServiceEdge { } type Software implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -9672,6 +9752,11 @@ type SoftwareEdge { } type Sound implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -10158,6 +10243,11 @@ type TextRestriction { } type Thesis implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -10717,6 +10807,11 @@ type UsageReportEdge { } type Work implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ @@ -11149,6 +11244,11 @@ type WorkEdge { } type Workflow implements DoiItem { + """ + Metadata in bibtex format + """ + bibtex: String + """ Total number of citations """ diff --git a/app/graphql/types/doi_item.rb b/app/graphql/types/doi_item.rb index d141afad6..e67be1e80 100644 --- a/app/graphql/types/doi_item.rb +++ b/app/graphql/types/doi_item.rb @@ -38,6 +38,7 @@ module DoiItem argument :style, String, required: false, default_value: "apa" argument :locale, String, required: false, default_value: "en-US" end + field :bibtex, String, null: true, description: "Metadata in bibtex format" field :reference_count, Int, null: true, description: "Total number of references" field :citation_count, Int, null: true, description: "Total number of citations" field :view_count, Int, null: true, description: "Total number of views" @@ -186,6 +187,28 @@ def descriptions(first: nil) object.descriptions[0...first] end + def bibtex + pages = object.container.to_h["firstPage"].present? ? [object.container["firstPage"], object.container["lastPage"]].join("-") : nil + + bib = { + bibtex_type: object.types["bibtex"].presence || "misc", + bibtex_key: normalize_doi(object.doi), + doi: object.doi, + url: object.url, + author: authors_as_string(object.creators), + keywords: object.subjects.present? ? Array.wrap(object.subjects).map { |k| parse_attributes(k, content: "subject", first: true) }.join(", ") : nil, + language: object.language, + title: parse_attributes(object.titles, content: "title", first: true), + journal: object.container && container["title"], + volume: object.container.to_h["volume"], + issue: object.container.to_h["issue"], + pages: pages, + publisher: object.publisher, + year: object.publication_year + }.compact + BibTeX::Entry.new(bib).to_s + end + # defaults to style: apa and locale: en-US def formatted_citation(style: nil, locale: nil) cp = CiteProc::Processor.new(style: style || "apa", locale: locale || "en-US", format: "html") diff --git a/spec/graphql/types/doi_item_spec.rb b/spec/graphql/types/doi_item_spec.rb index 493d5bb26..898e1f96c 100644 --- a/spec/graphql/types/doi_item_spec.rb +++ b/spec/graphql/types/doi_item_spec.rb @@ -26,6 +26,7 @@ it { is_expected.to have_field(:member).of_type("Member") } it { is_expected.to have_field(:registrationAgency).of_type("String") } it { is_expected.to have_field(:formattedCitation).of_type("String") } + it { is_expected.to have_field(:bibtex).of_type("String") } it { is_expected.to have_field(:citationCount).of_type("Int") } it { is_expected.to have_field(:referenceCount).of_type("Int") } it { is_expected.to have_field(:viewCount).of_type("Int") } diff --git a/spec/graphql/types/work_type_spec.rb b/spec/graphql/types/work_type_spec.rb index 7266dc819..e13cab97c 100644 --- a/spec/graphql/types/work_type_spec.rb +++ b/spec/graphql/types/work_type_spec.rb @@ -7,4 +7,34 @@ it { is_expected.to have_field(:id).of_type(!types.ID) } it { is_expected.to have_field(:type).of_type("String!") } end + + describe "find work", elasticsearch: true do + let!(:work) { create(:doi, aasm_state: "findable") } + + before do + Doi.import + sleep 2 + end + + let(:query) do + %(query { + work(id: "https://doi.org/#{work.doi}") { + id + bibtex + } + }) + end + + it "returns work" do + response = LupoSchema.execute(query).as_json + + expect(response.dig("data", "work", "id")).to eq("https://handle.test.datacite.org/#{work.doi.downcase}") + bibtex = BibTeX.parse(response.dig("data", "work", "bibtex")).to_a(quotes: '').first + expect(bibtex[:bibtex_type].to_s).to eq("misc") + expect(bibtex[:bibtex_key]).to eq("https://doi.org/#{work.doi.downcase}") + expect(bibtex[:author]).to eq("Ollomo, Benjamin and Durand, Patrick and Prugnolle, Franck and Douzery, Emmanuel J. P. and Arnathau, Céline and Nkoghe, Dieudonné and Leroy, Eric and Renaud, François") + expect(bibtex[:title]).to eq("Data from: A new malaria agent in African hominids.") + expect(bibtex[:year]).to eq("2011") + end + end end