thumbtack 0.0.1
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.
- 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
|