ess 0.9.1
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/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +448 -0
- data/Rakefile +5 -0
- data/ess.gemspec +21 -0
- data/lib/ess/dtd.rb +491 -0
- data/lib/ess/element.rb +266 -0
- data/lib/ess/ess.rb +8 -0
- data/lib/ess/examples.rb +432 -0
- data/lib/ess/helpers.rb +22 -0
- data/lib/ess/maker.rb +24 -0
- data/lib/ess/postprocessing.rb +69 -0
- data/lib/ess/pusher.rb +63 -0
- data/lib/ess/validation.rb +797 -0
- data/lib/ess/version.rb +3 -0
- data/lib/ess.rb +13 -0
- data/spec/ess/element_spec.rb +796 -0
- data/spec/ess/full_spec.rb +47 -0
- data/spec/ess/maker_spec.rb +30 -0
- data/spec/spec_helper.rb +5 -0
- metadata +88 -0
data/lib/ess/examples.rb
ADDED
@@ -0,0 +1,432 @@
|
|
1
|
+
module ESS
|
2
|
+
module Examples
|
3
|
+
|
4
|
+
def self.from_essfeeds_org_home
|
5
|
+
ess = Maker.make do |ess|
|
6
|
+
ess.channel do |channel|
|
7
|
+
channel.title "National Stadium Football events"
|
8
|
+
channel.link "http://sample.com/feeds/sample.ess"
|
9
|
+
channel.id "ESSID:50b4b412-1ad4-a731-1c6a-2523ffa33f81"
|
10
|
+
channel.published "2012-12-13T08:29:29Z"
|
11
|
+
channel.updated "2012-12-13T18:30:02-08:00"
|
12
|
+
channel.generator "ess:ruby:generator:version:0.9"
|
13
|
+
channel.rights "Copyright (c) 2013, John Doe"
|
14
|
+
|
15
|
+
channel.add_feed do |feed|
|
16
|
+
feed.title "Football match of saturday"
|
17
|
+
feed.uri "http://sample.com/events/specific-and-unique-event-page/"
|
18
|
+
feed.id "EVENTID:550b55b412-1ad4-a4731-155-2777fa37f866"
|
19
|
+
feed.published "2012-12-13T08:29:29Z"
|
20
|
+
feed.updated "2012-12-13T18:30:02-0800"
|
21
|
+
feed.access "PUBLIC"
|
22
|
+
feed.description("Welcome to my first football match event. " +
|
23
|
+
"This football match is very important. " +
|
24
|
+
"Our team is about to go up against our main league competitor.")
|
25
|
+
|
26
|
+
feed.tags do |tags|
|
27
|
+
tags.tag "Sport"
|
28
|
+
tags.tag "Footbal"
|
29
|
+
tags.tag "Soccer"
|
30
|
+
tags.tag "Match"
|
31
|
+
tags.tag "Game"
|
32
|
+
tags.tag "Team Sport"
|
33
|
+
tags.tag "Stadium"
|
34
|
+
end
|
35
|
+
|
36
|
+
feed.categories.add_item(:type => "competition") do |item|
|
37
|
+
item.name "Football"
|
38
|
+
item.id "C2AH"
|
39
|
+
end
|
40
|
+
|
41
|
+
feed.dates.add_item do |item|
|
42
|
+
item.type_attr "recurrent"
|
43
|
+
item.unit_attr "week"
|
44
|
+
item.limit_attr "4"
|
45
|
+
item.selected_day_attr "saturday,sunday"
|
46
|
+
|
47
|
+
item.name "Match Date"
|
48
|
+
item.start "2011-12-13T18:30:02Z"
|
49
|
+
item.duration "10800"
|
50
|
+
end
|
51
|
+
|
52
|
+
feed.places do |places|
|
53
|
+
places.add_item(:type => "fixed", :priority => 1) do |item|
|
54
|
+
item.name "Football Stade"
|
55
|
+
item.latitude "40.71675"
|
56
|
+
item.longitude "-74.00674"
|
57
|
+
item.address "Ave of Americas, 871"
|
58
|
+
item.city "New York"
|
59
|
+
item.zip "10001"
|
60
|
+
item.state_code "NY"
|
61
|
+
item.country_code "US"
|
62
|
+
end
|
63
|
+
|
64
|
+
places.add_item(:type => "fixed", :priority => 2) do |item|
|
65
|
+
item.name "Match direct on TV"
|
66
|
+
item.country_code "US"
|
67
|
+
item.medium_name "NBC super channel"
|
68
|
+
item.medium_type "television"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
feed.prices do |prices|
|
73
|
+
prices.add_item(:type => "standalone", :priority => 2) do |item|
|
74
|
+
item.mode_attr "invitation"
|
75
|
+
|
76
|
+
item.name "Free entrance"
|
77
|
+
item.value "0"
|
78
|
+
item.currency "USD"
|
79
|
+
end
|
80
|
+
|
81
|
+
prices.add_item(:type => "recurrent", :priority => 1) do |item|
|
82
|
+
item.unit_attr "month"
|
83
|
+
item.mode_attr "fixed"
|
84
|
+
item.limit_attr "12"
|
85
|
+
|
86
|
+
item.name "Subscribe monthly !"
|
87
|
+
item.value "17"
|
88
|
+
item.currency "USD"
|
89
|
+
item.start "2012-12-13T18:30:02Z"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
feed.media do |media|
|
94
|
+
media.add_item(:type => "image", :priority => 1) do |item|
|
95
|
+
item.name "Stade image"
|
96
|
+
item.uri "http://sample.com/small/image_1.png"
|
97
|
+
end
|
98
|
+
|
99
|
+
media.add_item(:type => "video", :priority => 3) do |item|
|
100
|
+
item.name "Stade video"
|
101
|
+
item.uri "http://sample.com/video/movie.mp4"
|
102
|
+
end
|
103
|
+
|
104
|
+
media.add_item(:type => "sound", :priority => 2) do |item|
|
105
|
+
item.name "Radio spot"
|
106
|
+
item.uri "http://sample.com/video/movie.mp3"
|
107
|
+
end
|
108
|
+
|
109
|
+
media.add_item(:type => "website", :priority => 4) do |item|
|
110
|
+
item.name "Football Stade website"
|
111
|
+
item.uri "http://my-football-website.com"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
feed.people do |people|
|
116
|
+
people.add_item(:type => "organizer") do |item|
|
117
|
+
item.id "THJP167:8URYRT24:BUEREBK:567TYEFGU:IPAAF"
|
118
|
+
item.uri "http://michaeldoe.com"
|
119
|
+
item.name "Michael Doe"
|
120
|
+
item.firstname "Michael"
|
121
|
+
item.lastname "Doe"
|
122
|
+
item.organization "Football club association"
|
123
|
+
item.address "80, 5th avenue / 45st E - #504"
|
124
|
+
item.city "New York"
|
125
|
+
item.zip "10001"
|
126
|
+
item.state "New York"
|
127
|
+
item.state_code "NY"
|
128
|
+
item.country "United States of America"
|
129
|
+
item.country_code "US"
|
130
|
+
item.logo "http://sample.com/logo_120x60.png"
|
131
|
+
item.icon "http://sample.com/icon_64x64.png"
|
132
|
+
item.email "contact@sample.com"
|
133
|
+
item.phone "+001 (646) 234-5566"
|
134
|
+
end
|
135
|
+
|
136
|
+
people.add_item(:type => "performer") do |item|
|
137
|
+
item.id "FDH56:G497D6:4564DD465:4F6S4S6"
|
138
|
+
item.uri "http://janettedoe.com"
|
139
|
+
item.name "Janette Doe"
|
140
|
+
end
|
141
|
+
|
142
|
+
people.add_item(:type => "attendee") do |item|
|
143
|
+
item.name "Attendees information:"
|
144
|
+
item.minpeople 0
|
145
|
+
item.maxpeople 500
|
146
|
+
item.minage 0
|
147
|
+
item.restriction "Smoking is not allowed in the stadium"
|
148
|
+
end
|
149
|
+
|
150
|
+
people.add_item(:type => "social") do |item|
|
151
|
+
item.name "Social network link to share or rate the event."
|
152
|
+
item.uri "http://social_network.com/my_events/my_friends/my_notes"
|
153
|
+
end
|
154
|
+
|
155
|
+
people.add_item(:type => "author") do |item|
|
156
|
+
item.name "Feed Powered by Event Promotion Tool"
|
157
|
+
item.uri "http://sample.com/my_events/"
|
158
|
+
item.logo "http://sample.com/logo_120x60.png"
|
159
|
+
item.icon "http://sample.com/icon_64x64.png"
|
160
|
+
end
|
161
|
+
|
162
|
+
people.add_item(:type => "contributor") do |item|
|
163
|
+
item.name "Jane Doe"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
feed.relations do |relations|
|
168
|
+
relations.add_item(:type => "alternative") do |item|
|
169
|
+
item.name "alternative event"
|
170
|
+
item.id "EVENTID:50412:1a904:a715731:1cera:25va33"
|
171
|
+
item.uri "http://sample.com/feed/event_2.ess"
|
172
|
+
end
|
173
|
+
|
174
|
+
relations.add_item(:type => "related") do |item|
|
175
|
+
item.name "related event title"
|
176
|
+
item.id "EVENTID:50b412:1a35d4:a731:1354c6a:225dg1"
|
177
|
+
item.uri "http://sample.com/feed/event_3.ess"
|
178
|
+
end
|
179
|
+
|
180
|
+
relations.add_item(:type => "enclosure") do |item|
|
181
|
+
item.name "nearby event"
|
182
|
+
item.id "EVENTID:50b12:3451d4:34f5a71:1cf6a:2ff81"
|
183
|
+
item.uri "http://sample.com/feed/event_5.ess"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def self.paying_attendees
|
192
|
+
ess = Maker.make do |ess|
|
193
|
+
ess.channel do |channel|
|
194
|
+
channel.title "Studio 54 Events Feed"
|
195
|
+
channel.id "ESSID:65ca2c92-2c98-068e-390d-543c376f8e7d"
|
196
|
+
channel.link "http://example.com/feed/sample.ess"
|
197
|
+
channel.published "2013-06-10T10:55:14Z"
|
198
|
+
|
199
|
+
channel.add_feed do |feed|
|
200
|
+
feed.title "Studio 54 Documentary Night Private Event"
|
201
|
+
feed.id "EVENTID:4e0ea291-0acc-b222-60bb-dda020ca8664"
|
202
|
+
feed.uri "http://studio54.com/events/saturday.html"
|
203
|
+
feed.published "2013-04-23T00:25:33+02:00"
|
204
|
+
feed.access "PRIVATE"
|
205
|
+
feed.description "Get payed to assist to a documentary about the Studio 54"
|
206
|
+
|
207
|
+
feed.categories.add_item :type => "party" do |item|
|
208
|
+
item.name "nightclub"
|
209
|
+
end
|
210
|
+
|
211
|
+
feed.dates.add_item :type => "standalone" do |item|
|
212
|
+
item.name "Only this night"
|
213
|
+
item.start "2013-10-25T15:30:00Z"
|
214
|
+
item.duration "7200"
|
215
|
+
end
|
216
|
+
|
217
|
+
feed.places.add_item :type => "fixed" do |item|
|
218
|
+
item.name "Studio 54"
|
219
|
+
item.address "254 W 54th St"
|
220
|
+
item.city "New York"
|
221
|
+
item.country_code "US"
|
222
|
+
end
|
223
|
+
|
224
|
+
feed.prices.add_item :type => "standalone", :mode => "renumerated" do |item|
|
225
|
+
item.name "Get Paied to Assist to This Documenary"
|
226
|
+
item.value 90
|
227
|
+
item.currency "USD"
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def self.osteopathy_course
|
235
|
+
ess = Maker.make do |ess|
|
236
|
+
ess.channel do |channel|
|
237
|
+
channel.title "London College of Osteopathy Feeds"
|
238
|
+
channel.id "ESSID:65ca2c92-2c98-068e-390d-543c376f8e7d"
|
239
|
+
channel.link "http://example.com/feed/sample.ess"
|
240
|
+
channel.published "2013-06-10T10:55:14Z"
|
241
|
+
|
242
|
+
channel.add_feed do |feed|
|
243
|
+
feed.title "A Twice a Month Intensive Course"
|
244
|
+
feed.id "EVENTID:4e0ea291-0acc-b222-60bb-dda020ca8664"
|
245
|
+
feed.uri "http://londoncollege.com/events/page.html"
|
246
|
+
feed.published "2013-04-23T00:25:33+02:00"
|
247
|
+
feed.access "PUBLIC"
|
248
|
+
feed.description "Intensive classes of six hours each filled with anatomy,\n" +
|
249
|
+
"gerontology, history of osteopathy and physiology"
|
250
|
+
|
251
|
+
feed.categories.add_item :type => "course" do |item|
|
252
|
+
item.name "University Course"
|
253
|
+
end
|
254
|
+
|
255
|
+
feed.tags do |tags|
|
256
|
+
tags.add_tag "Osteopathy"
|
257
|
+
tags.add_tag "Physiology"
|
258
|
+
tags.add_tag "Anatomy"
|
259
|
+
tags.add_tag "Gerontology"
|
260
|
+
end
|
261
|
+
|
262
|
+
feed.dates.add_item :type => "recurrent", :unit => "month", :limit => 6, :selected_day => "saturday", :selected_week => "first,last" do |item|
|
263
|
+
item.name "Course the first and last Saturdays of every month"
|
264
|
+
item.start "2013-10-25T15:30:00Z"
|
265
|
+
item.duration "21600"
|
266
|
+
end
|
267
|
+
|
268
|
+
feed.places.add_item :type => "fixed" do |item|
|
269
|
+
item.name "London College of Osteopathy"
|
270
|
+
item.address "380 Wellington St. Tower B, 6th Floor"
|
271
|
+
item.city "London"
|
272
|
+
item.country_code "GB"
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def self.belfast_festival
|
280
|
+
ess = Maker.make do |ess|
|
281
|
+
ess.channel do |channel|
|
282
|
+
channel.title "Belfast Film Festival Events"
|
283
|
+
channel.id "ESSID:65ca2c92-2c98-068e-390d-543c376f8e7d"
|
284
|
+
channel.link "http://belfastfilmfestival.org/feed/films.ess"
|
285
|
+
channel.published "2013-06-10T10:55:14Z"
|
286
|
+
|
287
|
+
channel.add_feed do |feed|
|
288
|
+
feed.title "First Horror Movie"
|
289
|
+
feed.id "EVENTID:4e0ea291-0acc-b222-60bb-dda020ca8664"
|
290
|
+
feed.uri "http://belfastfilmfestival.org/events/4567FSE/page.html"
|
291
|
+
feed.published "2013-04-23T00:25:33+02:00"
|
292
|
+
feed.access "PUBLIC"
|
293
|
+
feed.description "Description of the first horror movie."
|
294
|
+
|
295
|
+
feed.categories.add_item :type => "festival" do |item|
|
296
|
+
item.name "Horror Movie"
|
297
|
+
item.id "I10"
|
298
|
+
end
|
299
|
+
|
300
|
+
feed.tags do |tags|
|
301
|
+
tags.add_tag "Horror"
|
302
|
+
tags.add_tag "Movie"
|
303
|
+
tags.add_tag "Belfast"
|
304
|
+
tags.add_tag "Festival"
|
305
|
+
end
|
306
|
+
|
307
|
+
feed.dates.add_item :type => "standalone" do |item|
|
308
|
+
item.name "First Representation Date"
|
309
|
+
item.start "2013-10-25T15:30:00Z"
|
310
|
+
item.duration "7200"
|
311
|
+
end
|
312
|
+
|
313
|
+
feed.places.add_item :type => "fixed" do |item|
|
314
|
+
item.name "Congress Hall"
|
315
|
+
item.address "49 Donegall Place"
|
316
|
+
item.city "Belfast"
|
317
|
+
item.country_code "GB"
|
318
|
+
end
|
319
|
+
|
320
|
+
feed.prices.add_item :type => "standalone", :mode => "fixed" do |item|
|
321
|
+
item.name "One Uniq Price"
|
322
|
+
item.value 10
|
323
|
+
item.currency "GBP"
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
channel.add_feed do |feed|
|
328
|
+
feed.title "Second Fantastic Movie"
|
329
|
+
feed.id "EVENTID:4e0ea291-0acc-b222-60bb-dda020ca8664"
|
330
|
+
feed.uri "http://belfastfilmfestival.org/events/45098FSE/page.html"
|
331
|
+
feed.published "2013-04-23T00:25:33+02:00"
|
332
|
+
feed.access "PUBLIC"
|
333
|
+
feed.description "Description of the second fantastic movie."
|
334
|
+
|
335
|
+
feed.categories.add_item :type => "festival" do |item|
|
336
|
+
item.name "Mistery Movie"
|
337
|
+
item.id "I12"
|
338
|
+
end
|
339
|
+
|
340
|
+
feed.tags do |tags|
|
341
|
+
tags.add_tag "Fantastic"
|
342
|
+
tags.add_tag "Mistery"
|
343
|
+
tags.add_tag "Suspense"
|
344
|
+
tags.add_tag "Movie"
|
345
|
+
tags.add_tag "Belfast"
|
346
|
+
tags.add_tag "Festival"
|
347
|
+
end
|
348
|
+
|
349
|
+
feed.dates.add_item :type => "standalone" do |item|
|
350
|
+
item.name "Second Representation Date"
|
351
|
+
item.start "2013-12-25T15:30:00Z"
|
352
|
+
item.duration 7200
|
353
|
+
end
|
354
|
+
|
355
|
+
feed.places.add_item :type => "fixed" do |item|
|
356
|
+
item.name "Hotel Hilton"
|
357
|
+
item.address "4 Lanyon Place"
|
358
|
+
item.city "Belfast"
|
359
|
+
item.country_code "GB"
|
360
|
+
end
|
361
|
+
|
362
|
+
feed.prices do |prices|
|
363
|
+
prices.add_item :type => "standalone", :mode => "fixed" do |item|
|
364
|
+
item.name "Reservation VIP"
|
365
|
+
item.value 100
|
366
|
+
item.currency "GBP"
|
367
|
+
end
|
368
|
+
|
369
|
+
prices.add_item :type => "standalone", :mode => "fixed" do |item|
|
370
|
+
item.name "General Price"
|
371
|
+
item.value 20
|
372
|
+
item.currency "GBP"
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
def self.ring_cycle
|
381
|
+
ess = Maker.make do |ess|
|
382
|
+
ess.channel do |channel|
|
383
|
+
channel.title "Series of Ring Cycle Operas events"
|
384
|
+
channel.id "ESSID:65ca2c92-2c98-068e-390d-543c376f8e7d"
|
385
|
+
channel.link "http://example.com/feed/sample.ess"
|
386
|
+
channel.published "2013-06-10T10:55:14Z"
|
387
|
+
|
388
|
+
channel.add_feed do |feed|
|
389
|
+
feed.title "Recursive Event Cycle"
|
390
|
+
feed.id "EVENTID:4e0ea291-0acc-b222-60bb-dda020ca8664"
|
391
|
+
feed.uri "http://opera.com/events/page.html"
|
392
|
+
feed.published "2013-04-23T00:25:33+02:00"
|
393
|
+
feed.access "PUBLIC"
|
394
|
+
feed.description "Description of the Ring Cycle"
|
395
|
+
|
396
|
+
feed.categories.add_item :type => "entertainment" do |item|
|
397
|
+
item.name "Opera"
|
398
|
+
item.id "P1"
|
399
|
+
end
|
400
|
+
|
401
|
+
feed.dates.add_item :type => "recurrent", :unit => "month", :limit => 12, :selected_day => "monday,tuesday,thursday,friday", :selected_week => "last" do |item|
|
402
|
+
item.name "6H Opera every last week of every month (monday,tuesday,thursday and friday) for one year"
|
403
|
+
item.start "2013-01-25T08:30:00Z"
|
404
|
+
item.duration 21600
|
405
|
+
end
|
406
|
+
|
407
|
+
feed.places.add_item :type => "fixed" do |item|
|
408
|
+
item.name "London College of Osteopathy"
|
409
|
+
item.address "380 Wellington St. Tower B, 6th Floor"
|
410
|
+
item.city "London"
|
411
|
+
item.country_code "GB"
|
412
|
+
end
|
413
|
+
|
414
|
+
feed.media do |media|
|
415
|
+
media.add_item :type => "image" do |item|
|
416
|
+
item.name "Image 01"
|
417
|
+
item.uri "http://opera.com/ringcycle/image01.png"
|
418
|
+
end
|
419
|
+
|
420
|
+
media.add_item :type => "image" do |item|
|
421
|
+
item.name "Image 02"
|
422
|
+
item.uri "http://opera.com/ringcycle/image02.png"
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
data/lib/ess/helpers.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'digest/md5'
|
3
|
+
|
4
|
+
module ESS
|
5
|
+
module Helpers
|
6
|
+
def self.uuid key=nil, prefix='ESSID:'
|
7
|
+
new_id = nil
|
8
|
+
if key.nil?
|
9
|
+
new_id = SecureRandom.uuid
|
10
|
+
else
|
11
|
+
chars = Digest::MD5.hexdigest(key)
|
12
|
+
new_id = chars[0..8] + '-' +
|
13
|
+
chars[8..12] + '-' +
|
14
|
+
chars[12..16] + '-' +
|
15
|
+
chars[16..20] + '-' +
|
16
|
+
chars[20..32]
|
17
|
+
end
|
18
|
+
return prefix + new_id
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/lib/ess/maker.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module ESS
|
2
|
+
class Maker
|
3
|
+
DEFAULT_OPTIONS = {
|
4
|
+
:version => "0.9",
|
5
|
+
:lang => "en",
|
6
|
+
:validate => true,
|
7
|
+
:push => false
|
8
|
+
}
|
9
|
+
|
10
|
+
def self.make options={}, &block
|
11
|
+
options = DEFAULT_OPTIONS.merge options
|
12
|
+
ess = ESS.new
|
13
|
+
ess.xmlns_attr "http://essfeed.org/history/#{options[:version]}"
|
14
|
+
ess.version_attr options[:version]
|
15
|
+
ess.lang_attr options[:lang]
|
16
|
+
block.call(ess) if block
|
17
|
+
ess.channel.generator.text!("ess:ruby:generator:version:#{options[:version]}") if ess.channel.generator.text! == ""
|
18
|
+
ess.validate if options[:validate]
|
19
|
+
ess.push_to_aggregators(options) if options[:push] || options[:aggregators]
|
20
|
+
return ess
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'ess/helpers'
|
2
|
+
require 'time'
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
module ESS
|
6
|
+
module Postprocessing
|
7
|
+
class FeedTitle
|
8
|
+
def process feed_tag, title_tag
|
9
|
+
feed_tag.id(title_tag.text!) if feed_tag.id.text! == ""
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class FeedURI
|
14
|
+
def process feed_tag, uri_tag
|
15
|
+
feed_tag.id(uri_tag.text!) if feed_tag.id.text! == ""
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class FeedID
|
20
|
+
def process feed_tag, id_tag
|
21
|
+
unless id_tag.text!.start_with?('EVENTID:') || id_tag.text! == ""
|
22
|
+
id_tag.text!(Helpers::uuid(id_tag.text!, 'EVENTID:'))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class ChannelTitle
|
28
|
+
def process channel_tag, title_tag
|
29
|
+
channel_tag.id(title_tag.text!) if channel_tag.id.text! == ""
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class ChannelID
|
34
|
+
def process channel_tag, id_tag
|
35
|
+
unless id_tag.text!.start_with?('ESSID:') || id_tag.text! == ""
|
36
|
+
id_tag.text!(Helpers::uuid(id_tag.text!, 'ESSID:'))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class ChannelLink
|
42
|
+
def process channel_tag, link_tag
|
43
|
+
channel_tag.id(link_tag.text!) if channel_tag.id.text! == ""
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class ProcessTime
|
48
|
+
def process text
|
49
|
+
time = text
|
50
|
+
time = DateTime.parse(time) if time.class != Time
|
51
|
+
time.iso8601
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class StripSpecificHTMLTags
|
56
|
+
def process text
|
57
|
+
# skip any empty space between two tags
|
58
|
+
text = text.gsub(/>\s+</, '><')
|
59
|
+
text = text.gsub(/<noscript[^>]*?>.*?<\/noscript>/mi, '')
|
60
|
+
text = text.gsub(/<iframe[^>]*?>.*?<\/iframe>/mi, '')
|
61
|
+
text = text.gsub(/<script[^>]*?>.*?<\/script>/mi, '')
|
62
|
+
test = text.gsub(/<style[^>]*?>.*?<\/style>/mi, '')
|
63
|
+
test = text.gsub(/<![\s\S]*?--[ \t\n\r]*>/, '')
|
64
|
+
return text
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
data/lib/ess/pusher.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'json'
|
3
|
+
require 'net/http'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
module ESS
|
7
|
+
module Pusher
|
8
|
+
def self.aggregators= aggs
|
9
|
+
raise ArgumentError, "this method requires a list of links" if aggs.class != Array
|
10
|
+
@@aggregators = aggs
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.aggregators
|
14
|
+
@@aggregators ||= ["http://api.hypecal.com/v1/ess/aggregator.json"]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.push_to_aggregators options={}
|
18
|
+
options = { :aggregators => Pusher::aggregators,
|
19
|
+
:feed => nil,
|
20
|
+
:data => nil,
|
21
|
+
:request => nil,
|
22
|
+
:ignore_errors => false }.merge options
|
23
|
+
options[:aggregators].each do |aggregator|
|
24
|
+
url = URI.parse(aggregator)
|
25
|
+
request = Net::HTTP::Post.new(url.path)
|
26
|
+
|
27
|
+
form_data = { "output" => "json",
|
28
|
+
"LIBRARY_VERSION" => VERSION }
|
29
|
+
form_data["SERVER_ADMIN"] = ENV["SERVER_ADMIN"] if ENV["SERVER_ADMIN"]
|
30
|
+
if ENV["SERVER_PROTOCOL"]
|
31
|
+
if ENV["SERVER_PROTOCOL"].include? "HTTPS"
|
32
|
+
form_data["SERVER_PROTOCOL"] = "https://"
|
33
|
+
else
|
34
|
+
form_data["SERVER_PROTOCOL"] = "http://"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
form_data["HTTP_HOST"] = ENV["HTTP_HOST"] if ENV["HTTP_HOST"]
|
38
|
+
if options[:request]
|
39
|
+
form_data["REMOTE_ADDR"] = options[:request].remote_ip
|
40
|
+
form_data["REQUEST_URI"] = options[:request].fullpath
|
41
|
+
end
|
42
|
+
form_data["GEOIP_LATITUDE"] = ENV["GEOIP_LATITUDE"] if ENV["GEOIP_LATITUDE"]
|
43
|
+
form_data["GEOIP_LONGITUDE"] = ENV["GEOIP_LONGITUDE"] if ENV["GEOIP_LONGITUDE"]
|
44
|
+
|
45
|
+
if options[:feed].nil?
|
46
|
+
form_data["feed_file"] = options[:data]
|
47
|
+
else
|
48
|
+
form_data["feed"] = options[:feed]
|
49
|
+
end
|
50
|
+
request.form_data = form_data
|
51
|
+
response = Net::HTTP.start(url.host, url.port) { |http| http.request(request) }
|
52
|
+
response = JSON.parse response.body
|
53
|
+
unless options[:ignore_errors]
|
54
|
+
errors = response["result"]["error"]
|
55
|
+
unless errors.nil?
|
56
|
+
raise RuntimeError, "errors while submitting feed: #{errors}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|