Class: OrcidClient::Work

Inherits:
Object
  • Object
show all
Includes:
Bolognese::Utils, Api, Author, Base, Date, WorkType
Defined in:
lib/orcid_client/work.rb

Constant Summary collapse

SCHEMA =
File.expand_path("../../../resources/record_#{API_VERSION}/work-#{API_VERSION}.xsd", __FILE__)
VERSION_OF_RELATION_TYPES =
["IsVersionOf", "HasVersion", "IsNewVersionOf", "IsPreviousVersionOf", "IsIdenticalTo"].freeze

Constants included from Api

Api::API_VERSION

Constants included from WorkType

OrcidClient::WorkType::TYPE_OF_WORK

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Api

#create_external_identifier, #create_notification, #create_work, #delete_external_identifier, #delete_notification, #delete_work, #get_notification, #get_notification_access_token, #get_works, #update_work

Methods included from WorkType

#orcid_work_type

Methods included from Date

#get_date_parts, #get_date_parts_from_parts, #get_iso8601_from_epoch, #get_iso8601_from_time, #get_parts_from_date_parts, #get_year_month, #get_year_month_day

Methods included from Author

#get_credit_name, #get_full_name

Constructor Details

#initialize(doi:, orcid:, orcid_token:, **options) ⇒ Work

Returns a new instance of Work.



24
25
26
27
28
29
30
31
32
# File 'lib/orcid_client/work.rb', line 24

def initialize(doi:, orcid:, orcid_token:, **options)
  @doi = doi
  @orcid = orcid
  @orcid_token = orcid_token
  @sandbox = options.fetch(:sandbox, nil) || ENV['API_URL'] == "https://api.stage.datacite.org"
  @put_code = options.fetch(:put_code, nil)
  @agency = options.fetch(:agency, nil)
  @visibility = options.fetch(:visibility, 'public')
end

Instance Attribute Details

#agencyObject (readonly)

Returns the value of attribute agency.



20
21
22
# File 'lib/orcid_client/work.rb', line 20

def agency
  @agency
end

#doiObject (readonly)

Returns the value of attribute doi.



20
21
22
# File 'lib/orcid_client/work.rb', line 20

def doi
  @doi
end

#name_detectorObject (readonly)

recognize given name. Can be loaded once as ::NameDetector, e.g. in a Rails initializer



39
40
41
# File 'lib/orcid_client/work.rb', line 39

def name_detector
  @name_detector
end

#orcidObject (readonly)

Returns the value of attribute orcid.



20
21
22
# File 'lib/orcid_client/work.rb', line 20

def orcid
  @orcid
end

#orcid_tokenObject (readonly)

Returns the value of attribute orcid_token.



20
21
22
# File 'lib/orcid_client/work.rb', line 20

def orcid_token
  @orcid_token
end

#put_codeObject (readonly)

Returns the value of attribute put_code.



20
21
22
# File 'lib/orcid_client/work.rb', line 20

def put_code
  @put_code
end

#sandboxObject (readonly)

Returns the value of attribute sandbox.



20
21
22
# File 'lib/orcid_client/work.rb', line 20

def sandbox
  @sandbox
end

#schemaObject (readonly)

Returns the value of attribute schema.



20
21
22
# File 'lib/orcid_client/work.rb', line 20

def schema
  @schema
end

#validation_errorsObject (readonly)

Returns the value of attribute validation_errors.



20
21
22
# File 'lib/orcid_client/work.rb', line 20

def validation_errors
  @validation_errors
end

#visibilityObject

Returns the value of attribute visibility.



20
21
22
# File 'lib/orcid_client/work.rb', line 20

def visibility
  @visibility
end

Instance Method Details

#container_titleObject

user publisher name as fallback



63
64
65
# File 'lib/orcid_client/work.rb', line 63

def container_title
  .container_title || .publisher.present? ? .publisher["name"] : nil
end

#contributorsObject



47
48
49
50
51
52
53
54
55
56
# File 'lib/orcid_client/work.rb', line 47

def contributors
  Array.wrap(.creators).map do |contributor|
    orcid = Array.wrap(contributor["nameIdentifiers"]).find { |c| c["nameIdentifierScheme"] == "ORCID" }.to_h.fetch("nameIdentifier", nil)
    credit_name = contributor["familyName"].present? ? [contributor["givenName"], contributor["familyName"]].join(" ") : contributor["name"]

    { orcid: orcid,
      credit_name: credit_name,
      role: nil }.compact
  end
end

#dataObject



99
100
101
102
103
104
105
106
107
# File 'lib/orcid_client/work.rb', line 99

def data
  return nil unless has_required_elements?

  Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
    xml.send(:'work:work', root_attributes) do
      insert_work(xml)
    end
  end.to_xml
end

#descriptionObject



72
73
74
75
# File 'lib/orcid_client/work.rb', line 72

def description
  ct = parse_attributes(.descriptions, content: "description", first: true)
  ct.squish if ct.present?
end

#has_required_elements?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/orcid_client/work.rb', line 95

def has_required_elements?
  doi && contributors && title && container_title && publication_date
end

#insert_contributor(xml, contributor) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/orcid_client/work.rb', line 177

def insert_contributor(xml, contributor)
  if contributor[:orcid].present?
    xml.send(:'common:contributor-orcid') do
      xml.send(:'common:uri', contributor[:orcid])
      xml.send(:'common:path', validate_orcid(contributor[:orcid]))
      xml.send(:'common:host', 'orcid.org')
    end
  end
  xml.send(:'credit-name', contributor[:credit_name])
  if contributor[:role]
    xml.send(:'contributor-attributes') do
      xml.send(:'contributor-role', contributor[:role])
    end
  end
end

#insert_contributors(xml) ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
# File 'lib/orcid_client/work.rb', line 165

def insert_contributors(xml)
  return nil unless contributors.present?

  xml.send(:'work:contributors') do
    contributors.each do |contributor|
      xml.contributor do
        insert_contributor(xml, contributor)
      end
    end
  end
end

#insert_description(xml) ⇒ Object



128
129
130
131
132
# File 'lib/orcid_client/work.rb', line 128

def insert_description(xml)
  return nil unless description.present?

  xml.send(:'work:short-description', description.truncate(2500, separator: ' '))
end

#insert_id(xml, id_type, value, relationship) ⇒ Object



157
158
159
160
161
162
163
# File 'lib/orcid_client/work.rb', line 157

def insert_id(xml, id_type, value, relationship)
  xml.send(:'common:external-id') do
    xml.send(:'common:external-id-type', id_type)
    xml.send(:'common:external-id-value', value)
    xml.send(:'common:external-id-relationship', relationship)
  end
end

#insert_ids(xml) ⇒ Object



148
149
150
151
152
153
154
155
# File 'lib/orcid_client/work.rb', line 148

def insert_ids(xml)
  xml.send(:'common:external-ids') do
    insert_id(xml, 'doi', doi, 'self')
    version_of_dois.each do |version_of_doi|
      insert_id(xml, 'doi', version_of_doi, 'version-of')
    end
  end
end

#insert_pub_date(xml) ⇒ Object



138
139
140
141
142
143
144
145
146
# File 'lib/orcid_client/work.rb', line 138

def insert_pub_date(xml)
  if publication_date['year']
    xml.send(:'common:publication-date') do
      xml.year(publication_date.fetch('year'))
      xml.month(publication_date.fetch('month', nil)) if publication_date['month']
      xml.day(publication_date.fetch('day', nil)) if publication_date['month'] && publication_date['day']
    end
  end
end

#insert_titles(xml) ⇒ Object



118
119
120
121
122
123
124
125
126
# File 'lib/orcid_client/work.rb', line 118

def insert_titles(xml)
  if title
    xml.send(:'work:title') do
      xml.send(:'common:title', title.truncate(1000, separator: ' '))
    end
  end

  xml.send(:'work:journal-title', container_title) if container_title
end

#insert_type(xml) ⇒ Object



134
135
136
# File 'lib/orcid_client/work.rb', line 134

def insert_type(xml)
  xml.send(:'work:type', type)
end

#insert_work(xml) ⇒ Object



109
110
111
112
113
114
115
116
# File 'lib/orcid_client/work.rb', line 109

def insert_work(xml)
  insert_titles(xml)
  insert_description(xml)
  insert_type(xml)
  insert_pub_date(xml)
  insert_ids(xml)
  insert_contributors(xml)
end

#metadataObject



43
44
45
# File 'lib/orcid_client/work.rb', line 43

def 
  @metadata ||= Bolognese::Metadata.new(input: doi, sandbox: sandbox, from: agency)
end

#publication_dateObject



67
68
69
70
# File 'lib/orcid_client/work.rb', line 67

def publication_date
  pd = get_date(.dates, "Issued") || .publication_year
  get_year_month_day(pd)
end

#root_attributesObject



203
204
205
206
207
208
209
210
# File 'lib/orcid_client/work.rb', line 203

def root_attributes
  { :'put-code' => put_code,
    :'visibility' => visibility,
    :'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
    :'xsi:schemaLocation' => 'http://www.orcid.org/ns/work ../work-3.0.xsd',
    :'xmlns:common' => 'http://www.orcid.org/ns/common',
    :'xmlns:work' => 'http://www.orcid.org/ns/work' }.compact
end

#titleObject



58
59
60
# File 'lib/orcid_client/work.rb', line 58

def title
  parse_attributes(.titles, content: "title", first: true)
end

#typeObject



77
78
79
# File 'lib/orcid_client/work.rb', line 77

def type
  orcid_work_type(.types["resourceTypeGeneral"], .types["resourceType"])
end

#validate_doi(doi) ⇒ Object



89
90
91
92
93
# File 'lib/orcid_client/work.rb', line 89

def validate_doi(doi)
  doi = Array(/\A(?:(http|https):\/(\/)?(dx\.)?(doi.org|handle.stage.datacite.org|handle.test.datacite.org)\/)?(doi:)?(10\.\d{4,5}\/.+)\z/.match(doi)).last
  # remove non-printing whitespace and downcase
  doi.delete("\u200B").downcase if doi.present?
end

#version_of_doisObject



81
82
83
84
85
86
87
# File 'lib/orcid_client/work.rb', line 81

def version_of_dois
  Array.wrap(.related_identifiers).filter_map do |related_identifier|
    if related_identifier["relatedIdentifierType"] == "DOI" && VERSION_OF_RELATION_TYPES.include?(related_identifier["relationType"])
      validate_doi(related_identifier["relatedIdentifier"])
    end
  end.compact.uniq
end

#without_control(s) ⇒ Object



193
194
195
196
197
198
199
200
201
# File 'lib/orcid_client/work.rb', line 193

def without_control(s)
  r = ''
  s.each_codepoint do |c|
    if c >= 32
      r << c
    end
  end
  r
end