Skip to content

Commit

Permalink
repository model based on re3data api. #292
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Fenner committed Jun 16, 2019
1 parent 7f82fef commit 0902acb
Show file tree
Hide file tree
Showing 7 changed files with 377 additions and 0 deletions.
70 changes: 70 additions & 0 deletions app/models/repository.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
class Repository
def self.find_by_id(id)
doi = doi_from_url(id)
return {} unless doi.present?

url = "https://api.datacite.org/repositories/#{doi}"
response = Maremma.get(url, host: true)

return {} if response.status != 200 || response.body.dig("data", "id") != doi.upcase

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

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

{ data: data, errors: errors }
end

def self.query(query, options={})
# rows = options[:limit] || 25

if query.present?
url = "https://api.datacite.org/repositories?query=#{query}"
else
url = "https://api.datacite.org/repositories"
end

response = Maremma.get(url, host: true)

return [] if response.status != 200

data = Array.wrap(response.body.fetch("data", nil)).map do |message|
parse_message(id: doi_as_url(message["id"]), message: message["attributes"])
end
meta = { "total" => response.body.dig("meta", "total") }
errors = response.body.fetch("errors", nil)

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

def self.parse_message(id: nil, message: nil)
{
id: id,
re3data_id: message["re3dataId"],
name: message["repositoryName"],
url: message["repositoryUrl"],
contacts: message["repositoryContacts"],
description: message["description"],
certificates: message["certificates"],
types: message["types"],
additional_names: message["additionalNames"],
subjects: message["subjects"],
content_types: message["contentTypes"],
provider_types: message["providerTypes"],
keywords: message["keywords"] }.compact
end

def self.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

def self.doi_as_url(doi)
return nil unless doi.present?

"https://doi.org/#{doi.downcase}"
end
end
47 changes: 47 additions & 0 deletions spec/fixtures/vcr_cassettes/Repository/find_by_id/found.yml

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

62 changes: 62 additions & 0 deletions spec/fixtures/vcr_cassettes/Repository/find_by_id/not_found.yml

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

47 changes: 47 additions & 0 deletions spec/fixtures/vcr_cassettes/Repository/query/all.yml

Large diffs are not rendered by default.

47 changes: 47 additions & 0 deletions spec/fixtures/vcr_cassettes/Repository/query/found.yml

Large diffs are not rendered by default.

46 changes: 46 additions & 0 deletions spec/fixtures/vcr_cassettes/Repository/query/not_found.yml

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

58 changes: 58 additions & 0 deletions spec/models/repository_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
require 'rails_helper'

describe Repository, type: :model, vcr: true do
describe "find_by_id" do
it "found" do
id = "https://doi.org/10.17616/r3qp53"
repositories = Repository.find_by_id(id)
expect(repositories[:data].size).to eq(1)
repository = repositories[:data].first
expect(repository[:id]).to eq("https://doi.org/10.17616/r3qp53")
expect(repository[:re3data_id]).to eq("r3d100010468")
expect(repository[:name]).to eq("Zenodo")
expect(repository[:url]).to eq("https://zenodo.org/")
expect(repository[:certificates]).to eq([])
end

it "not found" do
id = "https://doi.org/10.17616/xxxxx"
repositories = Repository.find_by_id(id)
expect(repositories[:data]).to be_nil
expect(repositories[:errors]).to be_nil
end
end

describe "query" do
it "all" do
query = nil
repositories = Repository.query(query)
expect(repositories.dig(:meta, "total")).to eq(1562)
expect(repositories[:data].size).to eq(25)
repository = repositories[:data].first
expect(repository[:id]).to eq("https://doi.org/10.17616/r3w05r")
expect(repository[:re3data_id]).to eq("r3d100011565")
expect(repository[:name]).to eq("1000 Functional Connectomes Project")
expect(repository[:url]).to eq("http://fcon_1000.projects.nitrc.org/fcpClassic/FcpTable.html")
expect(repository[:certificates]).to eq([])
end

it "found" do
query = "climate"
repositories = Repository.query(query)
expect(repositories.dig(:meta, "total")).to eq(167)
expect(repositories[:data].size).to eq(25)
repository = repositories[:data].first
expect(repository[:id]).to eq("https://doi.org/10.17616/r3qd26")
expect(repository[:re3data_id]).to eq("r3d100011691")
expect(repository[:name]).to eq("ACTRIS Data Centre")
expect(repository[:url]).to eq("http://actris.nilu.no/")
expect(repository[:certificates]).to eq([])
end

it "not found" do
query = "xxx"
repositories = Repository.query(query)
expect(repositories[:data]).to be_empty
end
end
end

0 comments on commit 0902acb

Please sign in to comment.