thumbtack 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/thumbtack/client.rb +70 -0
- data/lib/thumbtack/note.rb +35 -0
- data/lib/thumbtack/note_summary.rb +35 -0
- data/lib/thumbtack/notes.rb +26 -0
- data/lib/thumbtack/post.rb +37 -0
- data/lib/thumbtack/posts.rb +186 -0
- data/lib/thumbtack/specification.rb +31 -0
- data/lib/thumbtack/tags.rb +45 -0
- data/lib/thumbtack/types/boolean.rb +52 -0
- data/lib/thumbtack/types/date.rb +47 -0
- data/lib/thumbtack/types/date_time.rb +49 -0
- data/lib/thumbtack/types/identity.rb +26 -0
- data/lib/thumbtack/types/integer.rb +27 -0
- data/lib/thumbtack/types/md5.rb +30 -0
- data/lib/thumbtack/types/tags.rb +53 -0
- data/lib/thumbtack/types/text.rb +26 -0
- data/lib/thumbtack/types/title.rb +26 -0
- data/lib/thumbtack/types/url.rb +26 -0
- data/lib/thumbtack/types.rb +10 -0
- data/lib/thumbtack/user.rb +23 -0
- data/lib/thumbtack/version.rb +6 -0
- data/lib/thumbtack.rb +32 -0
- data/test/test_helper.rb +18 -0
- data/test/thumbtack/client_test.rb +35 -0
- data/test/thumbtack/note_summary_test.rb +24 -0
- data/test/thumbtack/note_test.rb +26 -0
- data/test/thumbtack/notes_test.rb +61 -0
- data/test/thumbtack/post_test.rb +30 -0
- data/test/thumbtack/posts_test.rb +178 -0
- data/test/thumbtack/specification_test.rb +15 -0
- data/test/thumbtack/tags_test.rb +56 -0
- data/test/thumbtack/types/boolean_test.rb +28 -0
- data/test/thumbtack/types/date_test.rb +27 -0
- data/test/thumbtack/types/date_time_test.rb +27 -0
- data/test/thumbtack/types/identity_test.rb +18 -0
- data/test/thumbtack/types/integer_test.rb +26 -0
- data/test/thumbtack/types/md5_test.rb +28 -0
- data/test/thumbtack/types/tags_test.rb +29 -0
- data/test/thumbtack/types/text_test.rb +22 -0
- data/test/thumbtack/types/title_test.rb +22 -0
- data/test/thumbtack/types/url_test.rb +23 -0
- data/test/thumbtack/user_test.rb +29 -0
- metadata +162 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3d86b3db897475f83812368d11f5179d8b098af6
|
4
|
+
data.tar.gz: d92ba1381ba92772a4b7610b70c3d53a839f0f1d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d9ad33c40ef19811c378c9bbc6f09e54151ecb5a8c657ad05f48916f0a1b4e87ce152a1508c51a6ae290257287c5a7d0cbd463fe68dae6296a0502e5cddc2ef8
|
7
|
+
data.tar.gz: 32bd3769072670a57804a306fc46f78db993dbc6e91bd395a7433491c74381a13176f900429faab5f82b45f2b5e3a862e8e286c7636894631e9c949e4c3026e1
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
# Public: Wraps each interaction with the Pinboard API.
|
5
|
+
class Client
|
6
|
+
# Public: String of base Pinboard API URL.
|
7
|
+
BASE_URL = 'https://api.pinboard.in/v1'.freeze
|
8
|
+
|
9
|
+
# Public: Returns the String username being used by the client.
|
10
|
+
attr_reader :username
|
11
|
+
|
12
|
+
# Public: Returns the String API token being used by the client.
|
13
|
+
attr_reader :token
|
14
|
+
|
15
|
+
# Public: Creates a new client.
|
16
|
+
#
|
17
|
+
# username - A String naming the user account to authenticate with.
|
18
|
+
# token - A String of the API token for the user account. Can be found on
|
19
|
+
# the user's settings page.
|
20
|
+
def initialize(username, token)
|
21
|
+
@username, @token = username, token
|
22
|
+
end
|
23
|
+
|
24
|
+
# Internal: Request JSON from the Pinboard API.
|
25
|
+
#
|
26
|
+
# path - A String of the path to fetch from. The is relative from the root
|
27
|
+
# Pinboard API URL.
|
28
|
+
# params - A Hash of query parameters to append to the URL for the fetch
|
29
|
+
# (default: {}).
|
30
|
+
#
|
31
|
+
# Examples
|
32
|
+
#
|
33
|
+
# get('/posts/update')
|
34
|
+
# # => {'update_time' => '2014-06-24T15:39:46Z'}
|
35
|
+
#
|
36
|
+
# get('/posts/suggest', url: 'http://theinternate.com/')
|
37
|
+
# # => [{'popular' => []}, {'recommended' => []}]
|
38
|
+
#
|
39
|
+
# Returns a parsed JSON response from Pinboard's API.
|
40
|
+
def get(path, params = {})
|
41
|
+
uri = URI("#{BASE_URL}#{path}")
|
42
|
+
|
43
|
+
base_params = { auth_token: "#{@username}:#{@token}", format: 'json' }
|
44
|
+
uri.query = URI.encode_www_form(params.merge(base_params))
|
45
|
+
|
46
|
+
response = Net::HTTP.get_response(uri)
|
47
|
+
JSON.parse(response.body)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Public: Access posts-related API calls.
|
51
|
+
def posts
|
52
|
+
Posts.new(self)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Public: Access tags-related API calls.
|
56
|
+
def tags
|
57
|
+
Tags.new(self)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Public: Access user-related API calls.
|
61
|
+
def user
|
62
|
+
User.new(self)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Public: Access notes-related API calls.
|
66
|
+
def notes
|
67
|
+
Notes.new(self)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
# Public: Represents a note.
|
5
|
+
class Note
|
6
|
+
# Private: The attributes for a Note.
|
7
|
+
ATTRIBUTES = [
|
8
|
+
:id,
|
9
|
+
:title,
|
10
|
+
:hash,
|
11
|
+
:created_at,
|
12
|
+
:updated_at,
|
13
|
+
:text,
|
14
|
+
:length
|
15
|
+
].freeze
|
16
|
+
|
17
|
+
attr_reader(*ATTRIBUTES)
|
18
|
+
|
19
|
+
# Internal: Creates a new Note from a Hash, usually a Client#get response.
|
20
|
+
#
|
21
|
+
# hash - A Hash of attributes of the note.
|
22
|
+
def self.from_hash(hash)
|
23
|
+
new(Hash[hash.map { |key, value| [key.to_sym, value] }])
|
24
|
+
end
|
25
|
+
|
26
|
+
# Internal: Initialize a Note.
|
27
|
+
#
|
28
|
+
# attrs - A Hash of attributes of the Note.
|
29
|
+
def initialize(attrs = {})
|
30
|
+
ATTRIBUTES.each do |attribute|
|
31
|
+
instance_variable_set "@#{attribute}", attrs.fetch(attribute)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
# Public: Represents a note summary as returned from Notes#list.
|
5
|
+
class NoteSummary
|
6
|
+
# Private: The attributes for a NoteSummary.
|
7
|
+
ATTRIBUTES = [
|
8
|
+
:id,
|
9
|
+
:title,
|
10
|
+
:hash,
|
11
|
+
:created_at,
|
12
|
+
:updated_at,
|
13
|
+
:length
|
14
|
+
].freeze
|
15
|
+
|
16
|
+
attr_reader(*ATTRIBUTES)
|
17
|
+
|
18
|
+
# Internal: Creates a new NoteSummary from a Hash, usually a Client#get
|
19
|
+
# response.
|
20
|
+
#
|
21
|
+
# hash - A Hash of attributes of the note.
|
22
|
+
def self.from_hash(hash)
|
23
|
+
new(Hash[hash.map { |key, value| [key.to_sym, value] }])
|
24
|
+
end
|
25
|
+
|
26
|
+
# Internal: Initialize a NoteSummary.
|
27
|
+
#
|
28
|
+
# attrs - A Hash of attributes of the NoteSummary.
|
29
|
+
def initialize(attrs = {})
|
30
|
+
ATTRIBUTES.each do |attribute|
|
31
|
+
instance_variable_set "@#{attribute}", attrs.fetch(attribute)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
# Internal: Wraps API calls related to notes.
|
5
|
+
class Notes
|
6
|
+
# Internal: Creates a new Notes.
|
7
|
+
#
|
8
|
+
# client - a Thumbtack::Client to communicate with the Pinboard API.
|
9
|
+
def initialize(client)
|
10
|
+
@client = client
|
11
|
+
end
|
12
|
+
|
13
|
+
# Public: Returns a list of summaries of the user's notes.
|
14
|
+
def list
|
15
|
+
response = @client.get('/notes/list')
|
16
|
+
response.fetch('notes', []).map do |note_hash|
|
17
|
+
NoteSummary.from_hash(note_hash)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Public: Return an individual note.
|
22
|
+
def get(id)
|
23
|
+
Note.from_hash @client.get("/notes/#{id}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
# Public: Represents a bookmark.
|
5
|
+
class Post
|
6
|
+
# Private: The attributes for a Post.
|
7
|
+
ATTRIBUTES = [
|
8
|
+
:href,
|
9
|
+
:description,
|
10
|
+
:extended,
|
11
|
+
:meta,
|
12
|
+
:hash,
|
13
|
+
:time,
|
14
|
+
:shared,
|
15
|
+
:toread,
|
16
|
+
:tags
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
attr_reader(*ATTRIBUTES)
|
20
|
+
|
21
|
+
# Internal: Creates a new post from a Hash, usually a Client#get response.
|
22
|
+
#
|
23
|
+
# hash - A Hash of attributes of the Post.
|
24
|
+
def self.from_hash(hash)
|
25
|
+
new(Hash[hash.map { |key, value| [key.to_sym, value] }])
|
26
|
+
end
|
27
|
+
|
28
|
+
# Internal: Initialize a Post.
|
29
|
+
#
|
30
|
+
# attrs - A Hash of attributes of the Post.
|
31
|
+
def initialize(attrs = {})
|
32
|
+
ATTRIBUTES.each do |attribute|
|
33
|
+
instance_variable_set "@#{attribute}", attrs.fetch(attribute)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
# Internal: Wraps API calls related to posts.
|
5
|
+
class Posts
|
6
|
+
# Internal: Initialize a Posts.
|
7
|
+
#
|
8
|
+
# client - A Thumbtack::Client to communicate with the Pinboard API.
|
9
|
+
def initialize(client)
|
10
|
+
@client = client
|
11
|
+
end
|
12
|
+
|
13
|
+
# Public: The most recent time a bookmark was added, updated, or deleted.
|
14
|
+
#
|
15
|
+
# Examples
|
16
|
+
#
|
17
|
+
# update
|
18
|
+
# # => '2014-06-26T19:01:33Z'
|
19
|
+
#
|
20
|
+
# Returns a DateTime in UTC.
|
21
|
+
def update
|
22
|
+
response = @client.get('/posts/update')
|
23
|
+
Types::DateTime.from_parameter response.fetch('update_time')
|
24
|
+
end
|
25
|
+
|
26
|
+
# Public: Add a bookmark.
|
27
|
+
#
|
28
|
+
# url - A String containing the URL to be bookmarked.
|
29
|
+
# description - A String containing the title of the bookmark.
|
30
|
+
# options - The Hash options to be passed as arguments.
|
31
|
+
# :extended - A String containing a description of the item.
|
32
|
+
# :tags - An Array containing up to 100 tags.
|
33
|
+
# :dt - A DateTime containing the creation time for this
|
34
|
+
# bookmark.
|
35
|
+
# :replace - A Boolean containing whether or not to replace any
|
36
|
+
# existing bookmark with this URL.
|
37
|
+
# :shared - A Boolean containing whether or not to make the
|
38
|
+
# bookmark public.
|
39
|
+
# :toread - A Boolean containing whether or not to mark the
|
40
|
+
# bookmark as unread.
|
41
|
+
#
|
42
|
+
# Examples
|
43
|
+
#
|
44
|
+
# add('http://theinternate.com', 'The Internate')
|
45
|
+
# add('http://theinternate.com', 'The Internate', tags: ['best', 'ruby'])
|
46
|
+
#
|
47
|
+
# Returns the Posts instance.
|
48
|
+
def add(url, description, options = {})
|
49
|
+
parameters = Specification.new(
|
50
|
+
url: Types::URL,
|
51
|
+
description: Types::Text,
|
52
|
+
extended: Types::Text,
|
53
|
+
tags: Types::Tags,
|
54
|
+
dt: Types::DateTime,
|
55
|
+
replace: Types::Boolean,
|
56
|
+
shared: Types::Boolean,
|
57
|
+
toread: Types::Boolean
|
58
|
+
).parameters({ url: url, description: description }.merge(options))
|
59
|
+
@client.get('/posts/add', parameters)
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
63
|
+
# Public: Delete a bookmark.
|
64
|
+
#
|
65
|
+
# url - A String containing the URL of the bookmark to delete.
|
66
|
+
#
|
67
|
+
# Examples
|
68
|
+
#
|
69
|
+
# delete('http://delicio.us')
|
70
|
+
#
|
71
|
+
# Returns the Posts instance
|
72
|
+
def delete(url)
|
73
|
+
parameters = Specification.new(url: Types::URL).parameters(url: url)
|
74
|
+
@client.get('/posts/delete', parameters)
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
# Public: Return one or more posts matching the arguments.
|
79
|
+
#
|
80
|
+
# options - The Hash options to be passed as arguments.
|
81
|
+
# :tag - An Array containing a up to three tags to filter by.
|
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.
|
87
|
+
#
|
88
|
+
# Examples
|
89
|
+
#
|
90
|
+
# get(tag: 'webdev', meta: 'yes')
|
91
|
+
# get(url: 'http://www.pinboard.in')
|
92
|
+
#
|
93
|
+
# Returns a list of Post instances.
|
94
|
+
def get(options = {})
|
95
|
+
parameters = Specification.new(
|
96
|
+
tag: Types::Tags,
|
97
|
+
dt: Types::DateTime,
|
98
|
+
url: Types::URL,
|
99
|
+
meta: Types::Boolean
|
100
|
+
).parameters(options)
|
101
|
+
posts_from @client.get('/posts/get', parameters)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Public: Return a list of the most recent posts.
|
105
|
+
#
|
106
|
+
# options - The Hash options to be passed as arguments.
|
107
|
+
# :tag - An Array containing a up to three tags to filter by.
|
108
|
+
# :count - An Integer of the number of results to return. Default
|
109
|
+
# is 15, maximum is 100.
|
110
|
+
#
|
111
|
+
# Examples
|
112
|
+
#
|
113
|
+
# recent(tag: 'webdev', count: 25)
|
114
|
+
#
|
115
|
+
# Returns a list of Post instances.
|
116
|
+
def recent(options = {})
|
117
|
+
parameters = Specification.new(
|
118
|
+
tag: Types::Tags,
|
119
|
+
count: Types::Integer
|
120
|
+
).parameters(options)
|
121
|
+
posts_from @client.get('/posts/recent', parameters)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Public: Return all posts in the account.
|
125
|
+
#
|
126
|
+
# options - The Hash options to be passed as arguments.
|
127
|
+
# :tag - A String containing a list of up to three tags to
|
128
|
+
# filter by.
|
129
|
+
# :start - An Integer offset value. Default is 0.
|
130
|
+
# :results - An Integer of the number of results to return.
|
131
|
+
# :fromdt - Filter results to posts created after this DateTime.
|
132
|
+
# :todt - Filter results to posts created before this DateTime.
|
133
|
+
# :meta - A Boolean containing whether or not to include a
|
134
|
+
# change detection signature.
|
135
|
+
#
|
136
|
+
# Returns a list of Posts instances
|
137
|
+
def all(options = {})
|
138
|
+
parameters = Specification.new(
|
139
|
+
tag: Types::Tags,
|
140
|
+
start: Types::Integer,
|
141
|
+
results: Types::Integer,
|
142
|
+
fromdt: Types::DateTime,
|
143
|
+
todt: Types::DateTime,
|
144
|
+
meta: Types::Boolean
|
145
|
+
).parameters(options)
|
146
|
+
results = @client.get('/posts/all', parameters)
|
147
|
+
results.map { |post_hash| Post.from_hash(post_hash) }
|
148
|
+
end
|
149
|
+
|
150
|
+
# Public: Return a list of popular and recommended tags for a URL.
|
151
|
+
#
|
152
|
+
# url - A String containing a URL to fetch suggested tags for.
|
153
|
+
#
|
154
|
+
# Returns a Hash with two entries, :popular is a list of popular tags,
|
155
|
+
# :recommended is a list of recommended tags.
|
156
|
+
def suggest(url)
|
157
|
+
parameters = Specification.new(url: Types::URL).parameters(url: url)
|
158
|
+
result = @client.get('/posts/suggest', parameters)
|
159
|
+
{ popular: result.fetch('popular'),
|
160
|
+
recommended: result.fetch('recommended') }
|
161
|
+
end
|
162
|
+
|
163
|
+
# Public: Return a list dates with the count of posts made at each date.
|
164
|
+
#
|
165
|
+
# options - The Hash options to be passed as arguments
|
166
|
+
# :tag - An Array containing a up to three tags to filter by.
|
167
|
+
#
|
168
|
+
# Returns a Hash of Strings => Integer entries. The Strings contain a date
|
169
|
+
# and the Integer is the count of posts made on that date.
|
170
|
+
def dates(options = {})
|
171
|
+
parameters = Specification.new(tag: Types::Tags).parameters(options)
|
172
|
+
response = @client.get('/posts/dates', parameters)
|
173
|
+
Hash[
|
174
|
+
response.fetch('dates', {}).map do |date, count|
|
175
|
+
[Types::Date.from_parameter(date), count.to_i]
|
176
|
+
end
|
177
|
+
]
|
178
|
+
end
|
179
|
+
|
180
|
+
private
|
181
|
+
|
182
|
+
def posts_from(response)
|
183
|
+
response.fetch('posts', []).map { |post_hash| Post.from_hash(post_hash) }
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
# Internal: Validates and translates user-provided parameters to their
|
5
|
+
# Pinboard-supported equivalents
|
6
|
+
class Specification
|
7
|
+
|
8
|
+
# Create a new Specification.
|
9
|
+
#
|
10
|
+
# type_handlers - A Hash mapping parameter names to their type handlers.
|
11
|
+
def initialize(type_handlers)
|
12
|
+
@type_handlers = type_handlers
|
13
|
+
end
|
14
|
+
|
15
|
+
# Validate and translate user-provided parameters to their
|
16
|
+
# Pinboard-supported equivalents.
|
17
|
+
#
|
18
|
+
# arguments - A Hash mapping parameter names to their user-provided values.
|
19
|
+
#
|
20
|
+
# Returns the parameters translated to their Pinboard equivalents.
|
21
|
+
def parameters(arguments)
|
22
|
+
Hash[
|
23
|
+
arguments.map do |name, value|
|
24
|
+
type_handler = @type_handlers.fetch(name)
|
25
|
+
type_handler.validate(value)
|
26
|
+
[name, type_handler.to_parameter(value)]
|
27
|
+
end
|
28
|
+
]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
# Internal: Wraps API calls related to tags.
|
5
|
+
class Tags
|
6
|
+
# Internal: Creates a new Tags.
|
7
|
+
#
|
8
|
+
# client - a Thumbtack::Client to communicate with the Pinboard API.
|
9
|
+
def initialize(client)
|
10
|
+
@client = client
|
11
|
+
end
|
12
|
+
|
13
|
+
# Public: Returns a list of the user's tags with their counts.
|
14
|
+
def get
|
15
|
+
response = @client.get('/tags/get')
|
16
|
+
Hash[response.map { |tag, count| [tag, count.to_i] }]
|
17
|
+
end
|
18
|
+
|
19
|
+
# Public: Delete a tag.
|
20
|
+
#
|
21
|
+
# tag - A String containing the tag to delete.
|
22
|
+
#
|
23
|
+
# Returns the Tags instance.
|
24
|
+
def delete(tag)
|
25
|
+
parameters = Specification.new(tag: Types::Tags).parameters(tag: tag)
|
26
|
+
@client.get('/tags/delete', parameters)
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
# Public: Rename a tag.
|
31
|
+
#
|
32
|
+
# old - A String containing the tag to be renamed.
|
33
|
+
# new - A String containing the new name for the tag.
|
34
|
+
#
|
35
|
+
# Returns the Tags instance.
|
36
|
+
def rename(old, new)
|
37
|
+
parameters = Specification.new(
|
38
|
+
old: Types::Tags,
|
39
|
+
new: Types::Tags
|
40
|
+
).parameters(old: old, new: new)
|
41
|
+
@client.get('/tags/rename', parameters)
|
42
|
+
self
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
module Types
|
5
|
+
# Internal: Handles conversion and validation of Boolean types to the 'yes'
|
6
|
+
# and 'no' parameters supported by the Pinboard API.
|
7
|
+
class Boolean
|
8
|
+
# Validate something is a Boolean parameter.
|
9
|
+
#
|
10
|
+
# value - A Boolean to validate.
|
11
|
+
#
|
12
|
+
# Returns nothing.
|
13
|
+
# Raises Types::ValidationError if the value is not true or false
|
14
|
+
def self.validate(value)
|
15
|
+
case value
|
16
|
+
when TrueClass, FalseClass
|
17
|
+
self
|
18
|
+
else
|
19
|
+
fail ValidationError, "#{value} must be true or false"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Convert a Boolean value to a parameter acceptable to the Pinboard API.
|
24
|
+
#
|
25
|
+
# value - A Boolean to convert.
|
26
|
+
#
|
27
|
+
# Returns 'yes' or 'no'
|
28
|
+
def self.to_parameter(value)
|
29
|
+
case value
|
30
|
+
when TrueClass
|
31
|
+
'yes'
|
32
|
+
when FalseClass
|
33
|
+
'no'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Convert a parameter from the Pinboard API to a Ruby Boolean.
|
38
|
+
#
|
39
|
+
# parameter - A String containing 'yes' or 'no'.
|
40
|
+
#
|
41
|
+
# Returns true or false.
|
42
|
+
def self.from_parameter(parameter)
|
43
|
+
case parameter
|
44
|
+
when 'yes'
|
45
|
+
true
|
46
|
+
when 'no'
|
47
|
+
false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
module Types
|
5
|
+
# Internal: Handles conversion and validation of Date types to the String
|
6
|
+
# parameters supported by the Pinboard API.
|
7
|
+
class Date
|
8
|
+
# The earliest allowable date
|
9
|
+
EARLIEST = ::Date.new(1, 1, 1)
|
10
|
+
# The latest allowable date
|
11
|
+
LATEST = ::Date.new(2100, 1, 1)
|
12
|
+
|
13
|
+
# Validate a Date.
|
14
|
+
#
|
15
|
+
# value - The Date to validate.
|
16
|
+
#
|
17
|
+
# Returns nothing.
|
18
|
+
# Raises Types::ValidationError if the date is not between 0001-01-01 and
|
19
|
+
# 2100-01-01.
|
20
|
+
def self.validate(value)
|
21
|
+
unless value > EARLIEST && value < LATEST
|
22
|
+
fail ValidationError,
|
23
|
+
"#{value} must be between 0001-01-01 and 2100-01-01"
|
24
|
+
end
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
# Convert a Date value to a parameter acceptable to the Pinboard API.
|
29
|
+
#
|
30
|
+
# value - The Date to convert.
|
31
|
+
#
|
32
|
+
# Returns a String containing the date with format yyyy-mm-dd.
|
33
|
+
def self.to_parameter(value)
|
34
|
+
value.xmlschema
|
35
|
+
end
|
36
|
+
|
37
|
+
# Convert a parameter from the Pinboard API to a Ruby Date.
|
38
|
+
#
|
39
|
+
# parameter - A String of the date formatted yyyy-mm-dd.
|
40
|
+
#
|
41
|
+
# Returns a Date.
|
42
|
+
def self.from_parameter(parameter)
|
43
|
+
::Date.xmlschema(parameter)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
module Types
|
5
|
+
# Handles conversion and validation of DateTime types to the String
|
6
|
+
# parameters supported by the Pinboard API.
|
7
|
+
class DateTime
|
8
|
+
# The earliest allowable time
|
9
|
+
EARLIEST = ::DateTime.new(1, 1, 1)
|
10
|
+
# The latest allowable time
|
11
|
+
LATEST = ::DateTime.new(2100, 1, 1)
|
12
|
+
# The date format of the Pinboard API
|
13
|
+
FORMAT = '%Y-%m-%dT%H:%M:%SZ'.freeze
|
14
|
+
|
15
|
+
# Validate something is a valid DateTime parameter.
|
16
|
+
#
|
17
|
+
# value - The DateTime to validate.
|
18
|
+
#
|
19
|
+
# Returns nothing.
|
20
|
+
# Raises Types::ValidationError if the time is not between
|
21
|
+
# 0001-01-01 00:00:00 and 2100-01-01 00:00:00.
|
22
|
+
def self.validate(value)
|
23
|
+
unless value > EARLIEST && value < LATEST
|
24
|
+
fail ValidationError,
|
25
|
+
"#{value} must be between 0001-01-01 and 2100-01-01"
|
26
|
+
end
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
# Convert a DateTime value to a parameter acceptable to the Pinboard API.
|
31
|
+
#
|
32
|
+
# value - The DateTime to convert.
|
33
|
+
#
|
34
|
+
# Returns a String containing the date with format yyyy-mm-ddTHH:MM:SSZ.
|
35
|
+
def self.to_parameter(value)
|
36
|
+
value.strftime(FORMAT)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Convert a parameter from the Pinboard API to a Ruby DateTime.
|
40
|
+
#
|
41
|
+
# parameter - A String of the date formatted yyyy-mm-ddTHH:MM:SSZ.
|
42
|
+
#
|
43
|
+
# Returns a DateTime.
|
44
|
+
def self.from_parameter(parameter)
|
45
|
+
::DateTime.strptime(parameter)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
module Types
|
5
|
+
# Internal: An abstract type handler
|
6
|
+
class Identity
|
7
|
+
|
8
|
+
# Any value passed is valid.
|
9
|
+
#
|
10
|
+
# Returns nothing.
|
11
|
+
def self.validate(*)
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
# Return any value passed to this without conversion.
|
16
|
+
def self.to_parameter(value)
|
17
|
+
value
|
18
|
+
end
|
19
|
+
|
20
|
+
# Return any value passed to this without conversion.
|
21
|
+
def self.from_parameter(parameter)
|
22
|
+
parameter
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
module Types
|
5
|
+
# Internal: Handles validation of Integer types as the values supported by
|
6
|
+
# the Pinboard API.
|
7
|
+
class Integer < Identity
|
8
|
+
# The minimum allowable integer.
|
9
|
+
MIN = 0
|
10
|
+
# The maximum allowable integer.
|
11
|
+
MAX = 2**32
|
12
|
+
|
13
|
+
# Validate something is a valid integer parameter.
|
14
|
+
#
|
15
|
+
# value - An integer to validate.
|
16
|
+
#
|
17
|
+
# Returns nothing.
|
18
|
+
# Raises Types::ValidationError if the value is not between 0 and 2^32.
|
19
|
+
def self.validate(value)
|
20
|
+
unless value >= MIN && value <= MAX
|
21
|
+
fail ValidationError, "#{value} must be in range 0..2^32"
|
22
|
+
end
|
23
|
+
self
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|