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 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
@@ -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
- count = args.first || 20
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
@@ -103,7 +103,5 @@ module GoogleReader
103
103
  def unhtml(text)
104
104
  text.gsub("&lt;", "<").gsub("&gt;", ">").gsub("&amp;", "&").gsub("&quot;", '"')
105
105
  end
106
-
107
- GOOGLE_ATOM_NAMESPACE = "http://www.google.com/schemas/reader/atom/".freeze
108
106
  end
109
107
  end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module GoogleReader
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.1"
3
3
  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("Auth=abc")
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("Auth=my-fancy-token")
16
- GoogleReader::Client.should_receive(:new).with(hash_including("Authorization" => "GoogleLogin auth=my-fancy-token"))
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
@@ -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.0
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