pinterest-ruby 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rubocop.yml +63 -0
  4. data/.travis-gemfile +17 -0
  5. data/.travis.yml +12 -0
  6. data/.yardopts +1 -0
  7. data/CHANGELOG.md +3 -0
  8. data/Gemfile +24 -0
  9. data/README.md +34 -0
  10. data/Rakefile +44 -0
  11. data/docs/FaradayMiddleware/SafeOj.html +218 -0
  12. data/docs/FaradayMiddleware.html +125 -0
  13. data/docs/Pinterest/Board.html +410 -0
  14. data/docs/Pinterest/Client.html +1894 -0
  15. data/docs/Pinterest/Collection.html +1877 -0
  16. data/docs/Pinterest/Endpoints/Authentication.html +578 -0
  17. data/docs/Pinterest/Endpoints/Boards.html +1443 -0
  18. data/docs/Pinterest/Endpoints/Pins.html +1296 -0
  19. data/docs/Pinterest/Endpoints/Users.html +1220 -0
  20. data/docs/Pinterest/Endpoints.html +127 -0
  21. data/docs/Pinterest/Entity.html +473 -0
  22. data/docs/Pinterest/Errors/AuthorizationError.html +158 -0
  23. data/docs/Pinterest/Errors/BadRequestError.html +158 -0
  24. data/docs/Pinterest/Errors/BaseError.html +487 -0
  25. data/docs/Pinterest/Errors/MethodNotAllowedError.html +158 -0
  26. data/docs/Pinterest/Errors/NotFoundError.html +158 -0
  27. data/docs/Pinterest/Errors/NotImplementedError.html +158 -0
  28. data/docs/Pinterest/Errors/PermissionsError.html +158 -0
  29. data/docs/Pinterest/Errors/RateLimitError.html +158 -0
  30. data/docs/Pinterest/Errors/ServerError.html +158 -0
  31. data/docs/Pinterest/Errors/TimeoutError.html +158 -0
  32. data/docs/Pinterest/Errors.html +377 -0
  33. data/docs/Pinterest/Image.html +617 -0
  34. data/docs/Pinterest/Interest.html +402 -0
  35. data/docs/Pinterest/Pin.html +511 -0
  36. data/docs/Pinterest/User.html +408 -0
  37. data/docs/Pinterest/Version.html +187 -0
  38. data/docs/Pinterest.html +130 -0
  39. data/docs/_index.html +401 -0
  40. data/docs/class_list.html +51 -0
  41. data/docs/css/common.css +1 -0
  42. data/docs/css/full_list.css +58 -0
  43. data/docs/css/style.css +492 -0
  44. data/docs/file.README.html +106 -0
  45. data/docs/file_list.html +56 -0
  46. data/docs/frames.html +17 -0
  47. data/docs/index.html +106 -0
  48. data/docs/js/app.js +243 -0
  49. data/docs/js/full_list.js +216 -0
  50. data/docs/js/jquery.js +4 -0
  51. data/docs/method_list.html +643 -0
  52. data/docs/top-level-namespace.html +110 -0
  53. data/lib/pinterest/client.rb +146 -0
  54. data/lib/pinterest/collection.rb +97 -0
  55. data/lib/pinterest/endpoints/authentication.rb +99 -0
  56. data/lib/pinterest/endpoints/boards.rb +193 -0
  57. data/lib/pinterest/endpoints/pins.rb +187 -0
  58. data/lib/pinterest/endpoints/users.rb +158 -0
  59. data/lib/pinterest/errors.rb +94 -0
  60. data/lib/pinterest/models/board.rb +34 -0
  61. data/lib/pinterest/models/entity.rb +42 -0
  62. data/lib/pinterest/models/image.rb +49 -0
  63. data/lib/pinterest/models/interest.rb +30 -0
  64. data/lib/pinterest/models/pin.rb +43 -0
  65. data/lib/pinterest/models/user.rb +33 -0
  66. data/lib/pinterest/safe_oj.rb +25 -0
  67. data/lib/pinterest/version.rb +23 -0
  68. data/lib/pinterest.rb +31 -0
  69. data/pinterest.gemspec +32 -0
  70. data/spec/cassettes/Pinterest_Client/_perform_network_request_private_/should_correctly_handle_malformed_requests.yml +51 -0
  71. data/spec/cassettes/Pinterest_Endpoints_Authentication/_fetch_access_token/should_make_the_call_to_Pinterest_and_return_the_authorization_token_also_saving_it.yml +58 -0
  72. data/spec/cassettes/Pinterest_Endpoints_Authentication/_verify_access_token/should_return_an_exception_when_using_an_invalid_token.yml +52 -0
  73. data/spec/cassettes/Pinterest_Endpoints_Authentication/_verify_access_token/should_verify_the_token.yml +59 -0
  74. data/spec/cassettes/Pinterest_Endpoints_Boards/_board/should_complain_for_invalid_boards.yml +48 -0
  75. data/spec/cassettes/Pinterest_Endpoints_Boards/_board/should_get_the_current_informations.yml +63 -0
  76. data/spec/cassettes/Pinterest_Endpoints_Boards/_board/should_restrict_to_requested_fields.yml +57 -0
  77. data/spec/cassettes/Pinterest_Endpoints_Boards/_boards/should_only_get_requested_fields.yml +57 -0
  78. data/spec/cassettes/Pinterest_Endpoints_Boards/_boards/should_return_a_list_of_boards.yml +74 -0
  79. data/spec/cassettes/Pinterest_Endpoints_Boards/_create_board/should_create_the_board_and_return_it_with_only_the_requested_fields.yml +56 -0
  80. data/spec/cassettes/Pinterest_Endpoints_Boards/_delete_board/should_perform_the_call_and_return_an_error.yml +48 -0
  81. data/spec/cassettes/Pinterest_Endpoints_Boards/_delete_board/should_perform_the_call_and_return_true.yml +109 -0
  82. data/spec/cassettes/Pinterest_Endpoints_Boards/_edit_board/should_edit_the_board_and_return_it_with_only_the_requested_fields.yml +56 -0
  83. data/spec/cassettes/Pinterest_Endpoints_Boards/_follow_board/should_complain_for_invalid_boards.yml +56 -0
  84. data/spec/cassettes/Pinterest_Endpoints_Boards/_follow_board/should_perform_the_call_and_return_true.yml +109 -0
  85. data/spec/cassettes/Pinterest_Endpoints_Boards/_following_boards/should_only_get_requested_fields.yml +59 -0
  86. data/spec/cassettes/Pinterest_Endpoints_Boards/_following_boards/should_paginate_correctly.yml +72 -0
  87. data/spec/cassettes/Pinterest_Endpoints_Boards/_following_boards/should_return_the_followed_boards.yml +72 -0
  88. data/spec/cassettes/Pinterest_Endpoints_Boards/_search_my_boards/should_only_get_requested_fields.yml +59 -0
  89. data/spec/cassettes/Pinterest_Endpoints_Boards/_search_my_boards/should_paginate_correctly.yml +66 -0
  90. data/spec/cassettes/Pinterest_Endpoints_Boards/_search_my_boards/should_search_boards.yml +75 -0
  91. data/spec/cassettes/Pinterest_Endpoints_Boards/_suggested_boards/should_return_the_suggested_boards_returning_only_the_requested_fields.yml +56 -0
  92. data/spec/cassettes/Pinterest_Endpoints_Boards/_unfollow_board/should_complain_for_invalid_boards.yml +56 -0
  93. data/spec/cassettes/Pinterest_Endpoints_Boards/_unfollow_board/should_perform_the_call_and_return_true.yml +109 -0
  94. data/spec/cassettes/Pinterest_Endpoints_Pins/_board_pins/should_only_get_requested_fields.yml +59 -0
  95. data/spec/cassettes/Pinterest_Endpoints_Pins/_board_pins/should_paginate_correctly.yml +85 -0
  96. data/spec/cassettes/Pinterest_Endpoints_Pins/_board_pins/should_return_the_pins_of_the_board.yml +85 -0
  97. data/spec/cassettes/Pinterest_Endpoints_Pins/_create_pin/should_create_a_pin_by_using_a_image_URL.yml +71 -0
  98. data/spec/cassettes/Pinterest_Endpoints_Pins/_create_pin/should_create_a_pin_by_using_a_image_file.yml +1997 -0
  99. data/spec/cassettes/Pinterest_Endpoints_Pins/_create_pin/should_return_a_pin_containing_only_requested_fields.yml +56 -0
  100. data/spec/cassettes/Pinterest_Endpoints_Pins/_delete_pin/should_perform_the_call_and_return_an_error.yml +56 -0
  101. data/spec/cassettes/Pinterest_Endpoints_Pins/_delete_pin/should_perform_the_call_and_return_true.yml +109 -0
  102. data/spec/cassettes/Pinterest_Endpoints_Pins/_edit_pin/should_edit_the_pin_and_return_it_with_only_the_requested_fields.yml +56 -0
  103. data/spec/cassettes/Pinterest_Endpoints_Pins/_likes/should_only_get_requested_fields.yml +58 -0
  104. data/spec/cassettes/Pinterest_Endpoints_Pins/_likes/should_paginate_correctly.yml +87 -0
  105. data/spec/cassettes/Pinterest_Endpoints_Pins/_likes/should_return_the_list_of_liked_pins.yml +85 -0
  106. data/spec/cassettes/Pinterest_Endpoints_Pins/_pin/should_complain_for_non_existent_pins.yml +56 -0
  107. data/spec/cassettes/Pinterest_Endpoints_Pins/_pin/should_get_the_current_informations.yml +71 -0
  108. data/spec/cassettes/Pinterest_Endpoints_Pins/_pin/should_restrict_to_requested_fields.yml +56 -0
  109. data/spec/cassettes/Pinterest_Endpoints_Pins/_pins/should_only_get_requested_fields.yml +59 -0
  110. data/spec/cassettes/Pinterest_Endpoints_Pins/_pins/should_paginate_correctly.yml +808 -0
  111. data/spec/cassettes/Pinterest_Endpoints_Pins/_pins/should_return_my_pins.yml +88 -0
  112. data/spec/cassettes/Pinterest_Endpoints_Pins/_search_my_pins/should_only_get_requested_fields.yml +61 -0
  113. data/spec/cassettes/Pinterest_Endpoints_Pins/_search_my_pins/should_paginate_correctly.yml +89 -0
  114. data/spec/cassettes/Pinterest_Endpoints_Pins/_search_my_pins/should_search_my_pins.yml +89 -0
  115. data/spec/cassettes/Pinterest_Endpoints_Users/_follow_interest/should_perform_the_call_and_return_an_error.yml +48 -0
  116. data/spec/cassettes/Pinterest_Endpoints_Users/_follow_user/should_complain_for_invalid_users.yml +56 -0
  117. data/spec/cassettes/Pinterest_Endpoints_Users/_follow_user/should_perform_the_call_and_return_true.yml +109 -0
  118. data/spec/cassettes/Pinterest_Endpoints_Users/_followers/should_only_get_requested_fields.yml +62 -0
  119. data/spec/cassettes/Pinterest_Endpoints_Users/_followers/should_paginate_correctly.yml +62 -0
  120. data/spec/cassettes/Pinterest_Endpoints_Users/_followers/should_return_a_list_of_followers.yml +62 -0
  121. data/spec/cassettes/Pinterest_Endpoints_Users/_following_users/should_only_get_requested_fields.yml +62 -0
  122. data/spec/cassettes/Pinterest_Endpoints_Users/_following_users/should_paginate_correctly.yml +131 -0
  123. data/spec/cassettes/Pinterest_Endpoints_Users/_following_users/should_return_a_list_of_followed_users.yml +66 -0
  124. data/spec/cassettes/Pinterest_Endpoints_Users/_interests/should_paginate_correctly.yml +112 -0
  125. data/spec/cassettes/Pinterest_Endpoints_Users/_interests/should_return_a_list_of_followed_interest.yml +58 -0
  126. data/spec/cassettes/Pinterest_Endpoints_Users/_me/should_get_the_current_informations.yml +62 -0
  127. data/spec/cassettes/Pinterest_Endpoints_Users/_me/should_restrict_to_requested_fields.yml +56 -0
  128. data/spec/cassettes/Pinterest_Endpoints_Users/_unfollow_interest/should_perform_the_call_and_return_an_error.yml +48 -0
  129. data/spec/cassettes/Pinterest_Endpoints_Users/_unfollow_user/should_complain_for_invalid_users.yml +56 -0
  130. data/spec/cassettes/Pinterest_Endpoints_Users/_unfollow_user/should_perform_the_call_and_return_true.yml +109 -0
  131. data/spec/cassettes/Pinterest_Endpoints_Users/_user/should_complain_for_non_existent_users.yml +56 -0
  132. data/spec/cassettes/Pinterest_Endpoints_Users/_user/should_get_the_current_informations.yml +60 -0
  133. data/spec/cassettes/Pinterest_Endpoints_Users/_user/should_restrict_to_requested_fields.yml +56 -0
  134. data/spec/pinterest/client_spec.rb +70 -0
  135. data/spec/pinterest/collection_spec.rb +82 -0
  136. data/spec/pinterest/endpoints/authentication_spec.rb +81 -0
  137. data/spec/pinterest/endpoints/boards_spec.rb +209 -0
  138. data/spec/pinterest/endpoints/pins_spec.rb +239 -0
  139. data/spec/pinterest/endpoints/users_spec.rb +194 -0
  140. data/spec/pinterest/errors_spec.rb +59 -0
  141. data/spec/pinterest/fixtures/first.jpg +0 -0
  142. data/spec/pinterest/models/board_spec.rb +48 -0
  143. data/spec/pinterest/models/entity_spec.rb +35 -0
  144. data/spec/pinterest/models/image_spec.rb +50 -0
  145. data/spec/pinterest/models/interest_spec.rb +20 -0
  146. data/spec/pinterest/models/pin_spec.rb +55 -0
  147. data/spec/pinterest/models/user_spec.rb +45 -0
  148. data/spec/spec_helper.rb +49 -0
  149. data/tester.rb +19 -0
  150. metadata +341 -0
@@ -0,0 +1,187 @@
1
+ #
2
+ # This file is part of the pinterest-ruby gem. Copyright (C) 2017 and above Shogun <shogun@cowtech.it>.
3
+ # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
4
+ #
5
+
6
+ module Pinterest
7
+ module Endpoints
8
+ # Pins related endpoints.
9
+ module Pins
10
+ # Returns information about a pin.
11
+ #
12
+ # @param pin [Fixnum|String] The pin id.
13
+ # @param fields [Array] A list of fields to return.
14
+ # @return [Pinterest::User] A pin object.
15
+ def pin(pin, fields: nil)
16
+ # Validate the pin id
17
+ pin = validate_pin(pin)
18
+
19
+ # Ensure only valid fields are used
20
+ fields = ensure_pin_fields(fields)
21
+
22
+ # Perform the request and create the pin
23
+ data = perform_network_request(url: versioned_url("/pins/#{pin}/"), query: cleanup_params({fields: fields.join(",")})).body["data"]
24
+ ::Pinterest::Pin.create(data)
25
+ end
26
+
27
+ # Creates a new pin.
28
+ #
29
+ # @param board [String] The board path (username/id) or id.
30
+ # @param image [String] The image to pin.
31
+ # @param note [String] The note to attach to the pin.
32
+ # @param link [String] The link to attach to the pin.
33
+ # @param fields [Array] A list of fields to return.
34
+ # @return [Pinterest::User] The new created pin object.
35
+ def create_pin(board, image, note: nil, link: nil, fields: nil)
36
+ board = validate_board(board)
37
+
38
+ # Ensure only valid fields are used
39
+ fields = ensure_pin_fields(fields)
40
+
41
+ # Create the payload
42
+ payload = {note: note, board: board, link: link}
43
+
44
+ # Add the image - Try to detect whether is a URL or a path
45
+ payload.merge!(add_image(image))
46
+
47
+ # Perform the request and create the pin
48
+ data = perform_network_request(method: "POST", url: versioned_url("/pins/"), query: cleanup_params({fields: fields.join(",")}), body: payload)
49
+
50
+ ::Pinterest::Pin.create(data.body["data"])
51
+ end
52
+
53
+ # Edits a pin.
54
+ #
55
+ # @param pin [String] The pin id.
56
+ # @param board [String] The new board path (username/id) or id.
57
+ # @param note [String] The new note to attach to the pin.
58
+ # @param link [String] The new link to attach to the pin.
59
+ # @param fields [Array] A list of fields to return.
60
+ # @return [Pinterest::User] The updated pin object.
61
+ def edit_pin(pin, board: nil, note: nil, link: nil, fields: nil)
62
+ pin = validate_pin(pin)
63
+ board = validate_board(board) if board
64
+
65
+ # Ensure only valid fields are used
66
+ fields = ensure_pin_fields(fields)
67
+
68
+ # Create the payload
69
+ payload = cleanup_params({note: note, board: board, link: link})
70
+
71
+ # Perform the request and create the pin
72
+ data = perform_network_request(method: "PATCH", url: versioned_url("/pins/#{pin}/"), query: cleanup_params({fields: fields.join(",")}), body: payload)
73
+ ::Pinterest::Pin.create(data.body["data"])
74
+ end
75
+
76
+ # Deletes a pin.
77
+ #
78
+ # @param pin [String] The pin id.
79
+ # @return [Boolean] `true` if operation succeeded, `false` otherwise.
80
+ def delete_pin(pin)
81
+ # Validate the board id
82
+ pin = validate_pin(pin)
83
+
84
+ # Perform the request
85
+ perform_network_request(method: "DELETE", url: versioned_url("/pins/#{pin}/"))
86
+ true
87
+ end
88
+
89
+ # Returns the list of pins of the authenticated user.
90
+ #
91
+ # @param fields [Array] A list of fields to return.
92
+ # @param cursor [String] A cursor to paginate results, obtained by a previous call.
93
+ # @param limit [Fixnum] The maximum number of objects to return.
94
+ # @return [Pinterest::Collection] An collection of pin objects.
95
+ def pins(fields: nil, cursor: nil, limit: nil)
96
+ get_pins_collection("/me/pins/", nil, fields, cursor, limit)
97
+ end
98
+
99
+ # Search between of pins of the authenticated user.
100
+ #
101
+ # @param query [String] The query to perform.
102
+ # @param fields [Array] A list of fields to return.
103
+ # @param cursor [String] A cursor to paginate results, obtained by a previous call.
104
+ # @param limit [Fixnum] The maximum number of objects to return.
105
+ # @return [Pinterest::Collection] An collection of pin objects.
106
+ def search_my_pins(query = "", fields: nil, cursor: nil, limit: nil)
107
+ ensure_param(query, "You have to specify a query.")
108
+ get_pins_collection("/me/search/pins/", {query: query}, fields, cursor, limit)
109
+ end
110
+
111
+ # Returns the list of pins of a board of the authenticated user.
112
+ #
113
+ # @param board [Fixnum|String] The board path (username/id) or id.
114
+ # @param fields [Array] A list of fields to return.
115
+ # @param cursor [String] A cursor to paginate results, obtained by a previous call.
116
+ # @param limit [Fixnum] The maximum number of objects to return.
117
+ # @return [Pinterest::Collection] An collection of pin objects.
118
+ def board_pins(board, fields: nil, cursor: nil, limit: nil)
119
+ validate_board(board)
120
+ get_pins_collection("/boards/#{board}/pins/", nil, fields, cursor, limit)
121
+ end
122
+
123
+ # Returns the list of liked pins of the authenticated user.
124
+ #
125
+ # @param fields [Array] A list of fields to return.
126
+ # @param cursor [String] A cursor to paginate results, obtained by a previous call.
127
+ # @param limit [Fixnum] The maximum number of objects to return.
128
+ # @return [Pinterest::Collection] An collection of pin objects.
129
+ def likes(fields: nil, cursor: nil, limit: nil)
130
+ get_pins_collection("/me/likes/", nil, fields, cursor, limit)
131
+ end
132
+
133
+ private
134
+
135
+ # :nodoc:
136
+ def validate_pin(pin)
137
+ raise(ArgumentError, "You have to specify a pin or its id.") unless pin
138
+ pin = pin.id if pin.is_a?(::Pinterest::Pin)
139
+ pin
140
+ end
141
+
142
+ # :nodoc:
143
+ def get_pins_collection(path, params, fields, cursor, limit)
144
+ # Ensure only valid fields are used and merge params
145
+ fields = ensure_pin_fields(fields)
146
+ params ||= {}
147
+ params[:fields] = fields.join(",")
148
+
149
+ # Perform the request
150
+ data = perform_network_request(
151
+ url: versioned_url(path),
152
+ query: cleanup_params(params),
153
+ pagination: (cursor || limit), cursor: cursor, limit: limit
154
+ )
155
+
156
+ # Create the collection
157
+ ::Pinterest::Collection.new(data.body, cursor, limit) { |pin| ::Pinterest::Pin.create(pin) }
158
+ end
159
+
160
+ # :nodoc:
161
+ def ensure_pin_fields(fields = nil)
162
+ # Get fields and make sure only allowed fields are kept
163
+ fields = ensure_array(fields, ::Pinterest::Pin::FIELDS).map(&:to_s) & ::Pinterest::Pin::FIELDS
164
+
165
+ # Replace embedded fields
166
+ fields.map do |f|
167
+ case f
168
+ when "creator" then "creator(#{ensure_user_fields.join(",")})"
169
+ when "board" then "board(#{ensure_board_fields.join(",")})"
170
+ else f
171
+ end
172
+ end
173
+ end
174
+
175
+ # :nodoc:
176
+ def add_image(image)
177
+ raise(ArgumentError) if Addressable::URI.parse(image).scheme !~ /^http(s?)$/
178
+ {image_url: image}
179
+ rescue
180
+ type = FastImage.type(image)
181
+ raise(ArgumentError, "You have to specify a image URL or a valid image path.") unless type
182
+ type = type == :jpeg ? "jpg" : type.to_s
183
+ {image: Faraday::UploadIO.new(image, "image/#{type}")}
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,158 @@
1
+ #
2
+ # This file is part of the pinterest-ruby gem. Copyright (C) 2017 and above Shogun <shogun@cowtech.it>.
3
+ # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
4
+ #
5
+
6
+ module Pinterest
7
+ module Endpoints
8
+ # Users related endpoints.
9
+ module Users
10
+ # Returns information about the authenticated user.
11
+ #
12
+ # @param fields [Array] A list of fields to return.
13
+ # @return [Pinterest::User] A user object.
14
+ def me(fields: nil)
15
+ fields = ensure_user_fields(fields)
16
+
17
+ # Perform request and create the user
18
+ data = perform_network_request(url: versioned_url("/me/"), query: cleanup_params({fields: fields.join(",")}))
19
+ ::Pinterest::User.create(data.body["data"])
20
+ end
21
+
22
+ # Returns information about a user.
23
+ #
24
+ # @param user [Fixnum|String] The username or user id.
25
+ # @param fields [Array] A list of fields to return.
26
+ # @return [Pinterest::User] A user object.
27
+ def user(user, fields: nil)
28
+ user = validate_user(user)
29
+ fields = ensure_user_fields(fields)
30
+
31
+ # Perform request and create the user
32
+ data = perform_network_request(url: versioned_url("/users/#{user}/"), query: cleanup_params({fields: fields.join(",")}))
33
+ ::Pinterest::User.create(data.body["data"])
34
+ end
35
+
36
+ # Returns the list of users who follow the authenticated user.
37
+ #
38
+ # @param fields [Array] A list of fields to return.
39
+ # @param cursor [String] A cursor to paginate results, obtained by a previous call.
40
+ # @param limit [Fixnum] The maximum number of objects to return.
41
+ # @return [Pinterest::Collection] An collection of user objects.
42
+ def followers(fields: nil, cursor: nil, limit: nil)
43
+ get_users_collection("/me/followers/", fields, cursor, limit)
44
+ end
45
+
46
+ # Returns the list of users followed by the authenticated user.
47
+ #
48
+ # @param fields [Array] A list of fields to return.
49
+ # @param cursor [String] A cursor to paginate results, obtained by a previous call.
50
+ # @param limit [Fixnum] The maximum number of objects to return.
51
+ # @return [Pinterest::Collection] An collection of user objects.
52
+ def following_users(fields: nil, cursor: nil, limit: nil)
53
+ get_users_collection("/me/following/users/", fields, cursor, limit)
54
+ end
55
+
56
+ # Follows a user.
57
+ #
58
+ # @param user [Fixnum|String] The username or user id.
59
+ # @return [Boolean] `true` if operation succeeded, `false` otherwise.
60
+ def follow_user(user)
61
+ # Validate the user id
62
+ user = validate_user(user)
63
+
64
+ # Perform the request
65
+ perform_network_request(method: "POST", body: {user: user}, url: versioned_url("/me/following/users/"))
66
+ true
67
+ end
68
+
69
+ # Stops following a user.
70
+ #
71
+ # @param user [Fixnum|String] The username or user id.
72
+ # @return [Boolean] `true` if operation succeeded, `false` otherwise.
73
+ def unfollow_user(user)
74
+ # Validate the user id
75
+ user = validate_user(user)
76
+
77
+ # Perform the request
78
+ perform_network_request(method: "DELETE", url: versioned_url("/me/following/users/#{user}/"))
79
+ true
80
+ end
81
+
82
+ # Returns the list of interests (topics) followed by the authenticated user.
83
+ #
84
+ # @param cursor [String] A cursor to paginate results, obtained by a previous call.
85
+ # @param limit [Fixnum] The maximum number of objects to return.
86
+ # @return [Pinterest::Collection] An collection of interest objects.
87
+ def interests(cursor: nil, limit: nil)
88
+ # Perform request
89
+ data = perform_network_request(
90
+ url: versioned_url("/me/following/interests/"),
91
+ pagination: true, cursor: cursor, limit: limit
92
+ )
93
+
94
+ # Create the collection
95
+ ::Pinterest::Collection.new(data.body, cursor, limit) { |interest| ::Pinterest::Interest.create(interest) }
96
+ end
97
+
98
+ # Starts following a interest.
99
+ #
100
+ # @param interest [Fixnum|String] The interest id.
101
+ # @return [Boolean] `true` if operation succeeded, `false` otherwise.
102
+ # NOTE: This is currently returning 405 on the platform. Review ASAP.
103
+ def follow_interest(interest)
104
+ # Validate the interest id
105
+ raise(ArgumentError, "You have to specify a interest or its id.") unless interest
106
+ interest = interest.id if interest.is_a?(::Pinterest::Interest)
107
+
108
+ # Perform the request
109
+ perform_network_request(method: "POST", query: {interest: interest}, url: versioned_url("/me/following/interests/"))
110
+ end
111
+
112
+ # Stops following a interest.
113
+ #
114
+ # @param interest [Fixnum|String] The interest id.
115
+ # @return [Boolean] `true` if operation succeeded, `false` otherwise.
116
+ # NOTE: This is currently returning 404 on the platform. Review ASAP.
117
+ def unfollow_interest(interest)
118
+ # Validate the interest id
119
+ raise(ArgumentError, "You have to specify a interest or its id.") unless interest
120
+ interest = interest.id if interest.is_a?(::Pinterest::Interest)
121
+
122
+ # Perform the request
123
+ perform_network_request(method: "DELETE", url: versioned_url("/me/following/interests/#{interest}/"))
124
+ end
125
+
126
+ private
127
+
128
+ # :nodoc:
129
+ def validate_user(user)
130
+ raise(ArgumentError, "You have to specify a user or its id.") unless user
131
+ user = user.id if user.is_a?(::Pinterest::User)
132
+ user
133
+ end
134
+
135
+ # :nodoc:
136
+ def get_users_collection(path, fields, cursor, limit)
137
+ # Ensure only valid fields are used
138
+ fields = ensure_user_fields(fields)
139
+
140
+ # Perform the request
141
+ data = perform_network_request(
142
+ url: versioned_url(path),
143
+ query: cleanup_params({fields: fields.join(",")}),
144
+ pagination: (cursor || limit), cursor: cursor, limit: limit
145
+ )
146
+
147
+ # Create the collection
148
+ ::Pinterest::Collection.new(data.body, cursor, limit) { |user| ::Pinterest::User.create(user) }
149
+ end
150
+
151
+ # :nodoc:
152
+ def ensure_user_fields(fields = nil)
153
+ # Get fields and make sure only allowed fields are kept
154
+ ensure_array(fields, ::Pinterest::User::FIELDS).map(&:to_s) & ::Pinterest::User::FIELDS
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,94 @@
1
+ #
2
+ # This file is part of the pinterest-ruby gem. Copyright (C) 2017 and above Shogun <shogun@cowtech.it>.
3
+ # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
4
+ #
5
+
6
+ module Pinterest
7
+ # A list of errors returned by the client.
8
+ module Errors
9
+ # A dictionary that associates HTTP status codes to error classes.
10
+ CODES = {
11
+ 400 => "BadRequestError",
12
+ 401 => "AuthorizationError",
13
+ 403 => "PermissionsError",
14
+ 404 => "NotFoundError",
15
+ 405 => "MethodNotAllowedError",
16
+ 408 => "TimeoutError",
17
+ 429 => "RateLimitError",
18
+ 501 => "NotImplementedError"
19
+ }.freeze
20
+
21
+ # The base error.
22
+ class BaseError < RuntimeError
23
+ attr_accessor :code, :reason, :env
24
+
25
+ # Creates a new error.
26
+ #
27
+ # @param code [Fixnum] The error code.
28
+ # @param reason [String] The error message.
29
+ # @param env [Env] The environment.
30
+ def initialize(code, reason, env)
31
+ super("[#{code}] #{reason}")
32
+ @code = code
33
+ @reason = reason
34
+ @env = env
35
+ end
36
+ end
37
+
38
+ # Error raised in case of client errors.
39
+ class BadRequestError < BaseError
40
+ end
41
+
42
+ # Error raised in case of authorization errors.
43
+ class AuthorizationError < BaseError
44
+ end
45
+
46
+ # Error raised in case of permission errors.
47
+ class PermissionsError < BaseError
48
+ end
49
+
50
+ # Error raised in case of invalid requested entities.
51
+ class NotFoundError < BaseError
52
+ end
53
+
54
+ # Error raised in case of invalid requested actions.
55
+ class MethodNotAllowedError < BaseError
56
+ end
57
+
58
+ # Error raised in case of timeouts during network operations.
59
+ class TimeoutError < BaseError
60
+ end
61
+
62
+ # Error raised when rate-limited by Pinterest.
63
+ class RateLimitError < BaseError
64
+ end
65
+
66
+ # Error raised in case of unimplemented requested actions.
67
+ class NotImplementedError < BaseError
68
+ end
69
+
70
+ # Error raised in case of Pinterest server errors.
71
+ class ServerError < BaseError
72
+ end
73
+
74
+ # Creates a new error.
75
+ #
76
+ # @param response [Faraday::Response] The network response.
77
+ # @return [BaseError] A error object.
78
+ def self.create(response)
79
+ status = response.status
80
+ message = response.body["error"] || response.body["message"]
81
+
82
+ class_for_code(status).new(status, message, response.env)
83
+ end
84
+
85
+ # Get the class for a HTTP status code.
86
+ #
87
+ # @param status [Fixnum] The HTTP status code.
88
+ # @return [Class] The class.
89
+ def self.class_for_code(status)
90
+ klass = ::Pinterest::Errors::CODES.fetch(status, "ServerError")
91
+ Object.const_get("::Pinterest::Errors::#{klass}")
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,34 @@
1
+ #
2
+ # This file is part of the pinterest-ruby gem. Copyright (C) 2017 and above Shogun <shogun@cowtech.it>.
3
+ # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
4
+ #
5
+
6
+ module Pinterest
7
+ # A object representing a Pinterest board.
8
+ class Board < Entity
9
+ # The list of fields of the object.
10
+ FIELDS = ["id", "name", "url", "description", "creator", "created_at", "counts", "image"].freeze
11
+
12
+ attr_accessor(*FIELDS)
13
+
14
+ # Creates a new board object.
15
+ #
16
+ # @param data [Hash] The data of the new object. For a list of valid fields, see `Pinterest::Board::FIELDS`.
17
+ # @return [Pinterest::Board] The new board object.
18
+ def self.create(data)
19
+ data["created_at"] = Pinterest::Entity.parse_timestamp(data["created_at"]) if data["created_at"]
20
+ data["creator"] = Pinterest::User.create(data["creator"]) if data["creator"]
21
+ data["image"] = Pinterest::Image.new(data["image"]) if data["image"]
22
+
23
+ new(data)
24
+ end
25
+
26
+ # Serialize the object as a Hash that can be serialized as JSON.
27
+ #
28
+ # @param options [Hash] The options to use to serialize.
29
+ # @return [Hash] The serialized object.
30
+ def as_json(options = {})
31
+ super(::Pinterest::Board::FIELDS, options)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,42 @@
1
+ #
2
+ # This file is part of the pinterest-ruby gem. Copyright (C) 2017 and above Shogun <shogun@cowtech.it>.
3
+ # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
4
+ #
5
+
6
+ module Pinterest
7
+ # Base class for entity objects.
8
+ class Entity
9
+ # Parses a timestamps.
10
+ #
11
+ # @param timestamp [String] The string to parse.
12
+ # @return [DateTime] The parsed timestamp.
13
+ def self.parse_timestamp(timestamp)
14
+ return nil if !timestamp || timestamp.empty?
15
+ DateTime.parse(timestamp + "+00:00")
16
+ end
17
+
18
+ # Creates a new object.
19
+ #
20
+ # @param data [Hash] The data of the new object.
21
+ # @return [Pinterest::Board] The new object.
22
+ def initialize(data)
23
+ data.each do |field, value|
24
+ send("#{field}=", value) if respond_to?(field)
25
+ end
26
+ end
27
+
28
+ # Serialize the object as a Hash that can be serialized as JSON.
29
+ #
30
+ # @param options [Hash] The options to use to serialize.
31
+ # @return [Hash] The serialized object.
32
+ def as_json(fields, options = {})
33
+ fields.reduce({}) do |accu, field|
34
+ value = send(field)
35
+ value = value.as_json(options) if value.respond_to?(:as_json)
36
+
37
+ accu[field.to_sym] = value
38
+ accu
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,49 @@
1
+ #
2
+ # This file is part of the pinterest-ruby gem. Copyright (C) 2017 and above Shogun <shogun@cowtech.it>.
3
+ # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
4
+ #
5
+
6
+ module Pinterest
7
+ # A object representing a Pinterest image.
8
+ class Image
9
+ # Creates a new image object.
10
+ #
11
+ # @param data [Hash] The data of the new object.
12
+ # @return [Pinterest::Board] The new board object.
13
+ def initialize(data)
14
+ @data = data
15
+ end
16
+
17
+ # Returns the possible versions of a image.
18
+ #
19
+ # @return [Array] A list of possible version of a image.
20
+ def versions
21
+ @data.keys
22
+ end
23
+
24
+ # Returns the size of a version of the image.
25
+ #
26
+ # @param version [String] The version to inspect.
27
+ # @return [Hash] A hash with the `:width` and `:height` keys.
28
+ def size(version)
29
+ data = @data.fetch(version.to_s)
30
+ {width: data["width"], height: data["height"]}
31
+ end
32
+
33
+ # Returns the URL of a version of the image.
34
+ #
35
+ # @param version [String] The version to inspect.
36
+ # @return [String] The version URL.
37
+ def url(version)
38
+ @data.fetch(version.to_s)["url"]
39
+ end
40
+
41
+ # Serialize the object as a Hash that can be serialized as JSON.
42
+ #
43
+ # @param _ [Hash] The options to use to serialize.
44
+ # @return [Hash] The serialized object.
45
+ def as_json(_ = {})
46
+ @data
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,30 @@
1
+ #
2
+ # This file is part of the pinterest-ruby gem. Copyright (C) 2017 and above Shogun <shogun@cowtech.it>.
3
+ # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
4
+ #
5
+
6
+ module Pinterest
7
+ # A object representing a Pinterest interest (topic).
8
+ class Interest < Entity
9
+ # The list of fields of the object.
10
+ FIELDS = ["id", "name"].freeze
11
+
12
+ attr_accessor(*FIELDS)
13
+
14
+ # Creates a new interest (topic) object.
15
+ #
16
+ # @param data [Hash] The data of the new object. For a list of valid fields, see `Pinterest::Interest::FIELDS`.
17
+ # @return [Pinterest::Board] The new interest object.
18
+ def self.create(data)
19
+ new(data)
20
+ end
21
+
22
+ # Serialize the object as a Hash that can be serialized as JSON.
23
+ #
24
+ # @param options [Hash] The options to use to serialize.
25
+ # @return [Hash] The serialized object.
26
+ def as_json(options = {})
27
+ super(::Pinterest::Interest::FIELDS, options)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,43 @@
1
+ #
2
+ # This file is part of the pinterest-ruby gem. Copyright (C) 2017 and above Shogun <shogun@cowtech.it>.
3
+ # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
4
+ #
5
+
6
+ module Pinterest
7
+ # A object representing a Pinterest pin.
8
+ class Pin < Entity
9
+ # The list of fields of the object.
10
+ FIELDS = ["id", "link", "url", "creator", "board", "created_at", "note", "color", "counts", "media", "attribution", "image"].freeze
11
+
12
+ attr_accessor(*FIELDS)
13
+
14
+ # Creates a new pin object.
15
+ #
16
+ # @param data [Hash] The data of the new object. For a list of valid fields, see `Pinterest::Pin::FIELDS`.
17
+ # @return [Pinterest::Board] The new pin object.
18
+ def self.create(data)
19
+ data["created_at"] = Pinterest::Entity.parse_timestamp(data["created_at"]) if data["created_at"]
20
+ data = create_relationships(data)
21
+ new(data)
22
+ end
23
+
24
+ # Converts the relationships (user, board, images) of the pin to a gem object.
25
+ #
26
+ # @param data [Hash] The raw data.
27
+ # @return [Hash] The input data where relationships are gem objects.
28
+ def self.create_relationships(data)
29
+ data["creator"] = Pinterest::User.create(data["creator"]) if data["creator"]
30
+ data["board"] = Pinterest::Board.create(data["board"]) if data["board"]
31
+ data["image"] = Pinterest::Image.new(data["image"]) if data["image"]
32
+ data
33
+ end
34
+
35
+ # Serialize the object as a Hash that can be serialized as JSON.
36
+ #
37
+ # @param options [Hash] The options to use to serialize.
38
+ # @return [Hash] The serialized object.
39
+ def as_json(options = {})
40
+ super(::Pinterest::Pin::FIELDS, options)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,33 @@
1
+ #
2
+ # This file is part of the pinterest-ruby gem. Copyright (C) 2017 and above Shogun <shogun@cowtech.it>.
3
+ # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
4
+ #
5
+
6
+ module Pinterest
7
+ # A object representing a Pinterest user.
8
+ class User < Entity
9
+ # The list of fields of the object.
10
+ FIELDS = ["id", "username", "first_name", "last_name", "bio", "created_at", "counts", "image"].freeze
11
+
12
+ attr_accessor(*FIELDS)
13
+
14
+ # Creates a new user object.
15
+ #
16
+ # @param data [Hash] The data of the new object. For a list of valid fields, see `Pinterest::User::FIELDS`.
17
+ # @return [Pinterest::Board] The new user object.
18
+ def self.create(data)
19
+ data["created_at"] = Pinterest::Entity.parse_timestamp(data["created_at"]) if data["created_at"]
20
+ data["image"] = Pinterest::Image.new(data["image"]) if data["image"]
21
+
22
+ new(data)
23
+ end
24
+
25
+ # Serialize the object as a Hash that can be serialized as JSON.
26
+ #
27
+ # @param options [Hash] The options to use to serialize.
28
+ # @return [Hash] The serialized object.
29
+ def as_json(options = {})
30
+ super(::Pinterest::User::FIELDS, options)
31
+ end
32
+ end
33
+ end