delicious 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/delicious.gemspec +28 -0
- data/lib/delicious.rb +39 -0
- data/lib/delicious/api_model.rb +26 -0
- data/lib/delicious/bookmarks/api.rb +15 -0
- data/lib/delicious/bookmarks/methods/all.rb +112 -0
- data/lib/delicious/bookmarks/methods/create.rb +57 -0
- data/lib/delicious/bookmarks/methods/delete.rb +23 -0
- data/lib/delicious/bundle.rb +43 -0
- data/lib/delicious/bundles/api.rb +20 -0
- data/lib/delicious/bundles/methods/all.rb +23 -0
- data/lib/delicious/bundles/methods/delete.rb +23 -0
- data/lib/delicious/bundles/methods/find.rb +26 -0
- data/lib/delicious/bundles/methods/set.rb +27 -0
- data/lib/delicious/client.rb +57 -0
- data/lib/delicious/error.rb +6 -0
- data/lib/delicious/post.rb +42 -0
- data/lib/delicious/tag.rb +26 -0
- data/lib/delicious/tags/api.rb +15 -0
- data/lib/delicious/tags/methods/all.rb +24 -0
- data/lib/delicious/tags/methods/delete.rb +23 -0
- data/lib/delicious/tags/methods/rename.rb +24 -0
- data/lib/delicious/version.rb +5 -0
- data/spec/delicious/bookmarks/methods/all_spec.rb +122 -0
- data/spec/delicious/bookmarks/methods/create_spec.rb +120 -0
- data/spec/delicious/bundle_spec.rb +42 -0
- data/spec/delicious/bundles/methods/set_spec.rb +78 -0
- data/spec/delicious/client_spec.rb +189 -0
- data/spec/delicious/post_spec.rb +34 -0
- data/spec/delicious/tags/methods/all_spec.rb +70 -0
- data/spec/delicious/tags/methods/delete_spec.rb +47 -0
- data/spec/delicious/tags/methods/rename_spec.rb +47 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/helpers/request_helper.rb +10 -0
- data/spec/support/shared/api_action.rb +13 -0
- metadata +175 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 74e4142660e75f2be6e0d7bcd9380325bce9a431
|
4
|
+
data.tar.gz: 3dcecc74b8d2dde8cec29e100618b80068634e00
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9255873581070289605152cd08bc9eddc3a5279832f00fceb1f3d06eba16a42635fd0cefa8466c92814576ad3e8058a37c9a3398811b167209fb862ff111276b
|
7
|
+
data.tar.gz: 077a8f74f29452afc263b67aef2a88166fdc2592e112c0fc719928280a575dfcfcb899a1c190c4723eeacc0d2bf6946da758bfa5587976c765d6c54bae633540
|
data/delicious.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'delicious/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.add_dependency 'faraday'
|
7
|
+
spec.add_dependency 'faraday_middleware'
|
8
|
+
spec.add_dependency 'multi_xml'
|
9
|
+
spec.add_dependency 'activemodel'
|
10
|
+
spec.add_dependency 'activesupport'
|
11
|
+
|
12
|
+
spec.add_development_dependency 'bundler', '~> 1.0'
|
13
|
+
|
14
|
+
spec.authors = ['Andrey Chernih']
|
15
|
+
spec.description = 'Ruby wrapper for delicious.com API'
|
16
|
+
spec.email = %w(andrey.chernih@gmail.com)
|
17
|
+
spec.files = %w(delicious.gemspec)
|
18
|
+
spec.files += Dir.glob('lib/**/*.rb')
|
19
|
+
spec.files += Dir.glob('spec/**/*')
|
20
|
+
spec.homepage = 'http://github.com/andreychernih/delicious'
|
21
|
+
spec.licenses = ['Apache 2.0']
|
22
|
+
spec.name = 'delicious'
|
23
|
+
spec.require_paths = %w(lib)
|
24
|
+
spec.required_rubygems_version = '>= 1.3.5'
|
25
|
+
spec.summary = spec.description
|
26
|
+
spec.test_files = Dir.glob('spec/**/*')
|
27
|
+
spec.version = Delicious.version
|
28
|
+
end
|
data/lib/delicious.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Delicious
|
2
|
+
autoload :Client, 'delicious/client'
|
3
|
+
autoload :ApiModel, 'delicious/api_model'
|
4
|
+
autoload :Post, 'delicious/post'
|
5
|
+
autoload :Bundle, 'delicious/bundle'
|
6
|
+
autoload :Tag, 'delicious/tag'
|
7
|
+
autoload :Error, 'delicious/error'
|
8
|
+
|
9
|
+
module Bookmarks
|
10
|
+
autoload :Api, 'delicious/bookmarks/api'
|
11
|
+
|
12
|
+
module Methods
|
13
|
+
autoload :All, 'delicious/bookmarks/methods/all'
|
14
|
+
autoload :Create, 'delicious/bookmarks/methods/create'
|
15
|
+
autoload :Delete, 'delicious/bookmarks/methods/delete'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module Bundles
|
20
|
+
autoload :Api, 'delicious/bundles/api'
|
21
|
+
|
22
|
+
module Methods
|
23
|
+
autoload :Find, 'delicious/bundles/methods/find'
|
24
|
+
autoload :All, 'delicious/bundles/methods/all'
|
25
|
+
autoload :Delete, 'delicious/bundles/methods/delete'
|
26
|
+
autoload :Set, 'delicious/bundles/methods/set'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module Tags
|
31
|
+
autoload :Api, 'delicious/tags/api'
|
32
|
+
|
33
|
+
module Methods
|
34
|
+
autoload :All, 'delicious/tags/methods/all'
|
35
|
+
autoload :Delete, 'delicious/tags/methods/delete'
|
36
|
+
autoload :Rename, 'delicious/tags/methods/rename'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Delicious
|
4
|
+
|
5
|
+
module ApiModel
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
attr_writer :persisted, :delicious_client
|
10
|
+
end
|
11
|
+
|
12
|
+
def persisted?
|
13
|
+
!!@persisted
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
def build_persisted(client, attrs)
|
18
|
+
obj = new attrs
|
19
|
+
obj.persisted = true
|
20
|
+
obj.delicious_client = client
|
21
|
+
obj
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Delicious
|
4
|
+
module Bookmarks
|
5
|
+
module Methods
|
6
|
+
|
7
|
+
module All
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
class Criteria
|
11
|
+
include Enumerable
|
12
|
+
|
13
|
+
def self.param(param)
|
14
|
+
method, query_param = param.is_a?(Hash) ? param.first : [param, param]
|
15
|
+
define_method method do |value|
|
16
|
+
params[query_param] = value
|
17
|
+
self
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# @!method limit(count)
|
22
|
+
# Sets the limit
|
23
|
+
#
|
24
|
+
# @param count [Integer] How many bookmarks server should return at most
|
25
|
+
# @return [Criteria]
|
26
|
+
param limit: :results
|
27
|
+
# @!method offset(count)
|
28
|
+
# Sets the offset
|
29
|
+
#
|
30
|
+
# @param count [Integer] How many bookmarks server should skip
|
31
|
+
# @return [Criteria]
|
32
|
+
param offset: :start
|
33
|
+
# @!method tag(name)
|
34
|
+
# Sets tag-based filtering
|
35
|
+
#
|
36
|
+
# @param name [String] Name of the tag
|
37
|
+
# @return [Criteria]
|
38
|
+
param :tag
|
39
|
+
|
40
|
+
def initialize(&block)
|
41
|
+
@fetch = block
|
42
|
+
end
|
43
|
+
|
44
|
+
# Sets starting date and time for which you want to get bookmarks
|
45
|
+
#
|
46
|
+
# @!macro [new] time_criteria
|
47
|
+
# @param date [String,Time,DateTime] `String` time represenation or any object which responds to `strftime`
|
48
|
+
# @return [Criteria]
|
49
|
+
def from(date)
|
50
|
+
params[:fromdt] = format_time(date)
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
# Sets ending date and time for which you want to get bookmarks
|
55
|
+
#
|
56
|
+
# @!macro time_criteria
|
57
|
+
def to(date)
|
58
|
+
params[:todt] = format_time(date)
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
# Fetches bookmarks from server filtering by current criteria
|
63
|
+
def each(&block)
|
64
|
+
@fetch.call(self).each(&block)
|
65
|
+
end
|
66
|
+
|
67
|
+
def params
|
68
|
+
@params ||= {}
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def format_time(time)
|
74
|
+
time = Time.parse(time) if time.respond_to?(:to_str)
|
75
|
+
time.strftime "%FT%TZ"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns all bookmarks associated with given access token. Results can be paginated:
|
80
|
+
#
|
81
|
+
# ```ruby
|
82
|
+
# client.all.offset(150).limit(50).to_a
|
83
|
+
# ```
|
84
|
+
#
|
85
|
+
# And filtered by date and tag:
|
86
|
+
#
|
87
|
+
# ```ruby
|
88
|
+
# client.all.tag('angular').from('2013/11/12 10:23:00').to('2013/11/13 12:10:00')
|
89
|
+
# ```
|
90
|
+
#
|
91
|
+
# @see Criteria
|
92
|
+
# @return [Criteria]
|
93
|
+
def all
|
94
|
+
Criteria.new do |criteria|
|
95
|
+
response = @client.connection.get '/v1/posts/all', criteria.params.merge(tag_separator: 'comma')
|
96
|
+
posts = response.body['posts'] ? response.body['posts']['post'] : []
|
97
|
+
posts.map do |post_attrs|
|
98
|
+
Delicious::Post.build_persisted @client,
|
99
|
+
url: post_attrs['href'],
|
100
|
+
description: post_attrs['description'],
|
101
|
+
extended: post_attrs['extended'],
|
102
|
+
tags: post_attrs['tag'],
|
103
|
+
dt: post_attrs['time'],
|
104
|
+
shared: (post_attrs['shared'] == 'yes')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Delicious
|
4
|
+
module Bookmarks
|
5
|
+
module Methods
|
6
|
+
|
7
|
+
module Create
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
# Create new bookmark
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# client.bookmarks.create url: 'http://example.com',
|
14
|
+
# description: 'Example website',
|
15
|
+
# extended: 'Extended information',
|
16
|
+
# tags: %w(tag1 tag2),
|
17
|
+
# dt: '2014-04-15T10:20:00Z',
|
18
|
+
# shared: true,
|
19
|
+
# replace: false
|
20
|
+
#
|
21
|
+
# @param attrs [Hash] Bookmark attributes
|
22
|
+
# @return [Post]
|
23
|
+
def create(attrs)
|
24
|
+
post = Delicious::Post.new url: attrs[:url],
|
25
|
+
description: attrs[:description],
|
26
|
+
extended: attrs[:extended],
|
27
|
+
tags: attrs[:tags],
|
28
|
+
dt: attrs[:dt],
|
29
|
+
shared: attrs[:shared]
|
30
|
+
|
31
|
+
if post.valid?
|
32
|
+
response = @client.connection.post '/v1/posts/add', post_attrs(post, attrs[:replace])
|
33
|
+
code = response.body['result']['code']
|
34
|
+
fail Delicious::Error, code unless 'done' == code
|
35
|
+
post.persisted = true
|
36
|
+
post.delicious_client = @client
|
37
|
+
end
|
38
|
+
|
39
|
+
post
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def post_attrs(post, replace = false)
|
45
|
+
{ url: post.url,
|
46
|
+
description: post.description,
|
47
|
+
extended: post.extended,
|
48
|
+
tags: post.tags.join(','),
|
49
|
+
dt: post.dt,
|
50
|
+
shared: post.shared ? 'yes' : 'no',
|
51
|
+
replace: replace ? 'yes' : 'no' }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Delicious
|
4
|
+
module Bookmarks
|
5
|
+
module Methods
|
6
|
+
|
7
|
+
module Delete
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
# Deletes bookmark with given URL
|
11
|
+
#
|
12
|
+
# @param url [String] Bookmark URL
|
13
|
+
# @return [Boolean] `true` on successful deletion, `false` otherwise
|
14
|
+
def delete(url)
|
15
|
+
response = @client.connection.post '/v1/posts/delete', url: url
|
16
|
+
code = response.body['result']['code']
|
17
|
+
'done' == code
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
module Delicious
|
4
|
+
class Bundle
|
5
|
+
include ActiveModel::Model
|
6
|
+
include ActiveModel::Validations
|
7
|
+
include ApiModel
|
8
|
+
|
9
|
+
attr_accessor :name, :tags
|
10
|
+
|
11
|
+
validates :name, presence: true
|
12
|
+
validates :tags, presence: true
|
13
|
+
|
14
|
+
# Deletes this bundle
|
15
|
+
#
|
16
|
+
# @raise [Delicious::Error] if bundle was not saved yet
|
17
|
+
# @return [Boolean] `true` upon successful deletion, `false` otherwise
|
18
|
+
def delete
|
19
|
+
if persisted? && @delicious_client
|
20
|
+
@delicious_client.bundles.delete bundle: name
|
21
|
+
else
|
22
|
+
fail Delicious::Error, 'Bundle was not saved yet'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Creates or updates bundle
|
27
|
+
#
|
28
|
+
# @raise [Delicious::Error] if bundle is not associated with Delicious::Client or save failed
|
29
|
+
# @return [Boolean] `true` when saved
|
30
|
+
def save
|
31
|
+
if @delicious_client
|
32
|
+
@delicious_client.bundles.set name, tags
|
33
|
+
true
|
34
|
+
else
|
35
|
+
fail 'Bundle was not saved yet'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_s
|
40
|
+
%Q(Delicious::Bundle(name: "#{name}", tags: #{tags}))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Delicious
|
2
|
+
module Bundles
|
3
|
+
|
4
|
+
class Api
|
5
|
+
include Methods::Find
|
6
|
+
include Methods::All
|
7
|
+
include Methods::Delete
|
8
|
+
include Methods::Set
|
9
|
+
|
10
|
+
def self.model_attrs(attrs)
|
11
|
+
{ name: attrs['name'], tags: attrs['tags'].split(' ') }
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(client)
|
15
|
+
@client = client
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Delicious
|
4
|
+
module Bundles
|
5
|
+
module Methods
|
6
|
+
|
7
|
+
module All
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
# Get all user bundles
|
11
|
+
#
|
12
|
+
# @return [Array<Bundle>] List of bundles
|
13
|
+
def all
|
14
|
+
response = @client.connection.get '/v1/tags/bundles/all'
|
15
|
+
response.body['bundles']['bundle'].map do |attrs|
|
16
|
+
Bundle.build_persisted @client, self.class.model_attrs(attrs)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Delicious
|
4
|
+
module Bundles
|
5
|
+
module Methods
|
6
|
+
|
7
|
+
module Delete
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
# Delete bundle with given name
|
11
|
+
#
|
12
|
+
# @param name [String] Bundle name
|
13
|
+
# @return [Boolean] `true` upon a successful deletion, `false` otherwise
|
14
|
+
def delete(name)
|
15
|
+
response = @client.connection.post '/v1/tags/bundles/delete', bundle: name
|
16
|
+
code = response.body['result']['code']
|
17
|
+
'done' == code
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Delicious
|
4
|
+
module Bundles
|
5
|
+
module Methods
|
6
|
+
|
7
|
+
module Find
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
# Find a bundle with given name
|
11
|
+
#
|
12
|
+
# @param name [String] Bundle name
|
13
|
+
# @return [Bundle, nil] Found bundle or `nil` if it was not found
|
14
|
+
def find(name)
|
15
|
+
response = @client.connection.get '/v1/tags/bundles/all', bundle: name
|
16
|
+
bundle = response.body['bundles']['bundle']
|
17
|
+
Bundle.build_persisted @client, self.class.model_attrs(bundle)
|
18
|
+
rescue Faraday::ParsingError => e
|
19
|
+
# it's ridiculous, but delicious returns invalid XML response when bundle is missing
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|