orcid 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 148909130b9d10ade4c7e2e6b32d07321dcac06f
4
- data.tar.gz: 0fb6c0784ef0a0000bda7e737fe7604519c7afe3
3
+ metadata.gz: a6c934af18b7c7e4406bd1b4205e71dc44377838
4
+ data.tar.gz: c9c4b765a0ba649e91e1c79d6891158622c770ef
5
5
  SHA512:
6
- metadata.gz: 7d8b914e980f40cb79f6d19942c56ba5f3a5d27330b05d3ef3cb3b3f2c809b829e5c566803b1b5ac1b5025a52da4163e1ee495c232142e2ee1a63fa69575d34c
7
- data.tar.gz: 9bc94eba6a209de41c0fefa4719d511eb9528ff9c2fc02882bb3be065a0e80a1af06cef5d4afc7f2a23b77a731e76ce4460652536dd4eae7c9c2ebde71db0cd6
6
+ metadata.gz: c614efa5c8b7290fe4faf5ce20ed9f87a622dba3b2d54579c207aee34489985a2169c1d1e888217ded354d685842bb97512ddf621a008e6ddc824be82f9413c2
7
+ data.tar.gz: e95c8d1d8911a135eb334267b9796b9290a04af92a3ce96f3942af55df208c3ce1f6bf333d642872e39a4962cb8f28148547a664ff3b039d7b3cf7051f4578a0
data/README.md CHANGED
@@ -1,7 +1,18 @@
1
- # Orcid
1
+ # Orcid [![Version](https://badge.fury.io/rb/orcid.png)](http://badge.fury.io/rb/orcid) [![Build Status](https://travis-ci.org/jeremyf/orcid.png?branch=master)](https://travis-ci.org/jeremyf/orcid)
2
+
2
3
 
3
4
  A Rails Engine for integrating with Orcid
4
5
 
5
- ## TODO
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'orcid'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ And then install:
6
17
 
7
- * Create a generator for installing configuration options into your Rails application.
18
+ $ rails generate orcid:install
data/Rakefile CHANGED
@@ -6,11 +6,21 @@ end
6
6
 
7
7
  Bundler::GemHelper.install_tasks
8
8
 
9
- require 'engine_cart/rake_task'
10
9
 
10
+ begin
11
+ APP_RAKEFILE = File.expand_path("../spec/internal/Rakefile", __FILE__)
12
+ load 'rails/tasks/engine.rake'
13
+ rescue LoadError
14
+ puts "Unable to load all app tasks for #{APP_RAKEFILE}"
15
+ end
16
+
17
+ require 'engine_cart/rake_task'
11
18
  require 'rspec/core/rake_task'
12
19
 
13
20
  namespace :spec do
21
+ RSpec::Core::RakeTask.new(:all) do |t|
22
+ ENV['COVERAGE'] = 'true'
23
+ end
14
24
  desc 'Only run specs that do not require net connect'
15
25
  RSpec::Core::RakeTask.new(:offline) do |t|
16
26
  t.rspec_opts = "--tag ~requires_net_connect"
@@ -34,3 +44,4 @@ Rake::Task["default"].clear rescue nil
34
44
  Rake::Task["spec"].clear
35
45
 
36
46
  task :spec => 'spec:offline'
47
+ task :default => :spec
@@ -5,8 +5,8 @@ module Orcid
5
5
  private :mapper
6
6
  def initialize(orcid_profile_id, config = {})
7
7
  @orcid_profile_id = orcid_profile_id
8
- @mapper = config.fetch(:mapper) { ::Mappy }
9
- @remote_service = config.fetch(:remote_service) { Orcid::RemoteWorkService }
8
+ @mapper = config.fetch(:mapper) { Orcid.mapper }
9
+ @remote_service = config.fetch(:remote_service) { Orcid::Remote::WorkService }
10
10
  @xml_renderer = config.fetch(:xml_renderer) { Orcid::Work::XmlRenderer }
11
11
  @xml_parser = config.fetch(:xml_parser) { Orcid::Work::XmlParser }
12
12
  end
@@ -12,29 +12,44 @@ module Orcid
12
12
  validates :user, presence: true
13
13
  validates :orcid_profile_id, presence: true
14
14
 
15
- def persisted?; false; end
16
15
 
17
16
  def save(config = {})
18
17
  persister = config.fetch(:persister) { Orcid.method(:connect_user_and_orcid_profile) }
19
18
  valid? ? persister.call(user, orcid_profile_id) : false
20
19
  end
21
20
 
21
+ def persisted?; false; end
22
+
23
+ attr_writer :profile_lookup_service
24
+ def profile_lookup_service
25
+ @profile_lookup_service ||= default_profile_lookup_service
26
+ end
27
+ private :profile_lookup_service
28
+
29
+ def default_profile_lookup_service
30
+ ProfileLookupRunner.new {|on|
31
+ on.found {|results| self.orcid_profile_candidates = results }
32
+ on.not_found { self.orcid_profile_candidates = [] }
33
+ }
34
+ end
35
+ private :default_profile_lookup_service
36
+
22
37
  def with_orcid_profile_candidates
23
- if query_for_orcid_profile_candidates?
24
- yield(orcid_profile_candidates)
25
- end
38
+ yield(orcid_profile_candidates) if email.present?
26
39
  end
27
- attr_writer :orcid_profile_querier
28
- protected
40
+
41
+ attr_writer :orcid_profile_candidates
42
+ private :orcid_profile_candidates=
29
43
  def orcid_profile_candidates
30
- @orcid_profile_candidates ||= orcid_profile_querier.call({q: "email:#{email}"})
31
- end
32
- def query_for_orcid_profile_candidates?
33
- email.present?
44
+ @orcid_profile_candidates || lookup_profile_candidates
34
45
  end
35
46
 
36
- def orcid_profile_querier
37
- @orcid_profile_querier ||= ProfileLookupService
47
+ def lookup_profile_candidates
48
+ if email.present?
49
+ profile_lookup_service.call(email: email)
50
+ end
38
51
  end
52
+ private :lookup_profile_candidates
53
+
39
54
  end
40
55
  end
@@ -11,6 +11,7 @@ module Orcid
11
11
 
12
12
  self.table_name = :orcid_profile_requests
13
13
 
14
+ alias_attribute :email, :primary_email
14
15
  validates :user_id, presence: true, uniqueness: true
15
16
  validates :given_names, presence: true
16
17
  validates :family_name, presence: true
@@ -21,15 +22,18 @@ module Orcid
21
22
  def run(options = {})
22
23
  # Why dependency injection? Because this is going to be a plugin, and things
23
24
  # can't possibly be simple.
24
- before_run_validator = options.fetch(:before_run_validator) { method(:validate_before_run) }
25
- return false unless before_run_validator.call(self)
25
+ validator = options.fetch(:validator) { method(:validate_before_run) }
26
+ return false unless validator.call(self)
26
27
 
27
28
  payload_xml_builder = options.fetch(:payload_xml_builder) { method(:xml_payload) }
28
- profile_creation_service = options.fetch(:profile_creation_service) { Orcid::ProfileCreationService }
29
- profile_creation_responder = options.fetch(:profile_creation_responder) { method(:handle_profile_creation_response) }
29
+ profile_creation_service = options.fetch(:profile_creation_service) { default_profile_creation_service }
30
+ profile_creation_service.call(payload_xml_builder.call(attributes))
31
+ end
30
32
 
31
- orcid_profile_id = profile_creation_service.call(payload_xml_builder.call(attributes))
32
- profile_creation_responder.call(orcid_profile_id)
33
+ def default_profile_creation_service
34
+ @default_profile_creation_service ||= Orcid::Remote::ProfileCreationService.new do |on|
35
+ on.success {|orcid_profile_id| handle_profile_creation_response(orcid_profile_id) }
36
+ end
33
37
  end
34
38
 
35
39
  def validate_before_run(context = self)
@@ -0,0 +1,29 @@
1
+ require_dependency './app/runners/orcid/runner'
2
+ module Orcid
3
+ class ProfileLookupRunner < Runner
4
+
5
+ def initialize(config = {}, &block)
6
+ super(&block)
7
+ @query_service = config.fetch(:query_service) { Remote::ProfileLookupService }
8
+ end
9
+ attr_reader :query_service
10
+ private :query_service
11
+
12
+ def call(parameters)
13
+ email = parameters.fetch(:email)
14
+ response = query_service.call({q: "email:#{email}"})
15
+ handle(response)
16
+ end
17
+
18
+ private
19
+ def handle(response)
20
+ if response.any?
21
+ callback(:found, response)
22
+ else
23
+ callback(:not_found)
24
+ end
25
+ response
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ require_dependency './lib/orcid/named_callbacks'
2
+ module Orcid
3
+ class Runner
4
+ def initialize
5
+ @callbacks = NamedCallbacks.new
6
+ yield(@callbacks) if block_given?
7
+ end
8
+
9
+ def callback(name, *args)
10
+ @callbacks.call(name, *args)
11
+ args
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ module Orcid
2
+ module Remote
3
+ end
4
+ end
@@ -1,13 +1,15 @@
1
- # Responsible for minting a new ORCID for the given payload.
2
- module Orcid
3
- class ProfileCreationService
1
+ require_dependency './app/services/orcid/remote/service'
2
+ module Orcid::Remote
3
+ # Responsible for minting a new ORCID for the given payload.
4
+ class ProfileCreationService < Orcid::Remote::Service
4
5
 
5
- def self.call(payload, config = {})
6
- new(config).call(payload)
6
+ def self.call(payload, config = {}, &callback_config)
7
+ new(config, &callback_config).call(payload)
7
8
  end
8
9
 
9
10
  attr_reader :token, :path, :headers
10
- def initialize(config = {})
11
+ def initialize(config = {}, &callback_config)
12
+ super(&callback_config)
11
13
  @token = config.fetch(:token) { Orcid.client_credentials_token('/orcid-profile/create') }
12
14
  @path = config.fetch(:path) { "v1.1/orcid-profile" }
13
15
  @headers = config.fetch(:headers) { default_headers }
@@ -25,7 +27,13 @@ module Orcid
25
27
 
26
28
  def parse(response)
27
29
  uri = URI.parse(response.headers.fetch(:location))
28
- uri.path.sub(/\A\//, "").split("/").first
30
+ if orcid_profile_id = uri.path.sub(/\A\//, "").split("/").first
31
+ callback(:success, orcid_profile_id)
32
+ orcid_profile_id
33
+ else
34
+ callback(:failure)
35
+ false
36
+ end
29
37
  end
30
38
 
31
39
  def default_headers
@@ -1,18 +1,6 @@
1
- module Orcid
1
+ require_dependency 'json'
2
+ module Orcid::Remote
2
3
  class ProfileLookupService
3
- class SearchResponse
4
- delegate :fetch, :has_key?, :[], to: :@attributes
5
- def initialize(attributes = {})
6
- @attributes = attributes.with_indifferent_access
7
- end
8
- def id
9
- @attributes.fetch(:id)
10
- end
11
-
12
- def label
13
- @attributes.fetch(:label)
14
- end
15
- end
16
4
 
17
5
  def self.call(query, config = {})
18
6
  new(config).call(query)
@@ -54,7 +42,7 @@ module Orcid
54
42
  family_name = orcid_bio.fetch('personal-details').fetch('family-name').fetch('value')
55
43
  emails = orcid_bio.fetch('contact-details').fetch('email').collect {|email| email.fetch('value') }
56
44
  label = "#{given_names} #{family_name}"
57
- label << " (" << emails.join(",") << ")" if emails.present?
45
+ label << " (" << emails.join(",") << ")" if emails.any?
58
46
  label << " [ORCID: #{identifier}]"
59
47
 
60
48
  returning_value << response_builder.new("id" => identifier, "label" => label)
@@ -0,0 +1,23 @@
1
+
2
+ module Orcid::Remote
3
+ class ProfileLookupService
4
+ class SearchResponse
5
+ delegate :[], :has_key?, :fetch, to: :@records
6
+ def initialize(attributes = {})
7
+ @attributes = attributes.with_indifferent_access
8
+ end
9
+
10
+ def id
11
+ @attributes.fetch(:id)
12
+ end
13
+
14
+ def orcid_profile_id
15
+ @attributes.fetch(:id)
16
+ end
17
+
18
+ def label
19
+ @attributes.fetch(:label)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ require_dependency './lib/orcid/named_callbacks'
2
+ module Orcid::Remote
3
+ class Service
4
+ def initialize
5
+ @callbacks = Orcid::NamedCallbacks.new
6
+ yield(@callbacks) if block_given?
7
+ end
8
+
9
+ def call
10
+ raise NotImplementedError.new("Define #{self.class}#call")
11
+ end
12
+
13
+ def callback(name, *args)
14
+ @callbacks.call(name, *args)
15
+ args
16
+ end
17
+
18
+ end
19
+ end
@@ -1,5 +1,6 @@
1
- module Orcid
2
- class RemoteWorkService
1
+ require_dependency './lib/orcid/exceptions'
2
+ module Orcid::Remote
3
+ class WorkService
3
4
  def self.call(orcid_profile_id, options = {})
4
5
  new(orcid_profile_id, options).call
5
6
  end
@@ -27,7 +28,7 @@ module Orcid
27
28
  def deliver
28
29
  token.request(request_method, path, body: body, headers: headers)
29
30
  rescue OAuth2::Error => e
30
- raise RemoteServiceError.new(
31
+ raise Orcid::RemoteServiceError.new(
31
32
  response_body: e.response.body,
32
33
  response_status: e.response.status,
33
34
  client: token.client,
@@ -0,0 +1,47 @@
1
+ require 'rails/generators'
2
+
3
+ module Orcid
4
+ class InstallGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ class_option :devise, default: false, type: :boolean
8
+
9
+ def install_devise_multi_auth
10
+ if options[:devise]
11
+ generate 'devise:multi_auth:install --install_devise'
12
+ else
13
+ generate 'devise:multi_auth:install'
14
+ end
15
+ end
16
+
17
+ def install_migrations
18
+ rake "orcid:install:migrations"
19
+ end
20
+
21
+ def install_omniauth_strategies
22
+ config_code = ", :omniauthable, :omniauth_providers => [:orcid]"
23
+ insert_into_file 'app/models/user.rb', config_code, { :after => /:validatable/, :verbose => false }
24
+
25
+ init_code = %(
26
+ config.omniauth(:orcid, Orcid.provider.id, Orcid.provider.secret,
27
+ scope: Orcid.provider.authentication_scope,
28
+ client_options: {
29
+ site: Orcid.provider.site_url,
30
+ authorize_url: Orcid.provider.authorize_url,
31
+ token_url: Orcid.provider.token_url
32
+ }
33
+ )
34
+ )
35
+ insert_into_file 'config/initializers/devise.rb', init_code, {after: /Devise\.setup.*$/, verbose: true}
36
+ end
37
+
38
+ def mount_orcid_engine
39
+ route 'mount Orcid::Engine => "/orcid"'
40
+ end
41
+
42
+ def install_initializer
43
+ template 'orcid_initializer.rb.erb', 'config/orcid_initializer.rb'
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,18 @@
1
+ Orcid.configure do |config|
2
+ # # Configure your Orcid Client Application. See URL below for more
3
+ # # information
4
+ # # http://support.orcid.org/knowledgebase/articles/116739-register-a-client-application
5
+ # config.provider.id = "Your app's Orcid Client ID"
6
+ # config.provider.secret = "Your app's Orcid Client Secret"
7
+
8
+
9
+ # # Configure how your applications models will be mapped to an Orcid Work so
10
+ # # that your application can append the work to an Orcid Profile.
11
+ # config.register_mapping_to_orcid_work(
12
+ # :article,
13
+ # [
14
+ # [:title, :title],
15
+ # [lambda{|article| article.publishers.join("; ")}, :publishers]
16
+ # ]
17
+ # )
18
+ end
data/lib/orcid.rb CHANGED
@@ -12,40 +12,42 @@ require 'simple_form'
12
12
  module Orcid
13
13
 
14
14
  class << self
15
- attr_accessor :configuration
15
+ attr_writer :configuration
16
+
17
+ def configuration
18
+ @configuration ||= Configuration.new
19
+ end
16
20
  end
17
21
 
18
22
  module_function
19
23
  def configure
20
- self.configuration ||= Configuration.new
21
24
  yield(configuration)
22
25
  end
23
26
 
24
- def provider
25
- @provider ||= Configuration::Provider.new
27
+ def mapper
28
+ configuration.mapper
26
29
  end
27
30
 
28
- def provider_name
29
- configuration.provider_name
31
+ def provider
32
+ configuration.provider
30
33
  end
31
34
 
32
35
  def authentication_model
33
36
  configuration.authentication_model
34
37
  end
35
38
 
36
-
37
39
  def connect_user_and_orcid_profile(user, orcid_profile_id, options = {})
38
- authentication_model.create!(provider: provider_name, uid: orcid_profile_id, user: user)
40
+ authentication_model.create!(provider: 'orcid', uid: orcid_profile_id, user: user)
39
41
  end
40
42
 
41
43
  def access_token_for(orcid_profile_id, options = {})
42
44
  client = options.fetch(:client) { oauth_client }
43
45
  tokenizer = options.fetch(:tokenizer) { authentication_model }
44
- tokenizer.to_access_token(uid: orcid_profile_id, provider: provider_name, client: client)
46
+ tokenizer.to_access_token(uid: orcid_profile_id, provider: 'orcid', client: client)
45
47
  end
46
48
 
47
49
  def profile_for(user)
48
- if auth = authentication_model.where(provider: provider_name, user: user).first
50
+ if auth = authentication_model.where(provider: 'orcid', user: user).first
49
51
  Orcid::Profile.new(auth.uid)
50
52
  else
51
53
  nil
@@ -60,7 +62,7 @@ module Orcid
60
62
  # passing the site: option as Orcid's Sandbox has an invalid certificate
61
63
  # for the api.sandbox-1.orcid.org
62
64
  @oauth_client ||= Devise::MultiAuth.oauth_client_for(
63
- provider_name, options: { site: provider.site_url }
65
+ 'orcid', options: { site: provider.site_url }
64
66
  )
65
67
  end
66
68
 
@@ -1,20 +1,23 @@
1
1
  module Orcid
2
2
  class Configuration
3
- attr_reader :store
4
- def initialize(store = ::ENV)
5
- @store = store
3
+ attr_reader :mapper
4
+ def initialize(options = {})
5
+ @mapper = options.fetch(:mapper) { ::Mappy }
6
+ @provider = Configuration::Provider.new
6
7
  end
7
8
 
8
- attr_writer :provider_name
9
- def provider_name
10
- @provider_name ||= 'orcid'
11
- end
9
+ attr_reader :provider
12
10
 
13
11
  attr_writer :authentication_model
14
12
  def authentication_model
15
13
  @authentication_model ||= Devise::MultiAuth::Authentication
16
14
  end
17
15
 
16
+ def register_mapping_to_orcid_work(source_type, legend)
17
+ mapper.configure do |config|
18
+ config.register(source: source_type, target: 'orcid/work', legend: legend)
19
+ end
20
+ end
18
21
  end
19
22
  end
20
23
  require 'orcid/configuration/provider'
@@ -1,45 +1,51 @@
1
1
  module Orcid
2
- class Configuration::Provider
3
- attr_reader :store
4
- def initialize(store = ::ENV)
5
- @store = store
6
- end
2
+ class Configuration
3
+ class Provider
4
+ attr_reader :store
5
+ def initialize(store = ::ENV)
6
+ @store = store
7
+ end
7
8
 
8
- attr_writer :authentication_scope
9
- def authentication_scope
10
- @authentication_scope ||= store.fetch('ORCID_APP_AUTHENTICATION_SCOPE') {
11
- "/authenticate,/orcid-works/create,/orcid-works/update,/read-public,/orcid-grants/create"
12
- }
13
- end
9
+ attr_writer :authentication_scope
10
+ def authentication_scope
11
+ @authentication_scope ||= store.fetch('ORCID_APP_AUTHENTICATION_SCOPE') {
12
+ "/authenticate,/orcid-works/create,/orcid-works/update,/read-public"
13
+ }
14
+ end
14
15
 
15
- attr_writer :site_url
16
- def site_url
17
- @site_url ||= store.fetch('ORCID_SITE_URL') { "http://api.sandbox-1.orcid.org" }
18
- end
16
+ attr_writer :site_url
17
+ def site_url
18
+ @site_url ||= store.fetch('ORCID_SITE_URL') { "http://api.sandbox-1.orcid.org" }
19
+ end
19
20
 
20
- attr_writer :token_url
21
- def token_url
22
- @token_url ||= store.fetch('ORCID_TOKEN_URL') { "https://api.sandbox-1.orcid.org/oauth/token" }
23
- end
21
+ attr_writer :token_url
22
+ def token_url
23
+ @token_url ||= store.fetch('ORCID_TOKEN_URL') { "https://api.sandbox-1.orcid.org/oauth/token" }
24
+ end
24
25
 
25
- attr_writer :signin_via_json_url
26
- def signin_via_json_url
27
- @signin_via_json_url ||= store.fetch('ORCID_REMOTE_SIGNIN_URL') { "https://sandbox-1.orcid.org/signin/auth.json" }
28
- end
26
+ attr_writer :signin_via_json_url
27
+ def signin_via_json_url
28
+ @signin_via_json_url ||= store.fetch('ORCID_REMOTE_SIGNIN_URL') { "https://sandbox-1.orcid.org/signin/auth.json" }
29
+ end
29
30
 
30
- attr_writer :authorize_url
31
- def authorize_url
32
- @authorize_url ||= store.fetch('ORCID_AUTHORIZE_URL') { "https://sandbox-1.orcid.org/oauth/authorize" }
33
- end
31
+ attr_writer :authorize_url
32
+ def authorize_url
33
+ @authorize_url ||= store.fetch('ORCID_AUTHORIZE_URL') { "https://sandbox-1.orcid.org/oauth/authorize" }
34
+ end
34
35
 
35
- attr_writer :id
36
- def id
37
- @id ||= store.fetch('ORCID_APP_ID')
38
- end
36
+ attr_writer :id
37
+ def id
38
+ @id ||= store.fetch('ORCID_APP_ID') {
39
+ Rails.logger.error('Set your Orcid.provider.id')
40
+ }
41
+ end
39
42
 
40
- attr_writer :secret
41
- def secret
42
- @secret ||= store.fetch('ORCID_APP_SECRET')
43
+ attr_writer :secret
44
+ def secret
45
+ @secret ||= store.fetch('ORCID_APP_SECRET') {
46
+ Rails.logger.error('Set your Orcid.provider.secret')
47
+ }
48
+ end
43
49
  end
44
50
  end
45
51
  end
data/lib/orcid/engine.rb CHANGED
@@ -4,16 +4,12 @@ module Orcid
4
4
 
5
5
  initializer 'orcid.initializers' do |app|
6
6
  app.config.paths.add 'app/services', eager_load: true
7
+ app.config.paths.add 'app/runners', eager_load: true
7
8
  app.config.autoload_paths += %W(
8
9
  #{config.root}/app/services
10
+ #{config.root}/app/runners
9
11
  )
10
12
  end
11
13
 
12
- config.before_initialize do |app|
13
- Orcid.configure do |config|
14
- config.provider_name = 'orcid'
15
- end
16
- end
17
-
18
14
  end
19
15
  end
@@ -9,6 +9,9 @@ module Orcid
9
9
  text << "id:\n\t#{client.id.inspect}"
10
10
  text << "site:\n\t#{client.site.inspect}"
11
11
  text << "options:\n\t#{client.options.inspect}"
12
+ if defined?(Orcid.provider)
13
+ text << "scopes:\n\t#{Orcid.provider.authentication_scope}"
14
+ end
12
15
  end
13
16
  text << "\n-- Token --"
14
17
  if token = options[:token]
@@ -0,0 +1,19 @@
1
+ module Orcid
2
+ # Inspired by Jim Weirich's NamedCallbacks
3
+ # https://github.com/jimweirich/wyriki/blob/master/spec/runners/named_callbacks_spec.rb#L1-L28
4
+ class NamedCallbacks
5
+ def initialize
6
+ @callbacks = {}
7
+ end
8
+
9
+ def method_missing(callback_name, *args, &block)
10
+ @callbacks[callback_name] = block
11
+ end
12
+
13
+ def call(callback_name, *args)
14
+ name = callback_name.to_sym
15
+ cb = @callbacks[name]
16
+ cb ? cb.call(*args) : true
17
+ end
18
+ end
19
+ end
data/lib/orcid/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Orcid
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -1,4 +1,111 @@
1
- # desc "Explaining what the task does"
2
- # task :orcid do
3
- # # Task goes here
4
- # end
1
+ namespace :orcid do
2
+ namespace :batch do
3
+ desc 'Given the input: CSV query for existing Orcids and report to output: CSV'
4
+ task :query => [:environment, :init, :query_runner, :run]
5
+
6
+ task :query_runner do
7
+ @runner = lambda { |person|
8
+ puts "Processing: #{person.email}"
9
+ Orcid::ProfileLookupRunner.new {|on|
10
+ on.found {|results|
11
+ person.found(results)
12
+ puts "\tfound" if verbose
13
+ }
14
+ on.not_found {
15
+ person.not_found
16
+ puts "\tnot found" if verbose
17
+ }
18
+ }.call(email: person.email)
19
+ }
20
+ end
21
+
22
+ desc "Given the input: CSV query for existing Orcids and if not found create new ones recording output: CSV"
23
+ task :create => [:environment, :init, :create_runner, :run]
24
+
25
+ task :create_runner do
26
+ @creation_service = lambda {|person|
27
+ puts "Creating Profile for: #{person.email}"
28
+ profile_creation_service = Orcid::Remote::ProfileCreationService.new do |on|
29
+ on.success {|orcid_profile_id|
30
+ person.orcid_profile_id = orcid_profile_id
31
+ puts "\tcreated #{orcid_profile_id}" if verbose
32
+ }
33
+ end
34
+ profile_request = Orcid::ProfileRequest.new(person.attributes)
35
+ profile_request.run(
36
+ validator: lambda{|*| true},
37
+ profile_creation_service: profile_creation_service
38
+ )
39
+ }
40
+ @runner = lambda { |person|
41
+ puts "Processing: #{person.email}"
42
+ Orcid::ProfileLookupRunner.new {|on|
43
+ on.found {|results|
44
+ person.found(results)
45
+ puts "\tfound" if verbose
46
+ }
47
+ on.not_found {
48
+ person.not_found
49
+ puts "\tnot found" if verbose
50
+ @creation_service.call(person)
51
+ }
52
+ }.call(email: person.email)
53
+ }
54
+ end
55
+
56
+
57
+ task :run do
58
+ if defined?(WebMock)
59
+ WebMock.allow_net_connect!
60
+ end
61
+ input_file = ENV.fetch('input') { './tmp/orcid_input.csv' }
62
+ output_file = ENV.fetch('output') { './tmp/orcid_output.csv' }
63
+
64
+ require 'csv'
65
+ CSV.open(output_file, 'wb+') do |output|
66
+ output << @person_builder.to_header_row
67
+ CSV.foreach(input_file, headers: true, header_converters: [lambda{|col| col.strip }]) do |input|
68
+ person = @person_builder.new(input.to_hash)
69
+ @runner.call(person)
70
+ output << person.to_output_row
71
+ end
72
+ end
73
+ end
74
+
75
+ task :init do
76
+ module Orcid::Batch
77
+ class PersonRecord
78
+ def self.to_header_row
79
+ ['email', 'given_names', 'family_name', 'existing_orcids', 'created_orcid', 'queried_at']
80
+ end
81
+ attr_reader :email, :given_names, :family_name, :existing_orcids
82
+ attr_accessor :created_orcid
83
+ def initialize(row)
84
+ @email = row.fetch('email')
85
+ @given_names = row['given_names']
86
+ @family_name = row['family_name']
87
+ @existing_orcids = nil
88
+ end
89
+
90
+ def attributes
91
+ { email: email, given_names: given_names, family_name: family_name }
92
+ end
93
+
94
+ def found(existing_orcids)
95
+ @existing_orcids = Array(existing_orcids).collect(&:orcid_profile_id).join("; ")
96
+ end
97
+
98
+ def to_output_row
99
+ [email, given_names, family_name, existing_orcids, created_orcid, Time.now]
100
+ end
101
+
102
+ def not_found
103
+ @existing_orcids = 'null'
104
+ end
105
+
106
+ end
107
+ end
108
+ @person_builder = Orcid::Batch::PersonRecord
109
+ end
110
+ end
111
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orcid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Friesen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-21 00:00:00.000000000 Z
11
+ date: 2014-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -262,6 +262,20 @@ dependencies:
262
262
  - - '>='
263
263
  - !ruby/object:Gem::Version
264
264
  version: '0'
265
+ - !ruby/object:Gem::Dependency
266
+ name: simplecov
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - '>='
270
+ - !ruby/object:Gem::Version
271
+ version: '0'
272
+ type: :development
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - '>='
277
+ - !ruby/object:Gem::Version
278
+ version: '0'
265
279
  - !ruby/object:Gem::Dependency
266
280
  name: rest_client
267
281
  requirement: !ruby/object:Gem::Requirement
@@ -276,6 +290,20 @@ dependencies:
276
290
  - - '>='
277
291
  - !ruby/object:Gem::Version
278
292
  version: '0'
293
+ - !ruby/object:Gem::Dependency
294
+ name: rspec-given
295
+ requirement: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - '>='
298
+ - !ruby/object:Gem::Version
299
+ version: '0'
300
+ type: :development
301
+ prerelease: false
302
+ version_requirements: !ruby/object:Gem::Requirement
303
+ requirements:
304
+ - - '>='
305
+ - !ruby/object:Gem::Version
306
+ version: '0'
279
307
  description: A Rails engine for orcid.org integration.
280
308
  email:
281
309
  - jeremy.n.friesen@gmail.com
@@ -289,14 +317,18 @@ files:
289
317
  - app/controllers/orcid/profile_connections_controller.rb
290
318
  - app/controllers/orcid/profile_requests_controller.rb
291
319
  - app/helpers/orcid/application_helper.rb
292
- - app/models/orcid/configuration.rb
293
320
  - app/models/orcid/profile.rb
294
321
  - app/models/orcid/profile_connection.rb
295
322
  - app/models/orcid/profile_request.rb
296
323
  - app/models/orcid/work.rb
297
- - app/services/orcid/profile_creation_service.rb
298
- - app/services/orcid/profile_lookup_service.rb
299
- - app/services/orcid/remote_work_service.rb
324
+ - app/runners/orcid/profile_lookup_runner.rb
325
+ - app/runners/orcid/runner.rb
326
+ - app/services/orcid/remote/profile_creation_service.rb
327
+ - app/services/orcid/remote/profile_lookup_service/search_response.rb
328
+ - app/services/orcid/remote/profile_lookup_service.rb
329
+ - app/services/orcid/remote/service.rb
330
+ - app/services/orcid/remote/work_service.rb
331
+ - app/services/orcid/remote.rb
300
332
  - app/templates/orcid/work.template.v1.1.xml.erb
301
333
  - app/views/layouts/orcid/application.html.erb
302
334
  - app/views/orcid/profile_connections/new.html.erb
@@ -305,10 +337,13 @@ files:
305
337
  - config/locales/orcid.en.yml
306
338
  - config/routes.rb
307
339
  - db/migrate/20140205185338_create_orcid_profile_requests.rb
340
+ - lib/generators/orcid/install/install_generator.rb
341
+ - lib/generators/orcid/install/templates/orcid_initializer.rb.erb
308
342
  - lib/orcid/configuration/provider.rb
309
343
  - lib/orcid/configuration.rb
310
344
  - lib/orcid/engine.rb
311
345
  - lib/orcid/exceptions.rb
346
+ - lib/orcid/named_callbacks.rb
312
347
  - lib/orcid/spec_support.rb
313
348
  - lib/orcid/version.rb
314
349
  - lib/orcid.rb
@@ -1,19 +0,0 @@
1
- module Orcid
2
- class Configuration
3
- attr_reader :store
4
- def initialize(store = ::ENV)
5
- @store = store
6
- end
7
-
8
- attr_writer :provider_name
9
- def provider_name
10
- @provider_name ||= 'orcid'
11
- end
12
-
13
- attr_writer :authentication_model
14
- def authentication_model
15
- @authentication_model ||= Devise::MultiAuth::Authentication
16
- end
17
-
18
- end
19
- end