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.
Files changed (49) hide show
  1. data/CHANGELOG.rdoc +46 -0
  2. data/Manifest +49 -0
  3. data/README.rdoc +209 -0
  4. data/Rakefile +55 -0
  5. data/lib/www/delicious/bundle.rb +73 -0
  6. data/lib/www/delicious/element.rb +73 -0
  7. data/lib/www/delicious/errors.rb +46 -0
  8. data/lib/www/delicious/post.rb +123 -0
  9. data/lib/www/delicious/tag.rb +101 -0
  10. data/lib/www/delicious/version.rb +29 -0
  11. data/lib/www/delicious.rb +949 -0
  12. data/setup.rb +1585 -0
  13. data/test/fixtures/net_response_invalid_account.yml +25 -0
  14. data/test/fixtures/net_response_success.yml +23 -0
  15. data/test/helper.rb +49 -0
  16. data/test/test_all.rb +18 -0
  17. data/test/test_offline.rb +18 -0
  18. data/test/test_online.rb +20 -0
  19. data/test/testcases/element/bundle.xml +1 -0
  20. data/test/testcases/element/invalid_root.xml +2 -0
  21. data/test/testcases/element/post.xml +2 -0
  22. data/test/testcases/element/post_unshared.xml +2 -0
  23. data/test/testcases/element/tag.xml +1 -0
  24. data/test/testcases/response/bundles_all.xml +5 -0
  25. data/test/testcases/response/bundles_all_empty.xml +2 -0
  26. data/test/testcases/response/bundles_delete.xml +2 -0
  27. data/test/testcases/response/bundles_set.xml +2 -0
  28. data/test/testcases/response/bundles_set_error.xml +2 -0
  29. data/test/testcases/response/posts_add.xml +2 -0
  30. data/test/testcases/response/posts_all.xml +12 -0
  31. data/test/testcases/response/posts_dates.xml +14 -0
  32. data/test/testcases/response/posts_dates_with_tag.xml +14 -0
  33. data/test/testcases/response/posts_delete.xml +2 -0
  34. data/test/testcases/response/posts_get.xml +7 -0
  35. data/test/testcases/response/posts_get_with_tag.xml +6 -0
  36. data/test/testcases/response/posts_recent.xml +19 -0
  37. data/test/testcases/response/posts_recent_with_tag.xml +19 -0
  38. data/test/testcases/response/tags_get.xml +5 -0
  39. data/test/testcases/response/tags_get_empty.xml +2 -0
  40. data/test/testcases/response/tags_rename.xml +2 -0
  41. data/test/testcases/response/update.delicious1.xml +2 -0
  42. data/test/testcases/response/update.xml +3 -0
  43. data/test/unit/bundle_test.rb +63 -0
  44. data/test/unit/delicious_test.rb +369 -0
  45. data/test/unit/online/online_test.rb +148 -0
  46. data/test/unit/post_test.rb +68 -0
  47. data/test/unit/tag_test.rb +69 -0
  48. data/www-delicious.gemspec +146 -0
  49. 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