thumbtack 0.0.2 → 0.0.3
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 +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/types.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Thumbtack
|
4
|
-
# Handlers for each of the data types in the Pinboard API
|
5
|
-
#
|
4
|
+
# Handlers for each of the data types in the Pinboard API
|
5
|
+
#
|
6
|
+
# @see https://pinboard.in/api/#data
|
6
7
|
module Types
|
7
|
-
#
|
8
|
+
# Raised when given an argument that does not satisfy the type constraints
|
8
9
|
class ValidationError < StandardError; end
|
9
10
|
end
|
10
11
|
end
|
@@ -2,15 +2,20 @@
|
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
5
|
-
#
|
6
|
-
# and 'no' parameters supported by
|
5
|
+
# Handles conversion and validation of Booleans to the 'yes'
|
6
|
+
# and 'no' parameters supported by Pinboard
|
7
|
+
#
|
8
|
+
# @api private
|
7
9
|
class Boolean
|
8
|
-
# Validate
|
10
|
+
# Validate a value is a boolean parameter
|
9
11
|
#
|
10
|
-
#
|
12
|
+
# @param [Boolean] value
|
13
|
+
# the value to validate
|
11
14
|
#
|
12
|
-
#
|
13
|
-
#
|
15
|
+
# @return [undefined]
|
16
|
+
#
|
17
|
+
# @raise [Types::ValidationError]
|
18
|
+
# if the value is not true or false
|
14
19
|
def self.validate(value)
|
15
20
|
case value
|
16
21
|
when TrueClass, FalseClass
|
@@ -20,11 +25,13 @@ module Thumbtack
|
|
20
25
|
end
|
21
26
|
end
|
22
27
|
|
23
|
-
# Convert a
|
28
|
+
# Convert a boolean value to a parameter acceptable to Pinboard
|
24
29
|
#
|
25
|
-
#
|
30
|
+
# @param [Boolean] value
|
31
|
+
# the value to convert
|
26
32
|
#
|
27
|
-
#
|
33
|
+
# @return [String]
|
34
|
+
# 'yes' if value is true, 'no' otherwise
|
28
35
|
def self.to_parameter(value)
|
29
36
|
case value
|
30
37
|
when TrueClass
|
@@ -34,11 +41,12 @@ module Thumbtack
|
|
34
41
|
end
|
35
42
|
end
|
36
43
|
|
37
|
-
# Convert a parameter from
|
44
|
+
# Convert a parameter from Pinboard to a boolean value
|
38
45
|
#
|
39
|
-
#
|
46
|
+
# @param [String] parameter
|
47
|
+
# Either 'yes' or 'no'
|
40
48
|
#
|
41
|
-
#
|
49
|
+
# @return [Boolean]
|
42
50
|
def self.from_parameter(parameter)
|
43
51
|
case parameter
|
44
52
|
when 'yes'
|
data/lib/thumbtack/types/date.rb
CHANGED
@@ -2,21 +2,25 @@
|
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
5
|
-
#
|
6
|
-
#
|
5
|
+
# Handles conversion and validation of Dates to parameters supported by
|
6
|
+
# Pinboard
|
7
|
+
#
|
8
|
+
# @api private
|
7
9
|
class Date
|
8
10
|
# The earliest allowable date
|
9
11
|
EARLIEST = ::Date.new(1, 1, 1)
|
10
12
|
# The latest allowable date
|
11
13
|
LATEST = ::Date.new(2100, 1, 1)
|
12
14
|
|
13
|
-
# Validate a
|
15
|
+
# Validate a date
|
14
16
|
#
|
15
|
-
#
|
17
|
+
# @param [Date] value
|
18
|
+
# the date to validate
|
16
19
|
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
+
# @return [undefined]
|
21
|
+
#
|
22
|
+
# @raise [Types::ValidationError]
|
23
|
+
# if the date is not between 0001-01-01 and 2100-01-01
|
20
24
|
def self.validate(value)
|
21
25
|
unless value > EARLIEST && value < LATEST
|
22
26
|
fail ValidationError,
|
@@ -25,20 +29,23 @@ module Thumbtack
|
|
25
29
|
self
|
26
30
|
end
|
27
31
|
|
28
|
-
# Convert a
|
32
|
+
# Convert a date to a parameter acceptable to Pinboard
|
29
33
|
#
|
30
|
-
#
|
34
|
+
# @param [Date] value
|
35
|
+
# the date to convert
|
31
36
|
#
|
32
|
-
#
|
37
|
+
# @return [String]
|
38
|
+
# the date with format yyyy-mm-dd
|
33
39
|
def self.to_parameter(value)
|
34
40
|
value.xmlschema
|
35
41
|
end
|
36
42
|
|
37
|
-
# Convert a parameter from
|
43
|
+
# Convert a parameter from Pinboard to a date
|
38
44
|
#
|
39
|
-
#
|
45
|
+
# @param [String] parameter
|
46
|
+
# the date with format yyyy-mm-dd
|
40
47
|
#
|
41
|
-
#
|
48
|
+
# @return [Date]
|
42
49
|
def self.from_parameter(parameter)
|
43
50
|
::Date.xmlschema(parameter)
|
44
51
|
end
|
@@ -2,23 +2,27 @@
|
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
5
|
-
# Handles conversion and validation of
|
6
|
-
#
|
5
|
+
# Handles conversion and validation of DateTimes to parameters supported by
|
6
|
+
# Pinboard
|
7
|
+
#
|
8
|
+
# @api private
|
7
9
|
class DateTime
|
8
10
|
# The earliest allowable time
|
9
11
|
EARLIEST = ::DateTime.new(1, 1, 1)
|
10
12
|
# The latest allowable time
|
11
13
|
LATEST = ::DateTime.new(2100, 1, 1)
|
12
|
-
#
|
14
|
+
# Pinboard's date format
|
13
15
|
FORMAT = '%Y-%m-%dT%H:%M:%SZ'.freeze
|
14
16
|
|
15
|
-
# Validate
|
17
|
+
# Validate a time
|
16
18
|
#
|
17
|
-
#
|
19
|
+
# @param [DateTime] value
|
20
|
+
# The time to validate
|
18
21
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
+
# @return [undefined]
|
23
|
+
#
|
24
|
+
# @raise [Types::ValidationError]
|
25
|
+
# if the time is not between 0001-01-01 00:00:00 and 2100-01-01 00:00:00
|
22
26
|
def self.validate(value)
|
23
27
|
unless value > EARLIEST && value < LATEST
|
24
28
|
fail ValidationError,
|
@@ -27,20 +31,23 @@ module Thumbtack
|
|
27
31
|
self
|
28
32
|
end
|
29
33
|
|
30
|
-
# Convert a
|
34
|
+
# Convert a time to a parameter acceptable to Pinboard
|
31
35
|
#
|
32
|
-
#
|
36
|
+
# @param [DateTime] value
|
37
|
+
# the time to convert
|
33
38
|
#
|
34
|
-
#
|
39
|
+
# @return [String]
|
40
|
+
# the time formatted yyyy-mm-ddTHH:MM:SSZ.
|
35
41
|
def self.to_parameter(value)
|
36
42
|
value.strftime(FORMAT)
|
37
43
|
end
|
38
44
|
|
39
|
-
# Convert a parameter from
|
45
|
+
# Convert a parameter from Pinboard to a datetime value
|
40
46
|
#
|
41
|
-
#
|
47
|
+
# @param [String] parameter
|
48
|
+
# the time formatted yyyy-mm-ddTHH:MM:SSZ
|
42
49
|
#
|
43
|
-
#
|
50
|
+
# @return [DateTime]
|
44
51
|
def self.from_parameter(parameter)
|
45
52
|
::DateTime.strptime(parameter)
|
46
53
|
end
|
@@ -2,22 +2,27 @@
|
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
5
|
-
#
|
5
|
+
# An abstract type handler with no conversion or validation
|
6
|
+
#
|
7
|
+
# @api private
|
6
8
|
class Identity
|
7
|
-
|
8
|
-
# Any value passed is valid.
|
9
|
+
# Any value passed is valid
|
9
10
|
#
|
10
|
-
#
|
11
|
+
# @return [undefined]
|
11
12
|
def self.validate(*)
|
12
13
|
self
|
13
14
|
end
|
14
15
|
|
15
|
-
#
|
16
|
+
# Value is returned unconverted
|
17
|
+
#
|
18
|
+
# @return [value]
|
16
19
|
def self.to_parameter(value)
|
17
20
|
value
|
18
21
|
end
|
19
22
|
|
20
|
-
#
|
23
|
+
# Parameter is returned unconverted
|
24
|
+
#
|
25
|
+
# @return [parameter]
|
21
26
|
def self.from_parameter(parameter)
|
22
27
|
parameter
|
23
28
|
end
|
@@ -2,20 +2,24 @@
|
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
5
|
-
#
|
6
|
-
#
|
5
|
+
# Handles validation of Integer types as the values supported by Pinboard
|
6
|
+
#
|
7
|
+
# @api private
|
7
8
|
class Integer < Identity
|
8
|
-
# The minimum allowable integer
|
9
|
+
# The minimum allowable integer
|
9
10
|
MIN = 0
|
10
|
-
# The maximum allowable integer
|
11
|
+
# The maximum allowable integer
|
11
12
|
MAX = 2**32
|
12
13
|
|
13
|
-
# Validate something is a valid integer parameter
|
14
|
+
# Validate something is a valid integer parameter
|
14
15
|
#
|
15
|
-
#
|
16
|
+
# @param [Integer] value
|
17
|
+
# the integer to validate
|
16
18
|
#
|
17
|
-
#
|
18
|
-
#
|
19
|
+
# @return [undefined]
|
20
|
+
#
|
21
|
+
# @raise [Types::ValidationError]
|
22
|
+
# if the value is not between 0 and 2^32
|
19
23
|
def self.validate(value)
|
20
24
|
unless value >= MIN && value <= MAX
|
21
25
|
fail ValidationError, "#{value} must be in range 0..2^32"
|
data/lib/thumbtack/types/md5.rb
CHANGED
@@ -2,21 +2,24 @@
|
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
5
|
-
#
|
6
|
-
#
|
5
|
+
# Handles validation of MD5 types as the values supported by Pinboard
|
6
|
+
#
|
7
|
+
# @api private
|
7
8
|
class MD5 < Identity
|
8
|
-
# The length of an MD5 value
|
9
|
+
# The length of an MD5 value
|
9
10
|
LENGTH = 32
|
10
|
-
# The valid characters in an MD5 value
|
11
|
+
# The valid characters in an MD5 value
|
11
12
|
CHARACTERS = '0123456789abcdf'.freeze
|
12
13
|
|
13
|
-
# Validate
|
14
|
+
# Validate a string is a valid MD5 parameter
|
14
15
|
#
|
15
|
-
#
|
16
|
+
# @param [String] value
|
17
|
+
# the MD5 to validate
|
16
18
|
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
19
|
+
# @return [undefined]
|
20
|
+
#
|
21
|
+
# @raise [Types::ValidationError]
|
22
|
+
# if the value is not a 32 character hexadecimal MD5 hash
|
20
23
|
def self.validate(value)
|
21
24
|
unless value.length == 32 &&
|
22
25
|
value.each_char.all? { |char| CHARACTERS.include?(char) }
|
data/lib/thumbtack/types/tags.rb
CHANGED
@@ -2,24 +2,27 @@
|
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
5
|
-
#
|
6
|
-
# Pinboard
|
5
|
+
# Handles conversion and validation of tag lists to values supported by
|
6
|
+
# Pinboard
|
7
|
+
#
|
8
|
+
# @api private
|
7
9
|
class Tags
|
8
|
-
# The maximum tag length
|
10
|
+
# The maximum tag length
|
9
11
|
MAXIMUM_LENGTH = 255
|
10
|
-
# Tags cannot have commas
|
12
|
+
# Tags cannot have commas
|
11
13
|
INVALID_CHARACTER = ','.freeze
|
12
|
-
# Tag parameters are separated by spaces
|
14
|
+
# Tag parameters are separated by spaces
|
13
15
|
SEPARATOR = ' '.freeze
|
14
16
|
|
15
|
-
# Validate a tags value
|
17
|
+
# Validate a tags value
|
16
18
|
#
|
17
|
-
#
|
18
|
-
#
|
19
|
+
# @param [String, Array<String>] value
|
20
|
+
# a single tag or an array of many tags
|
19
21
|
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
22
|
+
# @return [undefined]
|
23
|
+
#
|
24
|
+
# @raise [Types::ValidationError]
|
25
|
+
# if any tag contains commas or are longer than 255 characters
|
23
26
|
def self.validate(value)
|
24
27
|
Array(value).each do |tag|
|
25
28
|
unless tag.length < MAXIMUM_LENGTH && !tag.include?(INVALID_CHARACTER)
|
@@ -30,21 +33,23 @@ module Thumbtack
|
|
30
33
|
self
|
31
34
|
end
|
32
35
|
|
33
|
-
# Convert a tag value to a parameter acceptable to
|
36
|
+
# Convert a tag value to a parameter acceptable to Pinboard
|
34
37
|
#
|
35
|
-
#
|
36
|
-
#
|
38
|
+
# @param [String, Array<String>] value
|
39
|
+
# a single tag or an array of many tags
|
37
40
|
#
|
38
|
-
#
|
41
|
+
# @return [String]
|
42
|
+
# space-separated list of tags
|
39
43
|
def self.to_parameter(value)
|
40
44
|
Array(value).map(&:strip).join(SEPARATOR)
|
41
45
|
end
|
42
46
|
|
43
|
-
# Convert a parameter from
|
47
|
+
# Convert a parameter from Pinboard to a list of tags
|
44
48
|
#
|
45
|
-
#
|
49
|
+
# @param [String] parameter
|
50
|
+
# space-separated list of tags
|
46
51
|
#
|
47
|
-
#
|
52
|
+
# @return [Array<String>]
|
48
53
|
def self.from_parameter(parameter)
|
49
54
|
parameter.split(SEPARATOR)
|
50
55
|
end
|
data/lib/thumbtack/types/text.rb
CHANGED
@@ -2,18 +2,22 @@
|
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
5
|
-
#
|
5
|
+
# Handles validation of text values as supported by Pinboard
|
6
|
+
#
|
7
|
+
# @api private
|
6
8
|
class Text < Identity
|
7
|
-
# Maximum length of a text value
|
9
|
+
# Maximum length of a text value
|
8
10
|
MAXIMUM_LENGTH = 65_536
|
9
11
|
|
10
|
-
# Validate text
|
12
|
+
# Validate text
|
11
13
|
#
|
12
|
-
#
|
14
|
+
# @param [String] value
|
15
|
+
# text to validate
|
13
16
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
+
# @return [undefined]
|
18
|
+
#
|
19
|
+
# @raise [Types::ValidationError]
|
20
|
+
# if the value is longer than 65536 characters
|
17
21
|
def self.validate(value)
|
18
22
|
unless value.length <= MAXIMUM_LENGTH
|
19
23
|
fail ValidationError,
|
@@ -2,18 +2,22 @@
|
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
5
|
-
#
|
5
|
+
# Handles validation of title values as supported by Pinboard
|
6
|
+
#
|
7
|
+
# @api private
|
6
8
|
class Title < Identity
|
7
|
-
# Maximum length of a title value
|
9
|
+
# Maximum length of a title value
|
8
10
|
MAXIMUM_LENGTH = 255
|
9
11
|
|
10
|
-
# Validate a title
|
12
|
+
# Validate a title
|
11
13
|
#
|
12
|
-
#
|
14
|
+
# @param [String] value
|
15
|
+
# the title to validate
|
13
16
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
+
# @return [undefined]
|
18
|
+
#
|
19
|
+
# @raise [Types::ValidationError]
|
20
|
+
# if the value is longer than 255 characters
|
17
21
|
def self.validate(value)
|
18
22
|
unless value.length <= MAXIMUM_LENGTH
|
19
23
|
fail ValidationError,
|
data/lib/thumbtack/types/url.rb
CHANGED
@@ -2,18 +2,23 @@
|
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
5
|
-
#
|
5
|
+
# Handles validation of URL values as supported by Pinboard
|
6
|
+
#
|
7
|
+
# @api private
|
6
8
|
class URL < Identity
|
7
|
-
# Valid URL schemes
|
9
|
+
# Valid URL schemes
|
8
10
|
VALID_SCHEMES = %w(http https javascript mailto ftp file feed).freeze
|
9
11
|
|
10
|
-
# Validate a URL
|
12
|
+
# Validate a URL
|
11
13
|
#
|
12
|
-
#
|
14
|
+
# @param [String] value
|
15
|
+
# the URL to validate
|
13
16
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
+
# @return [undefined]
|
18
|
+
#
|
19
|
+
# @raise [Types::ValidationError]
|
20
|
+
# if the URL's scheme isn't one of http, https, javascript, mailto, ftp,
|
21
|
+
# file, or feed
|
17
22
|
def self.validate(value)
|
18
23
|
unless VALID_SCHEMES.include? URI(value).scheme
|
19
24
|
fail ValidationError,
|