Skip to content

Commit

Permalink
Associate organization and works via member id. #635
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Fenner committed Sep 18, 2020
1 parent c768c15 commit 2b4a83c
Show file tree
Hide file tree
Showing 12 changed files with 269 additions and 14 deletions.
30 changes: 30 additions & 0 deletions app/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -5638,6 +5638,11 @@ type Member {
"""
logoUrl: Url

"""
Membership type
"""
memberRole: MemberRole

"""
Member name
"""
Expand Down Expand Up @@ -5799,6 +5804,21 @@ type MemberPrefixEdge {
node: MemberPrefix
}

"""
Information about the membership role.
"""
type MemberRole {
"""
Role ID
"""
id: ID

"""
Role name
"""
name: String
}

type Model implements DoiItem {
"""
Metadata in bibtex format
Expand Down Expand Up @@ -6149,6 +6169,16 @@ type Organization implements ActorItem {
"""
inceptionYear: Int

"""
Unique member identifier if a DataCite member
"""
memberId: ID

"""
Membership type if a DataCite member
"""
memberRole: MemberRole

"""
The name of the actor.
"""
Expand Down
8 changes: 8 additions & 0 deletions app/graphql/types/member_role_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

class MemberRoleType < BaseObject
description "Information about the membership role."

field :id, ID, null: true, description: "Role ID"
field :name, String, null: true, description: "Role name"
end
6 changes: 6 additions & 0 deletions app/graphql/types/member_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class MemberType < BaseObject
field :logo_url, Url, null: true, description: "URL for the member logo"
field :region, String, null: true, description: "Geographic region where the member is located"
field :country, CountryType, null: true, description: "Country where the member is located"
field :member_role, MemberRoleType, null: true, description: "Membership type"
field :organization_type, String, null: true, description: "Type of organization"
field :focus_area, String, null: true, description: "Field of science covered by member"
field :joined, GraphQL::Types::ISO8601Date, null: true, description: "Date member joined DataCite"
Expand Down Expand Up @@ -168,6 +169,11 @@ def type
"Member"
end

def member_role
{ "id" => object.member_type,
"name" => object.member_type.titleize }
end

def country
return {} unless object.country_code.present?
{
Expand Down
8 changes: 7 additions & 1 deletion app/graphql/types/organization_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class OrganizationType < BaseObject
description "Information about organizations"

field :identifiers, [IdentifierType], null: true, description: "The identifier(s) for the organization."
field :member_id, ID, null: true, description: "Unique member identifier if a DataCite member"
field :member_role, MemberRoleType, null: true, description: "Membership type if a DataCite member"
field :url, [Url], null: true, hash_key: "links", description: "URL of the organization."
field :wikipedia_url, Url, null: true, hash_key: "wikipedia_url", description: "Wikipedia URL of the organization."
field :twitter, String, null: true, description: "Twitter username of the organization."
Expand Down Expand Up @@ -150,6 +152,10 @@ def identifiers
object.isni.map { |o| { "identifierType" => "isni", "identifier" => o } }
end

def provider_id
object.member_id && %w(direct_member consortium_organization).include?(object.member_role["id"]) ? object.member_id : nil
end

def publications(**args)
args[:resource_type_id] = "Text"
ElasticsearchModelResponseConnection.new(response(args), context: self.context, first: args[:first], after: args[:after])
Expand Down Expand Up @@ -205,6 +211,6 @@ def citation_count
end

def response(**args)
Doi.gql_query(args[:query], ids: args[:ids], affiliation_id: object.id, organization_id: object.id, user_id: args[:user_id], client_id: args[:repository_id], provider_id: args[:member_id], funder_id: args[:funder_id] || object.fundref.join(","), resource_type_id: args[:resource_type_id], resource_type: args[:resource_type], agency: args[:registration_agency], language: args[:language], license: args[:license], has_person: args[:has_person], has_funder: args[:has_funder], has_citations: args[:has_citations], has_parts: args[:has_parts], has_versions: args[:has_versions], has_views: args[:has_views], has_downloads: args[:has_downloads], field_of_science: args[:field_of_science], published: args[:published], state: "findable", page: { cursor: args[:after].present? ? Base64.urlsafe_decode64(args[:after]) : [], size: args[:first] })
Doi.gql_query(args[:query], ids: args[:ids], affiliation_id: object.id, organization_id: object.id, provider_id: args[:member_id] || provider_id, user_id: args[:user_id], client_id: args[:repository_id], funder_id: args[:funder_id] || object.fundref.join(","), resource_type_id: args[:resource_type_id], resource_type: args[:resource_type], agency: args[:registration_agency], language: args[:language], license: args[:license], has_person: args[:has_person], has_funder: args[:has_funder], has_citations: args[:has_citations], has_parts: args[:has_parts], has_versions: args[:has_versions], has_views: args[:has_views], has_downloads: args[:has_downloads], field_of_science: args[:field_of_science], published: args[:published], state: "findable", page: { cursor: args[:after].present? ? Base64.urlsafe_decode64(args[:after]) : [], size: args[:first] })
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def total_count
object.total_count
end

def years
def published
facet_by_range(object.aggregations.published.buckets)
end

Expand Down
22 changes: 14 additions & 8 deletions app/models/doi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,6 @@ def self.gql_query(query, options={})
filter << { terms: { doi: options[:ids].map(&:upcase) }} if options[:ids].present?
filter << { term: { "types.resourceTypeGeneral": options[:resource_type_id].underscore.camelize }} if options[:resource_type_id].present?
filter << { terms: { "types.resourceType": options[:resource_type].split(",") }} if options[:resource_type].present?
filter << { terms: { provider_id: options[:provider_id].split(",") } } if options[:provider_id].present?
filter << { terms: { client_id: options[:client_id].to_s.split(",") } } if options[:client_id].present?
filter << { terms: { agency: options[:agency].split(",").map(&:downcase) } } if options[:agency].present?
filter << { terms: { prefix: options[:prefix].to_s.split(",") } } if options[:prefix].present?
Expand Down Expand Up @@ -886,8 +885,8 @@ def self.gql_query(query, options={})
minimum_should_match = 1
end

# match either ROR ID or Crossref Funder ID if either organization_id, affiliation_id or funder_id
# is a query parameter
# match either ROR ID, Crossref Funder ID or Member ID if either organization_id, affiliation_id,
# funder_id or provider_id is a query parameter
if options[:organization_id].present?
should << { term: { "creators.nameIdentifiers.nameIdentifier" => "https://#{ror_from_url(options[:organization_id])}" }}
should << { term: { "contributors.nameIdentifiers.nameIdentifier" => "https://#{ror_from_url(options[:organization_id])}" }}
Expand All @@ -901,6 +900,10 @@ def self.gql_query(query, options={})
should << { terms: { "funding_references.funderIdentifier" => options[:funder_id].split(",").map { |f| "https://doi.org/#{doi_from_url(f)}" } } }
minimum_should_match = 1
end
if options[:provider_id].present?
should << { terms: { provider_id: options[:provider_id].split(",") } }
minimum_should_match = 1
end

es_query = {
bool: {
Expand Down Expand Up @@ -1012,7 +1015,6 @@ def self.query(query, options={})
filter << { terms: { doi: options[:ids].map(&:upcase) }} if options[:ids].present?
filter << { term: { "types.resourceTypeGeneral": options[:resource_type_id].underscore.camelize }} if options[:resource_type_id].present?
filter << { terms: { "types.resourceType": options[:resource_type].split(",") }} if options[:resource_type].present?
filter << { terms: { provider_id: options[:provider_id].split(",") } } if options[:provider_id].present?
filter << { terms: { client_id: options[:client_id].to_s.split(",") } } if options[:client_id].present?
filter << { terms: { agency: options[:agency].split(",").map(&:downcase) } } if options[:agency].present?
filter << { terms: { prefix: options[:prefix].to_s.split(",") } } if options[:prefix].present?
Expand Down Expand Up @@ -1074,11 +1076,11 @@ def self.query(query, options={})
minimum_should_match = 1
end

# match either ROR ID or Crossref Funder ID if either organization_id, affiliation_id or funder_id
# is a query parameter
# match either ROR ID, Crossref Funder ID or Member ID if either organization_id, affiliation_id,
# funder_id or provider_id is a query parameter
if options[:organization_id].present?
should << { term: { "creators.nameIdentifiers.nameIdentifier" => ror_from_url(options[:organization_id]) }}
should << { term: { "contributors.nameIdentifiers.nameIdentifier" => ror_from_url(options[:organization_id]) }}
should << { term: { "creators.nameIdentifiers.nameIdentifier" => "https://#{ror_from_url(options[:organization_id])}" }}
should << { term: { "contributors.nameIdentifiers.nameIdentifier" => "https://#{ror_from_url(options[:organization_id])}" }}
minimum_should_match = 1
end
if options[:affiliation_id].present?
Expand All @@ -1089,6 +1091,10 @@ def self.query(query, options={})
should << { terms: { "funding_references.funderIdentifier" => options[:funder_id].split(",").map { |f| "https://doi.org/#{doi_from_url(f)}" } } }
minimum_should_match = 1
end
if options[:provider_id].present?
should << { terms: { provider_id: options[:provider_id].split(",") } }
minimum_should_match = 1
end

must_not << { terms: { agency: ["crossref", "kisti", "medra", "jalc", "istic", "airiti", "cnki", "op"] }} if options[:exclude_registration_agencies]

Expand Down
28 changes: 28 additions & 0 deletions app/models/organization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ class Organization
# include helper module for working with Wikidata
include Wikidatable

MEMBER_ROLES = {
"ROLE_CONSORTIUM" => "consortium",
"ROLE_CONSORTIUM_ORGANIZATION" => "consortium_organization",
"ROLE_ALLOCATOR" => "direct_member",
"ROLE_FOR_PROFIT_PROVIDER" => "for-profit_provider",
"ROLE_MEMBER" => "member_only" }

def self.find_by_id(id)
ror_id = ror_id_from_url(id)
return {} unless ror_id.present?
Expand All @@ -17,6 +24,9 @@ def self.find_by_id(id)
wikidata = data.dig(0, "wikidata", 0)
wikidata_data = find_by_wikidata_id(wikidata)
data = [data.first.reverse_merge(wikidata_data[:data].first)] if wikidata_data

datacite_data = find_datacite_member(id)
data = [data.first.reverse_merge(datacite_data)] if datacite_data

errors = response.body.fetch("errors", nil)

Expand All @@ -39,6 +49,9 @@ def self.find_by_grid_id(id)
wikidata_data = find_by_wikidata_id(wikidata)
data = [data.first.reverse_merge(wikidata_data[:data].first)] if wikidata_data

datacite_data = find_datacite_member(data.first["id"])
data = [data.first.reverse_merge(datacite_data)] if datacite_data

errors = response.body.fetch("errors", nil)

{ data: data, errors: errors }
Expand All @@ -60,11 +73,26 @@ def self.find_by_crossref_funder_id(id)
wikidata_data = find_by_wikidata_id(wikidata)
data = [data.first.reverse_merge(wikidata_data[:data].first)] if wikidata_data

datacite_data = find_datacite_member(data.first["id"])
data = [data.first.reverse_merge(datacite_data)] if datacite_data

errors = response.body.fetch("errors", nil)

{ data: data, errors: errors }
end

def self.find_datacite_member(id)
member = Provider.unscoped.where("allocator.role_name IN ('ROLE_FOR_PROFIT_PROVIDER', 'ROLE_CONSORTIUM' , 'ROLE_CONSORTIUM_ORGANIZATION', 'ROLE_ALLOCATOR', 'ROLE_MEMBER')").where(deleted_at: nil).where(ror_id: id).first
return nil unless member.present?

{ "member_id" => member.symbol.downcase,
"member_role" => {
"id" => MEMBER_ROLES[member.role_name],
"name" => MEMBER_ROLES[member.role_name].titleize
}
}
end

def self.query(query, options={})
# rows = options[:limit] || 20
page = options[:offset] || 1
Expand Down
2 changes: 1 addition & 1 deletion app/models/provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ def member_types
"ROLE_CONSORTIUM" => "consortium",
"ROLE_CONSORTIUM_ORGANIZATION" => "consortium_organization",
"ROLE_CONTRACTUAL_PROVIDER" => "contractual_member",
"ROLE_FOR_PROFIT_PROVIDER" => "for_profit_provider",
"ROLE_FOR_PROFIT_PROVIDER" => "for-profit_provider",
"ROLE_REGISTRATION_AGENCY" => "registration_agency",
}
end
Expand Down
Loading

0 comments on commit 2b4a83c

Please sign in to comment.