thumbtack 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/thumbtack.rb +6 -0
- data/lib/thumbtack/client.rb +70 -24
- data/lib/thumbtack/note.rb +68 -8
- data/lib/thumbtack/note_summary.rb +66 -11
- data/lib/thumbtack/notes.rb +30 -6
- data/lib/thumbtack/post.rb +82 -8
- data/lib/thumbtack/posts.rb +143 -85
- data/lib/thumbtack/specification.rb +12 -8
- data/lib/thumbtack/suggestion.rb +59 -0
- data/lib/thumbtack/tags.rb +41 -11
- data/lib/thumbtack/types.rb +4 -3
- data/lib/thumbtack/types/boolean.rb +20 -12
- data/lib/thumbtack/types/date.rb +20 -13
- data/lib/thumbtack/types/date_time.rb +21 -14
- data/lib/thumbtack/types/identity.rb +11 -6
- data/lib/thumbtack/types/integer.rb +12 -8
- data/lib/thumbtack/types/md5.rb +12 -9
- data/lib/thumbtack/types/tags.rb +23 -18
- data/lib/thumbtack/types/text.rb +11 -7
- data/lib/thumbtack/types/title.rb +11 -7
- data/lib/thumbtack/types/url.rb +12 -7
- data/lib/thumbtack/user.rb +26 -5
- data/lib/thumbtack/version.rb +1 -1
- data/test/test_helper.rb +4 -10
- data/test/thumbtack/client_test.rb +1 -1
- data/test/thumbtack/integration/client_test.rb +5 -2
- data/test/thumbtack/note_summary_test.rb +1 -1
- data/test/thumbtack/notes_test.rb +1 -7
- data/test/thumbtack/posts_test.rb +6 -13
- data/test/thumbtack/suggestion_test.rb +16 -0
- data/test/thumbtack/tags_test.rb +0 -6
- data/test/thumbtack/user_test.rb +0 -6
- metadata +15 -11
data/lib/thumbtack/posts.rb
CHANGED
@@ -1,51 +1,63 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Thumbtack
|
4
|
-
#
|
4
|
+
# Wraps API calls related to posts
|
5
5
|
class Posts
|
6
|
-
#
|
6
|
+
# Initialize a Posts
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# @param [Client] client
|
9
|
+
# client to communicate with the Pinboard API
|
10
|
+
#
|
11
|
+
# @api private
|
9
12
|
def initialize(client)
|
10
13
|
@client = client
|
11
14
|
end
|
12
15
|
|
13
|
-
#
|
16
|
+
# Fetch the most recent time a bookmark was added, updated, or deleted
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# update_time = posts.update
|
14
20
|
#
|
15
|
-
#
|
21
|
+
# @return [DateTime]
|
16
22
|
#
|
17
|
-
#
|
18
|
-
# # => '2014-06-26T19:01:33Z'
|
23
|
+
# @api public
|
19
24
|
#
|
20
|
-
#
|
25
|
+
# @see https://pinboard.in/api/#posts_update
|
21
26
|
def update
|
22
27
|
response = @client.get('/posts/update')
|
23
28
|
Types::DateTime.from_parameter response.fetch('update_time')
|
24
29
|
end
|
25
30
|
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# description
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
|
31
|
+
# Add a bookmark
|
32
|
+
#
|
33
|
+
# @example
|
34
|
+
# posts.add(url, description, tags: ['one', 'two', 'three'])
|
35
|
+
#
|
36
|
+
# @param [String] url
|
37
|
+
# the URL of the bookmark
|
38
|
+
# @param [String] description
|
39
|
+
# title of the bookmark
|
40
|
+
# @param [Hash] options
|
41
|
+
# options for the bookmark addition
|
42
|
+
# @option options [String] :extended
|
43
|
+
# a description of the bookmark
|
44
|
+
# @option options [Array[String]] :tags
|
45
|
+
# a list of up to 100 tags
|
46
|
+
# @option options [DateTime] :dt
|
47
|
+
# the creation time for this bookmark
|
48
|
+
# @option options [Boolean] :replace
|
49
|
+
# if true, replace any existing bookmark with the same URL
|
50
|
+
# @option options [Boolean] :shared
|
51
|
+
# if true, make the bookmark public
|
52
|
+
# @option options [Boolean] :toread
|
53
|
+
# if true, mark the bookmark unread
|
54
|
+
#
|
55
|
+
# @return [self]
|
56
|
+
#
|
57
|
+
# @api public
|
58
|
+
#
|
59
|
+
# @see https://pinboard.in/api/#posts_add
|
60
|
+
def add(url, description, options = EMPTY_HASH)
|
49
61
|
parameters = Specification.new(
|
50
62
|
url: Types::URL,
|
51
63
|
description: Types::Text,
|
@@ -60,38 +72,47 @@ module Thumbtack
|
|
60
72
|
self
|
61
73
|
end
|
62
74
|
|
63
|
-
#
|
75
|
+
# Delete a bookmark
|
76
|
+
#
|
77
|
+
# @example
|
78
|
+
# posts.delete(url)
|
64
79
|
#
|
65
|
-
#
|
80
|
+
# @param [String] url
|
81
|
+
# the URL of the bookmark to delete
|
66
82
|
#
|
67
|
-
#
|
83
|
+
# @return [self]
|
68
84
|
#
|
69
|
-
#
|
85
|
+
# @api public
|
70
86
|
#
|
71
|
-
#
|
87
|
+
# @see https://pinboard.in/api/#posts_delete
|
72
88
|
def delete(url)
|
73
89
|
parameters = Specification.new(url: Types::URL).parameters(url: url)
|
74
90
|
@client.get('/posts/delete', parameters)
|
75
91
|
self
|
76
92
|
end
|
77
93
|
|
78
|
-
#
|
94
|
+
# Fetch one or more bookmarks
|
79
95
|
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
# :dt - A DateTime containing the date when the results were
|
83
|
-
# bookmarked.
|
84
|
-
# :url - A String containing the URL for the the bookmark.
|
85
|
-
# :meta - A Boolean indicating whether or not to include a change
|
86
|
-
# detection signature.
|
96
|
+
# @example
|
97
|
+
# bookmarks = posts.get(tag: ['one', 'two', 'three'])
|
87
98
|
#
|
88
|
-
#
|
99
|
+
# @param [Hash] options
|
100
|
+
# options to filter the results by
|
101
|
+
# @option options [Array<String>] :tag
|
102
|
+
# up to three tags to filter by
|
103
|
+
# @option options [DateTime] :dt
|
104
|
+
# which day the results were bookmarked
|
105
|
+
# @option options [String] :url
|
106
|
+
# the URL for this bookmark
|
107
|
+
# @option options [Boolean] :meta
|
108
|
+
# if true, include the change detection signature in the results
|
89
109
|
#
|
90
|
-
#
|
91
|
-
# get(url: 'http://www.pinboard.in')
|
110
|
+
# @return [Array<Post>]
|
92
111
|
#
|
93
|
-
#
|
94
|
-
|
112
|
+
# @api public
|
113
|
+
#
|
114
|
+
# @see https://pinboard.in/api/#posts_get
|
115
|
+
def get(options = EMPTY_HASH)
|
95
116
|
parameters = Specification.new(
|
96
117
|
tag: Types::Tags,
|
97
118
|
dt: Types::DateTime,
|
@@ -101,19 +122,24 @@ module Thumbtack
|
|
101
122
|
posts_from @client.get('/posts/get', parameters)
|
102
123
|
end
|
103
124
|
|
104
|
-
#
|
125
|
+
# List the most recent bookmarks
|
126
|
+
#
|
127
|
+
# @example
|
128
|
+
# bookmarks = posts.recent(tag: ['one', 'two', 'three'], count: 25)
|
105
129
|
#
|
106
|
-
#
|
107
|
-
#
|
108
|
-
#
|
109
|
-
#
|
130
|
+
# @param [Hash] options
|
131
|
+
# options to filter the results by
|
132
|
+
# @option options [Array<String>] :tag
|
133
|
+
# up to three tags to filter by
|
134
|
+
# @option options [Integer] :count
|
135
|
+
# the number of results to return
|
110
136
|
#
|
111
|
-
#
|
137
|
+
# @return [Array<Post>]
|
112
138
|
#
|
113
|
-
#
|
139
|
+
# @api public
|
114
140
|
#
|
115
|
-
#
|
116
|
-
def recent(options =
|
141
|
+
# @see https://pinboard.in/api/#posts_recent
|
142
|
+
def recent(options = EMPTY_HASH)
|
117
143
|
parameters = Specification.new(
|
118
144
|
tag: Types::Tags,
|
119
145
|
count: Types::Integer
|
@@ -121,20 +147,32 @@ module Thumbtack
|
|
121
147
|
posts_from @client.get('/posts/recent', parameters)
|
122
148
|
end
|
123
149
|
|
124
|
-
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
130
|
-
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
#
|
134
|
-
#
|
135
|
-
#
|
136
|
-
#
|
137
|
-
|
150
|
+
# List all bookmarks
|
151
|
+
#
|
152
|
+
# @example
|
153
|
+
# posts.all(todt: yesterday, meta: true, tag: ['one', 'two', 'three'])
|
154
|
+
#
|
155
|
+
# @param [Hash] options
|
156
|
+
# options to filter the results by
|
157
|
+
# @option options [Array<String>] :tag
|
158
|
+
# up to three tags to filter by
|
159
|
+
# @option options [Array<String>] :start
|
160
|
+
# an offset value
|
161
|
+
# @option options [Array<String>] :results
|
162
|
+
# number of results to return
|
163
|
+
# @option options [DateTime] :fromdt
|
164
|
+
# limit results to those created after this time
|
165
|
+
# @option options [DateTime] :todt
|
166
|
+
# limit results to those created before this time
|
167
|
+
# @option options [Boolean] :meta
|
168
|
+
# if true, include the change detection signature in the results
|
169
|
+
#
|
170
|
+
# @return [Array<Post>]
|
171
|
+
#
|
172
|
+
# @api public
|
173
|
+
#
|
174
|
+
# @see https://pinboard.in/api/#posts_all
|
175
|
+
def all(options = EMPTY_HASH)
|
138
176
|
parameters = Specification.new(
|
139
177
|
tag: Types::Tags,
|
140
178
|
start: Types::Integer,
|
@@ -147,31 +185,49 @@ module Thumbtack
|
|
147
185
|
results.map { |post_hash| Post.from_hash(post_hash) }
|
148
186
|
end
|
149
187
|
|
150
|
-
#
|
188
|
+
# List popular and recommended tags for a URL
|
189
|
+
#
|
190
|
+
# @example
|
191
|
+
# suggestion = posts.suggest(url)
|
151
192
|
#
|
152
|
-
#
|
193
|
+
# @param [String] url
|
194
|
+
# URL to fetch suggested tags for
|
153
195
|
#
|
154
196
|
# Returns a Hash with two entries, :popular is a list of popular tags,
|
155
197
|
# :recommended is a list of recommended tags.
|
198
|
+
#
|
199
|
+
# @return [Array<Suggestion>]
|
200
|
+
#
|
201
|
+
# @api public
|
202
|
+
#
|
203
|
+
# @see https://pinboard.in/api/#posts_suggest
|
156
204
|
def suggest(url)
|
157
205
|
parameters = Specification.new(url: Types::URL).parameters(url: url)
|
158
|
-
|
159
|
-
{ popular: result.fetch('popular'),
|
160
|
-
recommended: result.fetch('recommended') }
|
206
|
+
Suggestion.from_array(@client.get('/posts/suggest', parameters))
|
161
207
|
end
|
162
208
|
|
163
|
-
#
|
209
|
+
# List dates with the number of bookmarks created on each
|
210
|
+
#
|
211
|
+
# @example
|
212
|
+
# dates = posts.dates(tag: ['one', 'two', 'three'])
|
213
|
+
#
|
214
|
+
# @param [Hash] options
|
215
|
+
# options to filter the results by
|
216
|
+
# @option options [Array<String>] :tag
|
217
|
+
# up to three tags to filter by
|
218
|
+
#
|
219
|
+
# @return [Hash{Date => Integer}]
|
220
|
+
# dates on which bookmarks were created associated with the number of
|
221
|
+
# bookmarks created on that date
|
164
222
|
#
|
165
|
-
#
|
166
|
-
# :tag - An Array containing a up to three tags to filter by.
|
223
|
+
# @api public
|
167
224
|
#
|
168
|
-
#
|
169
|
-
|
170
|
-
def dates(options = {})
|
225
|
+
# @see https://pinboard.in/api/#posts_dates
|
226
|
+
def dates(options = EMPTY_HASH)
|
171
227
|
parameters = Specification.new(tag: Types::Tags).parameters(options)
|
172
228
|
response = @client.get('/posts/dates', parameters)
|
173
229
|
Hash[
|
174
|
-
response.fetch('dates',
|
230
|
+
response.fetch('dates', EMPTY_HASH).map do |date, count|
|
175
231
|
[Types::Date.from_parameter(date), count.to_i]
|
176
232
|
end
|
177
233
|
]
|
@@ -180,7 +236,9 @@ module Thumbtack
|
|
180
236
|
private
|
181
237
|
|
182
238
|
def posts_from(response)
|
183
|
-
response.fetch('posts',
|
239
|
+
response.fetch('posts', EMPTY_ARRAY).map do |post_hash|
|
240
|
+
Post.from_hash(post_hash)
|
241
|
+
end
|
184
242
|
end
|
185
243
|
end
|
186
244
|
end
|
@@ -1,23 +1,27 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Thumbtack
|
4
|
-
#
|
5
|
-
#
|
4
|
+
# Validates and translates user-provided parameters to their Pinboard
|
5
|
+
# supported equivalents
|
6
|
+
#
|
7
|
+
# @api private
|
6
8
|
class Specification
|
7
|
-
|
8
|
-
# Create a new Specification.
|
9
|
+
# Initialize a Specification
|
9
10
|
#
|
10
|
-
#
|
11
|
+
# @param [Hash{Symbol => Type}] type_handlers
|
12
|
+
# a map of parameter names to their type handlers
|
11
13
|
def initialize(type_handlers)
|
12
14
|
@type_handlers = type_handlers
|
13
15
|
end
|
14
16
|
|
15
17
|
# Validate and translate user-provided parameters to their
|
16
|
-
# Pinboard-supported
|
18
|
+
# Pinboard-supported values
|
17
19
|
#
|
18
|
-
#
|
20
|
+
# @param [Hash{Symbol => Object}] arguments
|
21
|
+
# parameter names associated with their values
|
19
22
|
#
|
20
|
-
#
|
23
|
+
# @return [Hash{Symbol => Object}]
|
24
|
+
# parameter names associated with translations to their Pinboard values
|
21
25
|
def parameters(arguments)
|
22
26
|
Hash[
|
23
27
|
arguments.map do |name, value|
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
# Represents a suggestion
|
5
|
+
#
|
6
|
+
# @api public
|
7
|
+
class Suggestion
|
8
|
+
# The key associated with popular tags
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
POPULAR_KEY = 'popular'.freeze
|
12
|
+
|
13
|
+
# The key associated with suggested tags
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
RECOMMENDED_KEY = 'recommended'.freeze
|
17
|
+
|
18
|
+
# A list of popular tags for URL
|
19
|
+
#
|
20
|
+
# @return [Array<String>]
|
21
|
+
#
|
22
|
+
# @api public
|
23
|
+
attr_reader :popular
|
24
|
+
|
25
|
+
# A list of recommended tags for the URL
|
26
|
+
#
|
27
|
+
# @return [Array<String>]
|
28
|
+
#
|
29
|
+
# @api public
|
30
|
+
attr_reader :recommended
|
31
|
+
|
32
|
+
# Initialize a Suggestion
|
33
|
+
#
|
34
|
+
# @param [Hash] attrs
|
35
|
+
# Suggestion attributes
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
def initialize(attrs = EMPTY_HASH)
|
39
|
+
@popular = attrs.fetch(:popular)
|
40
|
+
@recommended = attrs.fetch(:recommended)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Creates a new Suggestions from an Array of Hashes
|
44
|
+
#
|
45
|
+
# @param [Array<Hash{String => Array<String>}>] array
|
46
|
+
# Suggestions attributes
|
47
|
+
#
|
48
|
+
# @return [Suggestion]
|
49
|
+
#
|
50
|
+
# @api private
|
51
|
+
# @see Client#get
|
52
|
+
def self.from_array(array)
|
53
|
+
popular = array.find { |hash| hash.key?(POPULAR_KEY) }
|
54
|
+
recommended = array.find { |hash| hash.key?(RECOMMENDED_KEY) }
|
55
|
+
new(popular: popular.fetch(POPULAR_KEY, EMPTY_ARRAY),
|
56
|
+
recommended: recommended.fetch(RECOMMENDED_KEY, EMPTY_ARRAY))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/thumbtack/tags.rb
CHANGED
@@ -1,38 +1,68 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Thumbtack
|
4
|
-
#
|
4
|
+
# Wraps API calls related to tags
|
5
5
|
class Tags
|
6
|
-
#
|
6
|
+
# Initialize a Tags
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# @param [Client] client
|
9
|
+
# client to communicate with the Pinboard API
|
10
|
+
#
|
11
|
+
# @api private
|
9
12
|
def initialize(client)
|
10
13
|
@client = client
|
11
14
|
end
|
12
15
|
|
13
|
-
#
|
16
|
+
# List tags with their counts
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# tag_counts = tags.get
|
20
|
+
#
|
21
|
+
# @return [Hash{String => Integer}]
|
22
|
+
# tags associated with the number of times they have been used
|
23
|
+
#
|
24
|
+
# @api public
|
25
|
+
#
|
26
|
+
# @see https://pinboard.in/api/#tags_get
|
14
27
|
def get
|
15
28
|
response = @client.get('/tags/get')
|
16
29
|
Hash[response.map { |tag, count| [tag, count.to_i] }]
|
17
30
|
end
|
18
31
|
|
19
|
-
#
|
32
|
+
# Delete a tag
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
# tags.delete(tag)
|
20
36
|
#
|
21
|
-
#
|
37
|
+
# @param [String] tag
|
38
|
+
# the tag to delete
|
22
39
|
#
|
23
|
-
#
|
40
|
+
# @return [self]
|
41
|
+
#
|
42
|
+
# @api public
|
43
|
+
#
|
44
|
+
# @see https://pinboard.in/api/#tags_delete
|
24
45
|
def delete(tag)
|
25
46
|
parameters = Specification.new(tag: Types::Tags).parameters(tag: tag)
|
26
47
|
@client.get('/tags/delete', parameters)
|
27
48
|
self
|
28
49
|
end
|
29
50
|
|
30
|
-
#
|
51
|
+
# Rename a tag
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
# tags.rename(old, new)
|
55
|
+
#
|
56
|
+
# @param [String] old
|
57
|
+
# the tag to be renamed
|
58
|
+
# @param [String] new
|
59
|
+
# the new name for the tag
|
60
|
+
#
|
61
|
+
# @return [self]
|
31
62
|
#
|
32
|
-
#
|
33
|
-
# new - A String containing the new name for the tag.
|
63
|
+
# @api public
|
34
64
|
#
|
35
|
-
#
|
65
|
+
# @see https://pinboard.in/api/#tags_rename
|
36
66
|
def rename(old, new)
|
37
67
|
parameters = Specification.new(
|
38
68
|
old: Types::Tags,
|