feed-abstract 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -3,3 +3,4 @@ pkg/*
3
3
  .bundle
4
4
  Gemfile.lock
5
5
  *.swp
6
+ .rvmrc
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ begin
10
10
  s.name = "feed-abstract"
11
11
  s.version = FeedAbstract::VERSION
12
12
  s.homepage = "https://github.com/berkmancenter/feed-abstract"
13
- s.summary = %q{Abstracts RSS/Atom/RDF parsing features from the ruby standard lib into a common object graph.}
13
+ s.summary = %q{Abstracts RSS/Atom/RDF stdlib parsing into a common object graph.}
14
14
  s.description = %q{This library creates a common object graph for the RSS/Atom/RDF parsing classes in the ruby standard library. This allows you parse different feed formats and get back the same (or at least a very similar) set of results - item authors are accessible under an "author(s)" attribute, categories/tags/subjects are accessible under "category(ies)" attributes, etc. We do our best to make sure the data makes sense, too - RSS items lack an "updated" attribute, so we use "pubDate" to populate it. }
15
15
  s.authors = ["Daniel Collis-Puro"]
16
16
  s.email = ["djcp@cyber.law.harvard.edu"]
@@ -20,6 +20,7 @@ begin
20
20
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
21
  s.require_paths = ["lib"]
22
22
  s.add_development_dependency("rspec",['>= 0'])
23
+ s.add_development_dependency("simplecov",['>= 0'])
23
24
  s.extra_rdoc_files = [
24
25
  "README.rdoc"
25
26
  ]
@@ -30,23 +31,6 @@ end
30
31
 
31
32
  Jeweler::RubygemsDotOrgTasks.new
32
33
 
33
- require 'rake/testtask'
34
- Rake::TestTask.new(:test) do |test|
35
- test.libs << 'lib' << 'test'
36
- test.pattern = 'test/**/test_*.rb'
37
- test.verbose = true
38
- end
39
-
40
- require 'rcov/rcovtask'
41
- Rcov::RcovTask.new do |test|
42
- test.libs << 'test'
43
- test.pattern = 'test/**/test_*.rb'
44
- test.verbose = true
45
- test.rcov_opts << '--exclude "gems/*"'
46
- end
47
-
48
- task :default => :test
49
-
50
34
  require 'rake/rdoctask'
51
35
  Rake::RDocTask.new do |rdoc|
52
36
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{feed-abstract}
8
- s.version = "0.0.7"
7
+ s.name = "feed-abstract"
8
+ s.version = "0.0.8"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = [%q{Daniel Collis-Puro}]
12
- s.date = %q{2011-09-16}
13
- s.description = %q{This library creates a common object graph for the RSS/Atom/RDF parsing classes in the ruby standard library. This allows you parse different feed formats and get back the same (or at least a very similar) set of results - item authors are accessible under an "author(s)" attribute, categories/tags/subjects are accessible under "category(ies)" attributes, etc. We do our best to make sure the data makes sense, too - RSS items lack an "updated" attribute, so we use "pubDate" to populate it. }
14
- s.email = [%q{djcp@cyber.law.harvard.edu}]
11
+ s.authors = ["Daniel Collis-Puro"]
12
+ s.date = "2012-02-19"
13
+ s.description = "This library creates a common object graph for the RSS/Atom/RDF parsing classes in the ruby standard library. This allows you parse different feed formats and get back the same (or at least a very similar) set of results - item authors are accessible under an \"author(s)\" attribute, categories/tags/subjects are accessible under \"category(ies)\" attributes, etc. We do our best to make sure the data makes sense, too - RSS items lack an \"updated\" attribute, so we use \"pubDate\" to populate it. "
14
+ s.email = ["djcp@cyber.law.harvard.edu"]
15
15
  s.extra_rdoc_files = [
16
16
  "README.rdoc"
17
17
  ]
@@ -43,6 +43,7 @@ Gem::Specification.new do |s|
43
43
  "spec/test_data/djcp.rss92",
44
44
  "spec/test_data/djcp_code.rss",
45
45
  "spec/test_data/djcp_delicious.rss",
46
+ "spec/test_data/djcp_twitter.rss",
46
47
  "spec/test_data/doc.atom",
47
48
  "spec/test_data/feedburner.rss",
48
49
  "spec/test_data/katanapg.atom",
@@ -50,11 +51,11 @@ Gem::Specification.new do |s|
50
51
  "spec/test_data/pyblosxom.atom",
51
52
  "spec/test_data/zotero.rss"
52
53
  ]
53
- s.homepage = %q{https://github.com/berkmancenter/feed-abstract}
54
- s.rdoc_options = [%q{--charset=UTF-8}]
55
- s.require_paths = [%q{lib}]
56
- s.rubygems_version = %q{1.8.6}
57
- s.summary = %q{Abstracts RSS/Atom/RDF parsing features from the ruby standard lib into a common object graph.}
54
+ s.homepage = "https://github.com/berkmancenter/feed-abstract"
55
+ s.rdoc_options = ["--charset=UTF-8"]
56
+ s.require_paths = ["lib"]
57
+ s.rubygems_version = "1.8.10"
58
+ s.summary = "Abstracts RSS/Atom/RDF stdlib parsing into a common object graph."
58
59
 
59
60
  if s.respond_to? :specification_version then
60
61
  s.specification_version = 3
@@ -63,15 +64,33 @@ Gem::Specification.new do |s|
63
64
  s.add_runtime_dependency(%q<feed-abstract>, [">= 0"])
64
65
  s.add_development_dependency(%q<rspec>, [">= 0"])
65
66
  s.add_development_dependency(%q<rspec>, [">= 0"])
67
+ s.add_development_dependency(%q<rspec>, [">= 0"])
68
+ s.add_development_dependency(%q<rspec>, [">= 0"])
69
+ s.add_development_dependency(%q<rspec>, [">= 0"])
70
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
71
+ s.add_development_dependency(%q<rspec>, [">= 0"])
72
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
66
73
  else
67
74
  s.add_dependency(%q<feed-abstract>, [">= 0"])
68
75
  s.add_dependency(%q<rspec>, [">= 0"])
69
76
  s.add_dependency(%q<rspec>, [">= 0"])
77
+ s.add_dependency(%q<rspec>, [">= 0"])
78
+ s.add_dependency(%q<rspec>, [">= 0"])
79
+ s.add_dependency(%q<rspec>, [">= 0"])
80
+ s.add_dependency(%q<simplecov>, [">= 0"])
81
+ s.add_dependency(%q<rspec>, [">= 0"])
82
+ s.add_dependency(%q<simplecov>, [">= 0"])
70
83
  end
71
84
  else
72
85
  s.add_dependency(%q<feed-abstract>, [">= 0"])
73
86
  s.add_dependency(%q<rspec>, [">= 0"])
74
87
  s.add_dependency(%q<rspec>, [">= 0"])
88
+ s.add_dependency(%q<rspec>, [">= 0"])
89
+ s.add_dependency(%q<rspec>, [">= 0"])
90
+ s.add_dependency(%q<rspec>, [">= 0"])
91
+ s.add_dependency(%q<simplecov>, [">= 0"])
92
+ s.add_dependency(%q<rspec>, [">= 0"])
93
+ s.add_dependency(%q<simplecov>, [">= 0"])
75
94
  end
76
95
  end
77
96
 
data/lib/feed-abstract.rb CHANGED
@@ -21,14 +21,3 @@ require 'feed-abstract/item/atom'
21
21
  require 'feed-abstract/item/rdf'
22
22
 
23
23
  require 'feed-abstract/feed'
24
-
25
-
26
- #RSS::Rss::Channel::Item.class_eval{
27
- # def foobar
28
- # 'asdfasdf'
29
- # end
30
- #}
31
-
32
- #RSS::Rss::Channel::Item.instance_eval{
33
- # install_get_attribute('category', '', false )
34
- #}
@@ -24,12 +24,14 @@ module FeedAbstract
24
24
  end
25
25
  alias :subtitle :description
26
26
 
27
- # The generator of this feed as a string. Sometimes a URL, sometimes a string (e.g. the application name).
27
+ # The generator of this feed as a string. Sometimes a URL, sometimes a string (e.g. the application name). We will "sniff" out the generator for some feed sources - wordpress, delicious, twitter, etc.
28
28
  def generator
29
29
  if ! @feed.channel.generator.nil? && @feed.channel.generator.match(/wordpress\.org/i)
30
30
  return 'WordPress'
31
31
  elsif @feed.channel.link.match(/www\.delicious\.com/i)
32
32
  return 'Delicious'
33
+ elsif @feed.channel.link.match(/https?:\/\/twitter\.com/i)
34
+ return 'Twitter'
33
35
  end
34
36
  return '' if @feed.channel.generator.nil?
35
37
  @feed.channel.generator
@@ -97,13 +97,13 @@ module FeedAbstract
97
97
  def negotiate_channel_class
98
98
  if @raw_feed.class == RSS::Atom::Feed
99
99
  @channel = Channel::Atom.new(@raw_feed)
100
- @items = Items::Atom.new(@raw_feed)
100
+ @items = Items::Atom.new(@raw_feed,@channel)
101
101
  elsif @raw_feed.class == RSS::RDF
102
102
  @channel = Channel::RDF.new(@raw_feed)
103
- @items = Items::RDF.new(@raw_feed)
103
+ @items = Items::RDF.new(@raw_feed,@channel)
104
104
  else
105
105
  @channel = Channel::RSS.new(@raw_feed)
106
- @items = Items::RSS.new(@raw_feed)
106
+ @items = Items::RSS.new(@raw_feed,@channel)
107
107
  end
108
108
  end
109
109
 
@@ -8,10 +8,11 @@ module FeedAbstract
8
8
  # See FeedAbstractMixins::Atom for more instance methods.
9
9
  class Atom
10
10
  include FeedAbstractMixins::Atom
11
- attr_reader :item, :source
11
+ attr_reader :item, :source, :channel
12
12
 
13
- def initialize(item)
13
+ def initialize(item,channel)
14
14
  @item = @source = item
15
+ @channel = channel
15
16
  end
16
17
 
17
18
  # The full content of the item, most likely html.
@@ -5,10 +5,11 @@ module FeedAbstract
5
5
  class RSS
6
6
 
7
7
  include FeedAbstractMixins::RSS
8
- attr_reader :item, :source
8
+ attr_reader :item, :source, :channel
9
9
 
10
- def initialize(item)
10
+ def initialize(item,channel)
11
11
  @item = @source = item
12
+ @channel = channel
12
13
  end
13
14
 
14
15
  def title
@@ -33,6 +34,9 @@ module FeedAbstract
33
34
 
34
35
  # The author list (a merge of the RSS author and dc:creator elements) as an array.
35
36
  def authors
37
+ if self.channel.generator == 'Twitter'
38
+ return [@item.title.split(':')[0]]
39
+ end
36
40
  [@item.author, ((@item.dc_creators.empty?) ? nil : @item.dc_creators.collect{|c| c.content})].flatten.uniq.compact.reject{|au| au == '' || au.match(/^\s+$/)}
37
41
  end
38
42
 
@@ -53,13 +57,19 @@ module FeedAbstract
53
57
 
54
58
  # The category list as an array.
55
59
  def categories
60
+ if self.channel.generator == 'Twitter'
61
+ return @item.title.scan(/#([^#\s]+)/).flatten
62
+ end
56
63
  return [] if @item.categories.empty?
57
64
  @item.categories.collect{|c| c.content}.reject{|c| c == '' || c.match(/^\s+$/)}
58
65
  end
59
66
 
60
67
  # The category list as a string, joined with a comma.
61
68
  def category
62
- return '' if @item.categories.empty?
69
+ if self.channel.generator == 'Twitter'
70
+ return self.categories.join(', ')
71
+ end
72
+ return '' if @item.categories.empty?
63
73
  @item.categories.collect{|c| c.content}.join(', ')
64
74
  end
65
75
 
@@ -7,11 +7,12 @@ module FeedAbstract
7
7
  class Atom < Array
8
8
  attr_reader :feed, :items
9
9
 
10
- def initialize(feed)
10
+ def initialize(feed,channel)
11
11
  @feed = feed
12
+ @channel = channel
12
13
  return [] if @feed.items.empty?
13
14
  @feed.items.each do|item|
14
- self << ::FeedAbstract::Item::Atom.new(item)
15
+ self << ::FeedAbstract::Item::Atom.new(item,channel)
15
16
  end
16
17
  end
17
18
 
@@ -5,11 +5,12 @@ module FeedAbstract
5
5
  class RDF < Array
6
6
  attr_reader :feed, :items
7
7
 
8
- def initialize(feed)
8
+ def initialize(feed,channel)
9
9
  @feed = feed
10
+ @channel = channel
10
11
  return [] if @feed.items.empty?
11
12
  @feed.items.each do|item|
12
- self << ::FeedAbstract::Item::RDF.new(item)
13
+ self << ::FeedAbstract::Item::RDF.new(item,channel)
13
14
  end
14
15
  end
15
16
 
@@ -5,11 +5,12 @@ module FeedAbstract
5
5
  class RSS < Array
6
6
  attr_reader :feed, :items
7
7
 
8
- def initialize(feed)
8
+ def initialize(feed,channel)
9
9
  @feed = feed
10
+ @channel = channel
10
11
  return [] if @feed.items.empty?
11
12
  @feed.items.each do|item|
12
- self << ::FeedAbstract::Item::RSS.new(item)
13
+ self << ::FeedAbstract::Item::RSS.new(item,channel)
13
14
  end
14
15
  end
15
16
 
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module FeedAbstract
4
- VERSION = "0.0.7"
4
+ VERSION = "0.0.8"
5
5
  end
@@ -19,6 +19,7 @@ module FeedAbstract
19
19
  it { @feedburner.channel.should respond_to att}
20
20
  it { @pyblosxom.channel.should respond_to att}
21
21
  it { @chill.channel.should respond_to att}
22
+ it { @twitter.channel.should respond_to att}
22
23
 
23
24
  it { @docatom.channel.send(att).should_not == false}
24
25
  it { @kpgatom.channel.send(att).should_not == false}
@@ -30,6 +31,7 @@ module FeedAbstract
30
31
  it { @feedburner.channel.send(att).should_not == false}
31
32
  it { @pyblosxom.channel.send(att).should_not == false}
32
33
  it { @chill.channel.send(att).should_not == false}
34
+ it { @twitter.channel.send(att).should_not == false}
33
35
  end
34
36
 
35
37
  it "should have the correct title" do
@@ -43,6 +45,7 @@ module FeedAbstract
43
45
  @feedburner.channel.title.should == 'CNN.com'
44
46
  @pyblosxom.channel.title.should == 'Copyrighteous'
45
47
  @chill.channel.title.should == 'Chilling Effects Clearinghouse Weather Reports'
48
+ @twitter.channel.title.should == 'Twitter / djcp'
46
49
  end
47
50
 
48
51
  it "should have the correct subtitle and description" do
@@ -75,6 +78,9 @@ module FeedAbstract
75
78
 
76
79
  @chill.channel.description.should == 'Monitoring the legal climate for Internet activity (database of annotated cease and desist letters)'
77
80
  @chill.channel.subtitle.should == 'Monitoring the legal climate for Internet activity (database of annotated cease and desist letters)'
81
+
82
+ @twitter.channel.description.should == 'Twitter updates from Daniel Collis Puro / djcp.'
83
+ @twitter.channel.subtitle.should == 'Twitter updates from Daniel Collis Puro / djcp.'
78
84
  end
79
85
 
80
86
  it "should have the correct link" do
@@ -88,6 +94,7 @@ module FeedAbstract
88
94
  @feedburner.channel.link.should == 'http://www.cnn.com/?eref=rss_topstories'
89
95
  @pyblosxom.channel.link.should == 'http://mako.cc/copyrighteous'
90
96
  @chill.channel.link.should == 'http://www.chillingeffects.org'
97
+ @twitter.channel.link.should == 'http://twitter.com/djcp'
91
98
  end
92
99
 
93
100
  it "should have the correct generator" do
@@ -101,6 +108,7 @@ module FeedAbstract
101
108
  @feedburner.channel.generator.should == ''
102
109
  @pyblosxom.channel.generator.should == "\nPyBlosxom http://pyblosxom.sourceforge.net/ 1.5rc2 20100803\n"
103
110
  @chill.channel.generator.should == ''
111
+ @twitter.channel.generator.should == 'Twitter'
104
112
  end
105
113
 
106
114
  it "should have the correct language" do
@@ -114,6 +122,7 @@ module FeedAbstract
114
122
  @feedburner.channel.language.should == 'en-us'
115
123
  @pyblosxom.channel.language.should == 'en'
116
124
  @chill.channel.language.should == 'en-us'
125
+ @twitter.channel.language.should == 'en-us'
117
126
  end
118
127
 
119
128
  it "should have the correct authors" do
@@ -127,6 +136,7 @@ module FeedAbstract
127
136
  @feedburner.channel.authors.should == []
128
137
  @pyblosxom.channel.authors.should == ['Benjamin Mako Hill']
129
138
  @chill.channel.authors.should == ['Wendy Seltzer, wseltzer@chillingeffects.org']
139
+ @twitter.channel.authors.should == []
130
140
 
131
141
  @docatom.channel.author.should == 'Doc Searls'
132
142
  @kpgatom.channel.author.should == 'Nick Pappas'
@@ -138,6 +148,7 @@ module FeedAbstract
138
148
  @feedburner.channel.author.should == ''
139
149
  @pyblosxom.channel.author.should == 'Benjamin Mako Hill'
140
150
  @chill.channel.author.should == 'Wendy Seltzer, wseltzer@chillingeffects.org'
151
+ @twitter.channel.author.should == ''
141
152
 
142
153
  end
143
154
 
@@ -152,6 +163,7 @@ module FeedAbstract
152
163
  @feedburner.channel.categories.should == []
153
164
  @pyblosxom.channel.categories.should == []
154
165
  @chill.channel.categories.should == ['Your rights online']
166
+ @twitter.channel.categories.should == []
155
167
 
156
168
  @docatom.channel.category.should == ''
157
169
  @kpgatom.channel.category.should == 'photos'
@@ -163,6 +175,7 @@ module FeedAbstract
163
175
  @feedburner.channel.category.should == ''
164
176
  @pyblosxom.channel.category.should == ''
165
177
  @chill.channel.category.should == 'Your rights online'
178
+ @twitter.channel.category.should == ''
166
179
  end
167
180
 
168
181
  it "should have the correct icon" do
@@ -176,6 +189,7 @@ module FeedAbstract
176
189
  @feedburner.channel.icon.should == 'http://i2.cdn.turner.com/cnn/.element/img/1.0/logo/cnn.logo.rss.gif'
177
190
  @pyblosxom.channel.icon.should == ''
178
191
  @chill.channel.icon.should == 'http://images.chillingeffects.org/chilling_effects.gif'
192
+ @twitter.channel.icon.should == ''
179
193
  end
180
194
 
181
195
  it "should have the correct logo" do
@@ -189,6 +203,7 @@ module FeedAbstract
189
203
  @feedburner.channel.logo.should == 'http://i2.cdn.turner.com/cnn/.element/img/1.0/logo/cnn.logo.rss.gif'
190
204
  @pyblosxom.channel.logo.should == ''
191
205
  @chill.channel.logo.should == 'http://images.chillingeffects.org/chilling_effects.gif'
206
+ @twitter.channel.logo.should == ''
192
207
  end
193
208
 
194
209
  it "should have the correct rights" do
@@ -202,6 +217,7 @@ module FeedAbstract
202
217
  @feedburner.channel.rights.should == ' 2011 Cable News Network LP, LLLP.'
203
218
  @pyblosxom.channel.rights.should == 'Creative Commons Attribution-ShareAlike'
204
219
  @chill.channel.rights.should == ''
220
+ @twitter.channel.rights.should == ''
205
221
  end
206
222
 
207
223
  it "should have the correct updated value" do
@@ -215,6 +231,7 @@ module FeedAbstract
215
231
  @feedburner.channel.updated.should == Time.parse('Sat, 03 Sep 2011 16:14:16 EDT')
216
232
  @pyblosxom.channel.updated.should == Time.parse('2011-09-15T05:21:00Z')
217
233
  @chill.channel.updated.should == Time.parse('2002-02-25T12:00+00:00')
234
+ @twitter.channel.updated.should == ''
218
235
  end
219
236
 
220
237
  it "should have the correct guid" do
@@ -228,6 +245,7 @@ module FeedAbstract
228
245
  @feedburner.channel.guid.should == 'http://www.cnn.com/?eref=rss_topstories'
229
246
  @pyblosxom.channel.guid.should == 'http://mako.cc/copyrighteous/'
230
247
  @chill.channel.guid.should == 'http://www.chillingeffects.org'
248
+ @twitter.channel.guid.should == 'http://twitter.com/djcp'
231
249
  end
232
250
  end
233
251
  end
@@ -13,7 +13,7 @@ module FeedAbstract
13
13
 
14
14
  it "responds to all attributes without causing an error" do
15
15
  @all_feeds.each do |feed|
16
- [:title, :summary, :content, :link, :authors, :author, :contributor, :contributors, :categories, :category, :rights, :updated, :guid, :published].each do|att|
16
+ [:title, :summary, :content, :link, :authors, :author, :contributor, :contributors, :categories, :category, :rights, :updated, :guid, :published, :channel].each do|att|
17
17
  feed.items.each do|item|
18
18
  item.should respond_to att
19
19
  item.send(att).should_not == false
@@ -32,6 +32,7 @@ module FeedAbstract
32
32
  @feedburneritem.title.should == 'Did Libya help CIA with renditions of terror suspects?'
33
33
  @pyblosxomitem.title.should == "Anxiety\n"
34
34
  @chillitem.title.should == "Takedown Complaints in the Android Marketplace"
35
+ @twitteritem.title.should == "djcp: @csoghoian @BrookingsInst and the clipboard as well, presumably. #security #keylogging"
35
36
 
36
37
  end
37
38
 
@@ -50,6 +51,8 @@ module FeedAbstract
50
51
 
51
52
  @pyblosxomitem.summary.should == ""
52
53
  @chillitem.summary.should == %Q$<br>\n<img src=\"//images.chillingeffects.org/thermometer.gif\" alt=\"thermometer\" width=\"35\" height=\"120\"align=left> <h2>Takedown Complaints in the Android Marketplace</h2><p>Wendy Seltzer, <i>Chilling Effects Clearinghouse</i>, March 3, 2011\n<p><i>Abstract:</i> Earlier this year, Google began sending to Chilling Effects the requests it received for takedown from the Android Marketplace. Since this represents a new source of data, we take a look at the first month's input, February 2011.<hr size=1>\n<p><hr size=1 width=\"75%\"><p>Since Apple launched its iPhone App Store, applications marketplaces have popped up with increasing prominence. Google, unlike Apple<a href=\"#note1\" name=\"back\">*</a>, does not lock Android users into purchasing from its <a href=\"https://market.android.com/\">Android Market</a>, but it does make that marketplace a convenient place to find Android applications (<a href=\"http://mashable.com/2010/10/25/android-100000-apps/\">passing 100,000 apps</a> late last year). <br><p><br>In February, Chilling Effects <a href=\"https://www.chillingeffects.org/search.cgi?search=Android\">saw</a> 206 complaints to Google regarding Android Market apps, almost evenly split between trademark and copyright.<a href=\"#note2\" name=\"back2\">*</a> Because the Android Market offers commercial transactions, its context differs somewhat from the search and blog hosting in which DMCA -- copyright -- complaints predominate. At the same time, many apps are offered free of charge.<p><br><img src=\"https://chart.googleapis.com/chart?cht=pc&chtt=Complaint+Subjects+to+Android+Market+(Feb+2011)&chs=750x400&chd=t:111,97,3|0.59,0.31,0.05,0.03,0.02,0.02,0.02,0.38,0.11,0.1,0.07,0.03,0.03,0.02,0.02,0.02,0.01,0.01,0.22&chl=[TM]|[C]||Trademark%20%20(59)|Facebook%20Trademark%20%20(31)|Bank%20Trademark%20%20(5)|SXSW%20Trademark%20%20(3)|Trademarks%20and%20Videos%20Copyright%20%20(2)|Game%20Trademark%20%20(2)|Disney%20Trademark%20and%20Copyright%20%20(2)|Game%20Copyright%20%20(38)|Software%20Copyright%20%20(11)|Logo%20Copyright%20%20(10)|Copyright%20%20(7)|Books%20Copyright%20%20(3)|Images%20Copyright%20%20(3)|Articles%20Copyright%20%20(2)|Television%20Copyright%20%20(2)|UFC%20Copyright%20%20(2)|Photo%20Copyright%20%20(1)|Website%20Copyright%20%20(1)|Other/Unidentified%20(22)&chco=0000FF,003333&chp=3.14\" title=\"Complaint Subjects to Google's Android Market, Feb. 2011\"><p>Slightly more than half of the complaints here claim trademark infringement: misleading use of a mark (word or logo) to cause consumer confusion about the application's source or sponsorship. Facebook led the way, challenging 30+ apps that borrowed its name or \"f\" logo (e.g. <a href=\"/trademark/notice.cgi?NoticeID=56735\">Facebook Trademark Complaint to Google: Android Market</a>). Banks and financial institutions challenged applications that used their logos, even to offer a mobile version of the bank's own site. Here is trademark as the law of consumer protection: you want to be sure an unauthorized Wells Fargo application won't channel your deposit into its coffers rather than your savings account. Google even filed several complaints against apps in its marketplace that were a bit too free with the Google name. Starbucks used copyright in its logo to similar end, requesting takedown or alteration of apps that used the coffee company's logo as their icon (e.g. <a href=\"/dmca512c/notice.cgi?NoticeID=60149\">Logo DMCA (Copyright) Complaint to Google: Android Market</a>). Some, including <a href=\"https://market.android.com/details?id=com.birbeck.starbuckscard\">My Coffee Card</a> (formerly Starbucks Card Widget) changed their name and icon in response.<p>Sometimes, these complaints didn't do much to allege \"likelihood of consumer confusion,\" the traditional hallmark of trademark infringement. South By SouthWest's complaint against the \"Unauthorized SXSW\" party scheduler app -- <a href=\"/trademark/notice.cgi?NoticeID=60951\">SXSW Trademark Complaint to Google: Android Market</a> -- sounds like an overstep, into nominative fair use. There's no good alternative way to refer to the big conference/music festival in Austin later in March, and \"unauthorized\" plainly indicates it's not an officially endorsed product. (Neither Unofficial SXSW nor the official \"SXSW&reg; GO\" gets particularly high marks from reviewers yet, but that may be because the event hasn't yet kicked off to fill them with data.)<p>Another 82 complaints (less 11 \"logo\" complaints) alleged copyright infringement -- copying of code, of graphical elements or \"look and feel\" (Nintendo complained about many \"Super Mario\" derivatives), of characters (Columbia's \"Qbert\"), or of audiovisual elements including video clips, wallpapers, and eBooks. Most of these were phrased in DMCA terms, since like a blog platform, the marketplace hosts \"information residing on systems or networks at direction of users\" <a href=\"http://static.chillingeffects.org/512.html#c\">512(c)</a>. <p>Unique among the copyright complaints in its indirection, the RIAA filed three complaints naming dozens of apps that allegedly \"facilitate the unauthorized streaming and downloading of popular sound recordings, the vast majority of which are owned or controlled by RIAA members.\" Its <a href=\"/dmca512c/notice.cgi?NoticeID=61677\">complaints</a>, complete with screenshots, asked for the removal of apps for ringtone creation and MP3 listening. This is an attenuated claim. RIAA isn't alleging that Google, or even the apps, are direct infringers of member copyrights. Rather, it claims that because Google hosts apps (or in some cases, serves ads inside them) that enable end-users to make infringing copies of music, Google should be held responsible for the users' infringing conduct -- a sort of once-removed contributory or vicarious liability claim. Is there a law of contributory inducement, after <a href=\"http://w2.eff.org/IP/P2P/MGM_v_Grokster/\">Grokster</a>? <p><br>I haven't followed all of the URLs to see how Google has responded to each of these complaints, but to its credit, it does not appear to have pulled the \"Unauthorized SXSW,\" for example. Others accused of trademark infringement appear to have changed their names or logos. Because the <a href=\"https://www.chillingeffects.org/dmca512/faq\">DMCA</a> applies only to copyright, not trademark, there is less settled procedure around the trademark claims. There's no safe-harbor, but neither is there an assumption that the service provider will be liable for its users' activity (see <a href=\"http://www.eff.org/deeplinks/2010/04/tiffany-v-ebay-what-about-put-back\">Tiffany v. eBay</a>, where the Second Circuit Court of Appeals held that \"for contributory trademark infringement liability to lie, a service provider must have more than a general knowledge or reason to know that its service is being used to sell counterfeit goods.\"). <p><br><img src=\"https://chart.googleapis.com/chart?cht=p&chtt=Complaint+Senders+to+Android+Market+(Feb+2011)&chs=750x400&chd=t:0.3,0.2,0.08,0.06,0.04,0.03,0.03,0.03,0.03,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,0.02,1.09&chl=Facebook,%20Inc.%20(30)|Nintendo%20of%20America%20Inc.%20(20)|Google%20Inc.%20(8)|Starbucks%20Corporation%20(6)|Hatched%20Games%20(4)|RIAA%20(3)|Photo%20Hunt%20(3)|Atari,%20Inc.%20(3)|ESPN%20Inc.%20(3)|Playboy%20Enterprises%20International,%20Inc.%20(2)|Electronic%20Arts%20Inc.%20(2)|The%20Walt%20Disney%20Company%20(2)|Monotype%20Imaging%20Inc.%20(2)|Kodansha%20Ltd.%20(2)|Metro,%20a%20division%20of%20Associated%20Newspapers%20Limited%20(2)|Dorna%20Sports%20(2)|Justin.tv,%20Inc.%20(2)|Rocket%20Radar%20(2)|eBay%20Inc.%20(2)|Promevo,%20LLC%20(2)|Other/Unidentified%20(109)&chco=0000FF&chp=3.14\" title=\"Takedown Senders\"><p><a name=\"note1\" href=\"#back\">*</a> Copyright geeks will recall that the last <a href=\"http://www.loc.gov/today/pr/2010/10-169.html\">anticircumvention rulemaking</a> exempted phone jailbreaking from the circumvention rule, so iPhone owners can confidently unlock their phones to use the <a href=\"http://cydia.saurik.com/\">cydia</a> marketplace or others.<br><a name=\"note2\" href=\"#back2\">*</a> Note that this is a simple count of distinct complaint submissions, each of which may target one or multiple allegedly infringing applications. $
54
+
55
+ @twitteritem.summary.should == "djcp: @csoghoian @BrookingsInst and the clipboard as well, presumably. #security #keylogging"
53
56
  end
54
57
 
55
58
  it "should have the correct content" do
@@ -101,6 +104,7 @@ module FeedAbstract
101
104
  @feedburneritem.content.should == ''
102
105
  @pyblosxomitem.content.should == %Q|<div><a href='http://www.flickr.com/photos/nffcnnr/401047557/' target='_blank'><img src='http://farm1.static.flickr.com/137/401047557_1dda26e16f.jpg' width=350 alt='MailBoxes by nffcnnr, on Flickr' title='MailBoxes by nffcnnr, on Flickr' border='0'/></a><br/><a href='http://creativecommons.org/licenses/by/2.0/' target='_blank'><img src='http://i.creativecommons.org/l/by/2.0/80x15.png' alt='Creative Commons Attribution 2.0 Generic License' title='Creative Commons Attribution 2.0 Generic License' border='0' align='left'></a>&nbsp;&nbsp;by&nbsp;<a href='http://www.flickr.com/people/nffcnnr/' target='_blank'>&nbsp;nffcnnr</a><a href='http://www.imagecodr.org/' target='_blank'>&nbsp;</a></div><p>I am haunted by the nagging fear that I have mailboxes, tucked into a\ndark corner of an office somewhere, and perhaps even full of checks\nand important documents, that I don't know exist.</p>\n|
103
106
  @chillitem.content.should == ''
107
+ @twitteritem.content.should == ""
104
108
  end
105
109
 
106
110
  it "should have the correct link" do
@@ -113,6 +117,7 @@ module FeedAbstract
113
117
  @feedburneritem.link.should == 'http://rss.cnn.com/~r/rss/cnn_topstories/~3/sV5N-C76mOM/index.html'
114
118
  @pyblosxomitem.link.should == 'http://mako.cc/copyrighteous/20110913-00'
115
119
  @chillitem.link.should == 'https://www.chillingeffects.org/weather.cgi?WeatherID=648'
120
+ @twitteritem.link.should == 'http://twitter.com/djcp/statuses/168381896559046656'
116
121
  end
117
122
 
118
123
  it "should have the correct author" do
@@ -125,6 +130,7 @@ module FeedAbstract
125
130
  @feedburneritem.author.should == ''
126
131
  @pyblosxomitem.author.should == ''
127
132
  @chillitem.author.should == ''
133
+ @twitteritem.author.should == 'djcp'
128
134
  end
129
135
 
130
136
  it "should have the correct authors" do
@@ -137,6 +143,7 @@ module FeedAbstract
137
143
  @feedburneritem.authors.should == []
138
144
  @pyblosxomitem.authors.should == []
139
145
  @chillitem.authors.should == []
146
+ @twitteritem.authors.should == ['djcp']
140
147
  end
141
148
 
142
149
  it "should have the correct contributor" do
@@ -149,6 +156,7 @@ module FeedAbstract
149
156
  @feedburneritem.contributor.should == ''
150
157
  @pyblosxomitem.contributor.should == ''
151
158
  @chillitem.contributor.should == ''
159
+ @twitteritem.contributor.should == ''
152
160
  end
153
161
 
154
162
  it "should have the correct contributors" do
@@ -161,6 +169,7 @@ module FeedAbstract
161
169
  @feedburneritem.contributors.should == []
162
170
  @pyblosxomitem.contributors.should == []
163
171
  @chillitem.contributors.should == []
172
+ @twitteritem.contributors.should == []
164
173
  end
165
174
 
166
175
  it "should have the correct category" do
@@ -173,6 +182,7 @@ module FeedAbstract
173
182
  @feedburneritem.category.should == ''
174
183
  @pyblosxomitem.category.should == ''
175
184
  @chillitem.category.should == ''
185
+ @twitteritem.category.should == 'security, keylogging'
176
186
  end
177
187
 
178
188
  it "should have the correct categories" do
@@ -185,6 +195,7 @@ module FeedAbstract
185
195
  @feedburneritem.categories.should == []
186
196
  @pyblosxomitem.categories.should == []
187
197
  @chillitem.categories.should == []
198
+ @twitteritem.categories.should == ['security', 'keylogging']
188
199
  end
189
200
 
190
201
  it "should have the correct rights" do
@@ -197,6 +208,7 @@ module FeedAbstract
197
208
  @feedburneritem.rights.should == ''
198
209
  @pyblosxomitem.rights.should == ''
199
210
  @chillitem.rights.should == ''
211
+ @twitteritem.rights.should == ''
200
212
  end
201
213
 
202
214
  it "should have been updated at the correct time" do
@@ -209,6 +221,7 @@ module FeedAbstract
209
221
  @feedburneritem.updated.should == Time.parse('Sat, 03 Sep 2011 16:11:39 EDT')
210
222
  @pyblosxomitem.updated.should == Time.parse('2011-09-15T05:21:00Z')
211
223
  @chillitem.updated.should == ""
224
+ @twitteritem.updated.should == Time.parse('2012-02-11 12:12:27 -0500')
212
225
  end
213
226
 
214
227
  it "should have been published at the proper time" do
@@ -221,6 +234,7 @@ module FeedAbstract
221
234
  @feedburneritem.published.should == Time.parse('Sat, 03 Sep 2011 16:11:39 EDT')
222
235
  @pyblosxomitem.published.should == Time.parse('2011-09-15T05:21:00Z')
223
236
  @chillitem.published.should == ''
237
+ @twitteritem.published.should == Time.parse('2012-02-11 12:12:27 -0500')
224
238
  end
225
239
 
226
240
  it "should have the proper guid" do
@@ -233,6 +247,7 @@ module FeedAbstract
233
247
  @feedburneritem.guid.should == 'http://www.cnn.com/2011/WORLD/africa/09/03/libya.west.spies/index.html?eref=rss_topstories'
234
248
  @pyblosxomitem.guid.should == 'http://mako.cc/copyrighteous/2011/09/15/20110913-00'
235
249
  @chillitem.guid.should == 'https://www.chillingeffects.org/weather.cgi?WeatherID=648'
250
+ @twitteritem.guid.should == 'http://twitter.com/djcp/statuses/168381896559046656'
236
251
  end
237
252
 
238
253
  end
@@ -22,6 +22,7 @@ module FeedAbstract
22
22
  @djcprss2.channel.class.should == Channel::RSS
23
23
  @djcprss92.channel.class.should == Channel::RSS
24
24
  @delicious.channel.class.should == Channel::RSS
25
+ @twitter.channel.class.should == Channel::RSS
25
26
  end
26
27
 
27
28
  it "should recognize rdf feeds properly" do
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  # encoding: UTF-8
2
+ require 'simplecov'
3
+ SimpleCov.start
2
4
 
3
5
  $:.unshift File.dirname(__FILE__) + '/../lib'
4
6
  require 'feed-abstract'
@@ -14,8 +16,9 @@ def instantiate_feeds
14
16
  @feedburner = FeedAbstract::Feed.new(File.open('spec/test_data/feedburner.rss'))
15
17
  @pyblosxom = FeedAbstract::Feed.new(File.open('spec/test_data/pyblosxom.atom'))
16
18
  @chill = FeedAbstract::Feed.new(File.open('spec/test_data/chillingeffects.xml'))
19
+ @twitter = FeedAbstract::Feed.new(File.open('spec/test_data/djcp_twitter.rss'))
17
20
 
18
- @all_feeds = [@docatom, @kpgatom, @djcprss2, @djcprss92, @oa, @delicious, @zotero, @feedburner,@pyblosxom,@chill]
21
+ @all_feeds = [@docatom, @kpgatom, @djcprss2, @djcprss92, @oa, @delicious, @zotero, @feedburner, @pyblosxom, @chill, @twitter]
19
22
  end
20
23
 
21
24
  def instantiate_example_items
@@ -28,4 +31,5 @@ def instantiate_example_items
28
31
  @feedburneritem = @feedburner.items.first
29
32
  @pyblosxomitem = @pyblosxom.items.first
30
33
  @chillitem = @chill.items.first
34
+ @twitteritem = @twitter.items.first
31
35
  end
@@ -0,0 +1,191 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <rss xmlns:georss="http://www.georss.org/georss" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:twitter="http://api.twitter.com" version="2.0">
3
+ <channel>
4
+ <title>Twitter / djcp</title>
5
+ <link>http://twitter.com/djcp</link>
6
+ <atom:link type="application/rss+xml" rel="self" href="https://twitter.com/statuses/user_timeline/djcp.rss"/>
7
+ <description>Twitter updates from Daniel Collis Puro / djcp.</description>
8
+ <language>en-us</language>
9
+ <ttl>40</ttl>
10
+ <item>
11
+ <title>djcp: @csoghoian @BrookingsInst and the clipboard as well, presumably. #security #keylogging</title>
12
+ <description>djcp: @csoghoian @BrookingsInst and the clipboard as well, presumably. #security #keylogging</description>
13
+ <pubDate>Sat, 11 Feb 2012 17:12:27 +0000</pubDate>
14
+ <guid>http://twitter.com/djcp/statuses/168381896559046656</guid>
15
+ <link>http://twitter.com/djcp/statuses/168381896559046656</link>
16
+ <twitter:source>web</twitter:source>
17
+ <twitter:place/>
18
+ </item>
19
+ <item>
20
+ <title>djcp: @slicehost STL migration got me disks that are twice as fast and a CPU upgrade to boot. Nice. Almost no down-time.</title>
21
+ <description>djcp: @slicehost STL migration got me disks that are twice as fast and a CPU upgrade to boot. Nice. Almost no down-time.</description>
22
+ <pubDate>Sat, 11 Feb 2012 17:09:43 +0000</pubDate>
23
+ <guid>http://twitter.com/djcp/statuses/168381208810618880</guid>
24
+ <link>http://twitter.com/djcp/statuses/168381208810618880</link>
25
+ <twitter:source>web</twitter:source>
26
+ <twitter:place/>
27
+ </item>
28
+ <item>
29
+ <title>djcp: If you walk slow and take wide turns, you are annoying.</title>
30
+ <description>djcp: If you walk slow and take wide turns, you are annoying.</description>
31
+ <pubDate>Thu, 09 Feb 2012 13:42:58 +0000</pubDate>
32
+ <guid>http://twitter.com/djcp/statuses/167604404399251456</guid>
33
+ <link>http://twitter.com/djcp/statuses/167604404399251456</link>
34
+ <twitter:source>&lt;a href=&quot;http://seesmic.com/&quot; rel=&quot;nofollow&quot;&gt;Seesmic&lt;/a&gt;</twitter:source>
35
+ <twitter:place/>
36
+ </item>
37
+ <item>
38
+ <title>djcp: As expected: Defendant Ordered to Decrypt Laptop May Have Forgotten Password http://t.co/CPQ8Zl2t</title>
39
+ <description>djcp: As expected: Defendant Ordered to Decrypt Laptop May Have Forgotten Password http://t.co/CPQ8Zl2t</description>
40
+ <pubDate>Tue, 07 Feb 2012 02:55:44 +0000</pubDate>
41
+ <guid>http://twitter.com/djcp/statuses/166716746378641408</guid>
42
+ <link>http://twitter.com/djcp/statuses/166716746378641408</link>
43
+ <twitter:source>&lt;a href=&quot;http://twitter.com/tweetbutton&quot; rel=&quot;nofollow&quot;&gt;Tweet Button&lt;/a&gt;</twitter:source>
44
+ <twitter:place/>
45
+ </item>
46
+ <item>
47
+ <title>djcp: Trying to cheat the system so I can check out my geek cred http://t.co/GpWRdu71 via @coderwall</title>
48
+ <description>djcp: Trying to cheat the system so I can check out my geek cred http://t.co/GpWRdu71 via @coderwall</description>
49
+ <pubDate>Mon, 06 Feb 2012 20:30:27 +0000</pubDate>
50
+ <guid>http://twitter.com/djcp/statuses/166619786040717312</guid>
51
+ <link>http://twitter.com/djcp/statuses/166619786040717312</link>
52
+ <twitter:source>&lt;a href=&quot;http://twitter.com/tweetbutton&quot; rel=&quot;nofollow&quot;&gt;Tweet Button&lt;/a&gt;</twitter:source>
53
+ <twitter:place/>
54
+ </item>
55
+ <item>
56
+ <title>djcp: The &quot;shocker&quot; example COMPLETELY turns me off #whiskey_disk. Frickin' #brogrammers. https://t.co/8KccqFLx</title>
57
+ <description>djcp: The &quot;shocker&quot; example COMPLETELY turns me off #whiskey_disk. Frickin' #brogrammers. https://t.co/8KccqFLx</description>
58
+ <pubDate>Mon, 06 Feb 2012 14:08:42 +0000</pubDate>
59
+ <guid>http://twitter.com/djcp/statuses/166523714396110848</guid>
60
+ <link>http://twitter.com/djcp/statuses/166523714396110848</link>
61
+ <twitter:source>web</twitter:source>
62
+ <twitter:place/>
63
+ </item>
64
+ <item>
65
+ <title>djcp: RT @csoghoian: Microsoft takes out full page ad in newspapers to tout privacy benefits of Bing+Hotmail. Yet Bing still doesn't work over ...</title>
66
+ <description>djcp: RT @csoghoian: Microsoft takes out full page ad in newspapers to tout privacy benefits of Bing+Hotmail. Yet Bing still doesn't work over ...</description>
67
+ <pubDate>Sat, 04 Feb 2012 00:16:06 +0000</pubDate>
68
+ <guid>http://twitter.com/djcp/statuses/165589410103033856</guid>
69
+ <link>http://twitter.com/djcp/statuses/165589410103033856</link>
70
+ <twitter:source>&lt;a href=&quot;http://seesmic.com/&quot; rel=&quot;nofollow&quot;&gt;Seesmic&lt;/a&gt;</twitter:source>
71
+ <twitter:place/>
72
+ </item>
73
+ <item>
74
+ <title>djcp: @berkmancenter now hosts 1,010 active blogs under our #wordpress #multisite install at http://t.co/NLzbUn6W</title>
75
+ <description>djcp: @berkmancenter now hosts 1,010 active blogs under our #wordpress #multisite install at http://t.co/NLzbUn6W</description>
76
+ <pubDate>Fri, 03 Feb 2012 14:56:40 +0000</pubDate>
77
+ <guid>http://twitter.com/djcp/statuses/165448625588146176</guid>
78
+ <link>http://twitter.com/djcp/statuses/165448625588146176</link>
79
+ <twitter:source>web</twitter:source>
80
+ <twitter:place/>
81
+ </item>
82
+ <item>
83
+ <title>djcp: @mirell not bragging, it's just great software. Totally worth the investment.</title>
84
+ <description>djcp: @mirell not bragging, it's just great software. Totally worth the investment.</description>
85
+ <pubDate>Thu, 02 Feb 2012 00:41:37 +0000</pubDate>
86
+ <guid>http://twitter.com/djcp/statuses/164871056916615172</guid>
87
+ <link>http://twitter.com/djcp/statuses/164871056916615172</link>
88
+ <twitter:source>&lt;a href=&quot;http://seesmic.com/&quot; rel=&quot;nofollow&quot;&gt;Seesmic&lt;/a&gt;</twitter:source>
89
+ <twitter:place/>
90
+ </item>
91
+ <item>
92
+ <title>djcp: @mirell I use agent forwarding, multiplexing, chaining and proxying every day. #ssh / fuse gives you easy remote file mounts too.</title>
93
+ <description>djcp: @mirell I use agent forwarding, multiplexing, chaining and proxying every day. #ssh / fuse gives you easy remote file mounts too.</description>
94
+ <pubDate>Thu, 02 Feb 2012 00:40:48 +0000</pubDate>
95
+ <guid>http://twitter.com/djcp/statuses/164870850011602944</guid>
96
+ <link>http://twitter.com/djcp/statuses/164870850011602944</link>
97
+ <twitter:source>&lt;a href=&quot;http://seesmic.com/&quot; rel=&quot;nofollow&quot;&gt;Seesmic&lt;/a&gt;</twitter:source>
98
+ <twitter:place/>
99
+ </item>
100
+ <item>
101
+ <title>djcp: RT @ApocalypseHow: You have to admit, &quot;Lunchables&quot; is a better name than &quot;Yes, Technically You Could Eat These.&quot;</title>
102
+ <description>djcp: RT @ApocalypseHow: You have to admit, &quot;Lunchables&quot; is a better name than &quot;Yes, Technically You Could Eat These.&quot;</description>
103
+ <pubDate>Wed, 01 Feb 2012 23:24:26 +0000</pubDate>
104
+ <guid>http://twitter.com/djcp/statuses/164851633497448448</guid>
105
+ <link>http://twitter.com/djcp/statuses/164851633497448448</link>
106
+ <twitter:source>&lt;a href=&quot;http://seesmic.com/&quot; rel=&quot;nofollow&quot;&gt;Seesmic&lt;/a&gt;</twitter:source>
107
+ <twitter:place/>
108
+ </item>
109
+ <item>
110
+ <title>djcp: RT @TwopTwips: TEACH your child about the importance of punctuation by making them some &quot;No, More Tears&quot; shampoo out of lemon juice and ...</title>
111
+ <description>djcp: RT @TwopTwips: TEACH your child about the importance of punctuation by making them some &quot;No, More Tears&quot; shampoo out of lemon juice and ...</description>
112
+ <pubDate>Mon, 30 Jan 2012 13:18:11 +0000</pubDate>
113
+ <guid>http://twitter.com/djcp/statuses/163974286573441024</guid>
114
+ <link>http://twitter.com/djcp/statuses/163974286573441024</link>
115
+ <twitter:source>&lt;a href=&quot;http://seesmic.com/&quot; rel=&quot;nofollow&quot;&gt;Seesmic&lt;/a&gt;</twitter:source>
116
+ <twitter:place/>
117
+ </item>
118
+ <item>
119
+ <title>djcp: More than a little psyched for the @Raspberry_Pi . Can think of a bunch of uses, replacing http://t.co/heC2AiVN for one.</title>
120
+ <description>djcp: More than a little psyched for the @Raspberry_Pi . Can think of a bunch of uses, replacing http://t.co/heC2AiVN for one.</description>
121
+ <pubDate>Mon, 30 Jan 2012 13:06:57 +0000</pubDate>
122
+ <guid>http://twitter.com/djcp/statuses/163971463404195842</guid>
123
+ <link>http://twitter.com/djcp/statuses/163971463404195842</link>
124
+ <twitter:source>&lt;a href=&quot;http://seesmic.com/&quot; rel=&quot;nofollow&quot;&gt;Seesmic&lt;/a&gt;</twitter:source>
125
+ <twitter:place/>
126
+ </item>
127
+ <item>
128
+ <title>djcp: RT @pmphlt: Don't the Megaupload indictments show that SOPA isn't needed to achieve what SOPA was supposedly needed to achieve?</title>
129
+ <description>djcp: RT @pmphlt: Don't the Megaupload indictments show that SOPA isn't needed to achieve what SOPA was supposedly needed to achieve?</description>
130
+ <pubDate>Fri, 27 Jan 2012 23:16:13 +0000</pubDate>
131
+ <guid>http://twitter.com/djcp/statuses/163037622833393665</guid>
132
+ <link>http://twitter.com/djcp/statuses/163037622833393665</link>
133
+ <twitter:source>&lt;a href=&quot;http://seesmic.com/&quot; rel=&quot;nofollow&quot;&gt;Seesmic&lt;/a&gt;</twitter:source>
134
+ <twitter:place/>
135
+ </item>
136
+ <item>
137
+ <title>djcp: RT @shortcomment: Newt Gingrich believes marriage should be between one man and one woman. And one more woman. #GOP #p2 #tcot</title>
138
+ <description>djcp: RT @shortcomment: Newt Gingrich believes marriage should be between one man and one woman. And one more woman. #GOP #p2 #tcot</description>
139
+ <pubDate>Fri, 20 Jan 2012 22:52:12 +0000</pubDate>
140
+ <guid>http://twitter.com/djcp/statuses/160494866743300097</guid>
141
+ <link>http://twitter.com/djcp/statuses/160494866743300097</link>
142
+ <twitter:source>&lt;a href=&quot;http://seesmic.com/&quot; rel=&quot;nofollow&quot;&gt;Seesmic&lt;/a&gt;</twitter:source>
143
+ <twitter:place/>
144
+ </item>
145
+ <item>
146
+ <title>djcp: RT @darrenelmore: Go ahead America, picture Newt strolling through a 1970s key party, naked with an open kimono and a snifter of brandy. ...</title>
147
+ <description>djcp: RT @darrenelmore: Go ahead America, picture Newt strolling through a 1970s key party, naked with an open kimono and a snifter of brandy. ...</description>
148
+ <pubDate>Fri, 20 Jan 2012 14:17:15 +0000</pubDate>
149
+ <guid>http://twitter.com/djcp/statuses/160365272979603456</guid>
150
+ <link>http://twitter.com/djcp/statuses/160365272979603456</link>
151
+ <twitter:source>&lt;a href=&quot;http://seesmic.com/&quot; rel=&quot;nofollow&quot;&gt;Seesmic&lt;/a&gt;</twitter:source>
152
+ <twitter:place/>
153
+ </item>
154
+ <item>
155
+ <title>djcp: RT @fightfortheftr: The Oatmeal's goes on #SOPAstrike with a hilarious take on #SOPA and #PIPA http://t.co/7hvUlyfd</title>
156
+ <description>djcp: RT @fightfortheftr: The Oatmeal's goes on #SOPAstrike with a hilarious take on #SOPA and #PIPA http://t.co/7hvUlyfd</description>
157
+ <pubDate>Wed, 18 Jan 2012 15:02:07 +0000</pubDate>
158
+ <guid>http://twitter.com/djcp/statuses/159651788226691072</guid>
159
+ <link>http://twitter.com/djcp/statuses/159651788226691072</link>
160
+ <twitter:source>web</twitter:source>
161
+ <twitter:place/>
162
+ </item>
163
+ <item>
164
+ <title>djcp: @rebekahredux @morninj Thanks, y'all! It's a mashup of http://t.co/kmgQcOmw and http://t.co/ScGmVFxm</title>
165
+ <description>djcp: @rebekahredux @morninj Thanks, y'all! It's a mashup of http://t.co/kmgQcOmw and http://t.co/ScGmVFxm</description>
166
+ <pubDate>Wed, 18 Jan 2012 14:58:02 +0000</pubDate>
167
+ <guid>http://twitter.com/djcp/statuses/159650762622910464</guid>
168
+ <link>http://twitter.com/djcp/statuses/159650762622910464</link>
169
+ <twitter:source>web</twitter:source>
170
+ <twitter:place/>
171
+ </item>
172
+ <item>
173
+ <title>djcp: RT @michaelianblack: Am I the only one who's worried that once Wikipedia goes black it'll never go back?</title>
174
+ <description>djcp: RT @michaelianblack: Am I the only one who's worried that once Wikipedia goes black it'll never go back?</description>
175
+ <pubDate>Wed, 18 Jan 2012 04:48:51 +0000</pubDate>
176
+ <guid>http://twitter.com/djcp/statuses/159497458110578688</guid>
177
+ <link>http://twitter.com/djcp/statuses/159497458110578688</link>
178
+ <twitter:source>&lt;a href=&quot;http://seesmic.com/&quot; rel=&quot;nofollow&quot;&gt;Seesmic&lt;/a&gt;</twitter:source>
179
+ <twitter:place/>
180
+ </item>
181
+ <item>
182
+ <title>djcp: Take action against #SOPA and #PIPA - Support the #Wikipediablackout on Jan 18 http://t.co/lGWJyhnS</title>
183
+ <description>djcp: Take action against #SOPA and #PIPA - Support the #Wikipediablackout on Jan 18 http://t.co/lGWJyhnS</description>
184
+ <pubDate>Tue, 17 Jan 2012 14:32:34 +0000</pubDate>
185
+ <guid>http://twitter.com/djcp/statuses/159281963608453120</guid>
186
+ <link>http://twitter.com/djcp/statuses/159281963608453120</link>
187
+ <twitter:source>&lt;a href=&quot;http://twitter.com/tweetbutton&quot; rel=&quot;nofollow&quot;&gt;Tweet Button&lt;/a&gt;</twitter:source>
188
+ <twitter:place/>
189
+ </item>
190
+ </channel>
191
+ </rss>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: feed-abstract
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-16 00:00:00.000000000Z
12
+ date: 2012-02-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: feed-abstract
16
- requirement: &90048490 !ruby/object:Gem::Requirement
16
+ requirement: &26584200 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *90048490
24
+ version_requirements: *26584200
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &90048210 !ruby/object:Gem::Requirement
27
+ requirement: &26583020 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *90048210
35
+ version_requirements: *26583020
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &90047870 !ruby/object:Gem::Requirement
38
+ requirement: &26582460 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,73 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *90047870
46
+ version_requirements: *26582460
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &26581020 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *26581020
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &26580180 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *26580180
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: &26579000 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *26579000
80
+ - !ruby/object:Gem::Dependency
81
+ name: simplecov
82
+ requirement: &29053020 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *29053020
91
+ - !ruby/object:Gem::Dependency
92
+ name: rspec
93
+ requirement: &29052500 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *29052500
102
+ - !ruby/object:Gem::Dependency
103
+ name: simplecov
104
+ requirement: &29052020 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *29052020
47
113
  description: ! 'This library creates a common object graph for the RSS/Atom/RDF parsing
48
114
  classes in the ruby standard library. This allows you parse different feed formats
49
115
  and get back the same (or at least a very similar) set of results - item authors
@@ -85,6 +151,7 @@ files:
85
151
  - spec/test_data/djcp.rss92
86
152
  - spec/test_data/djcp_code.rss
87
153
  - spec/test_data/djcp_delicious.rss
154
+ - spec/test_data/djcp_twitter.rss
88
155
  - spec/test_data/doc.atom
89
156
  - spec/test_data/feedburner.rss
90
157
  - spec/test_data/katanapg.atom
@@ -112,9 +179,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
179
  version: '0'
113
180
  requirements: []
114
181
  rubyforge_project:
115
- rubygems_version: 1.8.6
182
+ rubygems_version: 1.8.10
116
183
  signing_key:
117
184
  specification_version: 3
118
- summary: Abstracts RSS/Atom/RDF parsing features from the ruby standard lib into a
119
- common object graph.
185
+ summary: Abstracts RSS/Atom/RDF stdlib parsing into a common object graph.
120
186
  test_files: []