Bloglines4R 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.
Files changed (4) hide show
  1. data/README.txt +50 -0
  2. data/lib/bloglines.rb +105 -0
  3. data/test/bloglines_test.rb +40 -0
  4. metadata +40 -0
@@ -0,0 +1,50 @@
1
+ = Bloglines4R -- Bloglines API for Ruby
2
+
3
+ This is Bloglines4R, a little library to access Bloglines Web Services
4
+ at http://rpc.bloglines.com from the Ruby programming language.
5
+
6
+ Author:: Giulio Piancastelli <giulio.piancastelli@gmail.com>
7
+ Requires:: Ruby 1.8 or later
8
+ License:: Bloglines4R is Copyright (c) 2004 by Giulio Piancastelli
9
+ Bloglines4R is released under the terms of the GNU General
10
+ Public License version 2 or later. See the license.txt file
11
+ included in the distribution for further details.
12
+
13
+ == Quick Start
14
+
15
+ Bloglines4R comes in RubyGems flavor and as tgz and zip archives
16
+ also. Automatic installation of the library is supported through
17
+ RubyGems only.
18
+
19
+ After installing Bloglines4R through RubyGems you should be able to
20
+ run a little example as the following:
21
+ begin
22
+ require 'rubygems'
23
+ require_gem 'Bloglines4R'
24
+ rescue LoadError
25
+ require 'bloglines'
26
+ end
27
+ bloglines = Bloglines::WebServices.new(:user => 'user@example.com')
28
+ puts bloglines.update
29
+ where you need to substituite the email address you registered to
30
+ Bloglines with for <tt>user@example.com</tt>.
31
+
32
+ == Unit Tests
33
+
34
+ Bloglines4R comes with a little suite of unit tests. If you want to
35
+ run it, you have to modify the script <tt>test/bloglines_test.rb</tt>
36
+ substituting your account's email address, password, and user_id for
37
+ the appropriate parameters in BloglinesTest#setup method.
38
+
39
+ Please note that if you run tests from within the RubyGems
40
+ installation process, they will entirely fail. This does not mean the
41
+ library won't work: run the example, and try the tests after modifying
42
+ them as required. If and only if those do not work, you can report a
43
+ problem within Bloglines4R.
44
+
45
+ == Known issues
46
+
47
+ - RSS documents are returned as REXML documents, but this will change in Ruby 1.8.2
48
+ when a RSS parser will be officially included in the distribution.
49
+ - Also OPML documents are returned as REXML documents: would it be better to build
50
+ an hash from elements in the subscriptions document?
@@ -0,0 +1,105 @@
1
+ # Bloglines4R
2
+ # Access the Bloglines Web Services at http://rpc.bloglines.com Web Services from Ruby.
3
+ # Copyright (c) 2004 Giulio Piancastelli.
4
+ # Released under the terms of the GNU General Public License version 2 or later.
5
+
6
+ module Bloglines
7
+
8
+ require 'base64'
9
+ require 'net/http'
10
+ require 'rexml/document'
11
+
12
+ HOSTNAME = 'rpc.bloglines.com'
13
+
14
+ class BloglinesException < Exception; end
15
+
16
+ class WebServices
17
+
18
+ # Initialize Bloglines web services.
19
+ # This method takes as parameters:
20
+ # :user is the email address used for a Bloglines account.
21
+ # :password is the Bloglines account password. It is an optional argument,
22
+ # because not every method in the Bloglines API request it.
23
+ # :proxy_host is the host for a proxy to access the internet. It is an
24
+ # optional parameter.
25
+ # :proxy_port is the port where the proxy host is listening for incoming
26
+ # connections. It is an optional parameter.
27
+ # :proxy_user specify the proxy username to work with authorization
28
+ # enabled proxies.
29
+ # :proxy_pass specify the proxy password to work with authorization
30
+ # enabled proxies.
31
+ def initialize params
32
+ @user = params.delete :user
33
+ @password = params.delete :password
34
+ if ENV['http_proxy'] =~ /http:\/\/(.*):(\d*)/
35
+ @proxy = {:proxy_host => $1, :proxy_port => $2}.merge params
36
+ else
37
+ @proxy = params
38
+ end
39
+ end
40
+
41
+ # Retrieve an unread count for a given Bloglines account.
42
+ # See http://www.bloglines.com/services/api/notifier for details.
43
+ def update version=1
44
+ response = Net::HTTP::Proxy(@proxy[:proxy_addr], @proxy[:proxy_port],
45
+ @proxy[:proxy_user], @proxy[:proxy_pass]).start(HOSTNAME) { |http|
46
+ http.get "/update?user=#{@user}&ver=#{version}"
47
+ }
48
+ raise BloglinesException.new unless response.code == '200'
49
+ raise BloglinesException.new('Unexpected response pattern') unless response.body =~ /\|(\-{0,1}[0-9]+)\|([^|]*)\|/
50
+ raise BloglinesException.new('User does not exist') if $1 == '-1'
51
+
52
+ $stderr.puts "Please upgrade to a new notifier at #{$2}" unless $2.empty?
53
+
54
+ $1.to_i
55
+ end
56
+
57
+ # Retrieve subscription information in OPML format for a given Bloglines account.
58
+ # See http://www.bloglines.com/services/api/listsubs for details.
59
+ def listsubs
60
+ response = Net::HTTP::Proxy(@proxy[:proxy_addr], @proxy[:proxy_port],
61
+ @proxy[:proxy_user], @proxy[:proxy_pass]).start(HOSTNAME) { |http|
62
+ headers = {'Authorization' => "Basic #{encode64(@user + ':' + @password)}"}
63
+ http.get "/listsubs", headers
64
+ }
65
+
66
+ raise BloglinesException.new("Incorrect email address or password") if response.code == '401'
67
+
68
+ REXML::Document.new response.body
69
+ end
70
+
71
+ # Retrieve unread blog entries for a given subscription, optionally marking them as read. If a
72
+ # date in seconds since Epoch is specified, all items since the passed UTC time are downloaded.
73
+ # See: http://www.bloglines.com/services/api/getitems for details.
74
+ def getitems subscription_id, mark_as_read=0, date=nil
75
+ query = "s=#{subscription_id}&n=#{mark_as_read}"
76
+ query += "&d=#{date}" unless date.nil?
77
+ response = Net::HTTP::Proxy(@proxy[:proxy_addr], @proxy[:proxy_port],
78
+ @proxy[:proxy_user], @proxy[:proxy_pass]).start(HOSTNAME) { |http|
79
+ headers = {'Authorization' => "Basic #{encode64(@user + ':' + @password)}"}
80
+ http.get "/getitems?#{query}", headers
81
+ }
82
+
83
+ case response.code
84
+ when '401' then raise BloglinesException.new("Incorrect email address or password")
85
+ when '403' then raise BloglinesException.new("Invalid or missing subscription ID")
86
+ when '410' then raise BloglinesException.new("Subscription has been deleted")
87
+ end
88
+
89
+ REXML::Document.new response.body
90
+ end
91
+
92
+ # Retrieve public subscription information in OPML format for a given Bloglines account.
93
+ # See http://www.bloglines.com/public/user_id, and click on Export Subscription at the
94
+ # bottom of the left frame for details.
95
+ def export user_id
96
+ response = Net::HTTP::Proxy(@proxy[:proxy_addr], @proxy[:proxy_port],
97
+ @proxy[:proxy_user], @proxy[:proxy_pass]).start(HOSTNAME) { |http|
98
+ http.get "/export?id=#{user_id}"
99
+ }
100
+ REXML::Document.new response.body
101
+ end
102
+
103
+ end
104
+
105
+ end
@@ -0,0 +1,40 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require 'bloglines'
4
+ require 'test/unit'
5
+
6
+ module Bloglines
7
+
8
+ class BloglinesTest < Test::Unit::TestCase
9
+ def setup
10
+ @user = 'user@example.com'
11
+ @password = 'mypassword'
12
+ @user_id = 'myuserid'
13
+ end
14
+ def test_update
15
+ bloglines = Bloglines::WebServices.new(:user => @user)
16
+ n = bloglines.update
17
+ assert n >= 0
18
+ end
19
+ def test_listsubs
20
+ bloglines = Bloglines::WebServices.new(:user => @user, :password => @password)
21
+ opml = bloglines.listsubs
22
+ outlines = opml.elements["//body/outline"]
23
+ assert outlines.size > 0
24
+ end
25
+ def test_getitems
26
+ sub_id = '1920365' # Scripting News
27
+ bloglines = Bloglines::WebServices.new(:user => @user, :password => @password)
28
+ rss = bloglines.getitems sub_id
29
+ channel_title = rss.elements["//channel/title"]
30
+ assert_equal 'Scripting News', channel_title[0].to_s
31
+ end
32
+ def test_export
33
+ bloglines = Bloglines::WebServices.new({}) # no need for any parameter
34
+ subscriptions = bloglines.export @user_id
35
+ outlines = subscriptions.elements["//body/outline"]
36
+ assert outlines.size > 0
37
+ end
38
+ end
39
+
40
+ end
metadata ADDED
@@ -0,0 +1,40 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.3
3
+ specification_version: 1
4
+ name: Bloglines4R
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2005-01-16
8
+ summary: A library to access the Bloglines API from Ruby
9
+ require_paths:
10
+ - lib
11
+ email: giulio.piancastelli@gmail.com
12
+ homepage: http://bloglines.rubyforge.org/
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: bloglines
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ authors:
28
+ - Giulio Piancastelli
29
+ files:
30
+ - lib/bloglines.rb
31
+ - README.txt
32
+ test_files:
33
+ - test/bloglines_test.rb
34
+ rdoc_options: []
35
+ extra_rdoc_files:
36
+ - README.txt
37
+ executables: []
38
+ extensions: []
39
+ requirements: []
40
+ dependencies: []