qa 0.10.1 → 0.10.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +12 -2
  3. data/app/controllers/qa/terms_controller.rb +14 -16
  4. data/app/models/qa/mesh_tree.rb +3 -5
  5. data/app/models/qa/subject_mesh_term.rb +15 -15
  6. data/config/routes.rb +1 -1
  7. data/lib/generators/qa/install/install_generator.rb +2 -3
  8. data/lib/generators/qa/local/tables/mysql/mysql_generator.rb +3 -5
  9. data/lib/generators/qa/local/tables/tables_generator.rb +4 -6
  10. data/lib/qa/authorities/assign_fast/generic_authority.rb +16 -19
  11. data/lib/qa/authorities/assign_fast_subauthority.rb +3 -5
  12. data/lib/qa/authorities/authority_with_sub_authority.rb +1 -2
  13. data/lib/qa/authorities/base.rb +2 -3
  14. data/lib/qa/authorities/geonames.rb +11 -12
  15. data/lib/qa/authorities/getty.rb +7 -8
  16. data/lib/qa/authorities/getty/aat.rb +11 -12
  17. data/lib/qa/authorities/getty/tgn.rb +15 -15
  18. data/lib/qa/authorities/getty/ulan.rb +15 -16
  19. data/lib/qa/authorities/loc/generic_authority.rb +32 -33
  20. data/lib/qa/authorities/loc_subauthority.rb +17 -20
  21. data/lib/qa/authorities/local.rb +41 -40
  22. data/lib/qa/authorities/local/file_based_authority.rb +18 -19
  23. data/lib/qa/authorities/local/mysql_table_based_authority.rb +8 -6
  24. data/lib/qa/authorities/local/registry.rb +5 -5
  25. data/lib/qa/authorities/local/table_based_authority.rb +26 -19
  26. data/lib/qa/authorities/mesh.rb +8 -16
  27. data/lib/qa/authorities/mesh_tools.rb +5 -5
  28. data/lib/qa/authorities/mesh_tools/mesh_data_parser.rb +4 -6
  29. data/lib/qa/authorities/mesh_tools/mesh_importer.rb +11 -13
  30. data/lib/qa/authorities/oclcts.rb +0 -1
  31. data/lib/qa/authorities/oclcts/generic_oclc_authority.rb +16 -16
  32. data/lib/qa/authorities/tgnlang.rb +7 -12
  33. data/lib/qa/version.rb +1 -1
  34. data/spec/controllers/terms_controller_spec.rb +44 -54
  35. data/spec/lib/authorities/assign_fast_spec.rb +25 -27
  36. data/spec/lib/authorities/file_based_authority_spec.rb +25 -26
  37. data/spec/lib/authorities/geonames_spec.rb +5 -6
  38. data/spec/lib/authorities/getty/aat_spec.rb +6 -10
  39. data/spec/lib/authorities/getty/tgn_spec.rb +6 -10
  40. data/spec/lib/authorities/getty/ulan_spec.rb +6 -10
  41. data/spec/lib/authorities/getty_spec.rb +4 -5
  42. data/spec/lib/authorities/loc_spec.rb +30 -36
  43. data/spec/lib/authorities/local_spec.rb +5 -7
  44. data/spec/lib/authorities/mesh_spec.rb +9 -9
  45. data/spec/lib/authorities/mysql_table_based_authority_spec.rb +13 -5
  46. data/spec/lib/authorities/oclcts_spec.rb +17 -21
  47. data/spec/lib/authorities/table_based_authority_spec.rb +21 -12
  48. data/spec/lib/authorities/tgnlang_spec.rb +4 -6
  49. data/spec/lib/authorities_loc_subauthorities.rb +50 -54
  50. data/spec/lib/mesh_data_parser_spec.rb +73 -79
  51. data/spec/lib/services/rdf_authority_parser_spec.rb +2 -7
  52. data/spec/lib/tasks/mesh.rake_spec.rb +16 -12
  53. data/spec/models/subject_mesh_term_spec.rb +4 -4
  54. data/spec/routing/route_spec.rb +13 -15
  55. data/spec/spec_helper.rb +3 -4
  56. data/spec/test_app_templates/lib/generators/test_app_generator.rb +0 -1
  57. metadata +45 -17
@@ -2,7 +2,7 @@ module Qa::Authorities
2
2
  class Getty::AAT < Base
3
3
  include WebServiceBase
4
4
 
5
- def search q
5
+ def search(q)
6
6
  parse_authority_response(json(build_query_url(q)))
7
7
  end
8
8
 
@@ -11,8 +11,7 @@ module Qa::Authorities
11
11
  get_json(*args)
12
12
  end
13
13
 
14
- def build_query_url q
15
- query = URI.escape(sparql(untaint(q)))
14
+ def build_query_url(q)
16
15
  "http://vocab.getty.edu/sparql.json?query=#{URI.escape(sparql(q))}&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql"
17
16
  end
18
17
 
@@ -25,32 +24,32 @@ module Qa::Authorities
25
24
  gvp:prefLabelGVP [skosxl:literalForm ?name].
26
25
  FILTER regex(?name, \"#{search}\", \"i\") .
27
26
  } ORDER BY ?name"
27
+ sparql
28
28
  end
29
29
 
30
30
  def untaint(q)
31
31
  q.gsub(/[^\w\s-]/, '')
32
32
  end
33
33
 
34
- def find id
34
+ def find(id)
35
35
  json(find_url(id))
36
36
  end
37
37
 
38
- def find_url id
38
+ def find_url(id)
39
39
  "http://vocab.getty.edu/aat/#{id}.json"
40
40
  end
41
41
 
42
42
  def request_options
43
- { accept: 'application/sparql-results+json'}
43
+ { accept: 'application/sparql-results+json' }
44
44
  end
45
45
 
46
46
  private
47
47
 
48
- # Reformats the data received from the Getty service
49
- def parse_authority_response(response)
50
- response['results']['bindings'].map do |result|
51
- { 'id' => result['s']['value'], 'label' => result['name']['value'] }
48
+ # Reformats the data received from the Getty service
49
+ def parse_authority_response(response)
50
+ response['results']['bindings'].map do |result|
51
+ { 'id' => result['s']['value'], 'label' => result['name']['value'] }
52
+ end
52
53
  end
53
- end
54
-
55
54
  end
56
55
  end
@@ -2,7 +2,7 @@ module Qa::Authorities
2
2
  class Getty::TGN < Base
3
3
  include WebServiceBase
4
4
 
5
- def search q
5
+ def search(q)
6
6
  parse_authority_response(json(build_query_url(q)))
7
7
  end
8
8
 
@@ -11,11 +11,11 @@ module Qa::Authorities
11
11
  get_json(*args)
12
12
  end
13
13
 
14
- def build_query_url q
14
+ def build_query_url(q)
15
15
  query = URI.escape(sparql(untaint(q)))
16
16
  # Replace ampersands, otherwise the query will fail
17
17
  # Gsub hack to convert the encoded regex in the REPLACE into a form Getty understands
18
- "http://vocab.getty.edu/sparql.json?query=#{query.gsub('&','%26').gsub(',[%5E,]+,[%5E,]+$','%2C[^%2C]%2B%2C[^%2C]%2B%24')}&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql"
18
+ "http://vocab.getty.edu/sparql.json?query=#{query.gsub('&', '%26').gsub(',[%5E,]+,[%5E,]+$', '%2C[^%2C]%2B%2C[^%2C]%2B%24')}&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql"
19
19
  end
20
20
 
21
21
  # Use a regex to exclude the continent and 'world' from the query
@@ -25,12 +25,12 @@ module Qa::Authorities
25
25
  search = untaint(q)
26
26
  if search.include?(' ')
27
27
  ex = "(("
28
- search.split(' ').each do | i |
28
+ search.split(' ').each do |i|
29
29
  ex += "regex(CONCAT(?name, ', ', REPLACE(str(?par), \",[^,]+,[^,]+$\", \"\")), \"#{i}\",\"i\" ) && "
30
30
  end
31
31
  ex = ex[0..ex.length - 4]
32
32
  ex += ') && ('
33
- search.split(' ').each do | i |
33
+ search.split(' ').each do |i|
34
34
  ex += "regex(?name, \"#{i}\",\"i\" ) || "
35
35
  end
36
36
  ex = ex[0..ex.length - 4]
@@ -48,33 +48,33 @@ module Qa::Authorities
48
48
  gvp:parentString ?par .
49
49
  FILTER #{ex} .
50
50
  } ORDER BY ?name ASC(?par)"
51
+ sparql
51
52
  end
52
53
 
53
54
  def untaint(q)
54
55
  q.gsub(/[^\w\s-]/, '')
55
56
  end
56
57
 
57
- def find id
58
+ def find(id)
58
59
  json(find_url(id))
59
60
  end
60
61
 
61
- def find_url id
62
+ def find_url(id)
62
63
  "http://vocab.getty.edu/tgn/#{id}.json"
63
64
  end
64
65
 
65
66
  def request_options
66
- { accept: 'application/sparql-results+json'}
67
+ { accept: 'application/sparql-results+json' }
67
68
  end
68
69
 
69
70
  private
70
71
 
71
- # Reformats the data received from the service
72
- # Adds the parentString, minus the contintent and 'World' for disambiguation
73
- def parse_authority_response(response)
74
- response['results']['bindings'].map do |result|
75
- { 'id' => result['s']['value'], 'label' => result['name']['value'] + ' (' + result['par']['value'].gsub(/\,[^\,]+\,[^\,]+$/, '') + ')' }
72
+ # Reformats the data received from the service
73
+ # Adds the parentString, minus the contintent and 'World' for disambiguation
74
+ def parse_authority_response(response)
75
+ response['results']['bindings'].map do |result|
76
+ { 'id' => result['s']['value'], 'label' => result['name']['value'] + ' (' + result['par']['value'].gsub(/\,[^\,]+\,[^\,]+$/, '') + ')' }
77
+ end
76
78
  end
77
- end
78
-
79
79
  end
80
80
  end
@@ -2,7 +2,7 @@ module Qa::Authorities
2
2
  class Getty::Ulan < Base
3
3
  include WebServiceBase
4
4
 
5
- def search q
5
+ def search(q)
6
6
  parse_authority_response(json(build_query_url(q)))
7
7
  end
8
8
 
@@ -11,10 +11,9 @@ module Qa::Authorities
11
11
  get_json(*args)
12
12
  end
13
13
 
14
- def build_query_url q
15
- query = URI.escape(sparql(untaint(q)))
16
- # Replace ampersands, otherwise the query will fail
17
- "http://vocab.getty.edu/sparql.json?query=#{URI.escape(sparql(q)).gsub('&','%26')}&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql"
14
+ # Replace ampersands, otherwise the query will fail
15
+ def build_query_url(q)
16
+ "http://vocab.getty.edu/sparql.json?query=#{URI.escape(sparql(q)).gsub('&', '%26')}&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql"
18
17
  end
19
18
 
20
19
  def sparql(q)
@@ -22,7 +21,7 @@ module Qa::Authorities
22
21
  # if more than one term is supplied, check both preferred and alt labels
23
22
  if search.include?(' ')
24
23
  ex = "("
25
- search.split(' ').each do | i |
24
+ search.split(' ').each do |i|
26
25
  ex += "regex(CONCAT(?name, ' ', ?alt), \"#{i}\",\"i\" ) && "
27
26
  end
28
27
  ex = ex[0..ex.length - 4]
@@ -39,33 +38,33 @@ module Qa::Authorities
39
38
  skos:altLabel ?alt .
40
39
  FILTER #{ex} .
41
40
  } ORDER BY ?name"
41
+ sparql
42
42
  end
43
43
 
44
44
  def untaint(q)
45
45
  q.gsub(/[^\w\s-]/, '')
46
46
  end
47
47
 
48
- def find id
48
+ def find(id)
49
49
  json(find_url(id))
50
50
  end
51
51
 
52
- def find_url id
52
+ def find_url(id)
53
53
  "http://vocab.getty.edu/ulan/#{id}.json"
54
54
  end
55
55
 
56
56
  def request_options
57
- { accept: 'application/sparql-results+json'}
57
+ { accept: 'application/sparql-results+json' }
58
58
  end
59
59
 
60
60
  private
61
61
 
62
- # Reformats the data received from the Getty service
63
- # Add the bio for disambiguation
64
- def parse_authority_response(response)
65
- response['results']['bindings'].map do |result|
66
- { 'id' => result['s']['value'], 'label' => result['name']['value'] + ' (' + result['bio']['value'] + ')' }
62
+ # Reformats the data received from the Getty service
63
+ # Add the bio for disambiguation
64
+ def parse_authority_response(response)
65
+ response['results']['bindings'].map do |result|
66
+ { 'id' => result['s']['value'], 'label' => result['name']['value'] + ' (' + result['bio']['value'] + ')' }
67
+ end
67
68
  end
68
- end
69
-
70
69
  end
71
70
  end
@@ -7,65 +7,64 @@ module Qa::Authorities
7
7
 
8
8
  include WebServiceBase
9
9
 
10
- def search q
10
+ def search(q)
11
11
  @raw_response = get_json(build_query_url(q))
12
12
  parse_authority_response
13
13
  end
14
14
 
15
- def build_query_url q
15
+ def build_query_url(q)
16
16
  escaped_query = URI.escape(q)
17
17
  authority_fragment = Loc.get_url_for_authority(subauthority) + URI.escape(subauthority)
18
- return "http://id.loc.gov/search/?q=#{escaped_query}&q=#{authority_fragment}&format=json"
18
+ "http://id.loc.gov/search/?q=#{escaped_query}&q=#{authority_fragment}&format=json"
19
19
  end
20
20
 
21
- def find id
21
+ def find(id)
22
22
  get_json(find_url(id))
23
23
  end
24
24
 
25
- def find_url id
25
+ def find_url(id)
26
26
  "http://id.loc.gov/authorities/#{@subauthority}/#{id}.json"
27
27
  end
28
28
 
29
29
  private
30
30
 
31
- # Reformats the data received from the LOC service
32
- def parse_authority_response
33
- @raw_response.select {|response| response[0] == "atom:entry"}.map do |response|
34
- loc_response_to_qa(response_to_struct(response))
31
+ # Reformats the data received from the LOC service
32
+ def parse_authority_response
33
+ @raw_response.select { |response| response[0] == "atom:entry" }.map do |response|
34
+ loc_response_to_qa(response_to_struct(response))
35
+ end
35
36
  end
36
- end
37
37
 
38
- # Converts most of the atom data into an OpenStruct object.
39
- #
40
- # Note that this is a pretty naive conversion. There should probably just
41
- # be a class that properly translates and stores the various pieces of
42
- # data, especially if this logic could be useful in other auth lookups.
43
- def response_to_struct response
44
- result = response.each_with_object({}) do |result_parts, result|
45
- next unless result_parts[0]
46
- key = result_parts[0].sub('atom:', '').sub('dcterms:', '')
47
- info = result_parts[1]
48
- val = result_parts[2]
38
+ # Converts most of the atom data into an OpenStruct object.
39
+ #
40
+ # Note that this is a pretty naive conversion. There should probably just
41
+ # be a class that properly translates and stores the various pieces of
42
+ # data, especially if this logic could be useful in other auth lookups.
43
+ def response_to_struct(response)
44
+ contents = response.each_with_object({}) do |result_parts, result|
45
+ next unless result_parts[0]
46
+ key = result_parts[0].sub('atom:', '').sub('dcterms:', '')
47
+ info = result_parts[1]
48
+ val = result_parts[2]
49
49
 
50
- case key
50
+ case key
51
51
  when 'title', 'id', 'name', 'updated', 'created'
52
52
  result[key] = val
53
53
  when 'link'
54
54
  result["links"] ||= []
55
55
  result["links"] << [info["type"], info["href"]]
56
+ end
56
57
  end
57
- end
58
-
59
- OpenStruct.new(result)
60
- end
61
58
 
62
- # Simple conversion from LoC-based struct to QA hash
63
- def loc_response_to_qa data
64
- {
65
- "id" => data.id || data.title,
66
- "label" => data.title
67
- }
68
- end
59
+ OpenStruct.new(contents)
60
+ end
69
61
 
62
+ # Simple conversion from LoC-based struct to QA hash
63
+ def loc_response_to_qa(data)
64
+ {
65
+ "id" => data.id || data.title,
66
+ "label" => data.title
67
+ }
68
+ end
70
69
  end
71
70
  end
@@ -1,11 +1,9 @@
1
1
  module Qa::Authorities::LocSubauthority
2
-
3
- def get_url_for_authority authority
4
- case
5
- when authorities.include?(authority) then authority_base_url
6
- when vocabularies.include?(authority) then vocab_base_url
7
- when datatypes.include?(authority) then datatype_base_url
8
- when preservation.include?(authority) then vocab_preservation_base_url
2
+ def get_url_for_authority(authority)
3
+ if authorities.include?(authority) then authority_base_url
4
+ elsif vocabularies.include?(authority) then vocab_base_url
5
+ elsif datatypes.include?(authority) then datatype_base_url
6
+ elsif preservation.include?(authority) then vocab_preservation_base_url
9
7
  end
10
8
  end
11
9
 
@@ -71,20 +69,19 @@ module Qa::Authorities::LocSubauthority
71
69
 
72
70
  private
73
71
 
74
- def vocab_base_url
75
- "cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fvocabulary%2F"
76
- end
77
-
78
- def authority_base_url
79
- "cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fauthorities%2F"
80
- end
72
+ def vocab_base_url
73
+ "cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fvocabulary%2F"
74
+ end
81
75
 
82
- def datatype_base_url
83
- "cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fdatatypes%2F"
84
- end
76
+ def authority_base_url
77
+ "cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fauthorities%2F"
78
+ end
85
79
 
86
- def vocab_preservation_base_url
87
- "cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fvocabulary%2Fpreservation%2F"
88
- end
80
+ def datatype_base_url
81
+ "cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fdatatypes%2F"
82
+ end
89
83
 
84
+ def vocab_preservation_base_url
85
+ "cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fvocabulary%2Fpreservation%2F"
86
+ end
90
87
  end
@@ -7,58 +7,59 @@ module Qa::Authorities
7
7
  autoload :TableBasedAuthority
8
8
  autoload :MysqlTableBasedAuthority
9
9
 
10
- def self.config
11
- @config
12
- end
10
+ class << self
11
+ attr_reader :config
13
12
 
14
- def self.load_config(file)
15
- @config = YAML.load_file(file)
16
- end
13
+ def load_config(file)
14
+ @config = YAML.load_file(file)
15
+ end
17
16
 
18
- # Path to sub-authority files is either the full path to a directory or
19
- # the path to a directory relative to the Rails application
20
- def self.subauthorities_path
21
- if config[:local_path].starts_with?(File::Separator)
22
- config[:local_path]
23
- else
24
- File.join(Rails.root, config[:local_path])
17
+ # Path to sub-authority files is either the full path to a directory or
18
+ # the path to a directory relative to the Rails application
19
+ def subauthorities_path
20
+ if config[:local_path].starts_with?(File::Separator)
21
+ config[:local_path]
22
+ else
23
+ File.join(Rails.root, config[:local_path])
24
+ end
25
25
  end
26
- end
27
26
 
28
- # Local sub-authorities are any YAML files in the subauthorities_path
29
- def self.names
30
- unless Dir.exists? subauthorities_path
31
- raise Qa::ConfigDirectoryNotFound, "There's no directory at #{subauthorities_path}. You must create it in order to use local authorities"
27
+ # Local sub-authorities are any YAML files in the subauthorities_path
28
+ def names
29
+ unless Dir.exist? subauthorities_path
30
+ raise Qa::ConfigDirectoryNotFound, "There's no directory at #{subauthorities_path}. You must create it in order to use local authorities"
31
+ end
32
+ Dir.entries(subauthorities_path).map { |f| File.basename(f, ".yml") if f =~ /yml$/ }.compact
32
33
  end
33
- Dir.entries(subauthorities_path).map { |f| File.basename(f, ".yml") if f.match(/yml$/) }.compact
34
- end
35
34
 
36
- def self.subauthority_for(subauthority)
37
- validate_subauthority!(subauthority)
38
- registry.instance_for(subauthority)
39
- end
35
+ def subauthority_for(subauthority)
36
+ validate_subauthority!(subauthority)
37
+ registry.instance_for(subauthority)
38
+ end
40
39
 
41
- def self.registry
42
- @registry ||= begin
43
- Registry.new do |reg|
44
- register_defaults(reg)
40
+ def registry
41
+ @registry ||= begin
42
+ Registry.new do |reg|
43
+ register_defaults(reg)
44
+ end
45
45
  end
46
46
  end
47
- end
48
47
 
49
- def self.register_subauthority(subauthority, class_name)
50
- registry.add(subauthority, class_name)
51
- end
48
+ def register_subauthority(subauthority, class_name)
49
+ registry.add(subauthority, class_name)
50
+ end
52
51
 
53
- def self.subauthorities
54
- registry.keys
55
- end
52
+ def subauthorities
53
+ registry.keys
54
+ end
55
+
56
+ private
56
57
 
57
- private
58
- def self.register_defaults(reg)
59
- names.each do |name|
60
- reg.add(name, 'Qa::Authorities::Local::FileBasedAuthority')
58
+ def register_defaults(reg)
59
+ names.each do |name|
60
+ reg.add(name, 'Qa::Authorities::Local::FileBasedAuthority')
61
+ end
61
62
  end
62
- end
63
+ end
63
64
  end
64
65
  end