www-delicious 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|