www-delicious 0.3.0 → 0.4.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/CHANGELOG.rdoc +11 -0
- data/LICENSE.rdoc +1 -1
- data/README.rdoc +19 -34
- data/lib/www/delicious.rb +259 -258
- data/lib/www/delicious/bundle.rb +14 -14
- data/lib/www/delicious/element.rb +21 -21
- data/lib/www/delicious/errors.rb +12 -11
- data/lib/www/delicious/post.rb +31 -31
- data/lib/www/delicious/tag.rb +25 -26
- data/lib/www/delicious/version.rb +6 -7
- data/test/online_test.rb +0 -16
- data/test/test_helper.rb +0 -16
- data/test/{bundle_test.rb → www/delicious/bundle_test.rb} +0 -16
- data/test/{post_test.rb → www/delicious/post_test.rb} +0 -16
- data/test/{tag_test.rb → www/delicious/tag_test.rb} +0 -16
- data/test/{delicious_test.rb → www/delicious_test.rb} +4 -17
- data/www-delicious.gemspec +15 -22
- metadata +43 -59
- data/Manifest +0 -46
- data/Rakefile +0 -57
- data/setup.rb +0 -1585
- data/test/test_all.rb +0 -19
data/CHANGELOG.rdoc
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
= Changelog
|
2
2
|
|
3
3
|
|
4
|
+
== Release 0.4.0
|
5
|
+
|
6
|
+
* FIXED: A trivial bug causes the test `test_request_waits_necessary_time_between_requests` to fail in case the subsequent request is sent exactly 1 second after the prior one.
|
7
|
+
|
8
|
+
* FIXED: Object#blank? is always redefined regardless already defined before.
|
9
|
+
|
10
|
+
* CHANGED: Removed dependency from Echoe.
|
11
|
+
|
12
|
+
* REMOVED: Removed old setup.rb installation method.
|
13
|
+
|
14
|
+
|
4
15
|
== Release 0.3.0
|
5
16
|
|
6
17
|
* FIXED: Compatibility fixes for Ruby 1.9. WWW::Delicious is now 100% compatible with 1.9. You should remember to define the proper content encoding with magic comments when working with UTF-8/MultiByte XML or Ruby files, see http://redmine.ruby-lang.org/wiki/ruby-19/ScriptEncoding (closes #142).
|
data/LICENSE.rdoc
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
(The MIT License)
|
4
4
|
|
5
|
-
Copyright (c) 2008-
|
5
|
+
Copyright (c) 2008-2010 Simone Carletti <weppos@weppos.net>
|
6
6
|
|
7
7
|
Permission is hereby granted, free of charge, to any person obtaining
|
8
8
|
a copy of this software and associated documentation files (the
|
data/README.rdoc
CHANGED
@@ -1,19 +1,13 @@
|
|
1
1
|
= WWW::Delicious
|
2
2
|
|
3
|
-
WWW::Delicious is a Ruby client for http://
|
3
|
+
WWW::Delicious is a Ruby client for {delicious.com}[http://delicious.com] XML API.
|
4
4
|
|
5
5
|
It provides both read and write functionality. You can read user Posts, Tags
|
6
6
|
and Bundles but you can create new Posts, Tags and Bundles as well.
|
7
7
|
|
8
|
+
WWW::Delicious maps all the original del.icio.us API calls and provides some additional convenient methods to perform common tasks. For a full API overview, visit the official {Delicious API documentation}[http://delicious.com/help/api].
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
WWW::Delicious maps all the original del.icio.us API calls and provides some
|
12
|
-
additional convenient methods to perform common tasks.
|
13
|
-
Please read the official documentation (http://del.icio.us/help/api/)
|
14
|
-
to learn more about del.icio.us API.
|
15
|
-
|
16
|
-
WWW::Delicious is 100% compatible with all del.icio.us API constraints,
|
10
|
+
WWW::Delicious is compatible with all {delicious.com}[http://delicious.com] API constraints,
|
17
11
|
including the requirement to set a valid user agent or wait at least
|
18
12
|
one second between queries.
|
19
13
|
Basically, the main benefit from using this library is that you don't need
|
@@ -21,36 +15,28 @@ to take care of all these low level details, if you don't want:
|
|
21
15
|
WWW::Delicious will try to give you the most with less efforts.
|
22
16
|
|
23
17
|
|
24
|
-
==
|
25
|
-
|
26
|
-
* Ruby >= 1.8.6 (not tested with previous versions)
|
18
|
+
== Requirements
|
27
19
|
|
28
|
-
|
20
|
+
* Ruby >= 1.8.6 or Ruby 1.9.x
|
29
21
|
|
30
22
|
|
31
23
|
== Download and Installation
|
32
24
|
|
33
|
-
|
34
|
-
To get the latest version, simply type the following instruction into your command prompt:
|
25
|
+
This library is intended to be installed as a Gem.
|
35
26
|
|
36
|
-
$
|
37
|
-
|
38
|
-
Depending on your system, you might need su privileges.
|
39
|
-
|
40
|
-
To install the library manually, downlad the latest version from
|
41
|
-
navigate to the root library directory and enter:
|
27
|
+
$ gem install www-delicious
|
42
28
|
|
43
|
-
|
29
|
+
You might need administrator privileges on your system to install it.
|
44
30
|
|
45
|
-
If you need the latest development version you can download the
|
46
|
-
|
31
|
+
If you need the latest development version you can download the
|
32
|
+
{source code}[http://github.com/weppos/www-delicious/] from GitHub.
|
47
33
|
Beware that the code might not be as stable as the official release.
|
48
34
|
|
49
35
|
|
50
36
|
== Getting Started
|
51
37
|
|
52
|
-
In order to use this library you need a valid
|
53
|
-
Go to http://
|
38
|
+
In order to use this library you need a valid Delicious account.
|
39
|
+
Go to http://delicious.com and register for a new account if you don't already have one.
|
54
40
|
|
55
41
|
Then create a valid instance of WWW::Delicious providing your account credentials.
|
56
42
|
|
@@ -171,16 +157,16 @@ You can also create new bundles or delete existing ones.
|
|
171
157
|
d.bundles_delete('OldBundle')
|
172
158
|
|
173
159
|
|
174
|
-
==
|
160
|
+
== Credits
|
175
161
|
|
176
|
-
{Simone Carletti}[http://www.simonecarletti.com/] <weppos@weppos.net>
|
162
|
+
Author:: {Simone Carletti}[http://www.simonecarletti.com/] <weppos@weppos.net>
|
177
163
|
|
178
164
|
|
179
165
|
== Resources
|
180
166
|
|
181
|
-
* {Homepage}[http://
|
182
|
-
* {
|
183
|
-
* {
|
167
|
+
* {Homepage}[http://www.simonecarletti.com/code/www-delicious]
|
168
|
+
* {Repository}[http://github.com/weppos/www-delicious/]
|
169
|
+
* {API Documentation}[http://www.simonecarletti.com/code/www-delicious/api/] (RDoc)
|
184
170
|
* {RubyForge}[http://rubyforge.org/projects/www-delicious/]
|
185
171
|
|
186
172
|
|
@@ -188,7 +174,7 @@ You can also create new bundles or delete existing ones.
|
|
188
174
|
|
189
175
|
Feel free to email {Simone Carletti}[mailto:weppos@weppos.net] with any questions or feedback.
|
190
176
|
|
191
|
-
Please use the {Ticket System}[http://
|
177
|
+
Please use the {Ticket System}[http://github.com/weppos/www-delicious/issues] to submit bug reports or feature request.
|
192
178
|
|
193
179
|
|
194
180
|
== Changelog
|
@@ -198,5 +184,4 @@ See the CHANGELOG.rdoc file for details.
|
|
198
184
|
|
199
185
|
== License
|
200
186
|
|
201
|
-
Copyright (c) 2008-
|
202
|
-
|
187
|
+
Copyright (c) 2008-2010 Simone Carletti, WWW::Delicious is released under the MIT license.
|
data/lib/www/delicious.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
#
|
1
|
+
#
|
2
2
|
# = WWW::Delicious
|
3
3
|
#
|
4
4
|
# Ruby client for del.icio.us API.
|
5
|
-
#
|
5
|
+
#
|
6
6
|
#
|
7
7
|
# Category:: WWW
|
8
8
|
# Package:: WWW::Delicious
|
@@ -10,7 +10,7 @@
|
|
10
10
|
# License:: MIT License
|
11
11
|
#
|
12
12
|
#--
|
13
|
-
#
|
13
|
+
#
|
14
14
|
#++
|
15
15
|
|
16
16
|
|
@@ -29,68 +29,69 @@ module WWW #:nodoc:
|
|
29
29
|
|
30
30
|
#
|
31
31
|
# = WWW::Delicious
|
32
|
-
#
|
33
|
-
# WWW::Delicious is a Ruby client for http://
|
34
|
-
#
|
35
|
-
# It provides both read and write functionalities.
|
36
|
-
# You can read user Posts, Tags and Bundles
|
32
|
+
#
|
33
|
+
# WWW::Delicious is a Ruby client for http://delicious.com XML API.
|
34
|
+
#
|
35
|
+
# It provides both read and write functionalities.
|
36
|
+
# You can read user Posts, Tags and Bundles
|
37
37
|
# but you can create new Posts, Tags and Bundles as well.
|
38
38
|
#
|
39
39
|
#
|
40
40
|
# == Basic Usage
|
41
|
-
#
|
41
|
+
#
|
42
42
|
# The following is just a basic demonstration of the main features.
|
43
43
|
# See the README file for a deeper explanation about how to get the best
|
44
44
|
# from WWW::Delicious library.
|
45
|
-
#
|
45
|
+
#
|
46
46
|
# The examples in this page make the following assumptions
|
47
47
|
# * you have a valid del.icio.us account
|
48
48
|
# * +username+ is your account username
|
49
49
|
# * +password+ is your account password
|
50
|
-
#
|
50
|
+
#
|
51
51
|
# In order to make a query you first need to create
|
52
52
|
# a new WWW::Delicious instance as follows:
|
53
53
|
#
|
54
54
|
# require 'www/delicious'
|
55
|
-
#
|
55
|
+
#
|
56
56
|
# username = 'my delicious username'
|
57
57
|
# password = 'my delicious password'
|
58
58
|
#
|
59
59
|
# d = WWW::Delicious.new(username, password)
|
60
|
-
#
|
60
|
+
#
|
61
61
|
# The constructor accepts some additional options.
|
62
62
|
# For instance, if you want to customize the user agent:
|
63
|
-
#
|
63
|
+
#
|
64
64
|
# d = WWW::Delicious.new(username, password, :user_agent => 'FooAgent')
|
65
|
-
#
|
65
|
+
#
|
66
66
|
# Now you can use any of the API methods available.
|
67
|
-
#
|
67
|
+
#
|
68
68
|
# For example, you may want to know when your account was last updated
|
69
69
|
# to check whether someone else made some changes on behalf of you:
|
70
|
-
#
|
70
|
+
#
|
71
71
|
# datetime = d.update # => Wed Mar 12 08:41:20 UTC 2008
|
72
|
-
#
|
72
|
+
#
|
73
73
|
# Because the answer is a valid +Time+ instance, you can format it with +strftime+.
|
74
|
-
#
|
74
|
+
#
|
75
75
|
# datetime = d.update # => Wed Mar 12 08:41:20 UTC 2008
|
76
76
|
# datetime.strftime('%Y') # => 2008
|
77
77
|
#
|
78
78
|
class Delicious
|
79
|
-
|
80
|
-
NAME =
|
81
|
-
GEM =
|
82
|
-
|
83
|
-
|
79
|
+
|
80
|
+
NAME = "WWW::Delicious"
|
81
|
+
GEM = "www-delicious"
|
82
|
+
AUTHORS = ["Simone Carletti <weppos@weppos.net>"]
|
83
|
+
|
84
|
+
|
84
85
|
# del.icio.us account username
|
85
86
|
attr_reader :username
|
86
|
-
|
87
|
+
|
87
88
|
# del.icio.us account password
|
88
89
|
attr_reader :password
|
89
|
-
|
90
|
+
|
90
91
|
# base URI for del.icio.us API
|
91
92
|
attr_reader :base_uri
|
92
93
|
|
93
|
-
|
94
|
+
|
94
95
|
# API Base URL
|
95
96
|
API_BASE_URI = 'https://api.del.icio.us'
|
96
97
|
|
@@ -121,306 +122,306 @@ module WWW #:nodoc:
|
|
121
122
|
API_PATH_POSTS_ADD = '/v1/posts/add';
|
122
123
|
# API Path Delete Post
|
123
124
|
API_PATH_POSTS_DELETE = '/v1/posts/delete';
|
124
|
-
|
125
|
+
|
125
126
|
# Time to wait before sending a new request, in seconds
|
126
127
|
SECONDS_BEFORE_NEW_REQUEST = 1
|
127
|
-
|
128
|
+
|
128
129
|
# Time converter converts a Time instance into the format
|
129
130
|
# requested by Delicious API
|
130
|
-
TIME_CONVERTER = lambda { |time| time.iso8601
|
131
|
-
|
132
|
-
|
133
|
-
#
|
134
|
-
# Constructs a new <tt>WWW::Delicious</tt> object
|
131
|
+
TIME_CONVERTER = lambda { |time| time.iso8601 }
|
132
|
+
|
133
|
+
|
134
|
+
#
|
135
|
+
# Constructs a new <tt>WWW::Delicious</tt> object
|
135
136
|
# with given +username+ and +password+.
|
136
|
-
#
|
137
|
+
#
|
137
138
|
# # create a new object with username 'user' and password 'psw
|
138
139
|
# obj = WWW::Delicious('user', 'psw')
|
139
140
|
# # => self
|
140
|
-
#
|
141
|
+
#
|
141
142
|
# If a block is given, the instance is passed to the block
|
142
143
|
# but this method always returns the instance itself.
|
143
|
-
#
|
144
|
+
#
|
144
145
|
# WWW::Delicious('user', 'psw') do |d|
|
145
146
|
# d.update() # => Fri May 02 18:02:48 UTC 2008
|
146
147
|
# end
|
147
148
|
# # => self
|
148
|
-
#
|
149
|
+
#
|
149
150
|
# You can also specify some additional options, including a custom user agent
|
150
|
-
# or the base URI for
|
151
|
-
#
|
151
|
+
# or the base URI for delicious.com API.
|
152
|
+
#
|
152
153
|
# WWW::Delicious('user', 'psw', :base_uri => 'https://ma.gnolia.com/api/mirrord') do |d|
|
153
154
|
# # the following call is mirrored by ma.gnolia
|
154
155
|
# d.update() # => Fri May 02 18:02:48 UTC 2008
|
155
156
|
# end
|
156
157
|
# # => self
|
157
|
-
#
|
158
|
+
#
|
158
159
|
# === Options
|
159
160
|
# This class accepts a Hash with additional options.
|
160
161
|
# Here's the list of valid keys:
|
161
162
|
#
|
162
163
|
# <tt>:user_agent</tt>:: User agent to display in HTTP requests.
|
163
164
|
# <tt>:base_uri</tt>:: The base URI to del.icio.us API.
|
164
|
-
#
|
165
|
+
#
|
165
166
|
def initialize(username, password, options = {}, &block) # :yields: delicious
|
166
167
|
@username, @password = username.to_s, password.to_s
|
167
|
-
|
168
|
+
|
168
169
|
# set API base URI
|
169
170
|
@base_uri = URI.parse(options[:base_uri] || API_BASE_URI)
|
170
|
-
|
171
|
+
|
171
172
|
init_user_agent(options)
|
172
173
|
init_http_client(options)
|
173
|
-
|
174
|
+
|
174
175
|
yield self if block_given?
|
175
176
|
self # ensure to always return self even if block is given
|
176
177
|
end
|
177
|
-
|
178
|
-
|
179
|
-
#
|
178
|
+
|
179
|
+
|
180
|
+
#
|
180
181
|
# Returns the reference to current <tt>@http_client</tt>.
|
181
182
|
# The http is always valid unless it has been previously set to +nil+.
|
182
|
-
#
|
183
|
+
#
|
183
184
|
# # nil client
|
184
185
|
# obj.http_client # => nil
|
185
|
-
#
|
186
|
+
#
|
186
187
|
# # valid client
|
187
188
|
# obj.http_client # => Net::HTTP
|
188
|
-
#
|
189
|
+
#
|
189
190
|
def http_client()
|
190
191
|
return @http_client
|
191
192
|
end
|
192
193
|
|
193
|
-
#
|
194
|
+
#
|
194
195
|
# Sets the internal <tt>@http_client</tt> to +client+.
|
195
|
-
#
|
196
|
+
#
|
196
197
|
# # nil client
|
197
198
|
# obj.http_client = nil
|
198
|
-
#
|
199
|
+
#
|
199
200
|
# # http client
|
200
201
|
# obj.http_client = Net::HTTP.new()
|
201
|
-
#
|
202
|
+
#
|
202
203
|
# # invalid client
|
203
204
|
# obj.http_client = 'foo' # => ArgumentError
|
204
|
-
#
|
205
|
+
#
|
205
206
|
def http_client=(client)
|
206
207
|
unless client.kind_of?(Net::HTTP) or client.nil?
|
207
208
|
raise ArgumentError, "`client` expected to be a kind of `Net::HTTP`, `#{client.class}` given"
|
208
209
|
end
|
209
210
|
@http_client = client
|
210
211
|
end
|
211
|
-
|
212
|
+
|
212
213
|
# Returns current user agent string.
|
213
214
|
def user_agent()
|
214
215
|
return @headers['User-Agent']
|
215
216
|
end
|
216
|
-
|
217
|
-
|
218
|
-
#
|
217
|
+
|
218
|
+
|
219
|
+
#
|
219
220
|
# Returns true if given account credentials are valid.
|
220
|
-
#
|
221
|
+
#
|
221
222
|
# d = WWW::Delicious.new('username', 'password')
|
222
223
|
# d.valid_account? # => true
|
223
|
-
#
|
224
|
+
#
|
224
225
|
# d = WWW::Delicious.new('username', 'invalid_password')
|
225
226
|
# d.valid_account? # => false
|
226
|
-
#
|
227
|
+
#
|
227
228
|
# This method is not "exception safe".
|
228
229
|
# It doesn't return false if an HTTP error or any kind of other error occurs,
|
229
230
|
# it raises back the exception to the caller instead.
|
230
|
-
#
|
231
|
-
#
|
231
|
+
#
|
232
|
+
#
|
232
233
|
# Raises:: WWW::Delicious::Error
|
233
234
|
# Raises:: WWW::Delicious::HTTPError
|
234
235
|
# Raises:: WWW::Delicious::ResponseError
|
235
|
-
#
|
236
|
+
#
|
236
237
|
def valid_account?
|
237
238
|
update()
|
238
239
|
return true
|
239
240
|
rescue HTTPError => e
|
240
241
|
return false if e.message =~ /invalid username or password/i
|
241
|
-
raise
|
242
|
+
raise
|
242
243
|
end
|
243
244
|
|
244
|
-
#
|
245
|
+
#
|
245
246
|
# Checks to see when a user last posted an item
|
246
247
|
# and returns the last update +Time+ for the user.
|
247
|
-
#
|
248
|
+
#
|
248
249
|
# d.update() # => Fri May 02 18:02:48 UTC 2008
|
249
|
-
#
|
250
|
-
#
|
250
|
+
#
|
251
|
+
#
|
251
252
|
# Raises:: WWW::Delicious::Error
|
252
253
|
# Raises:: WWW::Delicious::HTTPError
|
253
254
|
# Raises:: WWW::Delicious::ResponseError
|
254
|
-
#
|
255
|
+
#
|
255
256
|
def update()
|
256
257
|
response = request(API_PATH_UPDATE)
|
257
258
|
return parse_update_response(response.body)
|
258
259
|
end
|
259
|
-
|
260
|
-
#
|
260
|
+
|
261
|
+
#
|
261
262
|
# Retrieves all of a user's bundles
|
262
263
|
# and returns an array of <tt>WWW::Delicious::Bundle</tt>.
|
263
|
-
#
|
264
|
+
#
|
264
265
|
# d.bundles_all() # => [#<WWW::Delicious::Bundle>, #<WWW::Delicious::Bundle>, ...]
|
265
266
|
# d.bundles_all() # => []
|
266
|
-
#
|
267
|
-
#
|
267
|
+
#
|
268
|
+
#
|
268
269
|
# Raises:: WWW::Delicious::Error
|
269
270
|
# Raises:: WWW::Delicious::HTTPError
|
270
271
|
# Raises:: WWW::Delicious::ResponseError
|
271
|
-
#
|
272
|
+
#
|
272
273
|
def bundles_all()
|
273
274
|
response = request(API_PATH_BUNDLES_ALL)
|
274
275
|
return parse_bundle_collection(response.body)
|
275
276
|
end
|
276
|
-
|
277
|
-
#
|
278
|
-
# Assignes a set of tags to a single bundle,
|
277
|
+
|
278
|
+
#
|
279
|
+
# Assignes a set of tags to a single bundle,
|
279
280
|
# wipes away previous settings for bundle.
|
280
|
-
#
|
281
|
+
#
|
281
282
|
# # create from a bundle
|
282
283
|
# d.bundles_set(WWW::Delicious::Bundle.new('MyBundle'), %w(foo bar))
|
283
|
-
#
|
284
|
+
#
|
284
285
|
# # create from a string
|
285
286
|
# d.bundles_set('MyBundle', %w(foo bar))
|
286
|
-
#
|
287
|
-
#
|
287
|
+
#
|
288
|
+
#
|
288
289
|
# Raises:: WWW::Delicious::Error
|
289
290
|
# Raises:: WWW::Delicious::HTTPError
|
290
291
|
# Raises:: WWW::Delicious::ResponseError
|
291
|
-
#
|
292
|
+
#
|
292
293
|
def bundles_set(bundle_or_name, tags = [])
|
293
294
|
params = prepare_bundles_set_params(bundle_or_name, tags)
|
294
295
|
response = request(API_PATH_BUNDLES_SET, params)
|
295
296
|
return parse_and_eval_execution_response(response.body)
|
296
297
|
end
|
297
|
-
|
298
|
-
#
|
298
|
+
|
299
|
+
#
|
299
300
|
# Deletes +bundle_or_name+ bundle from del.icio.us.
|
300
|
-
# +bundle_or_name+ can be either a WWW::Delicious::Bundle instance
|
301
|
+
# +bundle_or_name+ can be either a WWW::Delicious::Bundle instance
|
301
302
|
# or a string with the name of the bundle.
|
302
|
-
#
|
303
|
+
#
|
303
304
|
# This method doesn't care whether the exists.
|
304
305
|
# If not, the execution will silently return without rising any error.
|
305
|
-
#
|
306
|
+
#
|
306
307
|
# # delete from a bundle
|
307
308
|
# d.bundles_delete(WWW::Delicious::Bundle.new('MyBundle'))
|
308
|
-
#
|
309
|
+
#
|
309
310
|
# # delete from a string
|
310
311
|
# d.bundles_delete('MyBundle', %w(foo bar))
|
311
|
-
#
|
312
|
-
#
|
312
|
+
#
|
313
|
+
#
|
313
314
|
# Raises:: WWW::Delicious::Error
|
314
315
|
# Raises:: WWW::Delicious::HTTPError
|
315
316
|
# Raises:: WWW::Delicious::ResponseError
|
316
|
-
#
|
317
|
+
#
|
317
318
|
def bundles_delete(bundle_or_name)
|
318
319
|
params = prepare_bundles_delete_params(bundle_or_name)
|
319
320
|
response = request(API_PATH_BUNDLES_DELETE, params)
|
320
321
|
return parse_and_eval_execution_response(response.body)
|
321
322
|
end
|
322
|
-
|
323
|
-
#
|
323
|
+
|
324
|
+
#
|
324
325
|
# Retrieves the list of tags and number of times used by the user
|
325
326
|
# and returns an array of <tt>WWW::Delicious::Tag</tt>.
|
326
|
-
#
|
327
|
+
#
|
327
328
|
# d.tags_get() # => [#<WWW::Delicious::Tag>, #<WWW::Delicious::Tag>, ...]
|
328
329
|
# d.tags_get() # => []
|
329
|
-
#
|
330
|
-
#
|
330
|
+
#
|
331
|
+
#
|
331
332
|
# Raises:: WWW::Delicious::Error
|
332
333
|
# Raises:: WWW::Delicious::HTTPError
|
333
334
|
# Raises:: WWW::Delicious::ResponseError
|
334
|
-
#
|
335
|
+
#
|
335
336
|
def tags_get()
|
336
337
|
response = request(API_PATH_TAGS_GET)
|
337
338
|
return parse_tag_collection(response.body)
|
338
339
|
end
|
339
|
-
|
340
|
-
#
|
340
|
+
|
341
|
+
#
|
341
342
|
# Renames an existing tag with a new tag name.
|
342
|
-
#
|
343
|
+
#
|
343
344
|
# # rename from a tag
|
344
345
|
# d.bundles_set(WWW::Delicious::Tag.new('old'), WWW::Delicious::Tag.new('new'))
|
345
|
-
#
|
346
|
+
#
|
346
347
|
# # rename from a string
|
347
348
|
# d.bundles_set('old', 'new')
|
348
|
-
#
|
349
|
-
#
|
349
|
+
#
|
350
|
+
#
|
350
351
|
# Raises:: WWW::Delicious::Error
|
351
352
|
# Raises:: WWW::Delicious::HTTPError
|
352
353
|
# Raises:: WWW::Delicious::ResponseError
|
353
|
-
#
|
354
|
+
#
|
354
355
|
def tags_rename(from_name_or_tag, to_name_or_tag)
|
355
356
|
params = prepare_tags_rename_params(from_name_or_tag, to_name_or_tag)
|
356
357
|
response = request(API_PATH_TAGS_RENAME, params)
|
357
358
|
return parse_and_eval_execution_response(response.body)
|
358
359
|
end
|
359
|
-
|
360
|
-
#
|
360
|
+
|
361
|
+
#
|
361
362
|
# Returns an array of <tt>WWW::Delicious::Post</tt> matching +options+.
|
362
363
|
# If no option is given, the last post is returned.
|
363
364
|
# If no date or url is given, most recent date will be used.
|
364
|
-
#
|
365
|
+
#
|
365
366
|
# d.posts_get() # => [#<WWW::Delicious::Post>, #<WWW::Delicious::Post>, ...]
|
366
367
|
# d.posts_get() # => []
|
367
|
-
#
|
368
|
+
#
|
368
369
|
# # get all posts tagged with ruby
|
369
370
|
# d.posts_get(:tag => WWW::Delicious::Tag.new('ruby))
|
370
|
-
#
|
371
|
+
#
|
371
372
|
# # get all posts matching URL 'http://www.simonecarletti.com'
|
372
373
|
# d.posts_get(:url => URI.parse('http://www.simonecarletti.com'))
|
373
|
-
#
|
374
|
+
#
|
374
375
|
# # get all posts tagged with ruby and matching URL 'http://www.simonecarletti.com'
|
375
376
|
# d.posts_get(:tag => WWW::Delicious::Tag.new('ruby),
|
376
377
|
# :url => URI.parse('http://www.simonecarletti.com'))
|
377
|
-
#
|
378
|
-
#
|
378
|
+
#
|
379
|
+
#
|
379
380
|
# === Options
|
380
381
|
# <tt>:tag</tt>:: a tag to filter by. It can be either a <tt>WWW::Delicious::Tag</tt> or a +String+.
|
381
382
|
# <tt>:dt</tt>:: a +Time+ with a date to filter by.
|
382
383
|
# <tt>:url</tt>:: a valid URI to filter by. It can be either an instance of +URI+ or a +String+.
|
383
|
-
#
|
384
|
+
#
|
384
385
|
# Raises:: WWW::Delicious::Error
|
385
386
|
# Raises:: WWW::Delicious::HTTPError
|
386
387
|
# Raises:: WWW::Delicious::ResponseError
|
387
|
-
#
|
388
|
+
#
|
388
389
|
def posts_get(options = {})
|
389
390
|
params = prepare_posts_params(options.clone, [:dt, :tag, :url])
|
390
391
|
response = request(API_PATH_POSTS_GET, params)
|
391
392
|
return parse_post_collection(response.body)
|
392
393
|
end
|
393
394
|
|
394
|
-
#
|
395
|
+
#
|
395
396
|
# Returns a list of the most recent posts, filtered by argument.
|
396
|
-
#
|
397
|
+
#
|
397
398
|
# # get the most recent posts
|
398
399
|
# d.posts_recent()
|
399
|
-
#
|
400
|
+
#
|
400
401
|
# # get the 10 most recent posts
|
401
402
|
# d.posts_recent(:count => 10)
|
402
|
-
#
|
403
|
-
#
|
403
|
+
#
|
404
|
+
#
|
404
405
|
# === Options
|
405
406
|
# <tt>:tag</tt>:: a tag to filter by. It can be either a <tt>WWW::Delicious::Tag</tt> or a +String+.
|
406
407
|
# <tt>:count</tt>:: number of items to retrieve. (default: 15, maximum: 100).
|
407
|
-
#
|
408
|
+
#
|
408
409
|
def posts_recent(options = {})
|
409
410
|
params = prepare_posts_params(options.clone, [:count, :tag])
|
410
411
|
response = request(API_PATH_POSTS_RECENT, params)
|
411
412
|
return parse_post_collection(response.body)
|
412
413
|
end
|
413
|
-
|
414
|
-
#
|
414
|
+
|
415
|
+
#
|
415
416
|
# Returns a list of all posts, filtered by argument.
|
416
|
-
#
|
417
|
+
#
|
417
418
|
# # get all (this is a very expensive query)
|
418
419
|
# d.posts_all
|
419
|
-
#
|
420
|
+
#
|
420
421
|
# # get all posts matching ruby
|
421
422
|
# d.posts_all(:tag => WWW::Delicious::Tag.new('ruby'))
|
422
|
-
#
|
423
|
-
#
|
423
|
+
#
|
424
|
+
#
|
424
425
|
# === Options
|
425
426
|
# <tt>:tag</tt>:: a tag to filter by. It can be either a <tt>WWW::Delicious::Tag</tt> or a +String+.
|
426
427
|
#
|
@@ -432,16 +433,16 @@ module WWW #:nodoc:
|
|
432
433
|
|
433
434
|
#
|
434
435
|
# Returns a list of dates with the number of posts at each date.
|
435
|
-
#
|
436
|
+
#
|
436
437
|
# # get number of posts per date
|
437
438
|
# d.posts_dates
|
438
439
|
# # => { '2008-05-05' => 12, '2008-05-06' => 3, ... }
|
439
|
-
#
|
440
|
+
#
|
440
441
|
# # get number posts per date tagged as ruby
|
441
442
|
# d.posts_dates(:tag => WWW::Delicious::Tag.new('ruby'))
|
442
443
|
# # => { '2008-05-05' => 10, '2008-05-06' => 3, ... }
|
443
|
-
#
|
444
|
-
#
|
444
|
+
#
|
445
|
+
#
|
445
446
|
# === Options
|
446
447
|
# <tt>:tag</tt>:: a tag to filter by. It can be either a <tt>WWW::Delicious::Tag</tt> or a +String+.
|
447
448
|
#
|
@@ -456,13 +457,13 @@ module WWW #:nodoc:
|
|
456
457
|
# +post_or_values+ can be either a +WWW::Delicious::Post+ instance
|
457
458
|
# or a Hash of params. This method accepts all params available
|
458
459
|
# to initialize a new +WWW::Delicious::Post+.
|
459
|
-
#
|
460
|
+
#
|
460
461
|
# # add a post from WWW::Delicious::Post
|
461
462
|
# d.posts_add(WWW::Delicious::Post.new(:url => 'http://www.foobar.com', :title => 'Hello world!'))
|
462
|
-
#
|
463
|
+
#
|
463
464
|
# # add a post from values
|
464
465
|
# d.posts_add(:url => 'http://www.foobar.com', :title => 'Hello world!')
|
465
|
-
#
|
466
|
+
#
|
466
467
|
#
|
467
468
|
def posts_add(post_or_values)
|
468
469
|
params = prepare_param_post(post_or_values).to_params
|
@@ -473,16 +474,16 @@ module WWW #:nodoc:
|
|
473
474
|
#
|
474
475
|
# Deletes the post matching given +url+ from del.icio.us.
|
475
476
|
# +url+ can be either an URI instance or a string representation of a valid URL.
|
476
|
-
#
|
477
|
+
#
|
477
478
|
# This method doesn't care whether a post with given +url+ exists.
|
478
479
|
# If not, the execution will silently return without rising any error.
|
479
|
-
#
|
480
|
+
#
|
480
481
|
# # delete a post from URI
|
481
482
|
# d.post_delete(URI.parse('http://www.foobar.com/'))
|
482
|
-
#
|
483
|
+
#
|
483
484
|
# # delete a post from a string
|
484
485
|
# d.post_delete('http://www.foobar.com/')
|
485
|
-
#
|
486
|
+
#
|
486
487
|
#
|
487
488
|
def posts_delete(url)
|
488
489
|
params = prepare_posts_params({:url => url}, [:url])
|
@@ -490,9 +491,9 @@ module WWW #:nodoc:
|
|
490
491
|
return parse_and_eval_execution_response(response.body)
|
491
492
|
end
|
492
493
|
|
493
|
-
|
494
|
+
|
494
495
|
protected
|
495
|
-
|
496
|
+
|
496
497
|
# Initializes the HTTP client.
|
497
498
|
# It automatically enable +use_ssl+ flag according to +@base_uri+ scheme.
|
498
499
|
def init_http_client(options)
|
@@ -501,64 +502,64 @@ module WWW #:nodoc:
|
|
501
502
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # FIXME: not 100% supported
|
502
503
|
self.http_client = http
|
503
504
|
end
|
504
|
-
|
505
|
+
|
505
506
|
# Initializes user agent value for HTTP requests.
|
506
507
|
def init_user_agent(options)
|
507
508
|
user_agent = options[:user_agent] || default_user_agent()
|
508
509
|
@headers ||= {}
|
509
510
|
@headers['User-Agent'] = user_agent
|
510
511
|
end
|
511
|
-
|
512
|
-
#
|
512
|
+
|
513
|
+
#
|
513
514
|
# Creates and returns the default user agent string.
|
514
|
-
#
|
515
|
+
#
|
515
516
|
# By default, the user agent is composed by the following schema:
|
516
517
|
# <tt>NAME/VERSION (Ruby/RUBY_VERSION)</tt>
|
517
|
-
#
|
518
|
+
#
|
518
519
|
# * +NAME+ is the constant representing this library name
|
519
520
|
# * +VERSION+ is the constant representing current library version
|
520
521
|
# * +RUBY_VERSION+ is the version of Ruby interpreter the library is interpreted by
|
521
|
-
#
|
522
|
+
#
|
522
523
|
# default_user_agent
|
523
524
|
# # => WWW::Delicious/0.1.0 (Ruby/1.8.6)
|
524
|
-
#
|
525
|
+
#
|
525
526
|
def default_user_agent
|
526
527
|
return "#{NAME}/#{VERSION} (Ruby/#{RUBY_VERSION})"
|
527
528
|
end
|
528
|
-
|
529
|
-
|
530
|
-
#
|
529
|
+
|
530
|
+
|
531
|
+
#
|
531
532
|
# Composes an HTTP query string from an hash of +options+.
|
532
533
|
# The result is URI encoded.
|
533
|
-
#
|
534
|
+
#
|
534
535
|
# http_build_query(:foo => 'baa', :bar => 'boo')
|
535
536
|
# # => foo=baa&bar=boo
|
536
|
-
#
|
537
|
+
#
|
537
538
|
def http_build_query(params = {})
|
538
|
-
return params.collect do |k,v|
|
539
|
+
return params.collect do |k,v|
|
539
540
|
"#{URI.encode(k.to_s)}=#{URI.encode(v.to_s)}" unless v.nil?
|
540
541
|
end.compact.join('&')
|
541
542
|
end
|
542
|
-
|
543
|
-
#
|
543
|
+
|
544
|
+
#
|
544
545
|
# Sends an HTTP GET request to +path+ and appends given +params+.
|
545
|
-
#
|
546
|
+
#
|
546
547
|
# This method is 100% compliant with Delicious API reference.
|
547
548
|
# It waits at least 1 second between each HTTP request and
|
548
549
|
# provides an identifiable user agent by default,
|
549
|
-
# or the custom user agent set by +user_agent+ option
|
550
|
-
# when this
|
551
|
-
#
|
550
|
+
# or the custom user agent set by +user_agent+ option
|
551
|
+
# when this instance has been created.
|
552
|
+
#
|
552
553
|
# request('/v1/api/path', :foo => 1, :bar => 2)
|
553
554
|
# # => sends a GET request to /v1/api/path?foo=1&bar=2
|
554
|
-
#
|
555
|
+
#
|
555
556
|
def request(path, params = {})
|
556
557
|
raise Error, 'Invalid HTTP Client' unless http_client
|
557
558
|
wait_before_new_request
|
558
|
-
|
559
|
+
|
559
560
|
uri = @base_uri.merge(path)
|
560
561
|
uri.query = http_build_query(params) unless params.empty?
|
561
|
-
|
562
|
+
|
562
563
|
begin
|
563
564
|
@last_request = Time.now # see #wait_before_new_request
|
564
565
|
@last_request_uri = uri # useful for debug
|
@@ -566,7 +567,7 @@ module WWW #:nodoc:
|
|
566
567
|
rescue => e # catch EOFError, SocketError and more
|
567
568
|
raise HTTPError, e.message
|
568
569
|
end
|
569
|
-
|
570
|
+
|
570
571
|
case response
|
571
572
|
when Net::HTTPSuccess
|
572
573
|
return response
|
@@ -579,7 +580,7 @@ module WWW #:nodoc:
|
|
579
580
|
raise HTTPError, "HTTP #{response.code}: #{response.message}"
|
580
581
|
end
|
581
582
|
end
|
582
|
-
|
583
|
+
|
583
584
|
# Makes the real HTTP request to given +uri+ and returns the +response+.
|
584
585
|
# This method exists basically to simplify unit testing with mocha.
|
585
586
|
def make_request(uri)
|
@@ -589,55 +590,55 @@ module WWW #:nodoc:
|
|
589
590
|
http.request(req)
|
590
591
|
end
|
591
592
|
end
|
592
|
-
|
593
|
-
#
|
594
|
-
# Delicious API reference requests to wait AT LEAST ONE SECOND
|
593
|
+
|
594
|
+
#
|
595
|
+
# Delicious API reference requests to wait AT LEAST ONE SECOND
|
595
596
|
# between queries or the client is likely to get automatically throttled.
|
596
|
-
#
|
597
|
+
#
|
597
598
|
# This method calculates the difference between current time
|
598
599
|
# and the last request time and wait for the necessary time to meet
|
599
600
|
# SECONDS_BEFORE_NEW_REQUEST requirement.
|
600
|
-
#
|
601
|
+
#
|
601
602
|
# The difference is not rounded. If you only have to wait for 0.034 seconds
|
602
603
|
# then your don't have to wait 0 or 1 seconds, but 0.034 seconds!
|
603
|
-
#
|
604
|
+
#
|
604
605
|
def wait_before_new_request
|
605
606
|
return unless @last_request # this is the first request
|
606
607
|
# puts "Last request at #{TIME_CONVERTER.call(@last_request)}" if debug?
|
607
608
|
diff = Time.now - @last_request
|
608
609
|
if diff < SECONDS_BEFORE_NEW_REQUEST
|
609
610
|
# puts "Sleeping for #{diff} before new request..." if debug?
|
610
|
-
sleep(SECONDS_BEFORE_NEW_REQUEST - diff)
|
611
|
+
sleep(SECONDS_BEFORE_NEW_REQUEST - diff)
|
611
612
|
end
|
612
613
|
end
|
613
|
-
|
614
|
-
|
615
|
-
#
|
614
|
+
|
615
|
+
|
616
|
+
#
|
616
617
|
# Parses the response <tt>body</tt> and runs a common set of validators.
|
617
618
|
# Returns <tt>body</tt> as parsed REXML::Document on success.
|
618
|
-
#
|
619
|
+
#
|
619
620
|
# Raises:: WWW::Delicious::ResponseError in case of invalid response.
|
620
|
-
#
|
621
|
+
#
|
621
622
|
def parse_and_validate_response(body, options = {})
|
622
623
|
dom = REXML::Document.new(body)
|
623
|
-
|
624
|
+
|
624
625
|
if (value = options[:root_name]) && dom.root.name != value
|
625
626
|
raise ResponseError, "Invalid response, root node is not `#{value}`"
|
626
627
|
end
|
627
628
|
if (value = options[:root_text]) && dom.root.text != value
|
628
629
|
raise ResponseError, value
|
629
630
|
end
|
630
|
-
|
631
|
+
|
631
632
|
return dom
|
632
633
|
end
|
633
|
-
|
634
|
-
#
|
634
|
+
|
635
|
+
#
|
635
636
|
# Parses and evaluates the response returned by an execution,
|
636
637
|
# usually an update/delete/insert operation.
|
637
|
-
#
|
638
|
+
#
|
638
639
|
# Raises:: WWW::Delicious::ResponseError in case of invalid response
|
639
640
|
# Raises:: WWW::Delicious::Error in case of execution error
|
640
|
-
#
|
641
|
+
#
|
641
642
|
def parse_and_eval_execution_response(body)
|
642
643
|
dom = parse_and_validate_response(body, :root_name => 'result')
|
643
644
|
response = dom.root.if_attribute_value(:code)
|
@@ -645,53 +646,53 @@ module WWW #:nodoc:
|
|
645
646
|
raise Error, "Invalid response, #{response}" unless %w(done ok).include?(response)
|
646
647
|
true
|
647
648
|
end
|
648
|
-
|
649
|
+
|
649
650
|
# Parses the response of an Update request
|
650
651
|
# and returns the update Timestamp.
|
651
652
|
def parse_update_response(body)
|
652
653
|
dom = parse_and_validate_response(body, :root_name => 'update')
|
653
654
|
dom.root.if_attribute_value(:time) { |v| Time.parse(v) }
|
654
655
|
end
|
655
|
-
|
656
|
+
|
656
657
|
# Parses a response containing a collection of Bundles
|
657
658
|
# and returns an array of <tt>WWW::Delicious::Bundle</tt>.
|
658
659
|
def parse_bundle_collection(body)
|
659
660
|
dom = parse_and_validate_response(body, :root_name => 'bundles')
|
660
661
|
dom.root.elements.collect('bundle') { |xml| Bundle.from_rexml(xml) }
|
661
662
|
end
|
662
|
-
|
663
|
+
|
663
664
|
# Parses a response containing a collection of Tags
|
664
665
|
# and returns an array of <tt>WWW::Delicious::Tag</tt>.
|
665
666
|
def parse_tag_collection(body)
|
666
667
|
dom = parse_and_validate_response(body, :root_name => 'tags')
|
667
668
|
dom.root.elements.collect('tag') { |xml| Tag.from_rexml(xml) }
|
668
669
|
end
|
669
|
-
|
670
|
+
|
670
671
|
# Parses a response containing a collection of Posts
|
671
672
|
# and returns an array of <tt>WWW::Delicious::Post</tt>.
|
672
673
|
def parse_post_collection(body)
|
673
674
|
dom = parse_and_validate_response(body, :root_name => 'posts')
|
674
675
|
dom.root.elements.collect('post') { |xml| Post.from_rexml(xml) }
|
675
676
|
end
|
676
|
-
|
677
|
+
|
677
678
|
# Parses the response of a <tt>posts_dates</tt> request
|
678
679
|
# and returns a +Hash+ of date => count.
|
679
680
|
def parse_posts_dates_response(body)
|
680
681
|
dom = parse_and_validate_response(body, :root_name => 'dates')
|
681
682
|
return dom.root.get_elements('date').inject({}) do |collection, xml|
|
682
|
-
date = xml.if_attribute_value(:date)
|
683
|
+
date = xml.if_attribute_value(:date)
|
683
684
|
count = xml.if_attribute_value(:count)
|
684
685
|
collection.merge({ date => count })
|
685
686
|
end
|
686
687
|
end
|
687
|
-
|
688
|
-
|
689
|
-
#
|
688
|
+
|
689
|
+
|
690
|
+
#
|
690
691
|
# Prepares the params for a `bundles_set` call
|
691
692
|
# and returns a Hash with the params ready for the HTTP request.
|
692
|
-
#
|
693
|
+
#
|
693
694
|
# Raises:: WWW::Delicious::Error
|
694
|
-
#
|
695
|
+
#
|
695
696
|
def prepare_bundles_set_params(name_or_bundle, tags = [])
|
696
697
|
bundle = prepare_param_bundle(name_or_bundle, tags) do |b|
|
697
698
|
raise Error, "Bundle name is empty" if b.name.empty?
|
@@ -699,46 +700,46 @@ module WWW #:nodoc:
|
|
699
700
|
end
|
700
701
|
return { :bundle => bundle.name, :tags => bundle.tags.join(' ') }
|
701
702
|
end
|
702
|
-
|
703
|
-
#
|
703
|
+
|
704
|
+
#
|
704
705
|
# Prepares the params for a `bundles_set` call
|
705
706
|
# and returns a Hash with the params ready for the HTTP request.
|
706
|
-
#
|
707
|
+
#
|
707
708
|
# Raises:: WWW::Delicious::Error
|
708
|
-
#
|
709
|
+
#
|
709
710
|
def prepare_bundles_delete_params(name_or_bundle)
|
710
711
|
bundle = prepare_param_bundle(name_or_bundle) do |b|
|
711
712
|
raise Error, "Bundle name is empty" if b.name.empty?
|
712
713
|
end
|
713
714
|
return { :bundle => bundle.name }
|
714
715
|
end
|
715
|
-
|
716
|
-
#
|
716
|
+
|
717
|
+
#
|
717
718
|
# Prepares the params for a `tags_rename` call
|
718
719
|
# and returns a Hash with the params ready for the HTTP request.
|
719
|
-
#
|
720
|
+
#
|
720
721
|
# Raises:: WWW::Delicious::Error
|
721
|
-
#
|
722
|
+
#
|
722
723
|
def prepare_tags_rename_params(from_name_or_tag, to_name_or_tag)
|
723
724
|
from, to = [from_name_or_tag, to_name_or_tag].collect do |v|
|
724
725
|
prepare_param_tag(v)
|
725
726
|
end
|
726
727
|
return { :old => from, :new => to }
|
727
728
|
end
|
728
|
-
|
729
|
-
#
|
729
|
+
|
730
|
+
#
|
730
731
|
# Prepares the params for a `post_*` call
|
731
732
|
# and returns a Hash with the params ready for the HTTP request.
|
732
|
-
#
|
733
|
+
#
|
733
734
|
# Raises:: WWW::Delicious::Error
|
734
|
-
#
|
735
|
+
#
|
735
736
|
def prepare_posts_params(params, allowed_params = [])
|
736
737
|
compare_params(params, allowed_params)
|
737
|
-
|
738
|
+
|
738
739
|
# we don't need to check whether the following parameters
|
739
740
|
# are valid for this request because compare_params
|
740
741
|
# would raise if an invalid param is supplied
|
741
|
-
|
742
|
+
|
742
743
|
params[:tag] = prepare_param_tag(params[:tag]) if params[:tag]
|
743
744
|
params[:dt] = TIME_CONVERTER.call(params[:dt]) if params[:dt]
|
744
745
|
params[:url] = URI.parse(params[:url]) if params[:url]
|
@@ -748,18 +749,18 @@ module WWW #:nodoc:
|
|
748
749
|
else
|
749
750
|
15 # default value
|
750
751
|
end
|
751
|
-
|
752
|
+
|
752
753
|
return params
|
753
754
|
end
|
754
|
-
|
755
|
-
|
756
|
-
#
|
755
|
+
|
756
|
+
|
757
|
+
#
|
757
758
|
# Prepares the +post+ param for an API request.
|
758
|
-
#
|
759
|
+
#
|
759
760
|
# Creates and returns a <tt>WWW::Delicious::Post</tt> instance from <tt>post_or_values</tt>.
|
760
761
|
# <tt>post_or_values</tt> can be either an Hash with post attributes
|
761
762
|
# or a <tt>WWW::Delicious::Post</tt> instance.
|
762
|
-
#
|
763
|
+
#
|
763
764
|
def prepare_param_post(post_or_values, &block)
|
764
765
|
post = case post_or_values
|
765
766
|
when WWW::Delicious::Post
|
@@ -769,20 +770,20 @@ module WWW #:nodoc:
|
|
769
770
|
else
|
770
771
|
raise ArgumentError, 'Expected `args` to be `WWW::Delicious::Post` or `Hash`'
|
771
772
|
end
|
772
|
-
|
773
|
+
|
773
774
|
yield(post) if block_given?
|
774
775
|
# TODO: validate post with post.validate!
|
775
776
|
raise ArgumentError, 'Both `url` and `title` are required' unless post.api_valid?
|
776
777
|
post
|
777
778
|
end
|
778
|
-
|
779
|
-
#
|
779
|
+
|
780
|
+
#
|
780
781
|
# Prepares the +bundle+ param for an API request.
|
781
|
-
#
|
782
|
+
#
|
782
783
|
# Creates and returns a <tt>WWW::Delicious::Bundle</tt> instance from <tt>name_or_bundle</tt>.
|
783
784
|
# <tt>name_or_bundle</tt> can be either a string holding bundle name
|
784
785
|
# or a <tt>WWW::Delicious::Bundle</tt> instance.
|
785
|
-
#
|
786
|
+
#
|
786
787
|
def prepare_param_bundle(name_or_bundle, tags = [], &block) # :yields: bundle
|
787
788
|
bundle = case name_or_bundle
|
788
789
|
when WWW::Delicious::Bundle
|
@@ -790,19 +791,19 @@ module WWW #:nodoc:
|
|
790
791
|
else
|
791
792
|
Bundle.new(:name => name_or_bundle, :tags => tags)
|
792
793
|
end
|
793
|
-
|
794
|
+
|
794
795
|
yield(bundle) if block_given?
|
795
796
|
# TODO: validate bundle with bundle.validate!
|
796
797
|
bundle
|
797
798
|
end
|
798
|
-
|
799
|
-
#
|
799
|
+
|
800
|
+
#
|
800
801
|
# Prepares the +tag+ param for an API request.
|
801
|
-
#
|
802
|
+
#
|
802
803
|
# Creates and returns a <tt>WWW::Delicious::Tag</tt> instance from <tt>name_or_tag</tt>.
|
803
804
|
# <tt>name_or_tag</tt> can be either a string holding tag name
|
804
805
|
# or a <tt>WWW::Delicious::Tag</tt> instance.
|
805
|
-
#
|
806
|
+
#
|
806
807
|
def prepare_param_tag(name_or_tag, &block) # :yields: tag
|
807
808
|
tag = case name_or_tag
|
808
809
|
when WWW::Delicious::Tag
|
@@ -810,62 +811,62 @@ module WWW #:nodoc:
|
|
810
811
|
else
|
811
812
|
Tag.new(:name => name_or_tag.to_s)
|
812
813
|
end
|
813
|
-
|
814
|
+
|
814
815
|
yield(tag) if block_given?
|
815
816
|
# TODO: validate tag with tag.validate!
|
816
817
|
raise "Invalid `tag` value supplied" unless tag.api_valid?
|
817
818
|
tag
|
818
819
|
end
|
819
|
-
|
820
|
-
#
|
820
|
+
|
821
|
+
#
|
821
822
|
# Checks whether user given +params+ are valid against a defined collection of +valid_params+.
|
822
|
-
#
|
823
|
+
#
|
823
824
|
# === Examples
|
824
|
-
#
|
825
|
+
#
|
825
826
|
# params = {:foo => 1, :bar => 2}
|
826
827
|
#
|
827
828
|
# compare_params(params, [:foo, :bar])
|
828
829
|
# # => valid
|
829
|
-
#
|
830
|
+
#
|
830
831
|
# compare_params(params, [:foo, :bar, :baz])
|
831
832
|
# # => raises
|
832
|
-
#
|
833
|
+
#
|
833
834
|
# compare_params(params, [:foo])
|
834
835
|
# # => raises
|
835
|
-
#
|
836
|
+
#
|
836
837
|
# Raises:: WWW::Delicious::Error
|
837
|
-
#
|
838
|
+
#
|
838
839
|
def compare_params(params, valid_params)
|
839
840
|
raise ArgumentError, "Expected `params` to be a kind of `Hash`" unless params.kind_of?(Hash)
|
840
841
|
raise ArgumentError, "Expected `valid_params` to be a kind of `Array`" unless valid_params.kind_of?(Array)
|
841
|
-
|
842
|
+
|
842
843
|
# compute options difference
|
843
844
|
difference = params.keys - valid_params
|
844
845
|
raise Error, "Invalid params: `#{difference.join('`, `')}`" unless difference.empty?
|
845
846
|
end
|
846
|
-
|
847
|
-
|
847
|
+
|
848
|
+
|
848
849
|
module XMLUtils #:nodoc:
|
849
|
-
|
850
|
+
|
850
851
|
#
|
851
852
|
# Returns the +xmlattr+ attribute value for current <tt>REXML::Element</tt>.
|
852
|
-
#
|
853
|
+
#
|
853
854
|
# If block is given and attribute value is not nil,
|
854
855
|
# the content of the block is executed.
|
855
|
-
#
|
856
|
+
#
|
856
857
|
# === Examples
|
857
|
-
#
|
858
|
+
#
|
858
859
|
# dom = REXML::Document.new('<a name="1"><b>foo</b><b>bar</b></a>')
|
859
|
-
#
|
860
|
+
#
|
860
861
|
# dom.root.if_attribute_value(:name)
|
861
862
|
# # => "1"
|
862
|
-
#
|
863
|
+
#
|
863
864
|
# dom.root.if_attribute_value(:name) { |v| v.to_i }
|
864
865
|
# # => 1
|
865
|
-
#
|
866
|
+
#
|
866
867
|
# dom.root.if_attribute_value(:foo)
|
867
868
|
# # => nil
|
868
|
-
#
|
869
|
+
#
|
869
870
|
# dom.root.if_attribute_value(:name) { |v| v.to_i }
|
870
871
|
# # => nil
|
871
872
|
#
|
@@ -878,7 +879,7 @@ module WWW #:nodoc:
|
|
878
879
|
value = yield value if !value.nil? and block_given?
|
879
880
|
value
|
880
881
|
end
|
881
|
-
|
882
|
+
|
882
883
|
#
|
883
884
|
# Returns the value of +expression+ child of this element, if it exists.
|
884
885
|
# If blog is given, block is called on +expression+ element value
|
@@ -891,7 +892,7 @@ module WWW #:nodoc:
|
|
891
892
|
value
|
892
893
|
end
|
893
894
|
end
|
894
|
-
|
895
|
+
|
895
896
|
#
|
896
897
|
# Executes the content of +block+ on +expression+
|
897
898
|
# child of this element, if it exists.
|
@@ -905,7 +906,7 @@ module WWW #:nodoc:
|
|
905
906
|
nil
|
906
907
|
end
|
907
908
|
end
|
908
|
-
|
909
|
+
|
909
910
|
end # XMLUtils
|
910
911
|
|
911
912
|
end
|
@@ -913,24 +914,24 @@ end
|
|
913
914
|
|
914
915
|
|
915
916
|
class Object
|
916
|
-
|
917
|
+
|
917
918
|
# An object is blank if it's false, empty, or a whitespace string.
|
918
919
|
# For example, "", " ", +nil+, [], and {} are blank.
|
919
|
-
#
|
920
|
+
#
|
920
921
|
# This simplifies
|
921
|
-
#
|
922
|
+
#
|
922
923
|
# if !address.nil? && !address.empty?
|
923
|
-
#
|
924
|
+
#
|
924
925
|
# to
|
925
|
-
#
|
926
|
+
#
|
926
927
|
# if !address.blank?
|
927
928
|
#
|
928
929
|
# Object#blank? comes from the GEM ActiveSupport 2.1.
|
929
|
-
#
|
930
|
-
def blank?
|
930
|
+
#
|
931
|
+
def blank?
|
931
932
|
respond_to?(:empty?) ? empty? : !self
|
932
|
-
end unless Object.method_defined? :
|
933
|
-
|
933
|
+
end unless Object.method_defined? :blank?
|
934
|
+
|
934
935
|
end
|
935
936
|
|
936
937
|
|