ideaoforder-www-delicious 0.2.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 +46 -0
- data/Manifest +49 -0
- data/README.rdoc +209 -0
- data/Rakefile +55 -0
- data/lib/www/delicious/bundle.rb +73 -0
- data/lib/www/delicious/element.rb +73 -0
- data/lib/www/delicious/errors.rb +46 -0
- data/lib/www/delicious/post.rb +123 -0
- data/lib/www/delicious/tag.rb +101 -0
- data/lib/www/delicious/version.rb +29 -0
- data/lib/www/delicious.rb +949 -0
- data/setup.rb +1585 -0
- data/test/fixtures/net_response_invalid_account.yml +25 -0
- data/test/fixtures/net_response_success.yml +23 -0
- data/test/helper.rb +49 -0
- data/test/test_all.rb +18 -0
- data/test/test_offline.rb +18 -0
- data/test/test_online.rb +20 -0
- data/test/testcases/element/bundle.xml +1 -0
- data/test/testcases/element/invalid_root.xml +2 -0
- data/test/testcases/element/post.xml +2 -0
- data/test/testcases/element/post_unshared.xml +2 -0
- data/test/testcases/element/tag.xml +1 -0
- data/test/testcases/response/bundles_all.xml +5 -0
- data/test/testcases/response/bundles_all_empty.xml +2 -0
- data/test/testcases/response/bundles_delete.xml +2 -0
- data/test/testcases/response/bundles_set.xml +2 -0
- data/test/testcases/response/bundles_set_error.xml +2 -0
- data/test/testcases/response/posts_add.xml +2 -0
- data/test/testcases/response/posts_all.xml +12 -0
- data/test/testcases/response/posts_dates.xml +14 -0
- data/test/testcases/response/posts_dates_with_tag.xml +14 -0
- data/test/testcases/response/posts_delete.xml +2 -0
- data/test/testcases/response/posts_get.xml +7 -0
- data/test/testcases/response/posts_get_with_tag.xml +6 -0
- data/test/testcases/response/posts_recent.xml +19 -0
- data/test/testcases/response/posts_recent_with_tag.xml +19 -0
- data/test/testcases/response/tags_get.xml +5 -0
- data/test/testcases/response/tags_get_empty.xml +2 -0
- data/test/testcases/response/tags_rename.xml +2 -0
- data/test/testcases/response/update.delicious1.xml +2 -0
- data/test/testcases/response/update.xml +3 -0
- data/test/unit/bundle_test.rb +63 -0
- data/test/unit/delicious_test.rb +369 -0
- data/test/unit/online/online_test.rb +148 -0
- data/test/unit/post_test.rb +68 -0
- data/test/unit/tag_test.rb +69 -0
- data/www-delicious.gemspec +146 -0
- metadata +143 -0
data/CHANGELOG.rdoc
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
= Changelog
|
2
|
+
|
3
|
+
|
4
|
+
== development
|
5
|
+
|
6
|
+
* CHANGED: Don't use File.dirname(__FILE__) in require statement to prevent recursive inclusions.
|
7
|
+
|
8
|
+
|
9
|
+
== Release 0.2.0
|
10
|
+
|
11
|
+
* ADDED: :base_uri initialization option allows to create a new instance specifying a custom base_uri for all API calls. This is useful, for example, if you want to use ma.gno.lia Mirror'd APIs (http://wiki.ma.gnolia.com/Mirror%27d_API) instead the del.icio.us one (thanks to Jörg Battermann).
|
12
|
+
|
13
|
+
* ADDED: two new REXML::Element core extension elements to enhance interaction with node elements.
|
14
|
+
|
15
|
+
* FIXED: a wrong indentation in README file causes all list items to be rendered as source code.
|
16
|
+
|
17
|
+
* FIXED: Missing WWW::Delicious::Bundle#to_s method causes a class ID representation to be returned.
|
18
|
+
|
19
|
+
* FIXED: Missing unit tests for post_ calls (closes #18).
|
20
|
+
|
21
|
+
* FIXED: Added test for `shared` Post attribute and fixed an issue with duplicate `replace` method definition (closes #11).
|
22
|
+
|
23
|
+
* CHANGED: improved documentation and added more examples (closes #21).
|
24
|
+
|
25
|
+
* CHANGED: REXML::Element#attribute_value core extension has been renamed to REXML::Element#if_attribute_value.
|
26
|
+
|
27
|
+
* CHANGED: Renamed TESTCASE_PATH to TESTCASES_PATH.
|
28
|
+
|
29
|
+
* CHANGED: WWW::Delicious::Tag, WWW::Delicious::Bundle, WWW::Delicious::Post now extend WWW::Delicious::Element. Simplified classes.
|
30
|
+
|
31
|
+
* CHANGED: WWW::Delicious::Tag#to_s always returns a string even if name is nil.
|
32
|
+
|
33
|
+
* CHANGED: WWW::Delicious::Tag :count attribute is now stored and returned as Fixnum instead of String.
|
34
|
+
|
35
|
+
* CHANGED: Unit test reorganization (closes #22).
|
36
|
+
|
37
|
+
* CHANGED: Simplified and tidyfied test system with Mocha (closes #19).
|
38
|
+
|
39
|
+
* CHANGED: Various internal API methods have been renamed for coherence with their new scope.
|
40
|
+
|
41
|
+
* CHANGED: Integrated Echoe, cleaned Rakefile (closes #23).
|
42
|
+
|
43
|
+
|
44
|
+
== Release 0.1.0 (2008-05-11)
|
45
|
+
|
46
|
+
* Initial public release.
|
data/Manifest
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
CHANGELOG.rdoc
|
2
|
+
lib/www/delicious/bundle.rb
|
3
|
+
lib/www/delicious/element.rb
|
4
|
+
lib/www/delicious/errors.rb
|
5
|
+
lib/www/delicious/post.rb
|
6
|
+
lib/www/delicious/tag.rb
|
7
|
+
lib/www/delicious/version.rb
|
8
|
+
lib/www/delicious.rb
|
9
|
+
LICENSE.rdoc
|
10
|
+
Rakefile
|
11
|
+
README.rdoc
|
12
|
+
setup.rb
|
13
|
+
test/fixtures/net_response_invalid_account.yml
|
14
|
+
test/fixtures/net_response_success.yml
|
15
|
+
test/helper.rb
|
16
|
+
test/test_all.rb
|
17
|
+
test/test_offline.rb
|
18
|
+
test/test_online.rb
|
19
|
+
test/testcases/element/bundle.xml
|
20
|
+
test/testcases/element/invalid_root.xml
|
21
|
+
test/testcases/element/post.xml
|
22
|
+
test/testcases/element/post_unshared.xml
|
23
|
+
test/testcases/element/tag.xml
|
24
|
+
test/testcases/response/bundles_all.xml
|
25
|
+
test/testcases/response/bundles_all_empty.xml
|
26
|
+
test/testcases/response/bundles_delete.xml
|
27
|
+
test/testcases/response/bundles_set.xml
|
28
|
+
test/testcases/response/bundles_set_error.xml
|
29
|
+
test/testcases/response/posts_add.xml
|
30
|
+
test/testcases/response/posts_all.xml
|
31
|
+
test/testcases/response/posts_dates.xml
|
32
|
+
test/testcases/response/posts_dates_with_tag.xml
|
33
|
+
test/testcases/response/posts_delete.xml
|
34
|
+
test/testcases/response/posts_get.xml
|
35
|
+
test/testcases/response/posts_get_with_tag.xml
|
36
|
+
test/testcases/response/posts_recent.xml
|
37
|
+
test/testcases/response/posts_recent_with_tag.xml
|
38
|
+
test/testcases/response/tags_get.xml
|
39
|
+
test/testcases/response/tags_get_empty.xml
|
40
|
+
test/testcases/response/tags_rename.xml
|
41
|
+
test/testcases/response/update.delicious1.xml
|
42
|
+
test/testcases/response/update.xml
|
43
|
+
test/unit/bundle_test.rb
|
44
|
+
test/unit/delicious_test.rb
|
45
|
+
test/unit/online/online_test.rb
|
46
|
+
test/unit/post_test.rb
|
47
|
+
test/unit/tag_test.rb
|
48
|
+
TODO
|
49
|
+
Manifest
|
data/README.rdoc
ADDED
@@ -0,0 +1,209 @@
|
|
1
|
+
= WWW::Delicious
|
2
|
+
|
3
|
+
http://www-delicious.rubyforge.org/
|
4
|
+
http://code.simonecarletti.com/www-delicious
|
5
|
+
|
6
|
+
|
7
|
+
== Description
|
8
|
+
|
9
|
+
WWW::Delicious is a Ruby client for http://del.icio.us XML API.
|
10
|
+
|
11
|
+
It provides both read and write functionality. You can read user Posts, Tags
|
12
|
+
and Bundles but you can create new Posts, Tags and Bundles as well.
|
13
|
+
|
14
|
+
|
15
|
+
== Authors
|
16
|
+
|
17
|
+
* {Simone Carletti}[http://www.simonecarletti.com/] <weppos@weppos.net>
|
18
|
+
If you like this software, consider to {recommend me}[http://www.workingwithrails.com/person/11967-simone-carletti] at Working with Rails.
|
19
|
+
|
20
|
+
|
21
|
+
== Website
|
22
|
+
|
23
|
+
* {Homepage}[http://code.simonecarletti.com/www-delicious]
|
24
|
+
* {API}[http://www-delicious.rubyforge.org/]
|
25
|
+
|
26
|
+
|
27
|
+
== Source
|
28
|
+
|
29
|
+
* {at GitHub}[http://github.com/weppos/www-delicious/]
|
30
|
+
* {at RubyForge}[http://rubyforge.org/projects/www-delicious/]
|
31
|
+
|
32
|
+
|
33
|
+
== Dependencies
|
34
|
+
|
35
|
+
* Ruby >= 1.8.6 (not tested with previous versions)
|
36
|
+
|
37
|
+
|
38
|
+
== Download and Installation
|
39
|
+
|
40
|
+
RubyGems[http://rubyforge.org/projects/rubygems/] is the preferred install method.
|
41
|
+
To get the latest version, simply type the following instruction into your command prompt:
|
42
|
+
|
43
|
+
$ sudo gem install www-delicious
|
44
|
+
|
45
|
+
Depending on your system, you might need su privileges.
|
46
|
+
|
47
|
+
To install the library manually, downlad the latest version from
|
48
|
+
navigate to the root library directory and enter:
|
49
|
+
|
50
|
+
$ sudo ruby setup.rb
|
51
|
+
|
52
|
+
If you need the latest development version you can download the source code
|
53
|
+
from one of the GIT repositories listed above.
|
54
|
+
Beware that the code might not be as stable as the official release.
|
55
|
+
|
56
|
+
|
57
|
+
== Overview
|
58
|
+
|
59
|
+
WWW::Delicious maps all the original del.icio.us API calls and provides some
|
60
|
+
additional convenient methods to perform common tasks.
|
61
|
+
Please read the official documentation (http://del.icio.us/help/api/)
|
62
|
+
to learn more about del.icio.us API.
|
63
|
+
|
64
|
+
WWW::Delicious is 100% compatible with all del.icio.us API constraints,
|
65
|
+
including the requirement to set a valid user agent or wait at least
|
66
|
+
one second between queries.
|
67
|
+
Basically, the main benefit from using this library is that you don't need
|
68
|
+
to take care of all these low level details, if you don't want:
|
69
|
+
WWW::Delicious will try to give you the most with less efforts.
|
70
|
+
|
71
|
+
|
72
|
+
== Usage
|
73
|
+
|
74
|
+
In order to use this library you need a valid del.icio.us account.
|
75
|
+
Go to http://del.icio.us/ and register for a new account if you don't
|
76
|
+
already have one.
|
77
|
+
|
78
|
+
Then create a valid instance of WWW::Delicious with the account credentials.
|
79
|
+
|
80
|
+
require 'www/delicious'
|
81
|
+
|
82
|
+
# create a new instance with given username and password
|
83
|
+
d = WWW::Delicious.new('username', 'password')
|
84
|
+
|
85
|
+
Now you can use your delicious instance to call on of the API methods available.
|
86
|
+
|
87
|
+
|
88
|
+
=== Last account update
|
89
|
+
|
90
|
+
The following example show you how to get the last account update Time.
|
91
|
+
|
92
|
+
require 'www/delicious'
|
93
|
+
d = WWW::Delicious.new('username', 'password')
|
94
|
+
|
95
|
+
time = d.update # => Fri May 02 18:02:48 UTC 2008
|
96
|
+
|
97
|
+
|
98
|
+
=== Reading Posts
|
99
|
+
|
100
|
+
You can fetch your posts in 3 different ways:
|
101
|
+
|
102
|
+
require 'www/delicious'
|
103
|
+
d = WWW::Delicious.new('username', 'password')
|
104
|
+
|
105
|
+
# 1. get all posts
|
106
|
+
posts = d.posts_all
|
107
|
+
|
108
|
+
# 2. get recent posts
|
109
|
+
posts = d.posts_recent
|
110
|
+
|
111
|
+
# 3. get a single post (the latest one if no criteria is given)
|
112
|
+
posts = d.posts_get(:tag => 'ruby')
|
113
|
+
|
114
|
+
Each post call accepts some options to refine your search.
|
115
|
+
For example, you can always search for posts matching a specific tag.
|
116
|
+
|
117
|
+
posts = d.posts_all(:tag => 'ruby')
|
118
|
+
posts = d.posts_recent(:tag => 'ruby')
|
119
|
+
posts = d.posts_get(:tag => 'ruby')
|
120
|
+
|
121
|
+
|
122
|
+
=== Creating a new Post
|
123
|
+
|
124
|
+
require 'www/delicious'
|
125
|
+
d = WWW::Delicious.new('username', 'password')
|
126
|
+
|
127
|
+
# add a post from options
|
128
|
+
d.posts_add(:url => 'http://www.simonecarletti.com/', :title => 'Cool site!')
|
129
|
+
|
130
|
+
# add a post from WWW::Delicious::Post
|
131
|
+
d.posts_add(WWW::Delicious::Post.new(:url => 'http://www.simonecarletti.com/', :title => 'Cool site!'))
|
132
|
+
|
133
|
+
|
134
|
+
=== Deleting a Posts
|
135
|
+
|
136
|
+
require 'www/delicious'
|
137
|
+
d = WWW::Delicious.new('username', 'password')
|
138
|
+
|
139
|
+
# delete given post (the URL can be either a string or an URI)
|
140
|
+
d.posts_delete('http://www.foobar.com/')
|
141
|
+
|
142
|
+
Note. Actually you cannot delete a post from a WWW::Delicious::Post instance.
|
143
|
+
It means, the following example doesn't work as some ActiveRecord user might expect.
|
144
|
+
|
145
|
+
post = WWW::Delicious::Post.new(:url => 'http://www.foobar.com/')
|
146
|
+
post.delete
|
147
|
+
|
148
|
+
This feature is already in the TODO list. For now, use the following workaround
|
149
|
+
to delete a given Post.
|
150
|
+
|
151
|
+
# delete a post from an existing post = WWW::Delicious::Post
|
152
|
+
d.posts_delete(post.url)
|
153
|
+
|
154
|
+
|
155
|
+
=== Tags
|
156
|
+
|
157
|
+
Working with tags it's really easy. You can get all your tags or rename an existing tag.
|
158
|
+
|
159
|
+
require 'www/delicious'
|
160
|
+
d = WWW::Delicious.new('username', 'password')
|
161
|
+
|
162
|
+
# get all tags
|
163
|
+
tags = d.tags_get
|
164
|
+
|
165
|
+
# print all tag names
|
166
|
+
tags.each { |t| puts t.name }
|
167
|
+
|
168
|
+
# rename the tag gems to gem
|
169
|
+
d.tags_rename('gems', 'gem')
|
170
|
+
|
171
|
+
|
172
|
+
=== Bundles
|
173
|
+
|
174
|
+
WWW::Delicious enables you to get all bundles from given account.
|
175
|
+
|
176
|
+
require 'www/delicious'
|
177
|
+
d = WWW::Delicious.new('username', 'password')
|
178
|
+
|
179
|
+
# get all bundles
|
180
|
+
bundles = d.bundles_all
|
181
|
+
|
182
|
+
# print all bundle names
|
183
|
+
bundles.each { |b| puts b.name }
|
184
|
+
|
185
|
+
You can also create new bundles or delete existing ones.
|
186
|
+
|
187
|
+
require 'www/delicious'
|
188
|
+
d = WWW::Delicious.new('username', 'password')
|
189
|
+
|
190
|
+
# set a new bundle for tags ruby, rails and gem
|
191
|
+
d.bundles_set('MyBundle', %w(ruby rails gem))
|
192
|
+
|
193
|
+
# delete the old bundle
|
194
|
+
d.bundles_delete('OldBundle')
|
195
|
+
|
196
|
+
|
197
|
+
== FeedBack and Bug reports
|
198
|
+
|
199
|
+
Feel free to email {Simone Carletti}[mailto:weppos@weppos.net]
|
200
|
+
with any questions or feedback.
|
201
|
+
|
202
|
+
Please submit your bug reports to the Redmine installation for WWW::Delicious
|
203
|
+
available at http://code.simonecarletti.com/www-delicious.
|
204
|
+
|
205
|
+
|
206
|
+
== Changelog
|
207
|
+
|
208
|
+
See CHANGELOG for details.
|
209
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'echoe'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + "/lib")
|
5
|
+
require 'www/delicious'
|
6
|
+
|
7
|
+
|
8
|
+
# Common package properties
|
9
|
+
PKG_NAME = ENV['PKG_NAME'] || WWW::Delicious::GEM
|
10
|
+
PKG_VERSION = ENV['PKG_VERSION'] || WWW::Delicious::VERSION
|
11
|
+
PKG_SUMMARY = "Ruby client for del.icio.us API."
|
12
|
+
PKG_FILES = FileList.new("{lib,test}/**/*.rb") do |fl|
|
13
|
+
fl.exclude 'TODO'
|
14
|
+
fl.include %w(README.rdoc CHANGELOG.rdoc LICENSE.rdoc)
|
15
|
+
fl.include %w(Rakefile setup.rb)
|
16
|
+
end
|
17
|
+
RUBYFORGE_PROJECT = 'www-delicious'
|
18
|
+
|
19
|
+
if ENV['SNAPSHOT'].to_i == 1
|
20
|
+
PKG_VERSION << "." << Time.now.utc.strftime("%Y%m%d%H%M%S")
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
Echoe.new(PKG_NAME, PKG_VERSION) do |p|
|
25
|
+
p.author = "Simone Carletti"
|
26
|
+
p.email = "weppos@weppos.net"
|
27
|
+
p.summary = PKG_SUMMARY
|
28
|
+
p.description = <<-EOF
|
29
|
+
WWW::Delicious is a del.icio.us API client implemented in Ruby. \
|
30
|
+
It provides access to all available del.icio.us API queries \
|
31
|
+
and returns the original XML response as a friendly Ruby object.
|
32
|
+
EOF
|
33
|
+
p.url = "http://code.simonecarletti.com/www-delicious"
|
34
|
+
p.project = RUBYFORGE_PROJECT
|
35
|
+
|
36
|
+
p.need_zip = true
|
37
|
+
p.rcov_options = ["-x Rakefile -x mocha -x rcov"]
|
38
|
+
p.rdoc_pattern = /^(lib|CHANGELOG.rdoc|README.rdoc)/
|
39
|
+
|
40
|
+
p.development_dependencies = ["rake >=0.8",
|
41
|
+
"echoe >=3",
|
42
|
+
"mocha >=0.9"]
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
begin
|
47
|
+
require 'code_statistics'
|
48
|
+
desc "Show library's code statistics"
|
49
|
+
task :stats do
|
50
|
+
CodeStatistics.new(["WWW::Delicious", "lib"],
|
51
|
+
["Tests", "test"]).to_s
|
52
|
+
end
|
53
|
+
rescue LoadError
|
54
|
+
puts "CodeStatistics (Rails) is not available"
|
55
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#
|
2
|
+
# = WWW::Delicious
|
3
|
+
#
|
4
|
+
# Ruby client for del.icio.us API.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# Category:: WWW
|
8
|
+
# Package:: WWW::Delicious
|
9
|
+
# Author:: Simone Carletti <weppos@weppos.net>
|
10
|
+
# License:: MIT License
|
11
|
+
#
|
12
|
+
#--
|
13
|
+
# SVN: $Id$
|
14
|
+
#++
|
15
|
+
|
16
|
+
|
17
|
+
require 'www/delicious/element'
|
18
|
+
|
19
|
+
|
20
|
+
module WWW
|
21
|
+
class Delicious
|
22
|
+
|
23
|
+
#
|
24
|
+
# = Delicious Bundle
|
25
|
+
#
|
26
|
+
# Represents a single Bundle element.
|
27
|
+
#
|
28
|
+
class Bundle < Element
|
29
|
+
|
30
|
+
# The name of the bundle.
|
31
|
+
attr_accessor :name
|
32
|
+
|
33
|
+
# The collection of <tt>WWW::Delicious::Tags</tt>.
|
34
|
+
attr_accessor :tags
|
35
|
+
|
36
|
+
|
37
|
+
# Returns value for <tt>name</tt> attribute.
|
38
|
+
# Value is always normalized as lower string.
|
39
|
+
def name
|
40
|
+
@name.to_s.strip unless @name.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Returns a string representation of this Bundle.
|
45
|
+
# In case name is nil this method will return an empty string.
|
46
|
+
#
|
47
|
+
def to_s
|
48
|
+
name.to_s
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
class << self
|
53
|
+
|
54
|
+
#
|
55
|
+
# Creates and returns new instance from a REXML +element+.
|
56
|
+
#
|
57
|
+
# Implements Element#from_rexml.
|
58
|
+
#
|
59
|
+
def from_rexml(element)
|
60
|
+
raise ArgumentError, "`element` expected to be a `REXML::Element`" unless element.kind_of? REXML::Element
|
61
|
+
self.new do |instance|
|
62
|
+
instance.name = element.if_attribute_value(:name)
|
63
|
+
# FIXME: value must be converted to array of Tag
|
64
|
+
instance.tags = element.if_attribute_value(:tags) { |value| value.split(' ') }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#
|
2
|
+
# = WWW::Delicious
|
3
|
+
#
|
4
|
+
# Ruby client for del.icio.us API.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# Category:: WWW
|
8
|
+
# Package:: WWW::Delicious
|
9
|
+
# Author:: Simone Carletti <weppos@weppos.net>
|
10
|
+
# License:: MIT License
|
11
|
+
#
|
12
|
+
#--
|
13
|
+
# SVN: $Id$
|
14
|
+
#++
|
15
|
+
|
16
|
+
|
17
|
+
module WWW
|
18
|
+
class Delicious
|
19
|
+
|
20
|
+
#
|
21
|
+
# = Abstract structure
|
22
|
+
#
|
23
|
+
# Represent the most basic structure all Struc(s) must inherith from.
|
24
|
+
#
|
25
|
+
class Element
|
26
|
+
|
27
|
+
#
|
28
|
+
# Initializes a new instance and populate attributes from +attrs+.
|
29
|
+
#
|
30
|
+
# class User < Element
|
31
|
+
# attr_accessor :first_name
|
32
|
+
# attr_accessor :last_name
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# User.new
|
36
|
+
# User.new(:first_name => 'foo')
|
37
|
+
# User.new(:first_name => 'John', :last_name => 'Doe')
|
38
|
+
#
|
39
|
+
# You can even use a block.
|
40
|
+
# The following statements are equals:
|
41
|
+
#
|
42
|
+
# User.new(:first_name => 'John', :last_name => 'Doe')
|
43
|
+
#
|
44
|
+
# User.new do |user|
|
45
|
+
# user.first_name => 'John'
|
46
|
+
# user.last_name => 'Doe'
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# Warning. In order to set an attribute a valid attribute writer must be available,
|
50
|
+
# otherwise this method will raise an exception.
|
51
|
+
#
|
52
|
+
def initialize(attrs = {}, &block)
|
53
|
+
attrs.each { |key, value| self.send("#{key}=".to_sym, value) }
|
54
|
+
yield self if block_given?
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
class << self
|
60
|
+
|
61
|
+
#
|
62
|
+
# Creates and returns new instance from a REXML +element+.
|
63
|
+
#
|
64
|
+
def from_rexml(element, options)
|
65
|
+
raise NotImplementedError
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#
|
2
|
+
# = WWW::Delicious
|
3
|
+
#
|
4
|
+
# Ruby client for del.icio.us API.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# Category:: WWW
|
8
|
+
# Package:: WWW::Delicious
|
9
|
+
# Author:: Simone Carletti <weppos@weppos.net>
|
10
|
+
# License:: MIT License
|
11
|
+
#
|
12
|
+
#--
|
13
|
+
# SVN: $Id$
|
14
|
+
#++
|
15
|
+
|
16
|
+
|
17
|
+
module WWW
|
18
|
+
class Delicious
|
19
|
+
|
20
|
+
|
21
|
+
#
|
22
|
+
# = WWW::Delicious::Error
|
23
|
+
#
|
24
|
+
# Base exception for all WWW::Delicious errors.
|
25
|
+
#
|
26
|
+
class Error < StandardError; end
|
27
|
+
|
28
|
+
#
|
29
|
+
# = WWW::Delicious::HTTPError
|
30
|
+
#
|
31
|
+
# HTTP connection related error.
|
32
|
+
# Raised when an HTTP request fails or in case of unexpected behavior.
|
33
|
+
#
|
34
|
+
class HTTPError < Error; end
|
35
|
+
|
36
|
+
#
|
37
|
+
# = WWW::Delicious::ResponseError
|
38
|
+
#
|
39
|
+
# Response related error.
|
40
|
+
# Usually raised in case of a malformed, invalid or empty XML response.
|
41
|
+
#
|
42
|
+
class ResponseError < Error; end
|
43
|
+
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
#
|
2
|
+
# = WWW::Delicious
|
3
|
+
#
|
4
|
+
# Ruby client for del.icio.us API.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# Category:: WWW
|
8
|
+
# Package:: WWW::Delicious
|
9
|
+
# Subpackage:: WWW::Delicious::Post
|
10
|
+
# Author:: Simone Carletti <weppos@weppos.net>
|
11
|
+
#
|
12
|
+
#--
|
13
|
+
# SVN: $Id$
|
14
|
+
#++
|
15
|
+
|
16
|
+
|
17
|
+
require 'www/delicious/element'
|
18
|
+
|
19
|
+
|
20
|
+
module WWW
|
21
|
+
class Delicious
|
22
|
+
|
23
|
+
class Post < Element
|
24
|
+
|
25
|
+
# The Post URL
|
26
|
+
attr_accessor :url
|
27
|
+
|
28
|
+
# The title of the Post
|
29
|
+
attr_accessor :title
|
30
|
+
|
31
|
+
# The extended description for the Post
|
32
|
+
attr_accessor :notes
|
33
|
+
|
34
|
+
# The number of other users who saved this Post
|
35
|
+
attr_accessor :others
|
36
|
+
|
37
|
+
# The unique Id for this Post
|
38
|
+
attr_accessor :uid
|
39
|
+
|
40
|
+
# Tags for this Post
|
41
|
+
attr_accessor :tags
|
42
|
+
|
43
|
+
# Timestamp this Post was last saved at
|
44
|
+
attr_accessor :time
|
45
|
+
|
46
|
+
# Whether this Post must replace previous version of the same Post.
|
47
|
+
attr_accessor :replace
|
48
|
+
|
49
|
+
# Whether this Post is private
|
50
|
+
attr_accessor :shared
|
51
|
+
|
52
|
+
|
53
|
+
# Returns the value for <tt>shared</tt> attribute.
|
54
|
+
def shared
|
55
|
+
!(@shared == false)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns the value for <tt>replace</tt> attribute.
|
59
|
+
def replace
|
60
|
+
!(@replace == false)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns a params-style representation suitable for API calls.
|
64
|
+
def to_params()
|
65
|
+
params = {}
|
66
|
+
params[:url] = url # this could/should convert back from URI object (MD)
|
67
|
+
params[:description] = title
|
68
|
+
params[:extended] = notes if notes
|
69
|
+
params[:shared] = 'no' if !shared # (MD)
|
70
|
+
params[:tags] = tags.join(' ') if tags.respond_to? :join
|
71
|
+
params[:replace] = replace
|
72
|
+
params[:dt] = WWW::Delicious::TIME_CONVERTER.call(time) if time
|
73
|
+
params
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
#
|
78
|
+
# Returns whether this object is valid for an API request.
|
79
|
+
#
|
80
|
+
# To be valid +url+ and +title+ must not be empty.
|
81
|
+
#
|
82
|
+
# === Examples
|
83
|
+
#
|
84
|
+
# post = WWW::Delicious::Post.new(:url => 'http://localhost', :title => 'foo')
|
85
|
+
# post.api_valid?
|
86
|
+
# # => true
|
87
|
+
#
|
88
|
+
# post = WWW::Delicious::Post.new(:url => 'http://localhost')
|
89
|
+
# post.api_valid?
|
90
|
+
# # => false
|
91
|
+
#
|
92
|
+
def api_valid?
|
93
|
+
return !(url.nil? or url.empty? or title.nil? or title.empty?)
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
class << self
|
98
|
+
|
99
|
+
#
|
100
|
+
# Creates and returns new instance from a REXML +element+.
|
101
|
+
#
|
102
|
+
# Implements Element#from_rexml.
|
103
|
+
#
|
104
|
+
def from_rexml(element)
|
105
|
+
raise ArgumentError, "`element` expected to be a `REXML::Element`" unless element.kind_of? REXML::Element
|
106
|
+
self.new do |instance|
|
107
|
+
instance.url = element.if_attribute_value(:href) #{ |v| URI.parse(v) } - this was breaking a lot of the API calls (MD)
|
108
|
+
instance.title = element.if_attribute_value(:description)
|
109
|
+
instance.notes = element.if_attribute_value(:extended)
|
110
|
+
instance.others = element.if_attribute_value(:others).to_i # cast nil to 0
|
111
|
+
instance.uid = element.if_attribute_value(:hash)
|
112
|
+
instance.tags = element.if_attribute_value(:tag) { |v| v.split(' ') }.to_a
|
113
|
+
instance.time = element.if_attribute_value(:time) { |v| Time.parse(v) }
|
114
|
+
instance.shared = element.if_attribute_value(:shared) { |v| v == 'no' ? false : true }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|