feed-abstract 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/README.rdoc +23 -0
- data/Rakefile +2 -0
- data/feed-abstract.gemspec +23 -0
- data/lib/feed-abstract.rb +33 -0
- data/lib/feed-abstract/channel/atom.rb +47 -0
- data/lib/feed-abstract/channel/rdf.rb +63 -0
- data/lib/feed-abstract/channel/rss.rb +91 -0
- data/lib/feed-abstract/feed.rb +74 -0
- data/lib/feed-abstract/item/atom.rb +50 -0
- data/lib/feed-abstract/item/rdf.rb +48 -0
- data/lib/feed-abstract/item/rss.rb +86 -0
- data/lib/feed-abstract/items/atom.rb +22 -0
- data/lib/feed-abstract/items/rdf.rb +20 -0
- data/lib/feed-abstract/items/rss.rb +20 -0
- data/lib/feed-abstract/mixins.rb +66 -0
- data/lib/feed-abstract/version.rb +7 -0
- data/spec/feed_abstract_channel_spec.rb +132 -0
- data/spec/feed_abstract_item_spec.rb +160 -0
- data/spec/feed_abstract_spec.rb +30 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/test_data/djcp.rss +229 -0
- data/spec/test_data/djcp_code.rss +320 -0
- data/spec/test_data/djcp_delicious.rss +1122 -0
- data/spec/test_data/doc.atom +321 -0
- data/spec/test_data/katanapg.atom +137 -0
- data/spec/test_data/oa.africa.rss +330 -0
- metadata +105 -0
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Feed
|
4
|
+
class Abstract
|
5
|
+
class Item
|
6
|
+
class RSS
|
7
|
+
|
8
|
+
include Feed::AbstractMixins::RSS
|
9
|
+
attr_reader :item, :source
|
10
|
+
|
11
|
+
def initialize(item)
|
12
|
+
@item = @source = item
|
13
|
+
end
|
14
|
+
|
15
|
+
def title
|
16
|
+
return '' if @item.title.nil?
|
17
|
+
@item.title
|
18
|
+
end
|
19
|
+
|
20
|
+
# The full content of this item, theoretically.
|
21
|
+
def content
|
22
|
+
return '' if @item.content_encoded.nil?
|
23
|
+
@item.content_encoded
|
24
|
+
end
|
25
|
+
|
26
|
+
def summary
|
27
|
+
return '' if @item.description.nil?
|
28
|
+
@item.description
|
29
|
+
end
|
30
|
+
|
31
|
+
def link
|
32
|
+
@item.link
|
33
|
+
end
|
34
|
+
|
35
|
+
# The author list (a merge of the RSS author and dc:creator elements) as an array.
|
36
|
+
def authors
|
37
|
+
[@item.author, @item.dc_creators.collect{|c| c.content}].flatten.uniq.compact
|
38
|
+
end
|
39
|
+
|
40
|
+
# The author list as a string, joined with a comma.
|
41
|
+
def author
|
42
|
+
(self.authors.empty?) ? '' : self.authors.join(', ')
|
43
|
+
end
|
44
|
+
|
45
|
+
# The contributors (parsed from the dc:contributor element) as an array.
|
46
|
+
def contributors
|
47
|
+
(@item.dc_contributors.empty?) ? [] : @item.dc_contributors
|
48
|
+
end
|
49
|
+
|
50
|
+
# The contributor list as a string joined with a comma.
|
51
|
+
def contributor
|
52
|
+
(self.contributors.empty?) ? '' : self.contributors.join(', ')
|
53
|
+
end
|
54
|
+
|
55
|
+
# The category list as an array.
|
56
|
+
def categories
|
57
|
+
return [] if @item.categories.empty?
|
58
|
+
@item.categories.collect{|c| c.content}
|
59
|
+
end
|
60
|
+
|
61
|
+
# The category list as a string, joined with a comma.
|
62
|
+
def category
|
63
|
+
return '' if @item.categories.empty?
|
64
|
+
@item.categories.collect{|c| c.content}.join(', ')
|
65
|
+
end
|
66
|
+
|
67
|
+
# Copyright info.
|
68
|
+
def rights
|
69
|
+
(@item.dc_rights.nil?) ? '' : @item.dc_rights
|
70
|
+
end
|
71
|
+
|
72
|
+
def updated
|
73
|
+
(@item.pubDate.nil?) ? '' : @item.pubDate
|
74
|
+
end
|
75
|
+
alias :published :updated
|
76
|
+
|
77
|
+
# A globally unique id.
|
78
|
+
def guid
|
79
|
+
return '' if @item.guid.nil?
|
80
|
+
@item.guid.content
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Feed
|
4
|
+
class Abstract
|
5
|
+
|
6
|
+
#Nothing interesting. The classes in this namespace map the RSS::Parser object entries/items to the proper Feed::Abstract::Item classes. Perhap item-level transformations could be supported through this class in the future.
|
7
|
+
class Items
|
8
|
+
class Atom < Array
|
9
|
+
attr_reader :feed, :items
|
10
|
+
|
11
|
+
def initialize(feed)
|
12
|
+
@feed = feed
|
13
|
+
return [] if @feed.items.empty?
|
14
|
+
@feed.items.each do|item|
|
15
|
+
self << ::Feed::Abstract::Item::Atom.new(item)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Feed
|
4
|
+
class Abstract
|
5
|
+
class Items
|
6
|
+
class RDF < Array
|
7
|
+
attr_reader :feed, :items
|
8
|
+
|
9
|
+
def initialize(feed)
|
10
|
+
@feed = feed
|
11
|
+
return [] if @feed.items.empty?
|
12
|
+
@feed.items.each do|item|
|
13
|
+
self << ::Feed::Abstract::Item::RDF.new(item)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Feed
|
4
|
+
class Abstract
|
5
|
+
class Items
|
6
|
+
class RSS < Array
|
7
|
+
attr_reader :feed, :items
|
8
|
+
|
9
|
+
def initialize(feed)
|
10
|
+
@feed = feed
|
11
|
+
return [] if @feed.items.empty?
|
12
|
+
@feed.items.each do|item|
|
13
|
+
self << ::Feed::Abstract::Item::RSS.new(item)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Feed
|
4
|
+
module AbstractMixins
|
5
|
+
|
6
|
+
module RSS
|
7
|
+
end
|
8
|
+
|
9
|
+
# Instance methods shared between Feed::Abstract::Channel::Atom and Feed::Abstract::Item::Atom
|
10
|
+
module Atom
|
11
|
+
|
12
|
+
def title
|
13
|
+
@source.title.content
|
14
|
+
end
|
15
|
+
|
16
|
+
def link
|
17
|
+
return '' if @source.link.nil?
|
18
|
+
@source.link.href
|
19
|
+
end
|
20
|
+
|
21
|
+
# A globally unique ID to this resource, usually (but not always) a URL.
|
22
|
+
def guid
|
23
|
+
return '' if @source.id.nil?
|
24
|
+
@source.id.content
|
25
|
+
end
|
26
|
+
|
27
|
+
# A Time object representing when resource was updated.
|
28
|
+
def updated
|
29
|
+
return '' if @source.updated.nil?
|
30
|
+
@source.updated.content
|
31
|
+
end
|
32
|
+
|
33
|
+
# Copyright info.
|
34
|
+
def rights
|
35
|
+
return '' if @source.rights.nil?
|
36
|
+
@source.rights.content
|
37
|
+
end
|
38
|
+
|
39
|
+
# An array of author names
|
40
|
+
def authors
|
41
|
+
return [] if @source.authors.empty?
|
42
|
+
@source.authors.collect{|au| au.name.content}
|
43
|
+
end
|
44
|
+
|
45
|
+
# The authors list as a string, joined with a comma.
|
46
|
+
def author
|
47
|
+
return '' if self.authors.empty?
|
48
|
+
self.authors.join(', ')
|
49
|
+
end
|
50
|
+
|
51
|
+
# The categories list as an array.
|
52
|
+
def categories
|
53
|
+
return [] if @source.categories.empty?
|
54
|
+
@source.categories.collect{|c| c.term}
|
55
|
+
end
|
56
|
+
|
57
|
+
# The categories list as a string joined with a comma.
|
58
|
+
def category
|
59
|
+
return '' if self.categories.empty?
|
60
|
+
self.categories.join(', ')
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
require 'spec_helper'
|
4
|
+
class Feed::Abstract
|
5
|
+
|
6
|
+
describe 'Channels' do
|
7
|
+
before(:all) do
|
8
|
+
@docatom = Feed.new(File.read('spec/test_data/doc.atom'))
|
9
|
+
@kpgatom = Feed.new(File.read('spec/test_data/katanapg.atom'))
|
10
|
+
@djcprss2 = Feed.new(File.read('spec/test_data/djcp.rss'))
|
11
|
+
@oa = Feed.new(File.read('spec/test_data/oa.africa.rss'))
|
12
|
+
@delicious = Feed.new(File.read('spec/test_data/djcp_delicious.rss'))
|
13
|
+
end
|
14
|
+
|
15
|
+
[:title, :subtitle, :description, :link, :generator, :authors, :author, :categories, :category, :icon, :logo, :rights, :updated, :guid].each do|att|
|
16
|
+
it { @docatom.channel.should respond_to att}
|
17
|
+
it { @djcprss2.channel.should respond_to att}
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have the correct title" do
|
21
|
+
@docatom.channel.title.should == 'Doc Searls Weblog'
|
22
|
+
@kpgatom.channel.title.should == 'Katana Photo Groups: (Latest Updates)'
|
23
|
+
@djcprss2.channel.title.should == 'Dan Collis-Puro'
|
24
|
+
@oa.channel.title.should == 'Connotea: petersuber\'s bookmarks matching tag oa.africa'
|
25
|
+
@delicious.channel.title.should == 'Delicious/djcp'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have the correct subtitle and description" do
|
29
|
+
@docatom.channel.subtitle.should == 'Same old blog, brand new place'
|
30
|
+
@docatom.channel.description.should == 'Same old blog, brand new place'
|
31
|
+
|
32
|
+
@kpgatom.channel.subtitle.should == 'This is the place to go for the latest photo updates on Katana Photo Groups'
|
33
|
+
@kpgatom.channel.description.should == 'This is the place to go for the latest photo updates on Katana Photo Groups'
|
34
|
+
|
35
|
+
@djcprss2.channel.subtitle.should == 'Tech. Open Source. Stuff that doesn\'t suck.'
|
36
|
+
@djcprss2.channel.description.should == 'Tech. Open Source. Stuff that doesn\'t suck.'
|
37
|
+
|
38
|
+
@oa.channel.description.should == 'Connotea: petersuber\'s bookmarks matching tag oa.africa'
|
39
|
+
@oa.channel.subtitle.should == 'Connotea: petersuber\'s bookmarks matching tag oa.africa'
|
40
|
+
|
41
|
+
@delicious.channel.description.should == 'bookmarks posted by djcp'
|
42
|
+
@delicious.channel.subtitle.should == 'bookmarks posted by djcp'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should have the correct link" do
|
46
|
+
@docatom.channel.link.should == 'http://blogs.law.harvard.edu/doc'
|
47
|
+
@kpgatom.channel.link.should == 'http://www.katanapg.com/latest'
|
48
|
+
@djcprss2.channel.link.should == 'http://blogs.law.harvard.edu/djcp'
|
49
|
+
|
50
|
+
@oa.channel.link.should == 'http://www.connotea.org/user/petersuber/tag/oa.africa'
|
51
|
+
@delicious.channel.link.should == 'http://www.delicious.com/djcp'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should have the correct generator" do
|
55
|
+
@docatom.channel.generator.should == 'WordPress'
|
56
|
+
@kpgatom.channel.generator.should == ''
|
57
|
+
@djcprss2.channel.generator.should == 'WordPress'
|
58
|
+
@oa.channel.generator.should == 'Connotea'
|
59
|
+
@delicious.channel.generator.should == 'Delicious'
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should have the correct authors" do
|
63
|
+
@docatom.channel.authors.should == ['Doc Searls']
|
64
|
+
@kpgatom.channel.authors.should == ['Nick Pappas']
|
65
|
+
@djcprss2.channel.authors.should == ['DJCP']
|
66
|
+
@oa.channel.authors.should == []
|
67
|
+
@delicious.channel.authors.should == []
|
68
|
+
|
69
|
+
@docatom.channel.author.should == 'Doc Searls'
|
70
|
+
@kpgatom.channel.author.should == 'Nick Pappas'
|
71
|
+
@djcprss2.channel.author.should == 'DJCP'
|
72
|
+
@oa.channel.author.should == ''
|
73
|
+
@delicious.channel.author.should == ''
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should have the correct categories" do
|
78
|
+
@docatom.channel.categories.should == []
|
79
|
+
@kpgatom.channel.categories.should == ['photos']
|
80
|
+
@djcprss2.channel.categories.should == ['Tech','Open Source','oa.africa','oa.test']
|
81
|
+
@oa.channel.categories.should == ['oa.africa','oa.test']
|
82
|
+
@delicious.channel.categories.should == []
|
83
|
+
|
84
|
+
@docatom.channel.category.should == ''
|
85
|
+
@kpgatom.channel.category.should == 'photos'
|
86
|
+
@djcprss2.channel.category.should == 'Tech, Open Source'
|
87
|
+
@oa.channel.category.should == 'oa.africa, oa.test'
|
88
|
+
@delicious.channel.category.should == ''
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should have the correct icon" do
|
92
|
+
@docatom.channel.icon.should == ''
|
93
|
+
@kpgatom.channel.icon.should == '/favicon.ico'
|
94
|
+
@djcprss2.channel.icon.should == '/foobar.gif'
|
95
|
+
@oa.channel.icon.should == 'http://example.com/image.gif'
|
96
|
+
@delicious.channel.icon.should == ''
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should have the correct logo" do
|
100
|
+
@docatom.channel.logo.should == ''
|
101
|
+
@kpgatom.channel.logo.should == '/images/rss.gif'
|
102
|
+
@djcprss2.channel.logo.should == '/foobar.gif'
|
103
|
+
@oa.channel.logo.should == 'http://example.com/image.gif'
|
104
|
+
@delicious.channel.logo.should == ''
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should have the correct rights" do
|
108
|
+
@docatom.channel.rights.should == ''
|
109
|
+
@kpgatom.channel.rights.should == ''
|
110
|
+
@djcprss2.channel.rights.should == '2011 DJCP'
|
111
|
+
@oa.channel.rights.should == 'Connotea 2011'
|
112
|
+
@delicious.channel.rights.should == ''
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should have the correct updated value" do
|
116
|
+
@docatom.channel.updated.should == Time.parse('2011-07-29 12:33:29 UTC')
|
117
|
+
@kpgatom.channel.updated.should == Time.parse('2011-08-24 23:59:40 -0400')
|
118
|
+
@djcprss2.channel.updated.should == Time.parse('Tue, 02 Aug 2011 01:05:26 +0000')
|
119
|
+
@oa.channel.updated.should == Time.parse('2011-09-01T08:07:21Z')
|
120
|
+
@delicious.channel.updated.should == ''
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should have the correct guid" do
|
124
|
+
@docatom.channel.guid.should == 'http://blogs.law.harvard.edu/doc/feed/atom/'
|
125
|
+
@kpgatom.channel.guid.should == 'urn:uuid:www.katanapg.com-latest-xml'
|
126
|
+
|
127
|
+
@djcprss2.channel.guid.should == 'http://blogs.law.harvard.edu/djcp'
|
128
|
+
@oa.channel.guid.should == 'http://www.connotea.org/user/petersuber/tag/oa.africa'
|
129
|
+
@delicious.channel.guid.should == 'http://www.delicious.com/djcp'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
class Feed::Abstract
|
5
|
+
|
6
|
+
describe Item do
|
7
|
+
before(:all) do
|
8
|
+
@docatom = Feed.new(File.read('spec/test_data/doc.atom'))
|
9
|
+
@docatomitem = @docatom.items.first
|
10
|
+
|
11
|
+
@kpgatom = Feed.new(File.read('spec/test_data/katanapg.atom'))
|
12
|
+
@kpgatomitem = @kpgatom.items.first
|
13
|
+
|
14
|
+
@djcprss2 = Feed.new(File.read('spec/test_data/djcp.rss'))
|
15
|
+
@djcprss2item = @djcprss2.items.first
|
16
|
+
|
17
|
+
@oa = Feed.new(File.read('spec/test_data/oa.africa.rss'))
|
18
|
+
@oaitem = @oa.items.first
|
19
|
+
|
20
|
+
@delicious = Feed.new(File.read('spec/test_data/djcp_delicious.rss'))
|
21
|
+
@deliciousitem = @delicious.items.first
|
22
|
+
end
|
23
|
+
|
24
|
+
[:title, :summary, :content, :link, :authors, :author, :contributor, :contributors, :categories, :category, :rights, :updated, :guid, :published].each do|att|
|
25
|
+
it { @docatomitem.should respond_to att}
|
26
|
+
it { @djcprss2item.should respond_to att}
|
27
|
+
it { @oaitem.should respond_to att}
|
28
|
+
it { @deliciousitem.should respond_to att}
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should have the correct title" do
|
32
|
+
@docatomitem.title.should == 'Many years of now'
|
33
|
+
@kpgatomitem.title.should == '08/25 3AM - Second year college move in 8-22-11 [By: Peggy Pappas]'
|
34
|
+
@djcprss2item.title.should == 'S1:E7 – Justice'
|
35
|
+
@oaitem.title.should == 'Mali doctoral students learn about access to e-resources | EIFL'
|
36
|
+
@deliciousitem.title.should == 'aspic and other delights'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should have the correct summary" do
|
40
|
+
@docatomitem.summary.should == "“When I’m Sixty-Four” is 44 years old. I was 20 when it came out, in the summer of 1967, one among thirteen perfect tracks on The Beatles‘ Sgt. Pepper’s Lonely Hearts Club Band album. For all the years since, I’ve thought the song began, “When I get older, losing my head…” But yesterday, on the eve of actually [...]"
|
41
|
+
@kpgatomitem.summary.should == ''
|
42
|
+
|
43
|
+
@djcprss2item.summary.should == %q|“Everybody’s blonde – they’re all way too happy. I bet it will all be an animation. I bet that ship is making the whole planet. It’s sucking all the data out – of Data. They wear weird clothes. Eww. So … <a href="http://blogs.law.harvard.edu/djcp/2011/08/s1e7-justice/">Continue reading <span class="meta-nav">→</span></a>|
|
44
|
+
|
45
|
+
@oaitem.summary.should == %q|""On August 13, 2011, Consortium Malien des Bibliothèques (COMBI) organized a workshop on access and use of e-resources (both commercial and open access)....There was a special focus on resources made freely available through EIFL for Malian institutions and also on the various international initiatives working to improve access to scientific information in Mali. Digital libraries and portals for open access journals were also demonstrated...."" Posted by petersuber to oa.notes ru.no oa.event oa.africa oa.new on Thu Aug 18 2011|
|
46
|
+
@deliciousitem.summary.should == ''
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should have the correct content" do
|
50
|
+
@docatomitem.content.should == %q|<p><img class="alignleft size-full wp-image-4196" src="http://blogs.law.harvard.edu/doc/files/2011/07/lost-head.jpg" alt="" width="145" height="135" /><a href="http://en.wikipedia.org/wiki/When_I'm_Sixty-Four">“When I’m Sixty-Four”</a> is 44 years old.<img class="alignright size-full wp-image-4197" src="http://blogs.law.harvard.edu/doc/files/2011/07/lost-hair.jpg" alt="" width="148" height="134" /> I was 20 when it came out, in the summer of 1967, one among thirteen perfect tracks on <a href="http://en.wikipedia.org/wiki/The_Beatles">The Beatles</a>‘ <em><a href="http://en.wikipedia.org/wiki/Sgt._Pepper%27s_Lonely_Hearts_Club_Band">Sgt. Pepper’s Lonely Hearts Club Band</a></em> album. For all the years since, I’ve thought the song began, “When I get older, losing my head…” But yesterday, on the eve of actually turning sixty-four, I watched <a href="http://www.youtube.com/watch?v=tGtSpsYURAQ">this video animation of the song</a> (by theClemmer) and found that Paul McCartney actually sang, “… losing my <em>hair</em>.”</p>
|
51
|
+
<p>Well, that’s true. I’m not bald yet, but the bare spot in the back and the thin zone in the front are advancing toward each other, while my face continues falling down below.</p>
|
52
|
+
<p><img class="alignleft size-full wp-image-4199" src="http://blogs.law.harvard.edu/doc/files/2011/07/doc-then.jpg" alt="" width="128" height="137" />In July 2006, my old friend <a href="http://www.soundtraxnc.com/Tom/tom01.htm">Tom Guild</a><img class="alignright size-full wp-image-4200" src="http://blogs.law.harvard.edu/doc/files/2011/07/62.jpg" alt="" width="99" height="152" /> put <a href="http://www.youtube.com/watch?v=ec-YrUaeXAE">Doc Searls explains driftwood of the land</a> up on YouTube. It’s an improvisational comedy riff that Tom shot with his huge new shoulder-fire video camera at our friend Steve Tulsky’s house on a Marin County hillside in June, 1988. It was a reunion of sorts. Tom, Steve and I had all worked in radio together in North Carolina. I was forty at the time, and looked about half that age. When my ten-year-old kid saw it, he said “Papa, you don’t look like that.” I replied, “No, I <em>do</em> look like that. I don’t look like <em>this,</em>” pointing to my face.</p>
|
53
|
+
<p>Today it would be nice if I still looked like I did five years ago. The shot in the banner at the top of this blog was taken in the summer of 1999 (<a href="http://doc-weblogs.com/clues">here’s the original</a>), when I was fifty-two and looked half that age. The one on the right was taken last summer (the shades on my forehead masking a scalp that now reflects light), when I was a few days short of sixty-three. By then I was finally looking my age.</p>
|
54
|
+
<p>A couple months back I <a href="http://www.youtube.com/watch?v=4dn1jkWgFvM&feature=youtu.be">gave a talk</a> at the <a href="http://personaldemocracy.com/">Personal Democracy Forum</a> where I was warmly introduced as one of those elders we should all listen to. That was nice, but here’s the strange part: when it comes to what I do in the world, I’m still young. Most of the people I hang and work with are half my age or less, yet I rarely notice or think about that, because it’s irrelevant. My job is changing the world, and that’s an calling that tends to involve smart, young, energetic people. The difference with a few of us is that we’ve been young a lot longer.</p>
|
55
|
+
<p>But I don’t have illusions about the facts of life. It’s in one’s sixties that the croak rate starts to angle north on the Y axis as age ticks east on the X. Still, I’m in no less hurry to make things happen than I ever was. I’m just more patient. That’s because one of the things I’ve learned is that now is always earlier than it seems. None of the future has happened yet, and it’s always bigger than the past.</p>
|
56
|
+
|
|
57
|
+
|
58
|
+
@kpgatomitem.content.should == %q|<div xmlns="http://www.w3.org/1999/xhtml">
|
59
|
+
<img src="http://misuzu.katanapg.com/62/1134022551906b98/thumb.jpg"/>
|
60
|
+
</div>|
|
61
|
+
|
62
|
+
@djcprss2item.content.should == %q|<p style="padding-left: 30px;">“Everybody’s blonde – they’re all way too happy. I bet it will all be an animation. I bet that ship is making the whole planet. It’s sucking all the data out – of Data. They wear weird clothes. Eww. So the “god” just let them get away? What warp are they going to? Captain Picard didn’t say!”</p>
|
63
|
+
<p><em>TNG watches TNG – an ongoing series where my almost 11 year old daughter discovers Star Trek.</em></p>
|
64
|
+
|
|
65
|
+
@oaitem.content.should == %q|<link rel="stylesheet" href="http://www.connotea.org/global.css" type="text/css" title="styled"/><span class="internet"><div class="icons"> </div></span><a rel="nofollow" href="http://www.eifl.net/news/mali-doctoral-students-learn-about-access-e-r" onclick="this.href='http'+'://www.connotea.org/click?src=http%3A%2F%2Fwww.connotea.org%2Frss%2Ftag%2Foa.new%3Fnum%3D1000&dest=http%3A%2F%2Fwww.eifl.net%2Fnews%2Fmali-doctoral-students-learn-about-access-e-r'; return true;" title="Mali doctoral students learn about access to e-resources \| EIFL" class="rssitem">Mali doctoral students learn about access to e-resources \| EIFL</a><div class="actualurl">www.eifl.net</div><div class="description">"On August 13, 2011, Consortium Malien des Bibliothèques (COMBI) organized a workshop on access and use of e-resources (both commercial and open access)....There was a special focus on resources made freely available through EIFL for Malian institutions and also on the various international initiatives working to improve access to scientific information in Mali. Digital libraries and portals for open access journals were also demonstrated...."</div><div class="posted"><span class="postedby">Posted by <a rel="nofollow" href="http://www.connotea.org/user/petersuber" title="petersuber" class="postedby">petersuber</a></span> <span class="postedtags">to <a rel="nofollow" href="http://www.connotea.org/tag/oa.notes" title="oa.notes" class="postedtag">oa.notes</a> <a rel="nofollow" href="http://www.connotea.org/tag/ru.no" title="ru.no" class="postedtag">ru.no</a> <a rel="nofollow" href="http://www.connotea.org/tag/oa.event" title="oa.event" class="postedtag">oa.event</a> <a rel="nofollow" href="http://www.connotea.org/tag/oa.africa" title="oa.africa" class="postedtag">oa.africa</a> <a rel="nofollow" href="http://www.connotea.org/tag/oa.new" title="oa.new" class="postedtag">oa.new</a></span> <span class="postedtime">on <a rel="nofollow" href="http://www.connotea.org/date/2011-08-18" title="Thu Aug 18 2011">Thu Aug 18 2011</a> at 21:14 UTC</span> \| <a href="http://www.connotea.org/article/924b97cee02e01888a93473ca6752213">info</a> \| <a title="Results powered by Proximic" onclick="return false;" id="proximic_proxit:aid=npg&channel_expand=MEDIA&query_url=http://www.eifl.net/news/mali-doctoral-students-learn-about-access-e-r">related</a></div>|
|
66
|
+
|
67
|
+
@deliciousitem.content.should == ''
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should have the correct link" do
|
71
|
+
@docatomitem.link.should == "http://blogs.law.harvard.edu/doc/2011/07/29/many-years-of-now/"
|
72
|
+
@kpgatomitem.link.should == 'http://www.katanapg.com/group/2739'
|
73
|
+
@djcprss2item.link.should == 'http://blogs.law.harvard.edu/djcp/2011/08/s1e7-justice/'
|
74
|
+
@oaitem.link.should == 'http://www.eifl.net/news/mali-doctoral-students-learn-about-access-e-r'
|
75
|
+
@deliciousitem.link.should == 'http://aspicandotherdelights.tumblr.com/'
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should have the correct author" do
|
79
|
+
@docatomitem.author.should == 'Doc Searls'
|
80
|
+
@kpgatomitem.author.should == ''
|
81
|
+
@djcprss2item.author.should == 'djcp'
|
82
|
+
@oaitem.author.should == 'petersuber'
|
83
|
+
@deliciousitem.author.should == 'djcp'
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should have the correct authors" do
|
87
|
+
@docatomitem.authors.should == ['Doc Searls']
|
88
|
+
@kpgatomitem.authors.should == []
|
89
|
+
@djcprss2item.authors.should == ['djcp']
|
90
|
+
@oaitem.authors.should == ['petersuber']
|
91
|
+
@deliciousitem.authors.should == ['djcp']
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should have the correct contributor" do
|
95
|
+
@docatomitem.contributor.should == 'Doc Searls, The Beatles'
|
96
|
+
@kpgatomitem.contributor.should == ''
|
97
|
+
@djcprss2item.contributor.should == ''
|
98
|
+
@oaitem.contributor.should == ''
|
99
|
+
@deliciousitem.contributor.should == ''
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should have the correct contributors" do
|
103
|
+
@docatomitem.contributors.should == ['Doc Searls', 'The Beatles']
|
104
|
+
@kpgatomitem.contributors.should == []
|
105
|
+
@djcprss2item.contributors.should == []
|
106
|
+
@oaitem.contributors.should == []
|
107
|
+
@deliciousitem.contributors.should == []
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should have the correct category" do
|
111
|
+
@docatomitem.category.should == 'Art, Broadcasting, Events, Family, Fun, Future, Geography, Geology, Health, history, Life, North Carolina, Past, Personal'
|
112
|
+
@kpgatomitem.category.should == ''
|
113
|
+
@djcprss2item.category.should == 'Uncategorized, tngwatchestng'
|
114
|
+
@oaitem.category.should == 'oa.notes, ru.no, oa.event, oa.africa, oa.new'
|
115
|
+
@deliciousitem.category.should == 'cooking, oddness'
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should have the correct categories" do
|
119
|
+
@docatomitem.categories.should == ["Art", "Broadcasting", "Events", "Family", "Fun", "Future", "Geography", "Geology", "Health", "history", "Life", "North Carolina", "Past", "Personal"]
|
120
|
+
@kpgatomitem.categories.should == []
|
121
|
+
@djcprss2item.categories.should == ['Uncategorized', 'tngwatchestng']
|
122
|
+
@oaitem.categories.should == ["oa.notes", "ru.no", "oa.event", "oa.africa", "oa.new"]
|
123
|
+
@deliciousitem.categories.should == ['cooking', 'oddness']
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should have the correct rights" do
|
127
|
+
@docatomitem.rights.should == ''
|
128
|
+
@kpgatomitem.rights.should == ''
|
129
|
+
@djcprss2item.rights.should == ''
|
130
|
+
@oaitem.rights.should == ''
|
131
|
+
@deliciousitem.rights.should == ''
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should have been updated at the correct time" do
|
135
|
+
@docatomitem.updated.should == Time.parse('2011-07-29T12:33:29Z')
|
136
|
+
@kpgatomitem.updated.should == Time.parse('2011-08-25T03:59:40+00:00')
|
137
|
+
@djcprss2item.updated.should == Time.parse('Tue, 02 Aug 2011 01:05:26 +0000')
|
138
|
+
@oaitem.updated.should == Time.parse('2011-08-18T21:14:38Z')
|
139
|
+
@deliciousitem.updated.should == Time.parse('Fri, 19 Aug 2011 00:56:26 +0000')
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should have the proper guid" do
|
143
|
+
@docatomitem.guid.should == "http://blogs.law.harvard.edu/doc/?p=4195"
|
144
|
+
@kpgatomitem.guid.should == 'urn:uuid:www.katanapg.com-group-2739'
|
145
|
+
@djcprss2item.guid.should == 'http://blogs.law.harvard.edu/djcp/?p=227'
|
146
|
+
@oaitem.guid.should == 'http://www.connotea.org/user/petersuber/uri/924b97cee02e01888a93473ca6752213'
|
147
|
+
@deliciousitem.guid.should == 'http://www.delicious.com/url/6e0504ca698232809a0b5065e8b83031#djcp'
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should have been published at the proper time" do
|
151
|
+
@docatomitem.published.should == Time.parse("2011-07-29T10:43:27Z")
|
152
|
+
@kpgatomitem.published.should == ''
|
153
|
+
@djcprss2item.published.should == Time.parse('Tue, 02 Aug 2011 01:05:26 +0000')
|
154
|
+
@oaitem.published.should == Time.parse('2011-08-18T21:14:38Z')
|
155
|
+
@deliciousitem.published.should == Time.parse('Fri, 19 Aug 2011 00:56:26 +0000')
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|