ddr-models 3.0.0.rc1 → 3.0.0.rc2

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: 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