marcspec 0.2.1 → 0.5.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.
- data/CHANGES +15 -0
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/lib/marcspec/customspec.rb +3 -2
- data/lib/marcspec/marcfieldspec.rb +3 -1
- data/lib/marcspec/solrfieldspec.rb +3 -3
- data/lib/marcspec/specset.rb +46 -2
- data/spec/marcfieldspecs_spec.rb +5 -0
- data/spec/solrfieldspec_spec.rb +20 -1
- data/spec/specset_spec.rb +88 -0
- metadata +8 -5
data/CHANGES
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
0.5.0
|
2
|
+
* Allow solr field names to repeat in a spec set. This allows you to cumulatively add to a solr field based on "regular"
|
3
|
+
and custom (or, say, two custom) specs.
|
4
|
+
0.4.0
|
5
|
+
* MAJOR BACKWARD-INCOMPATIBLE CHANGE!! The signature for custom routines is now def function(doc, record, my, args), where
|
6
|
+
"doc" is a hashlike (usually a SolrDocument) that contains all the work that has happened up to this point. The idea is that you
|
7
|
+
can use previously-computed values to determine values for different fields. Use sparingly.
|
8
|
+
0.3.0
|
9
|
+
* Changed behavior with respect to repeated subfields. A spec such as '260 ac' returns the values of the 'a' and
|
10
|
+
'c' subfields concatenated together. A request for '631 z' would, similarly, return the values *of all the subfield
|
11
|
+
z's* concatenated together. I'm now treating this as a special case. If the request is for a single subfield code,
|
12
|
+
multiple values are returned separate from each other.
|
13
|
+
|
14
|
+
0.2.0
|
15
|
+
* First public release
|
data/README.rdoc
CHANGED
@@ -21,7 +21,7 @@ options.
|
|
21
21
|
* A MARC Field Spec is one of the following
|
22
22
|
* A {MARCSpec::LeaderSpec} for dealing with the leader
|
23
23
|
* A {MARCSpec::ControlFieldSpec}, consisting of a tag (as a string, not a number) and
|
24
|
-
an optional zero-based index (e.g., "001[3]") or range (e.g., "001
|
24
|
+
an optional zero-based index (e.g., "001[3]") or range (e.g., "001[11..13]")
|
25
25
|
* A {MARCSpec::VariableFieldSpec}, consisting of a tag, a couple indicator patterns
|
26
26
|
(currently ignored, but stay tuned), an optional list of subfields (default
|
27
27
|
is all), and an optional string used to join the subfields (default is
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/lib/marcspec/customspec.rb
CHANGED
@@ -176,8 +176,10 @@ module MARCSpec
|
|
176
176
|
vals = []
|
177
177
|
fields.each do |f|
|
178
178
|
subvals = f.sub_values(@codes)
|
179
|
-
|
179
|
+
subvals = subvals.join(@joiner) if subvals.size > 0 and (@codes.nil? or @codes.size > 1)
|
180
|
+
vals << subvals
|
180
181
|
end
|
182
|
+
vals.flatten!
|
181
183
|
return vals
|
182
184
|
end
|
183
185
|
|
@@ -17,7 +17,7 @@ module MARCSpec
|
|
17
17
|
end
|
18
18
|
|
19
19
|
|
20
|
-
def raw_marc_values r
|
20
|
+
def raw_marc_values r, doc
|
21
21
|
vals = []
|
22
22
|
@marcfieldspecs.each do |ts|
|
23
23
|
vals.concat ts.marc_values(r)
|
@@ -25,8 +25,8 @@ module MARCSpec
|
|
25
25
|
return vals
|
26
26
|
end
|
27
27
|
|
28
|
-
def marc_values r
|
29
|
-
vals = raw_marc_values r
|
28
|
+
def marc_values r, doc = {}
|
29
|
+
vals = raw_marc_values r, doc
|
30
30
|
unless vals.is_a? Array
|
31
31
|
vals = [vals]
|
32
32
|
end
|
data/lib/marcspec/specset.rb
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
require 'jruby_streaming_update_solr_server'
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
|
2
6
|
module MARCSpec
|
7
|
+
|
8
|
+
# Create a mock solr document based on a normal hash for mocking.
|
9
|
+
# All we really need is a compatible add method
|
10
|
+
class MockSolrDoc < Hash
|
11
|
+
def add key, value
|
12
|
+
if self.has_key? key
|
13
|
+
self[key] << value
|
14
|
+
else
|
15
|
+
self[key] = [value]
|
16
|
+
end
|
17
|
+
self[key].flatten!
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
3
21
|
class SpecSet
|
4
22
|
attr_accessor :tmaps, :solrfieldspecs
|
5
23
|
|
@@ -21,10 +39,35 @@ module MARCSpec
|
|
21
39
|
end
|
22
40
|
end
|
23
41
|
|
42
|
+
|
43
|
+
|
24
44
|
def add_map map
|
25
45
|
self.tmaps[map.mapname] = map
|
26
46
|
end
|
27
47
|
|
48
|
+
|
49
|
+
def buildSpecsFromList speclist
|
50
|
+
speclist.each do |spechash|
|
51
|
+
if spechash[:module]
|
52
|
+
solrspec = MARCSpec::CustomSolrSpec.fromHash(spechash)
|
53
|
+
else
|
54
|
+
solrspec = MARCSpec::SolrFieldSpec.fromHash(spechash)
|
55
|
+
end
|
56
|
+
if spechash[:mapname]
|
57
|
+
map = self.map(spechash[:mapname])
|
58
|
+
unless map
|
59
|
+
$LOG.error " Cannot find map #{spechash[:mapname]} for field #{spechash[:solrField]}"
|
60
|
+
else
|
61
|
+
$LOG.debug " Found map #{spechash[:mapname]} for field #{spechash[:solrField]}"
|
62
|
+
solrspec.map = map
|
63
|
+
end
|
64
|
+
end
|
65
|
+
self.add_spec solrspec
|
66
|
+
$LOG.debug "Added spec #{solrspec.solrField}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
28
71
|
def add_spec solrfieldspec
|
29
72
|
self.solrfieldspecs << solrfieldspec
|
30
73
|
end
|
@@ -39,7 +82,8 @@ module MARCSpec
|
|
39
82
|
|
40
83
|
def fill_hashlike_from_marc r, hashlike
|
41
84
|
@solrfieldspecs.each do |sfs|
|
42
|
-
hashlike
|
85
|
+
hashlike.add(sfs.solrField,sfs.marc_values(r, hashlike))
|
86
|
+
# hashlike[sfs.solrField] = sfs.marc_values(r, hashlike)
|
43
87
|
end
|
44
88
|
end
|
45
89
|
|
@@ -50,7 +94,7 @@ module MARCSpec
|
|
50
94
|
end
|
51
95
|
|
52
96
|
def hash_from_marc r
|
53
|
-
h =
|
97
|
+
h = MARCSpec::MockSolrDoc.new
|
54
98
|
fill_hashlike_from_marc r, h
|
55
99
|
return h
|
56
100
|
end
|
data/spec/marcfieldspecs_spec.rb
CHANGED
@@ -84,6 +84,11 @@ describe "VariableFieldSpec" do
|
|
84
84
|
dfs.marc_values(@one).should.equal ["Medina, Texas,"]
|
85
85
|
end
|
86
86
|
|
87
|
+
it "should return separate values for repeated subfields if only one code is specified" do
|
88
|
+
dfs = MARCSpec::VariableFieldSpec.new('651', 'z')
|
89
|
+
dfs.marc_values(@one).sort.should.equal ['Texas', 'United States of America.']
|
90
|
+
end
|
91
|
+
|
87
92
|
it "Should get all fields via several equal routes" do
|
88
93
|
a = MARCSpec::VariableFieldSpec.new('260').marc_values(@one)
|
89
94
|
ac = MARCSpec::VariableFieldSpec.new('260', ['a', 'c']).marc_values(@one)
|
data/spec/solrfieldspec_spec.rb
CHANGED
@@ -126,7 +126,7 @@ end
|
|
126
126
|
|
127
127
|
module A
|
128
128
|
module B
|
129
|
-
def self.titleUp r, codes=nil
|
129
|
+
def self.titleUp doc, r, codes=nil
|
130
130
|
title = r['245']
|
131
131
|
if codes
|
132
132
|
return [title.sub_values(codes).join(' ').upcase]
|
@@ -134,6 +134,18 @@ module A
|
|
134
134
|
return [title.value.upcase]
|
135
135
|
end
|
136
136
|
end
|
137
|
+
|
138
|
+
# downcase and strip punctuation to create a sortable entitiy. Here, we're actually
|
139
|
+
# ignoring the passed-in record entirely
|
140
|
+
def self.sortable doc, r, whereTheTitleIs
|
141
|
+
vals = []
|
142
|
+
if doc[]
|
143
|
+
doc[whereTheTitleIs].each do |title|
|
144
|
+
vals << title.gsub(/\p{Punct}/, ' ').gsub(/\s+/, ' ').strip.downcase
|
145
|
+
end
|
146
|
+
end
|
147
|
+
return vals
|
148
|
+
end
|
137
149
|
end
|
138
150
|
end
|
139
151
|
|
@@ -173,5 +185,12 @@ describe "CustomSolrSpec" do
|
|
173
185
|
css.marc_values(@one).should.equal [@mapValue]
|
174
186
|
end
|
175
187
|
|
188
|
+
it "works with a map that has multiple return values" do
|
189
|
+
@map[@titleACValue.upcase] = ['two', 'one']
|
190
|
+
css = MARCSpec::CustomSolrSpec.new(:solrField=>'solrField', :map=>@map, :module=>A::B, :methodSymbol=>:titleUp, :methodArgs=>[['a', 'c']])
|
191
|
+
css.marc_values(@one).should.equal ['two', 'one']
|
192
|
+
end
|
193
|
+
|
194
|
+
|
176
195
|
end
|
177
196
|
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module A
|
4
|
+
module B
|
5
|
+
def self.titleUp doc, r, codes=nil
|
6
|
+
title = r['245']
|
7
|
+
if codes
|
8
|
+
return [title.sub_values(codes).join(' ').upcase]
|
9
|
+
else
|
10
|
+
return [title.value.upcase]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# downcase and strip punctuation to create a sortable entitiy. Here, we're actually
|
15
|
+
# ignoring the passed-in record entirely
|
16
|
+
def self.sortable doc, r, whereTheTitleIs
|
17
|
+
vals = []
|
18
|
+
if doc[whereTheTitleIs]
|
19
|
+
doc[whereTheTitleIs].each do |title|
|
20
|
+
vals << title.gsub(/\p{Punct}/, ' ').gsub(/\s+/, ' ').strip.downcase
|
21
|
+
end
|
22
|
+
end
|
23
|
+
return vals
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
describe "SpecSet Basics" do
|
30
|
+
before do
|
31
|
+
@one = MARC4J4R::Reader.new("#{DIR}/data/one.dat").first
|
32
|
+
@places = ['Medina', 'Texas', 'United States of America.', 'Medina, Texas,']
|
33
|
+
@title = ['The Texas ranger [sound recording] / Sung by Beale D. Taylor.']
|
34
|
+
@titleA = ['The Texas ranger']
|
35
|
+
@speclist = [
|
36
|
+
{
|
37
|
+
:solrField=> "places",
|
38
|
+
:specs => [
|
39
|
+
["260", "*", "*", "a"],
|
40
|
+
["651", "*", "*", "a"],
|
41
|
+
["651", "*", "*", "z"],
|
42
|
+
]
|
43
|
+
},
|
44
|
+
{:solrField=>'title', :specs=>[['245', '*', '*']]},
|
45
|
+
{
|
46
|
+
:solrField => 'titleA',
|
47
|
+
:specs => [['245', '*', '*', 'a']]
|
48
|
+
}
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should build from a list" do
|
53
|
+
ss = MARCSpec::SpecSet.new
|
54
|
+
ss.buildSpecsFromList(@speclist)
|
55
|
+
ss.solrfieldspecs.size.should.equal 3
|
56
|
+
h = ss.hash_from_marc @one
|
57
|
+
h['places'].sort.should.equal @places.sort
|
58
|
+
h['title'].should.equal @title
|
59
|
+
h['titleA'].should.equal @titleA
|
60
|
+
end
|
61
|
+
|
62
|
+
it "allows customs that reference previous work" do
|
63
|
+
@speclist << {:solrField=>'titleSort', :module=>A::B, :methodSymbol=>:sortable, :methodArgs=>['title']}
|
64
|
+
ss = MARCSpec::SpecSet.new
|
65
|
+
ss.buildSpecsFromList(@speclist)
|
66
|
+
h = ss.hash_from_marc @one
|
67
|
+
h['title'].should.equal @title
|
68
|
+
h['titleSort'].should.equal @title.map{|a| a.gsub(/\p{Punct}/, ' ').gsub(/\s+/, ' ').strip.downcase}
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should allow repeated solrFields" do
|
72
|
+
@speclist << {:solrField=>'titleA', :specs=>[['260', '*', '*', 'c']]} # '1939.'
|
73
|
+
expected = @titleA
|
74
|
+
expected << '1939.'
|
75
|
+
ss = MARCSpec::SpecSet.new
|
76
|
+
ss.buildSpecsFromList(@speclist)
|
77
|
+
h = ss.hash_from_marc @one
|
78
|
+
h['titleA'].sort.should.equal expected.sort
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marcspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 5
|
9
|
+
- 0
|
10
|
+
version: 0.5.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- BillDueber
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-08-
|
18
|
+
date: 2010-08-16 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -90,6 +90,7 @@ extra_rdoc_files:
|
|
90
90
|
files:
|
91
91
|
- .document
|
92
92
|
- .gitignore
|
93
|
+
- CHANGES
|
93
94
|
- LICENSE
|
94
95
|
- README.rdoc
|
95
96
|
- Rakefile
|
@@ -124,6 +125,7 @@ files:
|
|
124
125
|
- spec/marcspec_spec.rb
|
125
126
|
- spec/solrfieldspec_spec.rb
|
126
127
|
- spec/spec_helper.rb
|
128
|
+
- spec/specset_spec.rb
|
127
129
|
has_rdoc: true
|
128
130
|
homepage: http://github.com/billdueber/marcspec
|
129
131
|
licenses: []
|
@@ -164,3 +166,4 @@ test_files:
|
|
164
166
|
- spec/marcspec_spec.rb
|
165
167
|
- spec/solrfieldspec_spec.rb
|
166
168
|
- spec/spec_helper.rb
|
169
|
+
- spec/specset_spec.rb
|