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.
- data/README.txt +50 -0
- data/lib/bloglines.rb +105 -0
- data/test/bloglines_test.rb +40 -0
- metadata +40 -0
data/README.txt
ADDED
@@ -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?
|
data/lib/bloglines.rb
ADDED
@@ -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: []
|