Skip to content

Commit

Permalink
graphql connections for funders. #257
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Fenner committed May 12, 2019
1 parent 260db2a commit 4f6d5d6
Show file tree
Hide file tree
Showing 14 changed files with 339 additions and 16 deletions.
4 changes: 2 additions & 2 deletions app/graphql/lupo_schema.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# frozen_string_literal: true

class LupoSchema < GraphQL::Schema
default_max_page_size 100
max_depth 5
default_max_page_size 250
max_depth 10

# mutation(Types::MutationType)
query(QueryType)
Expand Down
13 changes: 13 additions & 0 deletions app/graphql/types/dataset_connection_with_meta_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

class DatasetConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection
edge_type(EventEdgeType, edge_class: EventEdge)
# edge_type(EventEdgeType)
# field :total_count, Integer, null: false

# def total_count
# args = object.arguments

# 1
# end
end
23 changes: 23 additions & 0 deletions app/graphql/types/event_edge.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

class EventEdge < GraphQL::Relay::Edge
def event
logger = Logger.new(STDOUT)

@event ||= begin
Event.query(nil, subj_id: self.node[:id], obj_id: self.parent[:id])[:data].first
end
end

def source
event[:source_id].underscore.camelcase(:lower)
end

def relation_type
event[:relation_type_id].underscore.camelcase(:lower)
end

def total
event[:total]
end
end
9 changes: 9 additions & 0 deletions app/graphql/types/event_edge_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

class EventEdgeType < GraphQL::Types::Relay::BaseEdge
node_type(DatasetType)

field :source, String, null: false, description: "Source for this event"
field :relation_type, String, null: false, description: "Relation type for this event"
field :total, Integer, null: false, description: "Total count for this event"
end
13 changes: 13 additions & 0 deletions app/graphql/types/funder_connection_with_meta_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

class FunderConnectionWithMetaType < GraphQL::Types::Relay::BaseConnection
edge_type(FunderEdgeType)

field :total_count, Integer, null: false

def total_count
args = object.arguments

Funder.query(args[:query], limit: 0).dig(:meta, "total").to_i
end
end
5 changes: 5 additions & 0 deletions app/graphql/types/funder_edge_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

class FunderEdgeType < GraphQL::Types::Relay::BaseEdge
node_type(FunderType)
end
29 changes: 29 additions & 0 deletions app/graphql/types/funder_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,33 @@ class FunderType < BaseObject
field :alternate_name, [String], null: true, description: "Alternate funder names"
field :country, String, null: true, description: "Country where funder is located"
field :date_modified, String, null: false, description: "Date information was last updated"
field :datasets, DatasetConnectionWithMetaType, null: false, description: "Funded datasets", connection: true, max_page_size: 100 do
argument :first, Int, required: false, default_value: 25
end

field :publications, [PublicationType], null: false, description: "Funded publications" do
argument :query, String, required: false
argument :first, Int, required: false, default_value: 25
end

def datasets(**args)
ids = Event.query(nil, obj_id: object[:id], citation_type: "Dataset-Funder").fetch(:data, []).map do |e|
doi_from_url(e[:subj_id])
end.join(",")
Doi.find_by_ids(ids, page: { number: 1, size: args[:first] }).to_a
end

def publications(**args)
ids = Event.query(nil, obj_id: object[:id], citation_type: "Funder-ScholarlyArticle").fetch(:data, []).map do |e|
doi_from_url(e[:subj_id])
end.join(",")
Doi.find_by_ids(ids, page: { number: 1, size: args[:first] }).to_a
end

def doi_from_url(url)
if /\A(?:(http|https):\/\/(dx\.)?(doi.org|handle.test.datacite.org)\/)?(doi:)?(10\.\d{4,5}\/.+)\z/.match?(url)
uri = Addressable::URI.parse(url)
uri.path.gsub(/^\//, "").downcase
end
end
end
5 changes: 4 additions & 1 deletion app/models/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ def self.query(query, options={})
url = "https://api.datacite.org/events?page[size]=#{size}"
url += "&relation-type-id=#{options[:relation_type_id]}" if options[:relation_type_id].present?
url += "&source-id=#{options[:source_id]}" if options[:source_id].present?
url += "&citation-type=#{options[:citation_type]}" if options[:citation_type].present?
url += "&doi=#{doi}" if doi.present?

url += "&subj-id=#{options[:subj_id]}" if options[:subj_id].present?
url += "&obj-id=#{options[:obj_id]}" if options[:obj_id].present?

response = Maremma.get(url, accept: "application/vnd.api+json; version=2")

if response.status == 200
Expand Down
15 changes: 11 additions & 4 deletions app/models/funder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ def self.find_by_id(id)
return [] if response.status != 200

message = response.body.dig("data", "message")
[parse_message(id: id, message: message)]
data = [parse_message(id: id, message: message)]

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

{ data: data, errors: errors }
end

def self.query(query, options={})
Expand All @@ -27,11 +31,14 @@ def self.query(query, options={})
response = Maremma.get(url, host: true)

return [] if response.status != 200

items = response.body.dig("data", "message", "items")
items.map do |message|

data = response.body.dig("data", "message", "items").map do |message|
parse_message(id: "https://doi.org/10.13039/#{message['id']}", message: message)
end
meta = { "total" => response.body.dig("data", "message", "total-results") }
errors = response.body.fetch("errors", nil)

{ data: data, meta: meta, errors: errors }
end

def self.parse_message(id: nil, message: nil)
Expand Down
69 changes: 69 additions & 0 deletions spec/fixtures/vcr_cassettes/Event/query/citation_type.yml

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions spec/fixtures/vcr_cassettes/Event/query/obj_id.yml

Large diffs are not rendered by default.

50 changes: 50 additions & 0 deletions spec/fixtures/vcr_cassettes/Event/query/subj_id.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions spec/models/event_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,37 @@
it "limit" do
query = nil
response = Event.query(query, limit: 10)
expect(response.dig(:meta, "total")).to eq(9165580)
expect(response[:data].size).to eq(10)
expect(response[:data].first).to eq(:id=>"c8bcd46c-3433-47ac-b8db-d039ce346d65", :subj_id=>"https://doi.org/10.5281/zenodo.595698", :obj_id=>"https://doi.org/10.13039/501100000780", :source_id=>"datacite-funder", :relation_type_id=>"is-funded-by", :total=>1)
end

it "source_id" do
source_id = "datacite-usage"
response = Event.query(nil, source_id: source_id)
expect(response.dig(:meta, "total")).to eq(16672)
expect(response[:data].size).to eq(100)
expect(response[:data].first).to eq(:id=>"308185f3-1607-478b-a25e-ed5671994db5", :subj_id=>"https://api.datacite.org/reports/fa2ad308-1b25-4394-9bc6-e0c7511e763d", :obj_id=>"https://doi.org/10.7272/q6g15xs4", :source_id=>"datacite-usage", :relation_type_id=>"total-dataset-investigations-regular", :total=>4)
end

it "citation_type" do
citation_type = "Dataset-Funder"
response = Event.query(nil, citation_type: citation_type)
expect(response.dig(:meta, "total")).to eq(27246)
expect(response[:data].size).to eq(100)
expect(response[:data].first).to eq(:id => "28fa7d4f-60e0-4db8-8365-b19b1b9904e9",
:obj_id => "https://doi.org/10.13039/100000050",
:relation_type_id => "is-funded-by",
:source_id => "datacite-funder",
:subj_id => "https://doi.org/10.23725/e9sa-1y49",
:total => 1)
end

it "doi" do
doi = "https://doi.org/10.7272/q6z60kzd"
response = Event.query(nil, doi: doi)
expect(response[:data].size).to eq(22)
expect(response[:data].first).to eq(:id=>"758199db-95c9-4216-ae7a-70b9d00425d4", :subj_id=>"https://api.datacite.org/reports/08761bb6-f8d9-4d01-8012-fd21042fd71d", :obj_id=>"https://doi.org/10.7272/q6z60kzd", :source_id=>"datacite-usage", :relation_type_id=>"total-dataset-investigations-regular", :total=>58)
expect(response.dig(:meta, "relationTypes", 0, "yearMonths")).to eq([{"id"=>"2018-04", "title"=>"April 2018", "sum"=>23171.0},
{"id"=>"2018-05", "title"=>"May 2018", "sum"=>58.0},
{"id"=>"2018-06", "title"=>"June 2018", "sum"=>4.0},
Expand All @@ -53,6 +69,29 @@
{"id"=>"2019-05", "title"=>"May 2019", "sum"=>1.0}])
end

it "subj_id" do
subj_id = "https://doi.org/10.3389/feart.2018.00153"
response = Event.query(nil, subj_id: subj_id)
expect(response[:data].size).to eq(1)
expect(response[:data].first).to eq(:id=>"63897322-b0fd-4145-a3a7-014b37954aed", :subj_id=>"https://doi.org/10.3389/feart.2018.00153", :obj_id=>"https://doi.org/10.3886/icpsr04254.v1", :source_id=>"crossref", :relation_type_id=>"references", :total=>1)
expect(response.dig(:meta, "relationTypes", 0, "yearMonths")).to eq([{"id"=>"0000-01", "sum"=>1.0, "title"=>"January 0000"}])
end

it "obj_id" do
obj_id = "https://doi.org/10.7272/q6z60kzd"
response = Event.query(nil, obj_id: obj_id)
expect(response[:data].size).to eq(22)
expect(response[:data].first).to eq(:id=>"758199db-95c9-4216-ae7a-70b9d00425d4", :subj_id=>"https://api.datacite.org/reports/08761bb6-f8d9-4d01-8012-fd21042fd71d", :obj_id=>"https://doi.org/10.7272/q6z60kzd", :source_id=>"datacite-usage", :relation_type_id=>"total-dataset-investigations-regular", :total=>58)
expect(response.dig(:meta, "relationTypes", 0, "yearMonths")).to eq([{"id"=>"2018-04", "title"=>"April 2018", "sum"=>23171.0},
{"id"=>"2018-05", "title"=>"May 2018", "sum"=>58.0},
{"id"=>"2018-06", "title"=>"June 2018", "sum"=>4.0},
{"id"=>"2018-08", "title"=>"August 2018", "sum"=>16.0},
{"id"=>"2019-02", "title"=>"February 2019", "sum"=>11.0},
{"id"=>"2019-03", "title"=>"March 2019", "sum"=>5.0},
{"id"=>"2019-04", "title"=>"April 2019", "sum"=>2.0},
{"id"=>"2019-05", "title"=>"May 2019", "sum"=>2.0}])
end

it "not found" do
source_id = "xxx"
response = Event.query(nil, source_id: source_id)
Expand Down
22 changes: 13 additions & 9 deletions spec/models/funder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
it "found" do
id = "https://doi.org/10.13039/100011326"
funders = Funder.find_by_id(id)
expect(funders.size).to eq(1)
expect(funders.first).to eq(id: "https://doi.org/10.13039/100011326", name: "London School of Economics and Political Science", alternate_name: ["London School of Economics & Political Science", "LSE"], date_modified: "2019-04-18T00:00:00Z")
expect(funders[:data].size).to eq(1)
expect(funders[:data].first).to eq(id: "https://doi.org/10.13039/100011326", name: "London School of Economics and Political Science", alternate_name: ["London School of Economics & Political Science", "LSE"], date_modified: "2019-04-18T00:00:00Z")
end

it "not found" do
Expand All @@ -20,28 +20,32 @@
it "all" do
query = nil
funders = Funder.query(query)
expect(funders.size).to eq(100)
expect(funders.first).to eq(id: "https://doi.org/10.13039/100002569", name: "American Association of Endodontists Foundation", alternate_name: ["AAE Foundation for Endodontics", "AAE Foundation", "Foundation for Endodontics", "AAEF"], country: "United States", date_modified: "2019-04-18T00:00:00Z")
expect(funders.dig(:meta, "total")).to eq(19662)
expect(funders[:data].size).to eq(100)
expect(funders[:data].first).to eq(id: "https://doi.org/10.13039/100002569", name: "American Association of Endodontists Foundation", alternate_name: ["AAE Foundation for Endodontics", "AAE Foundation", "Foundation for Endodontics", "AAEF"], country: "United States", date_modified: "2019-04-18T00:00:00Z")
end

it "limit" do
query = nil
funders = Funder.query(query, limit: 10)
expect(funders.size).to eq(10)
expect(funders.first).to eq(id: "https://doi.org/10.13039/100002569", name: "American Association of Endodontists Foundation", alternate_name: ["AAE Foundation for Endodontics", "AAE Foundation", "Foundation for Endodontics", "AAEF"], country: "United States", date_modified: "2019-04-18T00:00:00Z")
expect(funders.dig(:meta, "total")).to eq(19662)
expect(funders[:data].size).to eq(10)
expect(funders[:data].first).to eq(id: "https://doi.org/10.13039/100002569", name: "American Association of Endodontists Foundation", alternate_name: ["AAE Foundation for Endodontics", "AAE Foundation", "Foundation for Endodontics", "AAEF"], country: "United States", date_modified: "2019-04-18T00:00:00Z")
end

it "found" do
query = "dfg"
funders = Funder.query(query)
expect(funders.size).to eq(3)
expect(funders.first).to eq(id: "https://doi.org/10.13039/501100001659", name: "Deutsche Forschungsgemeinschaft", alternate_name: ["DFG", "German Research Association", "German Research Foundation"], date_modified: "2019-04-18T00:00:00Z")
expect(funders.dig(:meta, "total")).to eq(3)
expect(funders[:data].size).to eq(3)
expect(funders[:data].first).to eq(id: "https://doi.org/10.13039/501100001659", name: "Deutsche Forschungsgemeinschaft", alternate_name: ["DFG", "German Research Association", "German Research Foundation"], date_modified: "2019-04-18T00:00:00Z")
end

it "not found" do
query = "xxx"
funders = Funder.query(query)
expect(funders).to be_empty
expect(funders[:data]).to be_empty
expect(funders[:errors]).to be_nil
end
end
end

0 comments on commit 4f6d5d6

Please sign in to comment.