superfeedr-rb 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Jeff Smick
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ Superfeedr rb
2
+ =============
3
+
4
+ A ruby library based on Blather for Superfeedr.
5
+
6
+ This library is *very* opinionated. In fact there's really only one method `feed`.
7
+
8
+ Install
9
+ -------
10
+ Gem is hosted on [Gemcutter](http://gemcutter.org/)
11
+
12
+ sudo gem install superfeedr-rb
13
+
14
+ Example
15
+ -------
16
+
17
+ require 'rubygems'
18
+ require 'superfeedr-rb'
19
+ require 'pp'
20
+
21
+ Superfeedr::Client.connect('demo@superfeedr.com', '*********').do |client|
22
+ client.feed('http://superfeedr.com/dummy.xml') do |status, entries|
23
+ pp({
24
+ :status => {
25
+ :feed => status.feed,
26
+ :code => status.code,
27
+ :http => status.http,
28
+ :next_fetch => status.next_fetch
29
+ },
30
+ :entries => entries.map { |entry| {
31
+ :id => entry.id,
32
+ :chunks => entry.chunks,
33
+ :chunk => entry.chunk,
34
+ :title => entry.title,
35
+ :published => entry.published,
36
+ :content => entry.content,
37
+ :summary => entry.summary,
38
+ :categories => entry.categories,
39
+ :links => entry.links.map { |link| {
40
+ :href => link.href,
41
+ :rel => link.rel,
42
+ :type => link.type,
43
+ :title => link.title
44
+ }},
45
+ :authors => entry.authors.map { |author| {
46
+ :name => author.name,
47
+ :email => author.email,
48
+ :uri => author.uri
49
+ }}
50
+ }}
51
+ })
52
+ end
53
+
54
+ client.feed('http://github.com/superfeedr.atom') do |notification|
55
+ pp notification
56
+ end
57
+ end
58
+
59
+
60
+ Copyright
61
+ ---------
62
+
63
+ Copyright (c) 2009 Jeff Smick. See LICENSE for details.
@@ -0,0 +1,89 @@
1
+ module Superfeedr
2
+ class Entry < Blather::Stanza::PubSubItem
3
+ NS = 'http://www.w3.org/2005/Atom'.freeze
4
+
5
+ def self.parse(node)
6
+ node.find('//ns:event/ns:items/ns:item', :ns => Blather::Stanza::PubSub::Event.registered_ns).map do |item|
7
+ Entry.new('item').inherit(item)
8
+ end
9
+ end
10
+
11
+ def chunks
12
+ self[:chunks].to_i
13
+ end
14
+
15
+ def chunk
16
+ self[:chunk].to_i
17
+ end
18
+
19
+ def id
20
+ self.entry.content_from 'ns:id', :ns => NS
21
+ end
22
+
23
+ def title
24
+ self.entry.content_from 'ns:title', :ns => NS
25
+ end
26
+
27
+ def published
28
+ if published = self.entry.content_from('ns:published', :ns => NS)
29
+ DateTime.parse published
30
+ end
31
+ end
32
+
33
+ def content
34
+ self.entry.content_from 'ns:content', :ns => NS
35
+ end
36
+
37
+ def summary
38
+ self.entry.content_from 'ns:summary', :ns => NS
39
+ end
40
+
41
+ def categories
42
+ self.entry.find('ns:category', :ns => NS).map { |cat| cat[:term] }
43
+ end
44
+
45
+ def links
46
+ self.entry.find('ns:link', :ns => NS).map { |l| Link.new.inherit(l) }
47
+ end
48
+
49
+ def authors
50
+ self.entry.find('ns:author', :ns => NS).map { |l| Author.new.inherit(l) }
51
+ end
52
+
53
+ def entry
54
+ Blather::XMPPNode.import(super)
55
+ end
56
+
57
+ class Link < Blather::XMPPNode
58
+ def href
59
+ self[:href]
60
+ end
61
+
62
+ def rel
63
+ self[:rel]
64
+ end
65
+
66
+ def type
67
+ self[:type]
68
+ end
69
+
70
+ def title
71
+ self[:title]
72
+ end
73
+ end
74
+
75
+ class Author < Blather::XMPPNode
76
+ def name
77
+ self.content_from 'ns:name', :ns => NS
78
+ end
79
+
80
+ def email
81
+ self.content_from 'ns:email', :ns => NS
82
+ end
83
+
84
+ def uri
85
+ self.content_from 'ns:uri', :ns => NS
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,36 @@
1
+ module Superfeedr
2
+ class Status < Blather::XMPPNode
3
+ NS = 'http://superfeedr.com/xmpp-pubsub-ext'.freeze
4
+
5
+ def self.parse(node)
6
+ self.new('status').inherit node.find_first('//ns:status', :ns => NS)
7
+ end
8
+
9
+ def failed?
10
+ false
11
+ end
12
+
13
+ def feed
14
+ self[:feed]
15
+ end
16
+
17
+ def code
18
+ self.http_node[:code].to_i
19
+ end
20
+
21
+ def http
22
+ self.http_node.content
23
+ end
24
+
25
+ def next_fetch
26
+ if next_fetch = self.find_first('//ns:next_fetch', :ns => NS).content
27
+ DateTime.parse next_fetch
28
+ end
29
+ end
30
+
31
+ protected
32
+ def http_node
33
+ self.find_first('//ns:http', :ns => NS)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,65 @@
1
+ %w[
2
+ blather
3
+ blather/client/client
4
+
5
+ superfeedr/entry
6
+ superfeedr/status
7
+ ].each { |r| require r }
8
+
9
+ module Superfeedr
10
+
11
+ class Client < Blather::Client
12
+ def self.connect(jid, pass, host = nil, port = nil)
13
+ if block_given?
14
+ client = self.setup jid, pass, host, port
15
+ EM.run {
16
+ yield client
17
+ client.connect
18
+ }
19
+ else
20
+ super
21
+ end
22
+ end
23
+
24
+ def initialize # :nodoc:
25
+ super
26
+ @deferred = []
27
+ end
28
+
29
+ def feed(url, &block)
30
+ return if defer(:feed, url, &block)
31
+ self.write Blather::Stanza::PubSub::Subscribe.new(:set, 'firehoser.superfeedr.com', url, self.jid.stripped)
32
+
33
+ self.register_handler(:pubsub_event, "//ns:items[@node='#{url}']", :ns => Blather::Stanza::PubSub::Event.registered_ns) do |evt, _|
34
+ block.call Status.parse(evt), Entry.parse(evt)
35
+ end
36
+ end
37
+
38
+ def client_post_init # :nodoc:
39
+ # overwrite the default actions to take after a client is setup
40
+ status = Blather::Stanza::Presence::Status.new
41
+ status.priority = 100
42
+ write status
43
+ end
44
+
45
+ # Allow users to setup callbacks before the connection is setup
46
+ def defer(*args, &block) # :nodoc:
47
+ if @stream
48
+ false
49
+ else
50
+ @deferred << [args, block]
51
+ true
52
+ end
53
+ end
54
+
55
+ # Run all deferred commands after the connection is established
56
+ def post_init(stream, jid = nil) # :nodoc:
57
+ super
58
+ until @deferred.empty?
59
+ args = @deferred.pop
60
+ self.__send__ *(args[0]), &args[1]
61
+ end
62
+ end
63
+ end
64
+
65
+ end
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'minitest/spec'
3
+
4
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), '..'))
5
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), *%w[.. lib]))
6
+ require 'superfeedr-rb'
7
+
8
+ def message_node
9
+ Blather::XMPPNode.import(Nokogiri::XML(<<-XML).root)
10
+ <message from="firehoser.superfeedr.com" to="sprsquish@superfeedr.com">
11
+ <event xmlns="http://jabber.org/protocol/pubsub#event">
12
+ <status xmlns="http://superfeedr.com/xmpp-pubsub-ext" feed="http://superfeedr.com/dummy.xml">
13
+ <http code="200">957 bytes fetched in 0.228013s</http>
14
+ <next_fetch>2009-11-05T16:34:12+00:00</next_fetch>
15
+ </status>
16
+ <items node="http://superfeedr.com/dummy.xml">
17
+ <item chunks="1" chunk="1">
18
+ <entry xmlns="http://www.w3.org/2005/Atom">
19
+ <title>16:32:41</title>
20
+ <id>tag:superfeedr.com,2005:String/1257438761</id>
21
+ <published>2009-11-05T16:32:41+00:00</published>
22
+ <summary>sprsquish wanted to know what time it was.</summary>
23
+ <content>Thursday November 05 16:32:41 UTC 2009 sprsquish wanted to know what time it was.</content>
24
+ <category term="tag" scheme="http://www.sixapart.com/ns/types#tag" />
25
+ <category term="category" scheme="http://www.sixapart.com/ns/types#tag" />
26
+ <link type="text/html" href="http://superfeedr.com/?1257438761" title="superfeedr" rel="alternate"/>
27
+ <author>
28
+ <name>Superfeedr</name>
29
+ <uri>http://superfeedr.com/</uri>
30
+ <email>julien@superfeedr.com</email>
31
+ </author>
32
+ </entry>
33
+ </item>
34
+ </items>
35
+ </event>
36
+ </message>
37
+ XML
38
+ end
39
+
40
+ MiniTest::Unit.autorun
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+
3
+ # <item chunks="1" chunk="1">
4
+ # <entry xmlns="http://www.w3.org/2005/Atom">
5
+ # <title>16:32:41</title>
6
+ # <id>tag:superfeedr.com,2005:String/1257438761</id>
7
+ # <published>2009-11-05T16:32:41+00:00</published>
8
+ # <summary>sprsquish wanted to know what time it was.</summary>
9
+ # <content>Thursday November 05 16:32:41 UTC 2009 sprsquish wanted to know what time it was.</content>
10
+ # <category term="tag" scheme="http://www.sixapart.com/ns/types#tag" />
11
+ # <category term="category" scheme="http://www.sixapart.com/ns/types#tag" />
12
+ # <link type="text/html" href="http://superfeedr.com/?1257438761" title="superfeedr" rel="alternate"/>
13
+ # <author>
14
+ # <name>Superfeedr</name>
15
+ # <uri>http://superfeedr.com/</uri>
16
+ # <email>julien@superfeedr.com</email>
17
+ # </author>
18
+ # </entry>
19
+ # </item>
20
+
21
+ describe Superfeedr::Entry do
22
+ before do
23
+ @events = Superfeedr::Entry.parse message_node
24
+ @event = @events.first
25
+ end
26
+
27
+ it 'parses apart a list of items' do
28
+ @events.must_be_kind_of Array
29
+ @events.size.must_equal 1
30
+ end
31
+
32
+ it 'knows how many chunks it has' do
33
+ @event.chunks.must_equal 1
34
+ end
35
+
36
+ it 'knows what chunk it is' do
37
+ @event.chunk.must_equal 1
38
+ end
39
+
40
+ it 'knows its title' do
41
+ @event.title.must_equal '16:32:41'
42
+ end
43
+
44
+ it 'knows its id' do
45
+ @event.id.must_equal 'tag:superfeedr.com,2005:String/1257438761'
46
+ end
47
+
48
+ it 'knows when it was published' do
49
+ @event.published.must_equal DateTime.parse('2009-11-05T16:32:41+00:00')
50
+ end
51
+
52
+ it 'has content' do
53
+ @event.content.must_equal 'Thursday November 05 16:32:41 UTC 2009 sprsquish wanted to know what time it was.'
54
+ end
55
+
56
+ it 'has a summary' do
57
+ @event.summary.must_equal 'sprsquish wanted to know what time it was.'
58
+ end
59
+
60
+ it 'knows its categories' do
61
+ @event.categories.must_equal %w[tag category]
62
+ end
63
+
64
+ it 'has a set of links' do
65
+ @event.links.size.must_equal 1
66
+ @event.links.first.must_be_kind_of Superfeedr::Entry::Link
67
+ end
68
+
69
+ it 'has a set of authors' do
70
+ @event.authors.size.must_equal 1
71
+ @event.authors.first.must_be_kind_of Superfeedr::Entry::Author
72
+ end
73
+ end
74
+
75
+ # <link type="text/html" href="http://superfeedr.com/?1257438761" title="superfeedr" rel="alternate"/>
76
+ describe Superfeedr::Entry::Link do
77
+ before do
78
+ @link = Superfeedr::Entry.parse(message_node).first.links.first
79
+ end
80
+
81
+ it 'knows its href' do
82
+ @link.href.must_equal 'http://superfeedr.com/?1257438761'
83
+ end
84
+
85
+ it 'knows its rel' do
86
+ @link.rel.must_equal 'alternate'
87
+ end
88
+
89
+ it 'knows its type' do
90
+ @link.type.must_equal 'text/html'
91
+ end
92
+
93
+ it 'knows its title' do
94
+ @link.title.must_equal 'superfeedr'
95
+ end
96
+ end
97
+
98
+ # <author>
99
+ # <name>Superfeedr</name>
100
+ # <uri>http://superfeedr.com/</uri>
101
+ # <email>julien@superfeedr.com</email>
102
+ # </author>
103
+ describe Superfeedr::Entry::Author do
104
+ before do
105
+ @author = Superfeedr::Entry.parse(message_node).first.authors.first
106
+ end
107
+
108
+ it 'knows its name' do
109
+ @author.name.must_equal 'Superfeedr'
110
+ end
111
+
112
+ it 'knows its uri' do
113
+ @author.uri.must_equal 'http://superfeedr.com/'
114
+ end
115
+
116
+ it 'knows its email' do
117
+ @author.email.must_equal 'julien@superfeedr.com'
118
+ end
119
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ # <status xmlns="http://superfeedr.com/xmpp-pubsub-ext" feed="http://superfeedr.com/dummy.xml">
4
+ # <http code="200">957 bytes fetched in 0.228013s</http>
5
+ # <next_fetch>2009-11-05T16:34:12+00:00</next_fetch>
6
+ # </status>
7
+
8
+ describe Superfeedr::Status do
9
+ before do
10
+ @status = Superfeedr::Status.parse message_node
11
+ end
12
+
13
+ it 'knows the feed it belongs to' do
14
+ @status.feed.must_equal 'http://superfeedr.com/dummy.xml'
15
+ end
16
+
17
+ it 'knows its status code' do
18
+ @status.code.must_equal 200
19
+ end
20
+
21
+ it 'has more info about the http code' do
22
+ @status.http.must_equal '957 bytes fetched in 0.228013s'
23
+ end
24
+
25
+ it 'knows when the next fetch will be' do
26
+ @status.next_fetch.must_equal DateTime.parse('2009-11-05T16:34:12+00:00')
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: superfeedr-rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jeff Smick
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-05 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: minitest
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: yard
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: blather
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ description: A ruby library based on Blather for Superfeedr
46
+ email: sprsquish@gmail.com
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - LICENSE
53
+ - README.md
54
+ files:
55
+ - lib/superfeedr-rb.rb
56
+ - lib/superfeedr/entry.rb
57
+ - lib/superfeedr/status.rb
58
+ - LICENSE
59
+ - README.md
60
+ has_rdoc: true
61
+ homepage: http://github.com/sprsquish/superfeedr-rb
62
+ licenses: []
63
+
64
+ post_install_message:
65
+ rdoc_options:
66
+ - --charset=UTF-8
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ version:
81
+ requirements: []
82
+
83
+ rubyforge_project:
84
+ rubygems_version: 1.3.5
85
+ signing_key:
86
+ specification_version: 3
87
+ summary: A ruby library based on Blather for Superfeedr
88
+ test_files:
89
+ - spec/spec_helper.rb
90
+ - spec/superfeedr/entry_spec.rb
91
+ - spec/superfeedr/status_spec.rb