qa 0.3.0 → 0.4.0
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 +4 -4
- data/README.md +24 -21
- data/Rakefile +1 -1
- data/app/controllers/qa/terms_controller.rb +22 -53
- data/config/routes.rb +4 -7
- data/lib/qa/authorities.rb +3 -1
- data/lib/qa/authorities/base.rb +27 -8
- data/lib/qa/authorities/getty.rb +56 -0
- data/lib/qa/authorities/loc.rb +27 -131
- data/lib/qa/authorities/loc_subauthority.rb +90 -0
- data/lib/qa/authorities/local.rb +38 -21
- data/lib/qa/authorities/local_subauthority.rb +18 -0
- data/lib/qa/authorities/mesh.rb +16 -23
- data/lib/qa/authorities/mesh_tools/mesh_data_parser.rb +0 -25
- data/lib/qa/authorities/mesh_tools/mesh_importer.rb +0 -2
- data/lib/qa/authorities/oclcts.rb +17 -24
- data/lib/qa/authorities/tgnlang.rb +4 -18
- data/lib/qa/authorities/web_service_base.rb +3 -10
- data/lib/qa/version.rb +1 -1
- data/spec/controllers/terms_controller_spec.rb +93 -44
- data/spec/fixtures/aat-response.txt +108 -0
- data/spec/fixtures/getty-aat-find-response.json +2494 -0
- data/spec/fixtures/loc-response.txt +1521 -17
- data/spec/fixtures/loc-subject-find-response.txt +24 -0
- data/spec/internal/Gemfile +16 -13
- data/spec/internal/Gemfile.lock +121 -86
- data/spec/internal/app/assets/javascripts/application.js +1 -1
- data/spec/internal/app/assets/stylesheets/application.css +1 -1
- data/spec/internal/bin/rails +1 -5
- data/spec/internal/bin/rake +0 -4
- data/spec/internal/bin/setup +29 -0
- data/spec/internal/config.ru +1 -1
- data/spec/internal/config/application.rb +3 -0
- data/spec/internal/config/boot.rb +1 -2
- data/spec/internal/config/environments/development.rb +4 -0
- data/spec/internal/config/environments/production.rb +14 -18
- data/spec/internal/config/environments/test.rb +5 -2
- data/spec/internal/config/initializers/assets.rb +11 -0
- data/spec/internal/config/initializers/cookies_serializer.rb +1 -1
- data/spec/internal/config/secrets.yml +2 -2
- data/spec/internal/db/development.sqlite3 +0 -0
- data/spec/internal/db/migrate/{20140620210534_create_qa_subject_mesh_terms.qa.rb → 20150311214117_create_qa_subject_mesh_terms.qa.rb} +0 -0
- data/spec/internal/db/migrate/{20140620210535_create_qa_mesh_tree.qa.rb → 20150311214118_create_qa_mesh_tree.qa.rb} +0 -0
- data/spec/internal/db/migrate/{20140620210536_add_term_lower_to_qa_subject_mesh_terms.qa.rb → 20150311214119_add_term_lower_to_qa_subject_mesh_terms.qa.rb} +0 -0
- data/spec/internal/db/schema.rb +3 -3
- data/spec/internal/db/test.sqlite3 +0 -0
- data/spec/internal/lib/generators/test_app_generator.rb +0 -1
- data/spec/internal/log/development.log +498 -207
- data/spec/internal/test/test_helper.rb +0 -3
- data/spec/lib/authorities_getty_spec.rb +71 -0
- data/spec/lib/authorities_loc_spec.rb +98 -65
- data/spec/lib/authorities_loc_subauthorities.rb +81 -0
- data/spec/lib/authorities_local_spec.rb +53 -79
- data/spec/lib/authorities_local_subauthorities_spec.rb +43 -0
- data/spec/lib/authorities_mesh_spec.rb +16 -12
- data/spec/lib/authorities_oclcts_spec.rb +17 -17
- data/spec/lib/authorities_tgnlang_spec.rb +4 -7
- data/spec/lib/mesh_data_parser_spec.rb +13 -13
- data/spec/lib/tasks/mesh.rake_spec.rb +4 -4
- data/spec/models/subject_mesh_term_spec.rb +5 -5
- data/spec/routing/route_spec.rb +34 -0
- data/spec/spec_helper.rb +5 -22
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +0 -1
- metadata +44 -12
- data/lib/qa/authorities/local/subauthority.rb +0 -65
- data/spec/internal/bin/spring +0 -18
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 0e22891ac5c80978a68ef9606122e197fb348c47
         | 
| 4 | 
            +
              data.tar.gz: dc3f442fa9a2f974100fea8e6ca7f42ae3f0c953
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 972243b9cd33d2267e14cb341765f87e7c0ac83cc3f8252f1b9f18e6a4e0078452e85ee9d58d62b0d31173ae317a054fd7499fdda883b6e5116a51095c5b9d85
         | 
| 7 | 
            +
              data.tar.gz: ad6c420a0e4507ff26b191f1c3b455f5eb900d06ca60638f84abf6ecc4f66c681feae69fe210e24c46f7357262554bc899740abd8bcf1de3d92f4efc66c98502
         | 
    
        data/README.md
    CHANGED
    
    | @@ -162,25 +162,34 @@ using the file's name as the sub-authority.  For example, if I create `foo.yml`, | |
| 162 162 | 
             
            		  :term: Term 2
         | 
| 163 163 | 
             
            		  :active: false
         | 
| 164 164 |  | 
| 165 | 
            -
             | 
| 166 | 
            -
             | 
| 167 | 
            -
            ## Medical Subject Headings (MeSH)
         | 
| 165 | 
            +
            ### Medical Subject Headings (MeSH)
         | 
| 168 166 |  | 
| 169 167 | 
             
            Provides autocompletion of [MeSH terms](http://www.nlm.nih.gov/mesh/introduction.html). This
         | 
| 170 168 | 
             
            implementation is simple, and only provides *descriptors* and does not implement *qualifiers* (in
         | 
| 171 169 | 
             
            the technical MeSH sense of these terms). The terms are stored in a local database, which is then
         | 
| 172 170 | 
             
            queried to provide the suggestions.
         | 
| 173 171 |  | 
| 174 | 
            -
             | 
| 172 | 
            +
            To use, run the included rake task to copy over the relevant database migrations into your application:
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                rake qa:install:migrations
         | 
| 175 | 
            +
             | 
| 176 | 
            +
            Then, create the tables in your database
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                rake db:migrate
         | 
| 179 | 
            +
             | 
| 180 | 
            +
            Now that you've setup your application to use MeSH terms, you'll now need to load the tems into your
         | 
| 181 | 
            +
            database so you can query them locally.
         | 
| 175 182 |  | 
| 176 183 | 
             
            To import the mesh terms into the local database, first download the MeSH descriptor dump in ASCII
         | 
| 177 | 
            -
            format | 
| 178 | 
            -
             | 
| 184 | 
            +
            format. You can read about doing this [here](http://www.nlm.nih.gov/mesh/filelist.html). Once you have this file, use the
         | 
| 185 | 
            +
            following rake task to load the terms into your database:
         | 
| 179 186 |  | 
| 180 187 | 
             
                MESH_FILE=path/to/mesh.txt rake mesh:import
         | 
| 181 188 |  | 
| 182 189 | 
             
            This may take a few minutes to finish.
         | 
| 183 190 |  | 
| 191 | 
            +
            **Note:** Updating the tables with new terms is currently not supported.
         | 
| 192 | 
            +
             | 
| 184 193 | 
             
            # Developer Notes
         | 
| 185 194 |  | 
| 186 195 | 
             
            [How to Contribute](./CONTRIBUTING.md)
         | 
| @@ -188,12 +197,17 @@ This may take a few minutes to finish. | |
| 188 197 | 
             
            To develop this gem, clone the repository, then run:
         | 
| 189 198 |  | 
| 190 199 | 
             
                bundle install
         | 
| 191 | 
            -
                rake
         | 
| 200 | 
            +
                rake ci
         | 
| 201 | 
            +
             | 
| 202 | 
            +
            This will install the gems, create a dummy application under spec/internal and run the tests.  After you've made changes, 
         | 
| 203 | 
            +
            make sure you've included tests and run the test suite with a new sample application:
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                rake engine_cart:clean
         | 
| 206 | 
            +
                rake ci
         | 
| 192 207 |  | 
| 193 | 
            -
             | 
| 194 | 
            -
            directory so that further tests and run against a new dummy application.
         | 
| 208 | 
            +
            Commit your features into a new branch and submit a pull request.
         | 
| 195 209 |  | 
| 196 | 
            -
            ##  | 
| 210 | 
            +
            ## Compatibility
         | 
| 197 211 |  | 
| 198 212 | 
             
            Currently, it is compatible with Rails 4.0 and 4.1 under both Ruby 2.0 and 2.1.
         | 
| 199 213 |  | 
| @@ -201,17 +215,6 @@ Currently, it is compatible with Rails 4.0 and 4.1 under both Ruby 2.0 and 2.1. | |
| 201 215 |  | 
| 202 216 | 
             
            For help with Questioning Authority, contact <hydra-tech@googlegroups.com>.
         | 
| 203 217 |  | 
| 204 | 
            -
            # Original Authors
         | 
| 205 | 
            -
             | 
| 206 | 
            -
            * [Stephen Anderson](https://github.com/scande3)
         | 
| 207 | 
            -
            * [Don Brower](https://github.com/dbrower)
         | 
| 208 | 
            -
            * [Jim Coble](https://github.com/coblej)
         | 
| 209 | 
            -
            * [Mike Durbin](https://github.com/mikedurbin)
         | 
| 210 | 
            -
            * [Randall Floyd](https://github.com/stormfin)
         | 
| 211 | 
            -
            * [Eric James](https://github.com/yulgit1)
         | 
| 212 | 
            -
            * [Mike Stroming](https://github.com/mstroming)
         | 
| 213 | 
            -
            * [Adam Wead](https://github.com/awead)
         | 
| 214 | 
            -
             | 
| 215 218 | 
             
            ### Special thanks to...
         | 
| 216 219 |  | 
| 217 220 | 
             
            [Jeremy Friesen](https://github.com/jeremyf) who gave us the name for our gem.
         | 
    
        data/Rakefile
    CHANGED
    
    
| @@ -4,74 +4,38 @@ | |
| 4 4 |  | 
| 5 5 | 
             
            class Qa::TermsController < ApplicationController
         | 
| 6 6 |  | 
| 7 | 
            -
              before_action : | 
| 8 | 
            -
              before_action : | 
| 7 | 
            +
              before_action :check_vocab_param, :init_authority
         | 
| 8 | 
            +
              before_action :check_query_param, only: :search
         | 
| 9 9 |  | 
| 10 | 
            -
              # | 
| 10 | 
            +
              # If the subauthority supports it, return a list of all terms in the authority
         | 
| 11 11 | 
             
              def index
         | 
| 12 | 
            -
                 | 
| 13 | 
            -
                @authority = authority_class.constantize.new
         | 
| 14 | 
            -
                @authority.search(params[:q], params[:sub_authority])
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                respond_to do |format|
         | 
| 17 | 
            -
                  format.html { render :layout => false, json: @authority.results }
         | 
| 18 | 
            -
                  format.json { render :layout => false, json: @authority.results }
         | 
| 19 | 
            -
                  format.js   { render :layout => false, :text => @authority.results }
         | 
| 20 | 
            -
                end
         | 
| 12 | 
            +
                render json: @authority.all
         | 
| 21 13 | 
             
              end
         | 
| 22 14 |  | 
| 15 | 
            +
              # Return a list of terms based on a query
         | 
| 23 16 | 
             
              def search
         | 
| 24 | 
            -
                 | 
| 25 | 
            -
                 | 
| 26 | 
            -
             | 
| 27 | 
            -
                #initialize the authority and run the search. if there's a sub-authority and it's valid, include that param
         | 
| 28 | 
            -
                @authority = authority_class.constantize.new
         | 
| 29 | 
            -
                @authority.search(params[:q], params[:sub_authority])
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                respond_to do |format|
         | 
| 32 | 
            -
                  format.html { render :layout => false, :text => @authority.results.to_json }
         | 
| 33 | 
            -
                  format.json { render :layout => false, :text => @authority.results.to_json }
         | 
| 34 | 
            -
                  format.js   { render :layout => false, :text => @authority.results }
         | 
| 35 | 
            -
                end
         | 
| 36 | 
            -
             | 
| 17 | 
            +
                terms = @authority.search(url_search)
         | 
| 18 | 
            +
                render json: terms
         | 
| 37 19 | 
             
              end
         | 
| 38 20 |  | 
| 21 | 
            +
              # If the subauthority supports it, return all the information for a given term
         | 
| 39 22 | 
             
              def show
         | 
| 40 | 
            -
                 | 
| 41 | 
            -
                 | 
| 42 | 
            -
                result = authority.full_record(params[:id], params[:sub_authority])
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                respond_to do |format|
         | 
| 45 | 
            -
                  format.html { render :layout => false, :text => result.to_json }
         | 
| 46 | 
            -
                  format.json { render :layout => false, :text => result.to_json }
         | 
| 47 | 
            -
                  format.js   { render :layout => false, :text => result }
         | 
| 48 | 
            -
                end
         | 
| 23 | 
            +
                term = @authority.find(params[:id])
         | 
| 24 | 
            +
                render json: term
         | 
| 49 25 | 
             
              end
         | 
| 50 26 |  | 
| 51 27 | 
             
              def check_vocab_param
         | 
| 52 | 
            -
                unless params[:vocab].present?
         | 
| 53 | 
            -
                  head :bad_request
         | 
| 54 | 
            -
                end
         | 
| 28 | 
            +
                head :not_found unless params[:vocab].present?
         | 
| 55 29 | 
             
              end
         | 
| 56 30 |  | 
| 57 | 
            -
              def  | 
| 58 | 
            -
                 | 
| 59 | 
            -
             | 
| 60 | 
            -
                 | 
| 31 | 
            +
              def init_authority
         | 
| 32 | 
            +
                @authority = authority_class.constantize.new(params[:sub_authority])
         | 
| 33 | 
            +
              rescue
         | 
| 34 | 
            +
                head :not_found
         | 
| 61 35 | 
             
              end
         | 
| 62 36 |  | 
| 63 | 
            -
              def  | 
| 64 | 
            -
                 | 
| 65 | 
            -
                  authority_class.constantize
         | 
| 66 | 
            -
                rescue
         | 
| 67 | 
            -
                  head :bad_request
         | 
| 68 | 
            -
                end
         | 
| 69 | 
            -
              end
         | 
| 70 | 
            -
             | 
| 71 | 
            -
              def check_sub_authority
         | 
| 72 | 
            -
                unless params[:sub_authority].nil?
         | 
| 73 | 
            -
                  head :bad_request unless authority_class.constantize.authority_valid?(params[:sub_authority])
         | 
| 74 | 
            -
                end
         | 
| 37 | 
            +
              def check_query_param
         | 
| 38 | 
            +
                head :not_found unless params[:q].present?
         | 
| 75 39 | 
             
              end
         | 
| 76 40 |  | 
| 77 41 | 
             
              private
         | 
| @@ -80,4 +44,9 @@ class Qa::TermsController < ApplicationController | |
| 80 44 | 
             
                "Qa::Authorities::"+params[:vocab].capitalize
         | 
| 81 45 | 
             
              end
         | 
| 82 46 |  | 
| 47 | 
            +
              # converts wildcards into URL-encoded characters
         | 
| 48 | 
            +
              def url_search
         | 
| 49 | 
            +
                params[:q].gsub("*", "%2A")
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 83 52 | 
             
            end
         | 
    
        data/config/routes.rb
    CHANGED
    
    | @@ -1,9 +1,6 @@ | |
| 1 1 | 
             
            Qa::Engine.routes.draw do
         | 
| 2 | 
            -
               | 
| 3 | 
            -
               | 
| 4 | 
            -
               | 
| 5 | 
            -
               | 
| 6 | 
            -
              match "/terms" => "terms#index", :via=>:get
         | 
| 7 | 
            -
              match "/show/:vocab/:id" => "terms#show", :via=>:get
         | 
| 8 | 
            -
              match "/show/:vocab/:sub_authority/:id" => "terms#show", :via=>:get
         | 
| 2 | 
            +
              get "/terms/:vocab(/:sub_authority)",  controller: :terms, action: :index
         | 
| 3 | 
            +
              get "/search/:vocab(/:sub_authority)", controller: :terms, action: :search
         | 
| 4 | 
            +
              get "/show/:vocab/:id",                controller: :terms, action: :show
         | 
| 5 | 
            +
              get "/show/:vocab/:sub_authority/:id", controller: :terms, action: :show
         | 
| 9 6 | 
             
            end
         | 
    
        data/lib/qa/authorities.rb
    CHANGED
    
    | @@ -2,9 +2,11 @@ module Qa::Authorities | |
| 2 2 | 
             
              extend ActiveSupport::Autoload
         | 
| 3 3 |  | 
| 4 4 | 
             
              autoload :Base
         | 
| 5 | 
            +
              autoload :Getty
         | 
| 5 6 | 
             
              autoload :Loc
         | 
| 7 | 
            +
              autoload :LocSubauthority
         | 
| 6 8 | 
             
              autoload :Local
         | 
| 7 | 
            -
              autoload : | 
| 9 | 
            +
              autoload :LocalSubauthority
         | 
| 8 10 | 
             
              autoload :Mesh
         | 
| 9 11 | 
             
              autoload :MeshTools
         | 
| 10 12 | 
             
              autoload :Oclcts
         | 
    
        data/lib/qa/authorities/base.rb
    CHANGED
    
    | @@ -2,21 +2,40 @@ require 'deprecation' | |
| 2 2 |  | 
| 3 3 | 
             
            module Qa::Authorities
         | 
| 4 4 | 
             
              class Base
         | 
| 5 | 
            +
                extend Deprecation
         | 
| 5 6 |  | 
| 6 | 
            -
                 | 
| 7 | 
            -
             | 
| 7 | 
            +
                attr_accessor :sub_authority
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                # Registers the authority and its sub-authority if it has one
         | 
| 10 | 
            +
                def initialize *args
         | 
| 11 | 
            +
                  if args.first
         | 
| 12 | 
            +
                    raise "Invalid sub-authority" unless sub_authorities.include?(args.first)
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                # By default, an authority has no subauthorities unless they
         | 
| 17 | 
            +
                # are defined by the subclassed authority.
         | 
| 18 | 
            +
                def sub_authorities
         | 
| 19 | 
            +
                  []
         | 
| 8 20 | 
             
                end
         | 
| 9 21 |  | 
| 10 | 
            -
                #  | 
| 11 | 
            -
                 | 
| 22 | 
            +
                # By default, #all is not implemented.
         | 
| 23 | 
            +
                # If the subclassed authority does have this feature
         | 
| 24 | 
            +
                # then you will overide the #all method in the subclassed authority.
         | 
| 25 | 
            +
                # TODO: need to set some kind of error here
         | 
| 26 | 
            +
                def all
         | 
| 12 27 | 
             
                end
         | 
| 13 28 |  | 
| 14 | 
            -
                 | 
| 15 | 
            -
             | 
| 29 | 
            +
                # By default, #find is not implemented.
         | 
| 30 | 
            +
                # If the subclassed authority does have this feature
         | 
| 31 | 
            +
                # then you will overide the #find method in the subclassed authority.
         | 
| 32 | 
            +
                # TODO: need to set some kind of error here
         | 
| 33 | 
            +
                def find id
         | 
| 16 34 | 
             
                end
         | 
| 17 35 |  | 
| 18 | 
            -
                def  | 
| 19 | 
            -
                   | 
| 36 | 
            +
                def full_record id, sub_authority=nil
         | 
| 37 | 
            +
                  Deprecation.warn(".full_record is deprecated. Use .find instead")
         | 
| 38 | 
            +
                  find(id)
         | 
| 20 39 | 
             
                end
         | 
| 21 40 |  | 
| 22 41 | 
             
              end
         | 
| @@ -0,0 +1,56 @@ | |
| 1 | 
            +
            require 'uri'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Qa::Authorities
         | 
| 4 | 
            +
              class Getty < WebServiceBase
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def initialize *args
         | 
| 7 | 
            +
                  super
         | 
| 8 | 
            +
                  @sub_authority ||= args.first
         | 
| 9 | 
            +
                  raise "No sub-authority provided" if sub_authority.nil?
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def sub_authorities
         | 
| 13 | 
            +
                  [ "aat" ]
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def search q
         | 
| 17 | 
            +
                  parse_authority_response(json(build_query_url(q)))
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                # get_json is not ideomatic, so we'll make an alias
         | 
| 21 | 
            +
                def json(*args)
         | 
| 22 | 
            +
                  get_json(*args)
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def build_query_url q
         | 
| 26 | 
            +
                  untainted = q.gsub(/[\w\s-]/, '')
         | 
| 27 | 
            +
                  sparql = "PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
         | 
| 28 | 
            +
                            SELECT * WHERE { ?s skos:prefLabel ?name .
         | 
| 29 | 
            +
                              ?s skos:inScheme <http://vocab.getty.edu/#{@sub_authority}/> .
         | 
| 30 | 
            +
                              ?s rdf:type <http://vocab.getty.edu/ontology#Concept> .
         | 
| 31 | 
            +
                              FILTER regex(?name, \"#{untainted}\", \"i\") .
         | 
| 32 | 
            +
                              FILTER langMatches( lang(?name), \"EN\" ) .
         | 
| 33 | 
            +
                            } LIMIT 10"
         | 
| 34 | 
            +
                  "http://vocab.getty.edu/sparql.json?query=#{URI.escape(sparql)}&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql"
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def find id
         | 
| 38 | 
            +
                  json(find_url(id))
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def find_url id
         | 
| 42 | 
            +
                  "http://vocab.getty.edu/#{@sub_authority}/#{id}.json"
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                private
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                # Reformats the data received from the LOC service
         | 
| 48 | 
            +
                def parse_authority_response(response)
         | 
| 49 | 
            +
                  response['results']['bindings'].map do |result|
         | 
| 50 | 
            +
                    { 'id' => result['s']['value'], 'label' => result['name']['value'] }
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
            end
         | 
| 56 | 
            +
             | 
    
        data/lib/qa/authorities/loc.rb
    CHANGED
    
    | @@ -1,97 +1,44 @@ | |
| 1 1 | 
             
            require 'uri'
         | 
| 2 2 |  | 
| 3 3 | 
             
            module Qa::Authorities
         | 
| 4 | 
            -
              class Loc <  | 
| 5 | 
            -
                extend Deprecation
         | 
| 4 | 
            +
              class Loc < WebServiceBase
         | 
| 6 5 |  | 
| 7 | 
            -
                 | 
| 8 | 
            -
                # This is set to a JSON object
         | 
| 9 | 
            -
                def initialize
         | 
| 10 | 
            -
                end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                def search(q, sub_authority=nil)
         | 
| 13 | 
            -
                  if ! (sub_authority.nil?  || Loc.sub_authorities.include?(sub_authority))
         | 
| 14 | 
            -
                    @raw_response = nil
         | 
| 15 | 
            -
                    @response = nil
         | 
| 16 | 
            -
                    return
         | 
| 17 | 
            -
                  end
         | 
| 6 | 
            +
                include Qa::Authorities::LocSubauthority
         | 
| 18 7 |  | 
| 19 | 
            -
             | 
| 20 | 
            -
                   | 
| 21 | 
            -
                   | 
| 22 | 
            -
                   | 
| 23 | 
            -
                  @response = parse_authority_response(@raw_response)
         | 
| 8 | 
            +
                def initialize *args
         | 
| 9 | 
            +
                  super
         | 
| 10 | 
            +
                  @sub_authority ||= args.first
         | 
| 11 | 
            +
                  raise "No sub-authority provided" if sub_authority.nil?
         | 
| 24 12 | 
             
                end
         | 
| 25 13 |  | 
| 26 | 
            -
                def  | 
| 27 | 
            -
                   | 
| 28 | 
            -
                    begin
         | 
| 29 | 
            -
                      vocab_base_url = 'cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fvocabulary%2F'
         | 
| 30 | 
            -
                      authority_base_url = 'cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fauthorities%2F'
         | 
| 31 | 
            -
                      datatype_base_url = 'cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fdatatypes%2F'
         | 
| 32 | 
            -
                      vocab_preservation_base_url = 'cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fvocabulary%2Fpreservation%2F'
         | 
| 33 | 
            -
                      {
         | 
| 34 | 
            -
                        'subjects' => authority_base_url,
         | 
| 35 | 
            -
                        'names' => authority_base_url,
         | 
| 36 | 
            -
                        'classification' => authority_base_url,
         | 
| 37 | 
            -
                        'childrensSubjects' => authority_base_url,
         | 
| 38 | 
            -
                        'genreForms' => authority_base_url,
         | 
| 39 | 
            -
                        'graphicMaterials' => vocab_base_url,
         | 
| 40 | 
            -
                        'organizations' => vocab_base_url,
         | 
| 41 | 
            -
                        'relators' => vocab_base_url,
         | 
| 42 | 
            -
                        'countries' => vocab_base_url,
         | 
| 43 | 
            -
                        'geographicAreas' => vocab_base_url,
         | 
| 44 | 
            -
                        'languages' => vocab_base_url,
         | 
| 45 | 
            -
                        'iso639-1' => vocab_base_url,
         | 
| 46 | 
            -
                        'iso639-2' => vocab_base_url,
         | 
| 47 | 
            -
                        'iso639-5' => vocab_base_url,
         | 
| 48 | 
            -
                        'edtf' => datatype_base_url,
         | 
| 49 | 
            -
                        'preservation' => vocab_base_url,
         | 
| 50 | 
            -
                        'actionsGranted' => vocab_base_url,
         | 
| 51 | 
            -
                        'agentType' => vocab_base_url,
         | 
| 52 | 
            -
                        'contentLocationType' => vocab_preservation_base_url,
         | 
| 53 | 
            -
                        'copyrightStatus' => vocab_preservation_base_url,
         | 
| 54 | 
            -
                        'cryptographicHashFunctions' => vocab_preservation_base_url,
         | 
| 55 | 
            -
                        'environmentCharacteristic' => vocab_preservation_base_url,
         | 
| 56 | 
            -
                        'environmentPurpose' => vocab_preservation_base_url,
         | 
| 57 | 
            -
                        'eventRelatedAgentRole' => vocab_preservation_base_url,
         | 
| 58 | 
            -
                        'eventRelatedObjectRole' => vocab_preservation_base_url,
         | 
| 59 | 
            -
                        'eventType' => vocab_preservation_base_url,
         | 
| 60 | 
            -
                        'formatRegistryRole' => vocab_preservation_base_url,
         | 
| 61 | 
            -
                        'hardwareType' => vocab_preservation_base_url,
         | 
| 62 | 
            -
                        'inhibitorTarget' => vocab_preservation_base_url,
         | 
| 63 | 
            -
                        'inhibitorType' => vocab_preservation_base_url,
         | 
| 64 | 
            -
                        'objectCategory' => vocab_preservation_base_url,
         | 
| 65 | 
            -
                        'preservationLevelRole' => vocab_preservation_base_url,
         | 
| 66 | 
            -
                        'relationshipSubType' => vocab_preservation_base_url,
         | 
| 67 | 
            -
                        'relationshipType' => vocab_preservation_base_url,
         | 
| 68 | 
            -
                        'rightsBasis' => vocab_preservation_base_url,
         | 
| 69 | 
            -
                        'rightsRelatedAgentRole' => vocab_preservation_base_url,
         | 
| 70 | 
            -
                        'signatureEncoding' => vocab_preservation_base_url,
         | 
| 71 | 
            -
                        'signatureMethod' => vocab_preservation_base_url,
         | 
| 72 | 
            -
                        'softwareType' => vocab_preservation_base_url,
         | 
| 73 | 
            -
                        'storageMedium' => vocab_preservation_base_url
         | 
| 74 | 
            -
                      }
         | 
| 75 | 
            -
                    end
         | 
| 14 | 
            +
                def sub_authorities
         | 
| 15 | 
            +
                  authorities + vocabularies + datatypes + preservation
         | 
| 76 16 | 
             
                end
         | 
| 77 17 |  | 
| 18 | 
            +
                def search q
         | 
| 19 | 
            +
                  @raw_response = get_json(build_query_url(q))
         | 
| 20 | 
            +
                  parse_authority_response
         | 
| 21 | 
            +
                end
         | 
| 78 22 |  | 
| 79 | 
            -
                def  | 
| 80 | 
            -
                   | 
| 81 | 
            -
                   | 
| 82 | 
            -
                   | 
| 23 | 
            +
                def build_query_url q
         | 
| 24 | 
            +
                  escaped_query = URI.escape(q)
         | 
| 25 | 
            +
                  authority_fragment = get_url_for_authority(sub_authority) + URI.escape(sub_authority)
         | 
| 26 | 
            +
                  return "http://id.loc.gov/search/?q=#{escaped_query}&q=#{authority_fragment}&format=json"
         | 
| 83 27 | 
             
                end
         | 
| 84 28 |  | 
| 85 | 
            -
                def  | 
| 86 | 
            -
                   | 
| 29 | 
            +
                def find id
         | 
| 30 | 
            +
                  get_json(find_url(id))
         | 
| 87 31 | 
             
                end
         | 
| 88 32 |  | 
| 89 | 
            -
                def  | 
| 90 | 
            -
                  @ | 
| 33 | 
            +
                def find_url id
         | 
| 34 | 
            +
                  "http://id.loc.gov/authorities/#{@sub_authority}/#{id}.json"
         | 
| 91 35 | 
             
                end
         | 
| 92 36 |  | 
| 93 | 
            -
                 | 
| 94 | 
            -
             | 
| 37 | 
            +
                private
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                # Reformats the data received from the LOC service
         | 
| 40 | 
            +
                def parse_authority_response
         | 
| 41 | 
            +
                  @raw_response.select {|response| response[0] == "atom:entry"}.map do |response|
         | 
| 95 42 | 
             
                    loc_response_to_qa(response_to_struct(response))
         | 
| 96 43 | 
             
                  end
         | 
| 97 44 | 
             
                end
         | 
| @@ -101,7 +48,7 @@ module Qa::Authorities | |
| 101 48 | 
             
                # Note that this is a pretty naive conversion.  There should probably just
         | 
| 102 49 | 
             
                # be a class that properly translates and stores the various pieces of
         | 
| 103 50 | 
             
                # data, especially if this logic could be useful in other auth lookups.
         | 
| 104 | 
            -
                def response_to_struct | 
| 51 | 
            +
                def response_to_struct response
         | 
| 105 52 | 
             
                  result = response.each_with_object({}) do |result_parts, result|
         | 
| 106 53 | 
             
                    next unless result_parts[0]
         | 
| 107 54 | 
             
                    key = result_parts[0].sub('atom:', '').sub('dcterms:', '')
         | 
| @@ -121,63 +68,12 @@ module Qa::Authorities | |
| 121 68 | 
             
                end
         | 
| 122 69 |  | 
| 123 70 | 
             
                # Simple conversion from LoC-based struct to QA hash
         | 
| 124 | 
            -
                def loc_response_to_qa | 
| 71 | 
            +
                def loc_response_to_qa data
         | 
| 125 72 | 
             
                  {
         | 
| 126 73 | 
             
                    "id" => data.id || data.title,
         | 
| 127 74 | 
             
                    "label" => data.title
         | 
| 128 75 | 
             
                  }
         | 
| 129 76 | 
             
                end
         | 
| 130 77 |  | 
| 131 | 
            -
                def find_record_in_response(raw_response, id)
         | 
| 132 | 
            -
                  raw_response.each do |single_response|
         | 
| 133 | 
            -
                    next if single_response[0] != "atom:entry"
         | 
| 134 | 
            -
                    single_response.each do |result_part|
         | 
| 135 | 
            -
                      if (result_part[0] == 'atom:title' ||
         | 
| 136 | 
            -
                          result_part[0] == 'atom:id') && id == result_part[2]
         | 
| 137 | 
            -
                        return single_response
         | 
| 138 | 
            -
                      end
         | 
| 139 | 
            -
                    end
         | 
| 140 | 
            -
                  end
         | 
| 141 | 
            -
                  return nil
         | 
| 142 | 
            -
                end
         | 
| 143 | 
            -
             | 
| 144 | 
            -
                def get_full_record(id, sub_authority)
         | 
| 145 | 
            -
                  Deprecation.warn(Loc, "get_full_record is deprecated and will be removed in 0.1.0. Use full_record instead", caller)
         | 
| 146 | 
            -
                  full_record(id, sub_authority)
         | 
| 147 | 
            -
                end
         | 
| 148 | 
            -
             | 
| 149 | 
            -
                def full_record(id, sub_authority)
         | 
| 150 | 
            -
                  search(id, sub_authority)
         | 
| 151 | 
            -
                  full_record = find_record_in_response(@raw_response, id)
         | 
| 152 | 
            -
             | 
| 153 | 
            -
                  if full_record.nil?
         | 
| 154 | 
            -
                    # record not found
         | 
| 155 | 
            -
                    return {}
         | 
| 156 | 
            -
                  end
         | 
| 157 | 
            -
             | 
| 158 | 
            -
                  parsed_result = {}
         | 
| 159 | 
            -
                  full_record.each do |section|
         | 
| 160 | 
            -
                    if section.class == Array
         | 
| 161 | 
            -
                      label = section[0].split(':').last.to_s
         | 
| 162 | 
            -
                      case label
         | 
| 163 | 
            -
                      when 'title', 'id', 'updated', 'created'
         | 
| 164 | 
            -
                        parsed_result[label] = section[2]
         | 
| 165 | 
            -
                      when 'link'
         | 
| 166 | 
            -
                        if section[1]['type'] != nil
         | 
| 167 | 
            -
                          parsed_result[label + "||#{section[1]['type']}"] = section[1]["href"]
         | 
| 168 | 
            -
                        else
         | 
| 169 | 
            -
                          parsed_result[label] = section[1]["href"]
         | 
| 170 | 
            -
                        end
         | 
| 171 | 
            -
                      when 'author'
         | 
| 172 | 
            -
                        author_list = []
         | 
| 173 | 
            -
                        #FIXME: Find example with two authors to better understand this data.
         | 
| 174 | 
            -
                        author_list << section[2][2]
         | 
| 175 | 
            -
                        parsed_result[label] = author_list
         | 
| 176 | 
            -
                      end
         | 
| 177 | 
            -
                    end
         | 
| 178 | 
            -
                  end
         | 
| 179 | 
            -
                  parsed_result
         | 
| 180 | 
            -
                end
         | 
| 181 | 
            -
             | 
| 182 78 | 
             
              end
         | 
| 183 79 | 
             
            end
         |