ddr-models 3.0.0.rc1 → 3.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3e6b6dc994859b545193b3ab914a59a97d465a9a
4
- data.tar.gz: 3bcd281d06aa80c0fa1eb970d809e55eae905d26
3
+ metadata.gz: 7de034ef99997f329a03eca2b79eee78a8a6ae12
4
+ data.tar.gz: 3d0f8694d937b5b6a6bfbf94f0889af0520c3ecb
5
5
  SHA512:
6
- metadata.gz: d69f123b6661631477dd7d6722ef911bde491831d38ed0f4f14eabd7b33649622e517353d8445a101278018fad45ea014cb1bbe2134dba5c961f06fab5d86550
7
- data.tar.gz: 73050a50d9221d5ec777183b319862a64b2a724b24caf4d22c72f6cca011d6f43b8fd8241479772b6d4abe027503f1658abf2aa00f6ea191f76b2fedeb2b4fe6
6
+ metadata.gz: 7d279fe99f40579c4409eaf63e89213c42c644f6836c50a56c2701602be81a86045ade82d993adb5bcc4f08511a1d66859d72dacfca41f6b1c62d7e5e5e6052b
7
+ data.tar.gz: db68f4040d5ac62d39a71bc7f7630ea297d2b07038812672a57273f7299caf3f05db2d31f5972362ed1cef74e006e079add3f166e9199b59fb7dd0dfa18dad8a
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
34
34
  s.add_dependency "ddr-antivirus", "~> 2.1.1"
35
35
  s.add_dependency "virtus", "~> 1.0.5"
36
36
  s.add_dependency "hashie", "~> 3.4.3"
37
+ s.add_dependency "edtf", "~> 2.3"
37
38
 
38
39
  s.add_development_dependency "bundler", "~> 1.11", ">= 1.11.2"
39
40
  s.add_development_dependency "rake"
@@ -1,5 +1,5 @@
1
1
  module Ddr
2
2
  module Models
3
- VERSION = "3.0.0.rc1"
3
+ VERSION = "3.0.0.rc2"
4
4
  end
5
5
  end
@@ -1,153 +1,95 @@
1
1
  require "date"
2
+ require "edtf"
2
3
 
3
4
  module Ddr::Models
4
5
  class YearFacet
5
6
 
6
7
  EARLIEST_YEAR = 1000
8
+ LATEST_YEAR = Date.today.year + 100
9
+ VALID_YEARS = (EARLIEST_YEAR..LATEST_YEAR)
10
+ VALUE_SEP = /;/
7
11
 
8
12
  # Between 1965 and 1968
9
13
  BETWEEN = Regexp.new '\A([Bb]etween\s+)(\d{4})(\s+and\s+)(\d{4})\??\z'
10
14
 
11
- # YYYx (192x)
12
- # YYYX (192X)
13
- # YYY? (192?)
14
- # YYY- (192-)
15
- # YYY-? (192-?)
16
- IN_DECADE = Regexp.new '\A(\d{3})([xX\-]\??|\?)\z'
17
-
18
- # YYxx (19xx)
19
- IN_CENTURY = Regexp.new '\A(\d{2})xx\z'
20
-
21
- # YYY0s (1920s)
22
- # YYY0s? (1920s?)
23
- DECADE = Regexp.new '\A(\d{3}0)s\??\z'
24
-
25
- # YYYY-MM (2010-01)
26
- # YYYY/MM (2010/01)
27
- YEAR_MONTH = Regexp.new '\A(\d{4})[/-](0[1-9]|1[0-2])\z'
28
-
29
- # YYYY-YYYY (1935-2010)
30
- # YYYY/YYYY (1935/2010)
31
- YEAR_RANGE = Regexp.new '\A(\d{4})[/-](\d{4})\z'
32
-
33
- # YYYY (1979)
34
- YEAR = Regexp.new '\A\d{4}\z'
35
-
36
- SQUARE_BRACKETS = Regexp.new '[\[\]]'
37
-
38
- # c. 1920
39
- # ca. 1920
40
- # c1920
15
+ # circa 1920, ca. 1920, c1920 => 1920
41
16
  CIRCA = Regexp.new '\b(circa\s+|ca?\.\s*|c(?=\d{4}[^\d]*))'
42
17
 
43
- class << self
44
- def call(obj)
45
- new(obj).values
46
- end
47
- end
48
-
49
- attr_reader :obj, :values
50
-
51
- def initialize(obj)
52
- @obj = obj
53
- @values = []
54
- facet_values
55
- end
56
-
57
- def facet_values
58
- obj.desc_metadata.date.each do |date|
59
- date.split(/;/).each do |value|
60
- clean! value
61
- years = extract_years(value)
62
- validate! years
63
- values.push *years
64
- end
65
- end
66
- end
67
-
68
- def extract_years(value)
69
- years = match_years(value) || parse_year(value)
70
- Array(years)
71
- end
72
-
73
- def clean!(value)
74
- value.strip!
75
- value.gsub! SQUARE_BRACKETS, ""
76
- value.gsub! CIRCA, ""
77
- end
18
+ # 1935-1940 => 1935/1940
19
+ YEAR_RANGE = Regexp.new '(?<=\d{4})-(?=\d{4})'
78
20
 
79
- def validate!(years)
80
- years = years & valid_years.to_a
81
- end
21
+ # 1920s, 1920s?, 192u, 192-, 192-?, 192? => 192x
22
+ DECADE = Regexp.new '(?<=\A\d{3})(-\??|0s\??|u|\?)\z'
82
23
 
83
- def parse_year(value)
84
- Date.parse(value).year
85
- rescue ArgumentError
86
- nil
87
- end
24
+ # 2010/01 => 2010-01
25
+ MONTH = Regexp.new '(?<=\A\d{4})\/(?=\d{2}\z)'
88
26
 
89
- def valid_years
90
- (EARLIEST_YEAR..latest_year)
91
- end
27
+ # 193u/, 193x/ => 1930/
28
+ START_DECADE = Regexp.new '(?<=\d{3})[uxX](?=\/)'
92
29
 
93
- def latest_year
94
- Date.today.year + 100
95
- end
30
+ # /194x, /194u => /1949
31
+ END_DECADE = Regexp.new '(?<=\/\d{3})[uxX]'
96
32
 
97
- def match_years(value)
98
- result = match_year_range(value) ||
99
- match_year_month(value) ||
100
- match_year(value) ||
101
- match_in_decade(value) ||
102
- match_in_century(value) ||
103
- match_decade(value) ||
104
- match_between(value)
105
- first_year, last_year = Array(result).map(&:to_i)
106
- last_year ? (first_year..last_year) : first_year
107
- end
33
+ # 19uu => 19xx
34
+ CENTURY = Regexp.new '(?<=\A\d{2})uu(?=\z)'
108
35
 
109
- def match_year_range(value)
110
- if m = YEAR_RANGE.match(value)
111
- m[1, 2]
112
- end
36
+ def self.call(object)
37
+ new(object).call
113
38
  end
114
39
 
115
- def match_year_month(value)
116
- if m = YEAR_MONTH.match(value)
117
- m[1]
118
- end
119
- end
40
+ attr_reader :object
120
41
 
121
- def match_year(value)
122
- if m = YEAR.match(value)
123
- value
124
- end
42
+ def initialize(object)
43
+ @object = object
125
44
  end
126
45
 
127
- def match_in_decade(value)
128
- if m = IN_DECADE.match(value)
129
- [ "#{m[1]}0", "#{m[1]}9" ]
46
+ def call
47
+ source_dates.each_with_object([]) do |date, facet_values|
48
+ date.split(VALUE_SEP).each do |value|
49
+ value.strip!
50
+ edtf_date = convert_to_edtf(value)
51
+ years = Array(edtf_years(edtf_date))
52
+ years.select! { |year| VALID_YEARS.include?(year) }
53
+ facet_values.push(*years)
54
+ end
130
55
  end
131
56
  end
132
57
 
133
- def match_in_century(value)
134
- if m = IN_CENTURY.match(value)
135
- [ "#{m[1]}00", "#{m[1]}99" ]
136
- end
137
- end
58
+ private
138
59
 
139
- def match_decade(value)
140
- if m = DECADE.match(value)
141
- [ m[1], m[1].sub(/0\z/, "9") ]
142
- end
60
+ def source_dates
61
+ object.desc_metadata.date
143
62
  end
144
63
 
145
- def match_between(value)
64
+ def convert_to_edtf(value)
146
65
  if m = BETWEEN.match(value)
147
66
  value.sub! m[1], "" # [Bb]etween
148
- value.sub! m[3], "-" # and
149
- match_year_range(value)
67
+ value.sub! m[3], "/" # and
150
68
  end
69
+ substitutions.reduce(value) { |memo, (regexp, repl)| memo.gsub(regexp, repl) }
70
+ end
71
+
72
+ def substitutions
73
+ [
74
+ [ CIRCA, "" ],
75
+ [ YEAR_RANGE, "/" ],
76
+ [ DECADE, "x" ],
77
+ [ MONTH, "-" ],
78
+ [ START_DECADE, "0" ],
79
+ [ END_DECADE, "9" ],
80
+ [ CENTURY, "xx" ],
81
+ ]
82
+ end
83
+
84
+ def edtf_years(value)
85
+ case parsed = EDTF.parse!(value)
86
+ when Date, EDTF::Season
87
+ parsed.year
88
+ when EDTF::Set, EDTF::Interval, EDTF::Epoch
89
+ parsed.map(&:year).uniq
90
+ end
91
+ rescue ArgumentError # EDTF cannot parse
92
+ nil
151
93
  end
152
94
 
153
95
  end
@@ -1,64 +1,91 @@
1
1
  module Ddr::Models
2
2
  RSpec.describe YearFacet do
3
3
 
4
- subject { described_class.new(obj) }
4
+ subject { described_class.call(obj) }
5
5
  let(:obj) { Item.new }
6
6
  before { obj.dc_date = [ date ] }
7
7
 
8
8
  describe "splitting on semicolons" do
9
9
  let(:date) { "1935; 1936; 1937; 1938" }
10
- its(:values) { is_expected.to eq([1935, 1936, 1937, 1938]) }
10
+ it { is_expected.to eq([1935, 1936, 1937, 1938]) }
11
11
  end
12
12
 
13
13
  describe "year range" do
14
- %w( 1935-1940 1935/1940 ).each do |value|
14
+ %w( 1935-1940 1935/1940 1935?/1940? 1935~/1940~ ).each do |value|
15
15
  describe value do
16
16
  let(:date) { value }
17
- its(:values) { is_expected.to eq((1935..1940).to_a) }
17
+ it { is_expected.to eq((1935..1940).to_a) }
18
18
  end
19
19
  end
20
20
  end
21
21
 
22
- describe "in decade" do
23
- %w( 192x 192X 192? 192- 192-? ).each do |value|
22
+ describe "decade" do
23
+ %w( 192u 192x 192X 192? 192- 192-? 1920s 1920s? ).each do |value|
24
24
  describe value do
25
25
  let(:date) { value }
26
- its(:values) { is_expected.to eq((1920..1929).to_a) }
26
+ it { is_expected.to eq((1920..1929).to_a) }
27
27
  end
28
28
  end
29
29
  end
30
30
 
31
- describe "in century -- YYxx (19xx)" do
32
- let(:date) { "19xx" }
33
- its(:values) { is_expected.to eq((1900..1999).to_a) }
31
+ describe "century" do
32
+ %w( 19xx 19uu ).each do |value|
33
+ describe value do
34
+ let(:date) { value }
35
+ it { is_expected.to eq((1900..1999).to_a) }
36
+ end
37
+ end
34
38
  end
35
39
 
36
- describe "decade" do
37
- %w( 1920s 1920s? ).each do |value|
40
+ describe "uncertain interval" do
41
+ let(:date) { "199u/200u" }
42
+ it { is_expected.to eq((1990..2009).to_a) }
43
+ end
44
+
45
+ describe "set" do
46
+ let(:date) { "[1999,2000,2003]" }
47
+ it { is_expected.to eq([1999, 2000, 2003]) }
48
+ end
49
+
50
+ describe "year" do
51
+ %w( 2010 2010? 2010~ ).each do |value|
38
52
  describe value do
39
53
  let(:date) { value }
40
- its(:values) { is_expected.to eq((1920..1929).to_a) }
54
+ it { is_expected.to eq([2010]) }
41
55
  end
42
56
  end
43
57
  end
44
58
 
45
- describe "year + month" do
46
- %w( 2010-01 2010/01 ).each do |value|
59
+ describe "month" do
60
+ %w( 2010-01 2010/01 2010-12? 2010-11/2010-12 ).each do |value|
47
61
  describe value do
48
62
  let(:date) { value }
49
- its(:values) { is_expected.to eq([2010]) }
63
+ it { is_expected.to eq([2010]) }
50
64
  end
51
65
  end
52
66
  end
53
67
 
54
- describe "between" do
55
- let(:date) { "Between 1965 and 1968" }
56
- its(:values) { is_expected.to eq((1965..1968).to_a) }
68
+ describe "day" do
69
+ %w( 2010-12-10 2010-12-10? 2010-12-10/2010-12-20 ).each do |value|
70
+ describe value do
71
+ let(:date) { value }
72
+ it { is_expected.to eq([2010]) }
73
+ end
74
+ end
57
75
  end
58
76
 
59
- describe "year" do
60
- let(:date) { "1965" }
61
- its(:values) { is_expected.to eq([1965]) }
77
+ describe "season" do
78
+ %w( 2010-21 2010-22 2010-23 2010-24 ).each do |value|
79
+ describe value do
80
+ let(:date) { value }
81
+ it { is_expected.to eq([2010]) }
82
+ end
83
+ end
84
+ end
85
+
86
+ describe "between" do
87
+ let(:date) { "Between 1965 and 1968" }
88
+ it { is_expected.to eq((1965..1968).to_a) }
62
89
  end
63
90
 
64
91
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ddr-models
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.rc1
4
+ version: 3.0.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Coble
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-04-22 00:00:00.000000000 Z
12
+ date: 2016-05-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -235,6 +235,20 @@ dependencies:
235
235
  - - "~>"
236
236
  - !ruby/object:Gem::Version
237
237
  version: 3.4.3
238
+ - !ruby/object:Gem::Dependency
239
+ name: edtf
240
+ requirement: !ruby/object:Gem::Requirement
241
+ requirements:
242
+ - - "~>"
243
+ - !ruby/object:Gem::Version
244
+ version: '2.3'
245
+ type: :runtime
246
+ prerelease: false
247
+ version_requirements: !ruby/object:Gem::Requirement
248
+ requirements:
249
+ - - "~>"
250
+ - !ruby/object:Gem::Version
251
+ version: '2.3'
238
252
  - !ruby/object:Gem::Dependency
239
253
  name: bundler
240
254
  requirement: !ruby/object:Gem::Requirement