orcid 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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