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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b204797fab0cc2277a9a96a0fb7f117351e77682
4
- data.tar.gz: e58eb6b1b2e6e82b4c8d90cbef2cda993756884b
3
+ metadata.gz: af013ae7caf72e5d517bd5ce42ef097a804fca78
4
+ data.tar.gz: 35a058f9bc768ab4fadf48882993d3393dd5c627
5
5
  SHA512:
6
- metadata.gz: edcf405a5c45dd0dd17786f292a650a44ba543de43a4318afd363b1acb592abe9b9893f037b32624a9410bc2f654eac5345708529db054919c3e1629bc41d380
7
- data.tar.gz: 625d10851ca09eb39916d42c34edbcebd6db93bb1e8f1d318a9048cab8283c1d2effc35377da3c4c829723e28b7f8e463b54bd5a8bff48fc4ec97bf76b3bda37
6
+ metadata.gz: 73795d3553e3e56dd4cbd6d83cb9e9e47f90750c46963f703811d7a53a6e8019ab8aebf3693f8fe675219e6a8a05adb6779bbd3e2a7af917434a8af740407c85
7
+ data.tar.gz: a33adcc946c096f2e8dccfc3a34a166eec774a4006b396fd2a02a0107750424c7f7b495f3cb0be4c9437fcb7b34c53a78d7d6218d5d79a81e7e03661e6e52c8f
@@ -2,6 +2,11 @@
2
2
 
3
3
  # A simple Pinboard API wrapper
4
4
  module Thumbtack
5
+ # An empty Hash to use for default options
6
+ EMPTY_HASH = {}.freeze
7
+
8
+ # An empty Hash to use for `#fetch` fallbacks
9
+ EMPTY_ARRAY = [].freeze
5
10
  end
6
11
 
7
12
  require 'date'
@@ -22,6 +27,7 @@ require 'thumbtack/types/title'
22
27
  require 'thumbtack/types/url'
23
28
  require 'thumbtack/specification'
24
29
  require 'thumbtack/post'
30
+ require 'thumbtack/suggestion'
25
31
  require 'thumbtack/posts'
26
32
  require 'thumbtack/tags'
27
33
  require 'thumbtack/user'
@@ -1,68 +1,114 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Thumbtack
4
- # Public: Wraps each interaction with the Pinboard API.
4
+ # Wraps each interaction with the Pinboard API
5
5
  class Client
6
- # Public: String of base Pinboard API URL.
6
+ # Raised when the API rate limit has been reached
7
+ class RateLimitError < StandardError; end
8
+
9
+ # The status code for rate limited responses from the Pinboard API
10
+ TOO_MANY_REQUESTS_CODE = '429'.freeze
11
+
12
+ # The base Pinboard API URL.
7
13
  BASE_URL = 'https://api.pinboard.in/v1'.freeze
8
14
 
9
- # Public: Returns the String username being used by the client.
15
+ # Username used by the client to make authenticated requests
16
+ #
17
+ # @return [String]
18
+ #
19
+ # @api public
10
20
  attr_reader :username
11
21
 
12
- # Public: Returns the String API token being used by the client.
22
+ # Token used by the client to make authenticated requests
23
+ #
24
+ # @return [String]
25
+ #
26
+ # @api public
13
27
  attr_reader :token
14
28
 
15
- # Public: Creates a new client.
29
+ # Initialize a Client
30
+ #
31
+ # @example
32
+ # client = Client.new(username, token)
33
+ #
34
+ # @param [String] username
35
+ # the user to authenticate with
36
+ # @param [String] token
37
+ # the API token for the user account, found on the Pinboard settings page
16
38
  #
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.
39
+ # @api public
20
40
  def initialize(username, token)
21
41
  @username, @token = username, token
22
42
  end
23
43
 
24
- # Internal: Request JSON from the Pinboard API.
44
+ # Retrieve JSON from the Pinboard API
25
45
  #
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: {}).
46
+ # @param [String] path
47
+ # the path to fetch from, relative to from the base Pinboard API URL
30
48
  #
31
- # Examples
49
+ # @param [Hash] params
50
+ # query parameters to append to the URL
32
51
  #
33
- # get('/posts/update')
34
- # # => {'update_time' => '2014-06-24T15:39:46Z'}
52
+ # @return [Hash] the response parsed from the JSON
35
53
  #
36
- # get('/posts/suggest', url: 'http://theinternate.com/')
37
- # # => [{'popular' => []}, {'recommended' => []}]
54
+ # @raise [RateLimitError] if the response is rate-limited
38
55
  #
39
- # Returns a parsed JSON response from Pinboard's API.
40
- def get(path, params = {})
56
+ # @api private
57
+ def get(path, params = EMPTY_HASH)
41
58
  uri = URI("#{BASE_URL}#{path}")
42
59
 
43
60
  base_params = { auth_token: "#{@username}:#{@token}", format: 'json' }
44
61
  uri.query = URI.encode_www_form(params.merge(base_params))
45
62
 
46
63
  response = Net::HTTP.get_response(uri)
64
+ fail Client::RateLimitError if response.code == TOO_MANY_REQUESTS_CODE
47
65
  JSON.parse(response.body)
48
66
  end
49
67
 
50
- # Public: Access posts-related API calls.
68
+ # Access posts-related API calls
69
+ #
70
+ # @example
71
+ # posts = client.posts
72
+ #
73
+ # @return [Posts]
74
+ #
75
+ # @api public
51
76
  def posts
52
77
  Posts.new(self)
53
78
  end
54
79
 
55
- # Public: Access tags-related API calls.
80
+ # Access tags-related API calls
81
+ #
82
+ # @example
83
+ # tags = client.tags
84
+ #
85
+ # @return [Tags]
86
+ #
87
+ # @api public
56
88
  def tags
57
89
  Tags.new(self)
58
90
  end
59
91
 
60
- # Public: Access user-related API calls.
92
+ # Access user-related API calls
93
+ #
94
+ # @example
95
+ # user = client.user
96
+ #
97
+ # @return [User]
98
+ #
99
+ # @api public
61
100
  def user
62
101
  User.new(self)
63
102
  end
64
103
 
65
- # Public: Access notes-related API calls.
104
+ # Access notes-related API calls
105
+ #
106
+ # @example
107
+ # notes = client.notes
108
+ #
109
+ # @return [Notes]
110
+ #
111
+ # @api public
66
112
  def notes
67
113
  Notes.new(self)
68
114
  end
@@ -1,9 +1,13 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Thumbtack
4
- # Public: Represents a note.
4
+ # Represents a note
5
+ #
6
+ # @api public
5
7
  class Note
6
- # Private: The attributes for a Note.
8
+ # The attributes for a Note
9
+ #
10
+ # @api private
7
11
  ATTRIBUTES = [
8
12
  :id,
9
13
  :title,
@@ -14,21 +18,77 @@ module Thumbtack
14
18
  :length
15
19
  ].freeze
16
20
 
17
- attr_reader(*ATTRIBUTES)
21
+ # The identifier for the note
22
+ #
23
+ # @return [String]
24
+ #
25
+ # @api public
26
+ attr_reader :id
27
+
28
+ # The title of the note
29
+ #
30
+ # @return [String]
31
+ #
32
+ # @api public
33
+ attr_reader :title
34
+
35
+ # The time at which the note was created
36
+ #
37
+ # @return [String]
38
+ #
39
+ # @api public
40
+ attr_reader :created_at
41
+
42
+ # The time at which the note was last updated
43
+ #
44
+ # @return [String]
45
+ #
46
+ # @api public
47
+ attr_reader :updated_at
48
+
49
+ # 20 character hexadecimal SHA1 hash of the note text
50
+ #
51
+ # @return [String]
52
+ #
53
+ # @api public
54
+ attr_reader :digest
55
+
56
+ # The text of the note
57
+ #
58
+ # @return [String]
59
+ #
60
+ # @api public
61
+ attr_reader :text
62
+
63
+ # The length of the note text
64
+ #
65
+ # @return [Integer]
66
+ #
67
+ # @api public
68
+ attr_reader :length
18
69
 
19
- # Internal: Creates a new Note from a Hash, usually a Client#get response.
70
+ # Creates a new Note from a Hash
20
71
  #
21
- # hash - A Hash of attributes of the note.
72
+ # @param [Hash{#to_sym => Object}] hash
73
+ # Note attributes
74
+ #
75
+ # @return [Note]
76
+ #
77
+ # @api private
78
+ # @see Client#get
22
79
  def self.from_hash(hash)
23
80
  attrs = hash.dup
24
81
  digest = attrs.delete('hash')
25
82
  new(Hash[attrs.map { |k, v| [k.to_sym, v] }].merge(digest: digest))
26
83
  end
27
84
 
28
- # Internal: Initialize a Note.
85
+ # Initialize a Note
86
+ #
87
+ # @param [Hash] attrs
88
+ # Note attributes
29
89
  #
30
- # attrs - A Hash of attributes of the Note.
31
- def initialize(attrs = {})
90
+ # @api private
91
+ def initialize(attrs = EMPTY_HASH)
32
92
  ATTRIBUTES.each do |attribute|
33
93
  instance_variable_set "@#{attribute}", attrs.fetch(attribute)
34
94
  end
@@ -1,32 +1,87 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Thumbtack
4
- # Public: Represents a note summary as returned from Notes#list.
4
+ # Represents a note summary as returned from Notes#list.
5
+ #
6
+ # @api public
7
+ # @see Notes#list
5
8
  class NoteSummary
6
- # Private: The attributes for a NoteSummary.
9
+ # The attributes for a NoteSummary
10
+ #
11
+ # @api private
7
12
  ATTRIBUTES = [
8
13
  :id,
9
14
  :title,
10
- :hash,
15
+ :digest,
11
16
  :created_at,
12
17
  :updated_at,
13
18
  :length
14
19
  ].freeze
15
20
 
16
- attr_reader(*ATTRIBUTES)
21
+ # The identifier for the note
22
+ #
23
+ # @return [String]
24
+ #
25
+ # @api public
26
+ attr_reader :id
27
+
28
+ # The title of the note
29
+ #
30
+ # @return [String]
31
+ #
32
+ # @api public
33
+ attr_reader :title
17
34
 
18
- # Internal: Creates a new NoteSummary from a Hash, usually a Client#get
19
- # response.
35
+ # The time at which the note was created
20
36
  #
21
- # hash - A Hash of attributes of the note.
37
+ # @return [String]
38
+ #
39
+ # @api public
40
+ attr_reader :created_at
41
+
42
+ # The time at which the note was last updated
43
+ #
44
+ # @return [String]
45
+ #
46
+ # @api public
47
+ attr_reader :updated_at
48
+
49
+ # 20 character hexadecimal SHA1 hash of the note text
50
+ #
51
+ # @return [String]
52
+ #
53
+ # @api public
54
+ attr_reader :digest
55
+
56
+ # The length of the note text
57
+ #
58
+ # @return [Integer]
59
+ #
60
+ # @api public
61
+ attr_reader :length
62
+
63
+ # Creates a new NoteSummary from a Hash
64
+ #
65
+ # @param [Hash{#to_sym => Object}] hash
66
+ # NoteSummary attributes
67
+ #
68
+ # @return [NoteSummary]
69
+ #
70
+ # @api private
71
+ # @see Client#get
22
72
  def self.from_hash(hash)
23
- new(Hash[hash.map { |key, value| [key.to_sym, value] }])
73
+ attrs = hash.dup
74
+ digest = attrs.delete('hash')
75
+ new(Hash[attrs.map { |k, v| [k.to_sym, v] }].merge(digest: digest))
24
76
  end
25
77
 
26
- # Internal: Initialize a NoteSummary.
78
+ # Initialize a NoteSummary
79
+ #
80
+ # @param [Hash] attrs
81
+ # NoteSummary attributes
27
82
  #
28
- # attrs - A Hash of attributes of the NoteSummary.
29
- def initialize(attrs = {})
83
+ # @api private
84
+ def initialize(attrs = EMPTY_HASH)
30
85
  ATTRIBUTES.each do |attribute|
31
86
  instance_variable_set "@#{attribute}", attrs.fetch(attribute)
32
87
  end
@@ -1,24 +1,48 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Thumbtack
4
- # Internal: Wraps API calls related to notes.
4
+ # Wraps API calls related to notes
5
5
  class Notes
6
- # Internal: Creates a new Notes.
6
+ # Initialize a Notes
7
7
  #
8
- # client - a Thumbtack::Client to communicate with the Pinboard API.
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
- # Public: Returns a list of summaries of the user's notes.
16
+ # List of summaries of the user's notes
17
+ #
18
+ # @example
19
+ # summaries = notes.list
20
+ #
21
+ # @return [Array<NoteSummary>]
22
+ #
23
+ # @api public
24
+ #
25
+ # @see https://pinboard.in/api/#notes_list
14
26
  def list
15
27
  response = @client.get('/notes/list')
16
- response.fetch('notes', []).map do |note_hash|
28
+ response.fetch('notes', EMPTY_ARRAY).map do |note_hash|
17
29
  NoteSummary.from_hash(note_hash)
18
30
  end
19
31
  end
20
32
 
21
- # Public: Return an individual note.
33
+ # Fetch a note
34
+ #
35
+ # @example
36
+ # note = notes.get(id)
37
+ #
38
+ # @param [#to_s] id
39
+ # the id of the note to fetch
40
+ #
41
+ # @return [Note]
42
+ #
43
+ # @api public
44
+ #
45
+ # @see https://pinboard.in/api/#notes_id
22
46
  def get(id)
23
47
  Note.from_hash @client.get("/notes/#{id}")
24
48
  end
@@ -1,9 +1,13 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Thumbtack
4
- # Public: Represents a bookmark.
4
+ # Represents a bookmark
5
+ #
6
+ # @api public
5
7
  class Post
6
- # Private: The attributes for a Post.
8
+ # The attributes for a Post
9
+ #
10
+ # @api private
7
11
  ATTRIBUTES = [
8
12
  :href,
9
13
  :description,
@@ -16,19 +20,89 @@ module Thumbtack
16
20
  :tags
17
21
  ].freeze
18
22
 
19
- attr_reader(*ATTRIBUTES)
23
+ # The url of the post
24
+ #
25
+ # @return [String]
26
+ #
27
+ # @api public
28
+ attr_reader :href
29
+
30
+ # The title of the post
31
+ #
32
+ # @return [String]
33
+ #
34
+ # @api public
35
+ attr_reader :description
36
+
37
+ # The description of the post
38
+ #
39
+ # @return [String]
40
+ #
41
+ # @api public
42
+ attr_reader :extended
43
+
44
+ # 32 character hexadecimal MD5 hash tag 'version' of the post
45
+ #
46
+ # @return [String]
47
+ #
48
+ # @api public
49
+ attr_reader :meta
50
+
51
+ # 32 character hexadecimal MD5 hash of the post URL
52
+ #
53
+ # @return [String]
54
+ #
55
+ # @api public
56
+ attr_reader :hash
57
+
58
+ # The time at which the post was created
59
+ #
60
+ # @return [String]
61
+ #
62
+ # @api public
63
+ attr_reader :time
64
+
65
+ # If true, this post is public
66
+ #
67
+ # @return [Boolean]
68
+ #
69
+ # @api public
70
+ attr_reader :shared
20
71
 
21
- # Internal: Creates a new post from a Hash, usually a Client#get response.
72
+ # If true, this post is marked unread
22
73
  #
23
- # hash - A Hash of attributes of the Post.
74
+ # @return [Boolean]
75
+ #
76
+ # @api public
77
+ attr_reader :toread
78
+
79
+ # The tags for this post, space-seperated
80
+ #
81
+ # @return [String]
82
+ #
83
+ # @api public
84
+ attr_reader :tags
85
+
86
+ # Creates a new Post from a Hash
87
+ #
88
+ # @param [Hash{#to_sym => Object}] hash
89
+ # Post attributes
90
+ #
91
+ # @return [Post]
92
+ #
93
+ # @api private
94
+ # @see Client#get
24
95
  def self.from_hash(hash)
25
96
  new(Hash[hash.map { |key, value| [key.to_sym, value] }])
26
97
  end
27
98
 
28
- # Internal: Initialize a Post.
99
+ # Initialize a Post
100
+ #
101
+ # @param [Hash] attrs
102
+ # Post attributes
29
103
  #
30
- # attrs - A Hash of attributes of the Post.
31
- def initialize(attrs = {})
104
+ # @api private
105
+ def initialize(attrs = EMPTY_HASH)
32
106
  ATTRIBUTES.each do |attribute|
33
107
  instance_variable_set "@#{attribute}", attrs.fetch(attribute)
34
108
  end