google_reader 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.textile +6 -0
- data/lib/google_reader/client.rb +19 -8
- data/lib/google_reader/entry.rb +0 -2
- data/lib/google_reader/feed.rb +39 -0
- data/lib/google_reader/version.rb +1 -1
- data/lib/google_reader.rb +3 -0
- data/spec/client_spec.rb +27 -10
- data/spec/feed_spec.rb +23 -0
- data/spec/fixtures/entry.xml +9 -0
- metadata +4 -1
data/README.textile
CHANGED
@@ -37,6 +37,12 @@ p item.author
|
|
37
37
|
p item.source
|
38
38
|
p item.liking_users
|
39
39
|
p item.summary
|
40
|
+
|
41
|
+
# You may also get feed objects back, which then allow you to query "since" a time
|
42
|
+
feed = client.read_feed
|
43
|
+
cutoff_at = feed.updated_at
|
44
|
+
sleep 30
|
45
|
+
client.read_feed(:since => cutoff_at) # Only new items since that cutoff time
|
40
46
|
</code></pre>
|
41
47
|
|
42
48
|
h2. Ruby Library
|
data/lib/google_reader/client.rb
CHANGED
@@ -54,11 +54,27 @@ module GoogleReader
|
|
54
54
|
tracking-item-link-used
|
55
55
|
tracking-body-link-used).each do |suffix|
|
56
56
|
|
57
|
+
method_name = suffix.gsub("-", "_") + "_feed"
|
58
|
+
define_method(method_name) do |*args|
|
59
|
+
options = args.first || Hash.new
|
60
|
+
params = Hash.new
|
61
|
+
params[:n] = options[:count] || 20
|
62
|
+
if options.has_key?(:since) then
|
63
|
+
params[:r] = "o"
|
64
|
+
params[:ot] = options[:since].to_i
|
65
|
+
end
|
66
|
+
|
67
|
+
str_params = params.map do |k, v|
|
68
|
+
CGI.escape(k.to_s) << "=" << CGI.escape(v.to_s)
|
69
|
+
end.join("&")
|
70
|
+
|
71
|
+
content = RestClient.get(STATE_URL + suffix + "?#{str_params}", headers)
|
72
|
+
Feed.new( Nokogiri::XML(content) )
|
73
|
+
end
|
74
|
+
|
57
75
|
method_name = suffix.gsub("-", "_") + "_items"
|
58
76
|
define_method(method_name) do |*args|
|
59
|
-
|
60
|
-
content = RestClient.get(STATE_URL + suffix + "?n=#{CGI.escape(count.to_s)}", headers)
|
61
|
-
parse_atom_feed(content)
|
77
|
+
__send__(method_name.sub("_items", "_feed"), *args).entries
|
62
78
|
end
|
63
79
|
end
|
64
80
|
|
@@ -66,10 +82,5 @@ module GoogleReader
|
|
66
82
|
content = RestClient.get(STATE_URL + suffix + "?n=#{CGI.escape(count.to_s)}&xt=#{CGI.escape("state/com.google/read")}", headers)
|
67
83
|
parse_atom_feed(content)
|
68
84
|
end
|
69
|
-
|
70
|
-
def parse_atom_feed(feed)
|
71
|
-
doc = Nokogiri::XML(feed)
|
72
|
-
doc.search("entry").map {|entry| Entry.new(entry)}
|
73
|
-
end
|
74
85
|
end
|
75
86
|
end
|
data/lib/google_reader/entry.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
require "time"
|
2
|
+
|
3
|
+
module GoogleReader
|
4
|
+
class Feed
|
5
|
+
attr_reader :feed
|
6
|
+
|
7
|
+
def initialize(feed)
|
8
|
+
@feed = feed
|
9
|
+
end
|
10
|
+
|
11
|
+
def entries
|
12
|
+
@entries ||= @feed.search("entry").map {|entry| Entry.new(entry)}
|
13
|
+
end
|
14
|
+
|
15
|
+
def id
|
16
|
+
@feed.search("id").first.text
|
17
|
+
end
|
18
|
+
|
19
|
+
def updated_at
|
20
|
+
Time.parse( @feed.search("updated").first.text )
|
21
|
+
end
|
22
|
+
|
23
|
+
def continuation
|
24
|
+
@feed.search("gr:continuation", "gr" => GoogleReader::GOOGLE_ATOM_NAMESPACE).first.text
|
25
|
+
end
|
26
|
+
|
27
|
+
def title
|
28
|
+
@feed.search("title").first.text
|
29
|
+
end
|
30
|
+
|
31
|
+
def href
|
32
|
+
@feed.search("link[rel=self]").first["href"]
|
33
|
+
end
|
34
|
+
|
35
|
+
def author
|
36
|
+
@feed.search("author name").first.text
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/google_reader.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
module GoogleReader
|
2
2
|
autoload :Client, "google_reader/client"
|
3
3
|
autoload :Source, "google_reader/source"
|
4
|
+
autoload :Feed, "google_reader/feed"
|
4
5
|
autoload :Entry, "google_reader/entry"
|
6
|
+
|
7
|
+
GOOGLE_ATOM_NAMESPACE = "http://www.google.com/schemas/reader/atom/".freeze
|
5
8
|
end
|
data/spec/client_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe GoogleReader::Client, "#authenticate" do
|
4
4
|
it "should immediately authenticate using Google's client login" do
|
5
|
-
RestClient.should_receive(:post).and_return("
|
5
|
+
RestClient.should_receive(:post).and_return("a=b\nAuth=my-fancy-token\nb=c")
|
6
6
|
GoogleReader::Client.authenticate("abc", "123")
|
7
7
|
end
|
8
8
|
|
@@ -12,8 +12,8 @@ describe GoogleReader::Client, "#authenticate" do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should instantiate a new GoogleReader::Client instance with the correct authentication header" do
|
15
|
-
RestClient.stub(:post).and_return("
|
16
|
-
GoogleReader::Client.should_receive(:new).with(
|
15
|
+
RestClient.stub(:post).and_return("a=b\nAuth=my-fancy-token\nb=c")
|
16
|
+
GoogleReader::Client.should_receive(:new).with("my-fancy-token")
|
17
17
|
GoogleReader::Client.authenticate("a", "b")
|
18
18
|
end
|
19
19
|
end
|
@@ -34,7 +34,7 @@ describe GoogleReader::Client do
|
|
34
34
|
|
35
35
|
it "should fetch the requested number of items from #read_items" do
|
36
36
|
RestClient.should_receive(:get).with("http://www.google.com/reader/atom/user/-/state/com.google/read?n=59", anything).and_return(xml_content)
|
37
|
-
subject.read_items(59)
|
37
|
+
subject.read_items(:count => 59)
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should fetch the default 20 items from #broadcast_items" do
|
@@ -44,7 +44,7 @@ describe GoogleReader::Client do
|
|
44
44
|
|
45
45
|
it "should fetch the requested number of items from #broadcast_items" do
|
46
46
|
RestClient.should_receive(:get).with("http://www.google.com/reader/atom/user/-/state/com.google/broadcast?n=59", anything).and_return(xml_content)
|
47
|
-
subject.broadcast_items(59)
|
47
|
+
subject.broadcast_items(:count => 59)
|
48
48
|
end
|
49
49
|
|
50
50
|
it "should fetch the default 20 items from #starred_items" do
|
@@ -54,7 +54,7 @@ describe GoogleReader::Client do
|
|
54
54
|
|
55
55
|
it "should fetch the requested number of items from #starred_items" do
|
56
56
|
RestClient.should_receive(:get).with("http://www.google.com/reader/atom/user/-/state/com.google/starred?n=31", anything).and_return(xml_content)
|
57
|
-
subject.starred_items(31)
|
57
|
+
subject.starred_items(:count => 31)
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should fetch the default 20 items from #subscriptions_items" do
|
@@ -64,7 +64,7 @@ describe GoogleReader::Client do
|
|
64
64
|
|
65
65
|
it "should fetch the requested number of items from #subscriptions_items" do
|
66
66
|
RestClient.should_receive(:get).with("http://www.google.com/reader/atom/user/-/state/com.google/subscriptions?n=19", anything).and_return(xml_content)
|
67
|
-
subject.subscriptions_items(19)
|
67
|
+
subject.subscriptions_items(:count => 19)
|
68
68
|
end
|
69
69
|
|
70
70
|
it "should fetch the default 20 items from #tracking_emailed_items" do
|
@@ -74,7 +74,7 @@ describe GoogleReader::Client do
|
|
74
74
|
|
75
75
|
it "should fetch the requested number of items from #tracking_emailed_items" do
|
76
76
|
RestClient.should_receive(:get).with("http://www.google.com/reader/atom/user/-/state/com.google/tracking-emailed?n=43", anything).and_return(xml_content)
|
77
|
-
subject.tracking_emailed_items(43)
|
77
|
+
subject.tracking_emailed_items(:count => 43)
|
78
78
|
end
|
79
79
|
|
80
80
|
it "should fetch the default 20 items from #tracking_item_link_used_items" do
|
@@ -84,7 +84,7 @@ describe GoogleReader::Client do
|
|
84
84
|
|
85
85
|
it "should fetch the requested number of items from #tracking_item_link_used_items" do
|
86
86
|
RestClient.should_receive(:get).with("http://www.google.com/reader/atom/user/-/state/com.google/tracking-item-link-used?n=43", anything).and_return(xml_content)
|
87
|
-
subject.tracking_item_link_used_items(43)
|
87
|
+
subject.tracking_item_link_used_items(:count => 43)
|
88
88
|
end
|
89
89
|
|
90
90
|
it "should fetch the default 20 items from #tracking_body_link_used_items" do
|
@@ -94,6 +94,23 @@ describe GoogleReader::Client do
|
|
94
94
|
|
95
95
|
it "should fetch the requested number of items from #tracking_body_link_used_items" do
|
96
96
|
RestClient.should_receive(:get).with("http://www.google.com/reader/atom/user/-/state/com.google/tracking-body-link-used?n=43", anything).and_return(xml_content)
|
97
|
-
subject.tracking_body_link_used_items(43)
|
97
|
+
subject.tracking_body_link_used_items(:count => 43)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should return a Feed instance on-demand" do
|
101
|
+
RestClient.stub(:get).and_return(xml_content)
|
102
|
+
subject.read_feed.should be_kind_of(GoogleReader::Feed)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should fetch items since a specific timestamp" do
|
106
|
+
cutoff_at = Time.now
|
107
|
+
RestClient.should_receive(:get).with do |*args|
|
108
|
+
url = args.first
|
109
|
+
uri = URI.parse(url)
|
110
|
+
pairs = Hash[ *uri.query.split("&").map {|pair| pair.split("=").map {|val| CGI.unescape(val)}}.flatten ]
|
111
|
+
url.split("?", 2).first == "http://www.google.com/reader/atom/user/-/state/com.google/read" && pairs["n"] == "240" && pairs["r"] == "o" && pairs["ot"] == cutoff_at.to_i.to_s
|
112
|
+
end.and_return(xml_content)
|
113
|
+
|
114
|
+
subject.read_items(:since => cutoff_at, :count => 240)
|
98
115
|
end
|
99
116
|
end
|
data/spec/feed_spec.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe GoogleReader::Feed do
|
4
|
+
let :entry_xml do
|
5
|
+
File.read(File.dirname(__FILE__) + "/fixtures/entry.xml")
|
6
|
+
end
|
7
|
+
|
8
|
+
let :doc do
|
9
|
+
Nokogiri::XML(entry_xml)
|
10
|
+
end
|
11
|
+
|
12
|
+
subject do
|
13
|
+
GoogleReader::Feed.new(doc)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should have a title" do
|
17
|
+
subject.title.should == %("tracking-item-link-used" via francois.beausoleil in Google Reader)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have an #udpated_at" do
|
21
|
+
subject.updated_at.should == Time.utc(2011, 5, 2, 17, 53, 46)
|
22
|
+
end
|
23
|
+
end
|
data/spec/fixtures/entry.xml
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
<?xml version="1.0"?>
|
2
2
|
<feed xmlns:idx="urn:atom-extension:indexing" xmlns:media="http://search.yahoo.com/mrss/" xmlns:gr="http://www.google.com/schemas/reader/atom/" xmlns="http://www.w3.org/2005/Atom" idx:index="no" gr:dir="ltr">
|
3
|
+
<generator uri="http://www.google.com/reader">Google Reader</generator>
|
4
|
+
<id>tag:google.com,2005:reader/user/10212770223479967035/state/com.google/tracking-item-link-used</id>
|
5
|
+
<title>"tracking-item-link-used" via francois.beausoleil in Google Reader</title>
|
6
|
+
<gr:continuation>CPX6rZKan6gC</gr:continuation>
|
7
|
+
<link rel="self" href="http://www.google.com/reader/atom/user/-/state/com.google/tracking-item-link-used"/>
|
8
|
+
<author>
|
9
|
+
<name>francois.beausoleil</name>
|
10
|
+
</author>
|
11
|
+
<updated>2011-05-02T17:53:46Z</updated>
|
3
12
|
<entry gr:crawl-timestamp-msec="1303995951053">
|
4
13
|
<id gr:original-id="http://www.depesz.com/?p=2149">tag:google.com,2005:reader/item/d5dee0c34e012ddb</id>
|
5
14
|
<category term="user/10212770223479967035/state/com.google/read" scheme="http://www.google.com/reader/" label="read"/>
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: google_reader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.1.
|
5
|
+
version: 1.1.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- "Fran\xC3\xA7ois Beausoleil"
|
@@ -65,10 +65,12 @@ files:
|
|
65
65
|
- lib/google_reader.rb
|
66
66
|
- lib/google_reader/client.rb
|
67
67
|
- lib/google_reader/entry.rb
|
68
|
+
- lib/google_reader/feed.rb
|
68
69
|
- lib/google_reader/source.rb
|
69
70
|
- lib/google_reader/version.rb
|
70
71
|
- spec/client_spec.rb
|
71
72
|
- spec/entry_spec.rb
|
73
|
+
- spec/feed_spec.rb
|
72
74
|
- spec/fixtures/entry-with-no-likes.xml
|
73
75
|
- spec/fixtures/entry-with-no-original-id.xml
|
74
76
|
- spec/fixtures/entry-with-unknown-author.xml
|
@@ -105,6 +107,7 @@ summary: An unofficial Ruby client for Google Reader
|
|
105
107
|
test_files:
|
106
108
|
- spec/client_spec.rb
|
107
109
|
- spec/entry_spec.rb
|
110
|
+
- spec/feed_spec.rb
|
108
111
|
- spec/fixtures/entry-with-no-likes.xml
|
109
112
|
- spec/fixtures/entry-with-no-original-id.xml
|
110
113
|
- spec/fixtures/entry-with-unknown-author.xml
|