ess 0.9.1 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +8 -0
- data/Gemfile +4 -1
- data/README.md +16 -18
- data/Rakefile +3 -0
- data/lib/ess/dtd.rb +6 -12
- data/lib/ess/element.rb +1 -1
- data/lib/ess/validation.rb +24 -9
- data/lib/ess/version.rb +1 -1
- data/spec/ess/element_spec.rb +44 -20
- metadata +3 -2
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
ruby-ess
|
2
|
-
|
1
|
+
ruby-ess [![ESS Feed Standard](http://essfeed.org/images/8/87/ESS_logo_32x32.png)](http://essfeed.org/)
|
2
|
+
=======================================================================================================
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
[![ESS Feed Standard](http://essfeed.org/images/8/87/ESS_logo_32x32.png)](http://essfeed.org/)
|
4
|
+
[![Build Status](https://travis-ci.org/essfeed/ruby-ess.png)](https://travis-ci.org/essfeed/ruby-ess)
|
7
5
|
|
8
6
|
Generate ESS XML feeds with Ruby
|
9
7
|
|
@@ -11,7 +9,7 @@ Generate ESS XML feeds with Ruby
|
|
11
9
|
|
12
10
|
Add this line to your application's Gemfile:
|
13
11
|
|
14
|
-
gem 'ess', '~> 0.9.
|
12
|
+
gem 'ess', '~> 0.9.3'
|
15
13
|
|
16
14
|
And then execute:
|
17
15
|
|
@@ -19,7 +17,7 @@ And then execute:
|
|
19
17
|
|
20
18
|
Or install it yourself as:
|
21
19
|
|
22
|
-
$ gem install ess -v 0.9.
|
20
|
+
$ gem install ess -v 0.9.3
|
23
21
|
|
24
22
|
## Usage
|
25
23
|
|
@@ -30,7 +28,7 @@ it's done, with most of the available tags available in ESS:
|
|
30
28
|
|
31
29
|
require 'ess'
|
32
30
|
|
33
|
-
ess = Maker.make do |ess|
|
31
|
+
ess = ESS::Maker.make do |ess|
|
34
32
|
ess.channel do |channel|
|
35
33
|
channel.title "National Stadium Football events"
|
36
34
|
channel.link "http://sample.com/feeds/sample.ess"
|
@@ -231,7 +229,7 @@ add an option to the 'make' class method:
|
|
231
229
|
|
232
230
|
```ruby
|
233
231
|
|
234
|
-
ess = Maker.make(:push => true) do |ess|
|
232
|
+
ess = ESS::Maker.make(:push => true) do |ess|
|
235
233
|
|
236
234
|
...
|
237
235
|
|
@@ -250,7 +248,7 @@ provide the aggregator with more useful data:
|
|
250
248
|
|
251
249
|
```ruby
|
252
250
|
|
253
|
-
ess = Maker.make(:request => request) do |ess|
|
251
|
+
ess = ESS::Maker.make(:request => request) do |ess|
|
254
252
|
|
255
253
|
...
|
256
254
|
|
@@ -263,7 +261,7 @@ can be done with the aggregators option:
|
|
263
261
|
|
264
262
|
```ruby
|
265
263
|
|
266
|
-
ess = Maker.make(:aggregators => ['http://aggregator.example.com/api.json', ...]) do |ess|
|
264
|
+
ess = ESS::Maker.make(:aggregators => ['http://aggregator.example.com/api.json', ...]) do |ess|
|
267
265
|
|
268
266
|
...
|
269
267
|
|
@@ -272,7 +270,7 @@ end
|
|
272
270
|
```
|
273
271
|
|
274
272
|
Another option is to set a new default list of aggregator services
|
275
|
-
using the Pusher class:
|
273
|
+
using the ESS::Pusher class:
|
276
274
|
|
277
275
|
```ruby
|
278
276
|
|
@@ -282,7 +280,7 @@ ESS::Pusher.aggregators = ['http://aggregator.example.com/api.json', ...]
|
|
282
280
|
|
283
281
|
### Validation
|
284
282
|
|
285
|
-
When using the Maker class, the resulting feed is
|
283
|
+
When using the ESS::Maker class, the resulting feed is
|
286
284
|
validated automatically at the end of the block. That means that
|
287
285
|
before the block ends, the feed has to have all the mandatory
|
288
286
|
tags, with valid values. There is however an option to turn that
|
@@ -290,7 +288,7 @@ behavior off, but there should be a good reason to do that.
|
|
290
288
|
|
291
289
|
```ruby
|
292
290
|
|
293
|
-
ess = Maker.make(:validate => false) do |ess|
|
291
|
+
ess = ESS::Maker.make(:validate => false) do |ess|
|
294
292
|
|
295
293
|
...
|
296
294
|
|
@@ -308,7 +306,7 @@ A tag with text can be specified like this:
|
|
308
306
|
|
309
307
|
```ruby
|
310
308
|
|
311
|
-
ess = Maker.make do |ess|
|
309
|
+
ess = ESS::Maker.make do |ess|
|
312
310
|
ess.channel do |channel|
|
313
311
|
|
314
312
|
channel.title "National Stadium Football events"
|
@@ -333,7 +331,7 @@ same name, the following construct can be used:
|
|
333
331
|
|
334
332
|
```ruby
|
335
333
|
|
336
|
-
ess = Maker.make do |ess|
|
334
|
+
ess = ESS::Maker.make do |ess|
|
337
335
|
ess.channel do |channel|
|
338
336
|
|
339
337
|
channel.add_feed do |feed|
|
@@ -361,7 +359,7 @@ Attributes have also their own methods for setting them, for example:
|
|
361
359
|
|
362
360
|
```ruby
|
363
361
|
|
364
|
-
ess = Maker.make do |ess|
|
362
|
+
ess = ESS::Maker.make do |ess|
|
365
363
|
ess.lang_attr "zu"
|
366
364
|
|
367
365
|
...
|
@@ -375,7 +373,7 @@ also a 'text!' method, which can be used to set a tags text:
|
|
375
373
|
|
376
374
|
```ruby
|
377
375
|
|
378
|
-
ess = Maker.make do |ess|
|
376
|
+
ess = ESS::Maker.make do |ess|
|
379
377
|
ess.channel do |channel|
|
380
378
|
|
381
379
|
channel.title do |title|
|
data/Rakefile
CHANGED
data/lib/ess/dtd.rb
CHANGED
@@ -106,11 +106,7 @@ module ESS
|
|
106
106
|
:interval => { :mandatory => false,
|
107
107
|
:max_occurs => 1 },
|
108
108
|
:selected_day => { :mandatory => false,
|
109
|
-
:max_occurs => :inf,
|
110
|
-
:valid_values => [
|
111
|
-
'number','monday','tuesday',
|
112
|
-
'wednesday','thursday','friday',
|
113
|
-
'saturday','sunday'] },
|
109
|
+
:max_occurs => :inf },
|
114
110
|
:selected_week => { :mandatory => false,
|
115
111
|
:max_occurs => :inf,
|
116
112
|
:valid_values => [
|
@@ -127,7 +123,8 @@ module ESS
|
|
127
123
|
:duration => { :dtd => BASIC_ELEMENT,
|
128
124
|
:mandatory => false,
|
129
125
|
:max_occurs => 1 } },
|
130
|
-
:validation => [ UnitMandatoryIfRecurrent.new
|
126
|
+
:validation => [ UnitMandatoryIfRecurrent.new,
|
127
|
+
SelectedDayCheck.new ]
|
131
128
|
}
|
132
129
|
|
133
130
|
DATES = {
|
@@ -216,11 +213,7 @@ module ESS
|
|
216
213
|
:interval => { :mandatory => false,
|
217
214
|
:max_occurs => 1 },
|
218
215
|
:selected_day => { :mandatory => false,
|
219
|
-
:max_occurs => :inf,
|
220
|
-
:valid_values => [
|
221
|
-
'number','monday','tuesday',
|
222
|
-
'wednesday','thursday','friday',
|
223
|
-
'saturday','sunday'] },
|
216
|
+
:max_occurs => :inf },
|
224
217
|
:selected_week => { :mandatory => false,
|
225
218
|
:max_occurs => :inf,
|
226
219
|
:valid_values => [
|
@@ -247,7 +240,8 @@ module ESS
|
|
247
240
|
:mandatory => false,
|
248
241
|
:max_occurs => 1 } },
|
249
242
|
:validation => [ CurrMandatoryIfValueGT0.new,
|
250
|
-
UnitMandatoryIfRecurrent.new
|
243
|
+
UnitMandatoryIfRecurrent.new,
|
244
|
+
SelectedDayCheck.new ]
|
251
245
|
}
|
252
246
|
|
253
247
|
PRICES = {
|
data/lib/ess/element.rb
CHANGED
@@ -131,7 +131,7 @@ module ESS
|
|
131
131
|
if args.length > 0 && args[0].class != Hash
|
132
132
|
if @dtd[:tags][m].include? :valid_values
|
133
133
|
unless @dtd[:tags][m][:valid_values].include?(args[0])
|
134
|
-
raise InvalidValueError, "\"#{args[0]}\" is not a valid value for the #{m} tag"
|
134
|
+
raise DTD::InvalidValueError, "\"#{args[0]}\" is not a valid value for the #{m} tag"
|
135
135
|
end
|
136
136
|
end
|
137
137
|
tag_list[0].text!(args[0])
|
data/lib/ess/validation.rb
CHANGED
@@ -10,7 +10,7 @@ module ESS
|
|
10
10
|
class TextIsNotNull
|
11
11
|
def validate tag
|
12
12
|
if tag.text!.strip == ''
|
13
|
-
raise
|
13
|
+
raise ValidationError, "the <#{tag.tag_name}> element cannot be empty"
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -25,7 +25,7 @@ module ESS
|
|
25
25
|
def validate_url text
|
26
26
|
unless text =~ /^(http|https|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i || text.length > 10
|
27
27
|
unless isValidIP text
|
28
|
-
raise
|
28
|
+
raise ValidationError, "invalid URL: #{text}"
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -54,7 +54,7 @@ module ESS
|
|
54
54
|
class TextIsValidLatitude
|
55
55
|
def validate tag
|
56
56
|
unless tag.text! =~ /^-?([0-8]?[0-9]|90)\.[0-9]{1,6}$/
|
57
|
-
raise
|
57
|
+
raise ValidationError, "invalid latitude: #{tag.text!}"
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
@@ -62,7 +62,7 @@ module ESS
|
|
62
62
|
class TextIsValidLongitude
|
63
63
|
def validate tag
|
64
64
|
unless tag.text! =~ /^-?((1?[0-7]?|[0-9]?)[0-9]|180)\.[0-9]{1,6}$/
|
65
|
-
raise
|
65
|
+
raise ValidationError, "invalid longitude: #{tag.text!}"
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
@@ -321,7 +321,7 @@ module ESS
|
|
321
321
|
|
322
322
|
def validate tag
|
323
323
|
unless COUNTRY_CODES.keys.include? tag.text!.strip.upcase
|
324
|
-
raise
|
324
|
+
raise ValidationError, "invalid country code: #{tag.text!}"
|
325
325
|
end
|
326
326
|
end
|
327
327
|
end
|
@@ -572,7 +572,7 @@ module ESS
|
|
572
572
|
|
573
573
|
def validate tag
|
574
574
|
unless CURRENCIES.values.include? tag.text!.strip.upcase
|
575
|
-
raise
|
575
|
+
raise ValidationError, "invalid currency: #{tag.text!}"
|
576
576
|
end
|
577
577
|
end
|
578
578
|
end
|
@@ -581,7 +581,7 @@ module ESS
|
|
581
581
|
def validate price_tag
|
582
582
|
if price_tag.value.text!.to_i != 0
|
583
583
|
if price_tag.currency.text! == ""
|
584
|
-
raise
|
584
|
+
raise ValidationError, "the <currency> element of a price item cannot be empty if <value> is not 0"
|
585
585
|
end
|
586
586
|
end
|
587
587
|
end
|
@@ -777,7 +777,7 @@ module ESS
|
|
777
777
|
|
778
778
|
def validate ess_tag
|
779
779
|
unless LANGUAGES.has_key?(ess_tag.lang_attr) || ess_tag.lang_attr == ""
|
780
|
-
raise
|
780
|
+
raise ValidationError, "the \"lang\" attribute value is invalid: #{ess_tag.lang_attr}"
|
781
781
|
end
|
782
782
|
end
|
783
783
|
end
|
@@ -786,7 +786,22 @@ module ESS
|
|
786
786
|
def validate item_tag
|
787
787
|
if item_tag.type_attr == "recurrent"
|
788
788
|
unless item_tag.unit_attr != ""
|
789
|
-
raise
|
789
|
+
raise ValidationError, "the \"unit\" attribute is mandatory in a date item if type is recurrent"
|
790
|
+
end
|
791
|
+
end
|
792
|
+
end
|
793
|
+
end
|
794
|
+
|
795
|
+
DAYS_OF_WEEK = [ 'monday', 'tuesday', 'wednesday', 'thursday', 'friday',
|
796
|
+
'saturday', 'sunday']
|
797
|
+
class SelectedDayCheck
|
798
|
+
def validate date_item_tag
|
799
|
+
sday = date_item_tag.selected_day_attr
|
800
|
+
if !sday.empty?
|
801
|
+
values = sday.split(",")
|
802
|
+
bad_values = values.delete_if { |day| DAYS_OF_WEEK.include?(day) || day.to_i.to_s == day }
|
803
|
+
if bad_values.any?
|
804
|
+
raise ValidationError, "the values \"#{bad_values}\" are not allowed in the \"selected_day\" attribute of date items"
|
790
805
|
end
|
791
806
|
end
|
792
807
|
end
|
data/lib/ess/version.rb
CHANGED
data/spec/ess/element_spec.rb
CHANGED
@@ -7,8 +7,8 @@ module ESS
|
|
7
7
|
|
8
8
|
describe '#new' do
|
9
9
|
it 'should require a name and a DTD argument' do
|
10
|
-
expect { Element.new }.to raise_error
|
11
|
-
expect { Element.new :tag_name }.to raise_error
|
10
|
+
expect { Element.new }.to raise_error(ArgumentError)
|
11
|
+
expect { Element.new :tag_name }.to raise_error(ArgumentError)
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'should accept a hash with both :attributes and :tags keys' do
|
@@ -68,9 +68,9 @@ module ESS
|
|
68
68
|
let(:element) { Element.new(:tags, DTD::TAGS) }
|
69
69
|
|
70
70
|
it 'should return an error when trying to set an invalid tag' do
|
71
|
-
expect { element.bad "Example text" }.to raise_error
|
72
|
-
expect { element.bad }.to raise_error
|
73
|
-
expect { element.add_bad "Example text" }.to raise_error
|
71
|
+
expect { element.bad "Example text" }.to raise_error(NoMethodError)
|
72
|
+
expect { element.bad }.to raise_error(NoMethodError)
|
73
|
+
expect { element.add_bad "Example text" }.to raise_error(NoMethodError)
|
74
74
|
end
|
75
75
|
|
76
76
|
describe '#tag' do
|
@@ -250,19 +250,7 @@ module ESS
|
|
250
250
|
end
|
251
251
|
|
252
252
|
it 'should raise error if an invalid value was used for an attribute' do
|
253
|
-
expect { element.type_attr "bad_value" }.to raise_error
|
254
|
-
end
|
255
|
-
|
256
|
-
it 'should allow multiple comma separated valid values' do
|
257
|
-
lambda {
|
258
|
-
element.selected_day_attr "friday,saturday"
|
259
|
-
}.should_not raise_error
|
260
|
-
end
|
261
|
-
|
262
|
-
it 'should raise error if one value is valid and the other is not' do
|
263
|
-
expect {
|
264
|
-
element.selected_day_attr "friday,bad"
|
265
|
-
}.to raise_error
|
253
|
+
expect { element.type_attr "bad_value" }.to raise_error(DTD::InvalidValueError)
|
266
254
|
end
|
267
255
|
end
|
268
256
|
|
@@ -355,7 +343,7 @@ module ESS
|
|
355
343
|
end
|
356
344
|
|
357
345
|
it 'should not allow other values' do
|
358
|
-
expect { element.access "bad" }.to raise_error
|
346
|
+
expect { element.access "bad" }.to raise_error(DTD::InvalidValueError)
|
359
347
|
end
|
360
348
|
end
|
361
349
|
end
|
@@ -650,7 +638,7 @@ module ESS
|
|
650
638
|
it 'should raise an error' do
|
651
639
|
lambda {
|
652
640
|
element.validate
|
653
|
-
}.should raise_error
|
641
|
+
}.should raise_error(Validation::ValidationError)
|
654
642
|
end
|
655
643
|
end
|
656
644
|
end
|
@@ -756,6 +744,42 @@ module ESS
|
|
756
744
|
end
|
757
745
|
end
|
758
746
|
|
747
|
+
context "a date item with selected_day attribute" do
|
748
|
+
let(:item) do
|
749
|
+
element = Element.new :item, DTD::DATE_ITEM
|
750
|
+
element.type_attr "recurrent"
|
751
|
+
element.unit_attr "month"
|
752
|
+
element.name "A date"
|
753
|
+
element.start Time.now
|
754
|
+
element
|
755
|
+
end
|
756
|
+
|
757
|
+
it 'should be invalid if the attribute has a random value' do
|
758
|
+
item.selected_day_attr "randomvalue"
|
759
|
+
item.should_not be_valid
|
760
|
+
end
|
761
|
+
|
762
|
+
it 'should be valid if the value is a day of the week' do
|
763
|
+
item.selected_day_attr "tuesday"
|
764
|
+
item.should be_valid
|
765
|
+
end
|
766
|
+
|
767
|
+
it 'should be valid if the value is a number' do
|
768
|
+
item.selected_day_attr "1"
|
769
|
+
item.should be_valid
|
770
|
+
end
|
771
|
+
|
772
|
+
it 'should be valid if the value is a comma-separated array of names of days of the week' do
|
773
|
+
item.selected_day_attr "monday,tuesday,sunday"
|
774
|
+
item.should be_valid
|
775
|
+
end
|
776
|
+
|
777
|
+
it 'should be valid if the value is a comma-separated array of numbers' do
|
778
|
+
item.selected_day_attr "1,30,31"
|
779
|
+
item.should be_valid
|
780
|
+
end
|
781
|
+
end
|
782
|
+
|
759
783
|
context "a price item" do
|
760
784
|
let(:element) do
|
761
785
|
element = Element.new(:item, DTD::PRICE_ITEM)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ess
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-06-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: builder
|
@@ -37,6 +37,7 @@ extra_rdoc_files: []
|
|
37
37
|
files:
|
38
38
|
- .gitignore
|
39
39
|
- .rspec
|
40
|
+
- .travis.yml
|
40
41
|
- Gemfile
|
41
42
|
- LICENSE.txt
|
42
43
|
- README.md
|