pinboard 1.0.0 → 2026.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 58de47162982b5d30e0005929b84ba6e7a079f63
4
- data.tar.gz: ebca1893e1b75d58f66a879deb5b07a2b7c59381
2
+ SHA256:
3
+ metadata.gz: 470e83a49c0d4a8709f119308bf8df0a154324da3f823feaa8db47f472eab380
4
+ data.tar.gz: c9ee799fe886eb9b74c4607f40b0427f9be4ad8969de8dbc054cb5d75c51bedb
5
5
  SHA512:
6
- metadata.gz: 0af9563d66912472406c124c1b3904e0d0e6537da9c76090b24cb48644967bf76650cb4a06d6908f9be60e83b522ecaec36f63fe2d7e4d22adb6539dcdd89a04
7
- data.tar.gz: a4820f99cfac42ac1554d28e18cc8e7548ae38ca4c1adaf17b57c3a2a6cd1af2ffd848cf9f3fb03ad00c5666030fd08ae7cd081da571a83f5adb4c080e5a37b7
6
+ metadata.gz: 012ab916021944ef1876ee3ad951833cac0ca247fd2f6585a2c92c75953eb43e54206d9d8ab735a70ba3a5cf453588f3f75b33a3c7bb46dab9af3e9e1311b0a2
7
+ data.tar.gz: 2c93413d6b0341862471b9f81ab3c0b755b12e6f9531dd5e28b6638512c5a80ff6b371830941c1bf65f1d6d0df463397e6e2c0feaf8e30b47ec49addaa7c192b
@@ -0,0 +1,24 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+ branches: [master]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby-version: ['3.0', '3.1', '3.2', '3.3']
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - name: Set up Ruby ${{ matrix.ruby-version }}
19
+ uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby-version }}
22
+ bundler-cache: true
23
+ - name: Run specs
24
+ run: bundle exec rspec
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.3
data/Gemfile CHANGED
@@ -1,8 +1,3 @@
1
- source 'http://rubygems.org'
2
-
3
- platforms :jruby do
4
- gem 'jruby-openssl', '~> 0.7'
5
- end
6
-
1
+ source 'https://rubygems.org'
7
2
 
8
3
  gemspec
data/README.md CHANGED
@@ -1,10 +1,13 @@
1
1
  The Pinboard Ruby Gem
2
2
  =====================
3
- A Ruby wrapper for the [Pinboard API](http://pinboard.in/api/).
3
+ A Ruby wrapper for the [Pinboard API](https://pinboard.in/api/).
4
+
5
+ [![CI](https://github.com/ryw/pinboard/actions/workflows/ci.yml/badge.svg)](https://github.com/ryw/pinboard/actions/workflows/ci.yml)
4
6
 
5
7
  Installation
6
8
  ------------
7
- gem install pinboard
9
+
10
+ `gem install pinboard`
8
11
 
9
12
  Examples
10
13
  --------
@@ -12,8 +15,8 @@ Examples
12
15
  I'm currently exploring two API interfaces:
13
16
 
14
17
  ```ruby
15
- pinboard = Pinboard::Client.new(:token => 'your_api_token')
16
- posts = pinboard.posts
18
+ pinboard = Pinboard::Client.new(:token => 'your_api_token')
19
+ posts = pinboard.posts
17
20
  ```
18
21
 
19
22
  Your [API token](https://blog.pinboard.in/2012/07/api_authentication_tokens/) can be found on your
@@ -22,67 +25,55 @@ Your [API token](https://blog.pinboard.in/2012/07/api_authentication_tokens/) ca
22
25
  or:
23
26
 
24
27
  ```ruby
25
- posts = Pinboard::Post.all(:username => 'foo', :password => 'bar')
28
+ posts = Pinboard::Post.all(:username => 'foo', :password => 'bar')
26
29
  ```
27
30
  Both examples work.
28
31
 
29
32
  Passing arguments: (works only for the Client API Interface)
30
33
 
31
34
  ```ruby
32
- pinboard.posts(:tag => 'ruby') #all posts tagged 'ruby'
33
- pinboard.posts(:tag => 'ruby,pinboard') #all posts tagged 'ruby' and 'pinboard'
34
- pinboard.posts(:start => 20) #starting on the 20th post
35
- pinboard.posts(:results => 20) #return only first 20 matching posts
36
- pinboard.posts(:fromdt => 4.days.ago) #all posts in past 4 days
37
- pinboard.posts(:todt => 4.days.ago) #all posts up to 4 days ago
35
+ pinboard.posts(:tag => 'ruby') #all posts tagged 'ruby'
36
+ pinboard.posts(:tag => 'ruby,pinboard') #all posts tagged 'ruby' and 'pinboard'
37
+ pinboard.posts(:start => 20) #starting on the 20th post
38
+ pinboard.posts(:results => 20) #return only first 20 matching posts
39
+ pinboard.posts(:fromdt => 4.days.ago) #all posts in past 4 days
40
+ pinboard.posts(:todt => 4.days.ago) #all posts up to 4 days ago
38
41
  ```
39
42
 
40
43
  Adding new posts:
41
44
 
42
45
  ```ruby
43
- pinboard.add(:url => "http://example.com/", :description => 'Example post')
46
+ pinboard.add(:url => "http://example.com/", :description => 'Example post')
44
47
  ```
45
48
 
46
-
47
49
  Future Examples (I don't need them, so I haven't written them)
48
50
  --------------------------------------------------------------
49
51
 
50
- pinboard.posts(:meta => true) #include meta data in post models
52
+ `pinboard.posts(:meta => true) #include meta data in post models`
51
53
 
52
54
  Ruby Support & Continuous Integration
53
55
  -------------------------------------
54
- I am using [travis-ci.org](http://travis-ci.org) for continuous
55
- integration and support of the following rubies in rvm:
56
-
57
- * 1.9.3
58
- * 2.0.0
59
- * 2.1
60
- * 2.2
61
- * jruby
62
- * ruby-head
63
-
64
- [![Build Status](https://secure.travis-ci.org/ryw/pinboard.png)](http://travis-ci.org/ryw/pinboard)
65
-
66
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/ryw/pinboard)
56
+ Tested on Ruby 3.0, 3.1, 3.2, and 3.3 via GitHub Actions.
67
57
 
68
58
  Links
69
59
  -----
70
- * [Pinboard API Documentation](http://pinboard.in/api/)
60
+
61
+ * [Pinboard API Documentation](https://pinboard.in/api/)
71
62
 
72
63
  How to Contribute
73
64
  -----------------
74
65
  If you find what looks like a bug:
75
66
 
76
- * Check the [GitHub issue tracker](http://github.com/ryw/pinboard/issues/)
77
- to see if anyone else has had the same issue.
78
- * If you dont see anything, create an issue with information on how to reproduce it.
67
+ * Check the [GitHub issue tracker](https://github.com/ryw/pinboard/issues/)
68
+ to see if anyone else has had the same issue.
69
+ * If you don't see anything, create an issue with information on how to reproduce it.
79
70
 
80
71
  If you want to contribute an enhancement or a fix:
81
72
 
82
- * Fork the [project on github](http://github.com/ryw/pinboard).
83
- * Make your changes with specs.
84
- * Commit the changes without messing with the Rakefile, VERSION, or history.
85
- * Send me a pull request.
73
+ * Fork the [project on github](https://github.com/ryw/pinboard).
74
+ * Make your changes with specs.
75
+ * Commit the changes without messing with the Rakefile, VERSION, or history.
76
+ * Send me a pull request.
86
77
 
87
78
  TODO
88
79
  ----
@@ -96,5 +87,5 @@ License
96
87
 
97
88
  See [MIT-LICENSE](MIT-LICENSE) for details.
98
89
 
99
- Copyright (c) 2011 Ryan Walker.
90
+ Copyright (c) 2011-2026 Ryan Walker.
100
91
  Copyright (c) 2013-2016 Jan-Erik Rediger.
@@ -1,13 +1,14 @@
1
- require 'httparty'
1
+ require 'net/http'
2
+ require 'uri'
2
3
  require 'time'
4
+ require 'pinboard/xml_parser'
3
5
 
4
6
  module Pinboard
5
7
  # Raised when API returns failure
6
8
  Error = Class.new(StandardError)
7
9
 
8
10
  class Client
9
- include HTTParty
10
- base_uri 'api.pinboard.in:443/v1'
11
+ BASE_URI = URI("https://api.pinboard.in:443/v1")
11
12
 
12
13
  # Construct a new instance of the client
13
14
  #
@@ -39,10 +40,9 @@ module Pinboard
39
40
  # @option params [Integer] :meta include a change detection signature for each bookmark
40
41
  # @return [Array<Post>] the list of bookmarks
41
42
  def posts(params = {})
42
- options = create_params(params)
43
- posts = self.class.get('/posts/all', options)['posts']['post']
43
+ posts = http_get('/posts/all', params)['posts']['post']
44
44
  posts = [] if posts.nil?
45
- posts = [posts] if posts.class != Array
45
+ posts = [posts] unless posts.is_a?(Array)
46
46
  posts.map { |p| Post.new(Util.symbolize_keys(p)) }
47
47
  end
48
48
 
@@ -57,10 +57,9 @@ module Pinboard
57
57
  def get(params = {})
58
58
  params[:dt] = params[:dt].to_date.to_s if params.is_a? Time
59
59
  params[:meta] = params[:meta] ? 'yes' : 'no' if params.has_key?(:meta)
60
- options = create_params(params)
61
- posts = self.class.get('/posts/get', options)['posts']['post']
60
+ posts = http_get('/posts/get', params)['posts']['post']
62
61
  posts = [] if posts.nil?
63
- posts = [posts] if posts.class != Array
62
+ posts = [posts] unless posts.is_a?(Array)
64
63
  posts.map { |p| Post.new(Util.symbolize_keys(p)) }
65
64
  end
66
65
 
@@ -71,15 +70,15 @@ module Pinboard
71
70
  # @param [String] url
72
71
  # @return [Hash<String, Array>]
73
72
  def suggest(url)
74
- options = create_params({url: url})
75
- suggested = self.class.get('/posts/suggest', options)['suggested']
76
- popular = suggested['popular']
77
- popular = [] if popular.nil?
78
- popular = [popular] if popular.class != Array
73
+ suggested = http_get('/posts/suggest', {url: url})['suggested']
79
74
 
80
- recommended = suggested['recommended']
81
- recommended = [] if recommended.nil?
82
- recommended = [recommended] if recommended.class != Array
75
+ if suggested.nil?
76
+ popular = []
77
+ recommended = []
78
+ else
79
+ popular = Array(suggested['popular'])
80
+ recommended = Array(suggested['recommended'])
81
+ end
83
82
 
84
83
  {:popular => popular, :recommended => recommended}
85
84
  end
@@ -118,8 +117,7 @@ module Pinboard
118
117
  end
119
118
  end
120
119
 
121
- options = create_params(params)
122
- result_code = self.class.post('/posts/add', options).parsed_response["result"]["code"]
120
+ result_code = http_post('/posts/add', params)["result"]["code"]
123
121
 
124
122
  raise Error.new(result_code) if result_code != "done"
125
123
 
@@ -133,8 +131,7 @@ module Pinboard
133
131
  #
134
132
  # @return [Time] the time a bookmark was modified
135
133
  def update
136
- options = create_params({})
137
- time = self.class.get('/posts/update', options)["update"]["time"]
134
+ time = http_get('/posts/update', {})["update"]["time"]
138
135
 
139
136
  Time.parse time
140
137
  end
@@ -148,8 +145,7 @@ module Pinboard
148
145
  #
149
146
  # @return [Array<Post>] the list of recent posts
150
147
  def recent(params={})
151
- options = create_params(params)
152
- posts = self.class.get('/posts/recent', options)['posts']['post']
148
+ posts = http_get('/posts/recent', params)['posts']['post']
153
149
  posts = [] if posts.nil?
154
150
  posts = [*posts]
155
151
  posts.map { |p| Post.new(Util.symbolize_keys(p)) }
@@ -165,8 +161,7 @@ module Pinboard
165
161
  params = {}
166
162
  params[:tag] = tag if tag
167
163
 
168
- options = create_params(params)
169
- dates = self.class.get('/posts/dates', options)['dates']['date']
164
+ dates = http_get('/posts/dates', params)['dates']['date']
170
165
  dates = [] if dates.nil?
171
166
  dates = [*dates]
172
167
  dates.each_with_object({}) { |value, hash|
@@ -183,8 +178,7 @@ module Pinboard
183
178
  # @raise [Error] if result code is not "done"
184
179
  def delete(url)
185
180
  params = { url: url }
186
- options = create_params(params)
187
- result_code = self.class.get('/posts/delete', options).parsed_response["result"]["code"]
181
+ result_code = http_get('/posts/delete', params)["result"]["code"]
188
182
 
189
183
  raise Error.new(result_code) if result_code != "done"
190
184
 
@@ -196,8 +190,7 @@ module Pinboard
196
190
  #
197
191
  # @return [Array<Tag>] List of all tags
198
192
  def tags_get(params={})
199
- options = create_params(params)
200
- tags = self.class.get('/tags/get', options)['tags']['tag']
193
+ tags = http_get('/tags/get', params)['tags']['tag']
201
194
  tags = [] if tags.nil?
202
195
  tags = [*tags]
203
196
  tags.map { |p| Tag.new(Util.symbolize_keys(p)) }
@@ -215,8 +208,7 @@ module Pinboard
215
208
  params[:old] = old_tag
216
209
  params[:new] = new_tag if new_tag
217
210
 
218
- options = create_params(params)
219
- result_code = self.class.get('/tags/rename', options).parsed_response["result"]
211
+ result_code = http_get('/tags/rename', params)["result"]
220
212
 
221
213
  raise Error.new(result_code) if result_code != "done"
222
214
 
@@ -230,8 +222,7 @@ module Pinboard
230
222
  def tags_delete(tag)
231
223
  params = { tag: tag }
232
224
 
233
- options = create_params(params)
234
- self.class.get('/tags/delete', options)
225
+ http_get('/tags/delete', params)
235
226
  nil
236
227
  end
237
228
 
@@ -239,14 +230,14 @@ module Pinboard
239
230
  #
240
231
  # @return [String]
241
232
  def user_secret()
242
- self.class.get('/user/secret', create_params({}))['result']
233
+ http_get('/user/secret', {})['result']
243
234
  end
244
235
 
245
236
  # Returns the user's API token (for making API calls without a password)
246
237
  #
247
238
  # @return [String]
248
239
  def user_api_token()
249
- self.class.get('/user/api_token', create_params({}))['result']
240
+ http_get('/user/api_token', {})['result']
250
241
  end
251
242
 
252
243
 
@@ -254,8 +245,7 @@ module Pinboard
254
245
  #
255
246
  # @return [Array<Note>] list of notes
256
247
  def notes_list
257
- options = create_params({})
258
- notes = self.class.get('/notes/list', options)['notes']['note']
248
+ notes = http_get('/notes/list', {})['notes']['note']
259
249
  notes = [] if notes.nil?
260
250
  notes = [*notes]
261
251
  notes.map { |p| Note.new(Util.symbolize_keys(p)) }
@@ -266,8 +256,7 @@ module Pinboard
266
256
  #
267
257
  # @return [Note] the note
268
258
  def notes_get(id)
269
- options = create_params({})
270
- note = self.class.get("/notes/#{id}", options)['note']
259
+ note = http_get("/notes/#{id}", {})['note']
271
260
 
272
261
  return nil unless note
273
262
 
@@ -284,21 +273,40 @@ module Pinboard
284
273
  end
285
274
 
286
275
  private
287
- # Construct params hash for HTTP request
288
- #
289
- # @param [Hash] params Query arguments to include in request
290
- # @return [Hash] Options hash for request
291
- def create_params params
292
- options = {}
293
- options[:query] = params
294
-
295
- if @auth_token
296
- options[:query].merge!(auth_token: @auth_token)
297
- else
298
- options[:basic_auth] = @auth
276
+
277
+ def http_get(path, params)
278
+ uri = build_uri(path, params)
279
+ request = Net::HTTP::Get.new(uri)
280
+ apply_auth(request, uri)
281
+ execute(uri, request)
282
+ end
283
+
284
+ def http_post(path, params)
285
+ uri = build_uri(path, params)
286
+ request = Net::HTTP::Post.new(uri)
287
+ apply_auth(request, uri)
288
+ execute(uri, request)
289
+ end
290
+
291
+ def build_uri(path, params)
292
+ uri = URI(BASE_URI.to_s + path)
293
+ query = params.transform_keys(&:to_s)
294
+ query['auth_token'] = @auth_token if @auth_token
295
+ uri.query = URI.encode_www_form(query) unless query.empty?
296
+ uri
297
+ end
298
+
299
+ def apply_auth(request, uri)
300
+ if @auth && !@auth_token
301
+ request.basic_auth(@auth[:username], @auth[:password])
299
302
  end
303
+ end
300
304
 
301
- options
305
+ def execute(uri, request)
306
+ response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
307
+ http.request(request)
308
+ end
309
+ XMLParser.parse(response.body)
302
310
  end
303
311
  end
304
312
  end
data/lib/pinboard/post.rb CHANGED
@@ -2,9 +2,7 @@ module Pinboard
2
2
  class Post < Struct.new(:href, :description, :extended, :tag, :time, :replace, :shared, :toread)
3
3
  def self.all(options={})
4
4
  client = Pinboard::Client.new(options)
5
- posts = client.class.get('/posts/all',
6
- :basic_auth => options)['posts']['post']
7
- posts.map { |p| Post.new(Util.symbolize_keys(p)) }
5
+ client.posts
8
6
  end
9
7
 
10
8
  def initialize(attributes={})
data/lib/pinboard/util.rb CHANGED
@@ -3,9 +3,8 @@ module Pinboard
3
3
  extend self
4
4
 
5
5
  def symbolize_keys(hash)
6
- hash.inject({}) do |options, (key, value)|
6
+ hash.each_with_object({}) do |(key, value), options|
7
7
  options[(key.to_sym rescue key) || key] = value
8
- options
9
8
  end
10
9
  end
11
10
 
@@ -0,0 +1,41 @@
1
+ require 'rexml/document'
2
+
3
+ module Pinboard
4
+ module XMLParser
5
+ module_function
6
+
7
+ def parse(xml_string)
8
+ doc = REXML::Document.new(xml_string)
9
+ {doc.root.name => convert_element(doc.root)}
10
+ end
11
+
12
+ def convert_element(element)
13
+ result = {}
14
+
15
+ element.attributes.each { |name, value| result[name] = value }
16
+
17
+ children = {}
18
+ element.each_element do |child|
19
+ (children[child.name] ||= []) << child
20
+ end
21
+
22
+ children.each do |name, elements|
23
+ if elements.size == 1
24
+ result[name] = convert_element(elements.first)
25
+ else
26
+ result[name] = elements.map { |e| convert_element(e) }
27
+ end
28
+ end
29
+
30
+ text = element.texts.map(&:value).join.strip
31
+
32
+ if result.empty?
33
+ return text.empty? ? nil : text
34
+ elsif !text.empty?
35
+ result['__content__'] = text
36
+ end
37
+
38
+ result
39
+ end
40
+ end
41
+ end
data/lib/pinboard.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'pinboard/util'
2
+ require 'pinboard/xml_parser'
2
3
  require 'pinboard/client'
3
4
  require 'pinboard/post'
4
5
  require 'pinboard/tag'
@@ -11,7 +12,8 @@ module Pinboard
11
12
  end
12
13
 
13
14
  def endpoint
14
- Pinboard::Client.base_uri
15
+ uri = Pinboard::Client::BASE_URI
16
+ "#{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}"
15
17
  end
16
18
  end
17
19
  end
data/pinboard.gemspec CHANGED
@@ -1,26 +1,17 @@
1
1
  Gem::Specification.new do |s|
2
- s.add_development_dependency 'yard', '~> 0.7'
3
- s.add_development_dependency 'rake', '~> 0.9'
4
- s.add_development_dependency 'rspec', '~> 2.6'
5
- s.add_development_dependency 'webmock', '~> 1.6'
6
- s.add_development_dependency 'guard-rspec', '~> 0.5'
7
- s.add_development_dependency 'guard-bundler'
8
- s.add_development_dependency 'libnotify'
9
- s.add_development_dependency 'rb-inotify'
10
- s.add_development_dependency 'rb-fsevent'
11
- s.add_development_dependency 'terminal-notifier-guard'
2
+ s.add_development_dependency 'yard'
3
+ s.add_development_dependency 'rake'
4
+ s.add_development_dependency 'rspec'
5
+ s.add_development_dependency 'webmock'
12
6
 
13
- s.add_runtime_dependency 'httparty', '= 0.11.0'
14
7
  s.name = 'pinboard'
15
- s.version = '1.0.0'
16
- s.date = '2016-01-05'
8
+ s.version = '2026.2.0'
17
9
  s.summary = "Ruby wrapper for the Pinboard API"
18
10
  s.description = "Ruby wrapper for the Pinboard API"
19
- s.authors = ["Ry Waker", "Jan-Erik Rediger"]
11
+ s.authors = ["Ry Waker", "Jan-Erik Rediger", "Nicholas E. Rabenau"]
20
12
  s.email = 'ry@rywalker.com'
21
13
  s.require_paths = ['lib']
22
14
  s.files = `git ls-files`.split("\n")
23
- s.test_files = `git ls-files -- spec/*`.split("\n")
24
- s.homepage = 'http://github.com/ryw/pinboard'
25
- s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
15
+ s.homepage = 'https://github.com/ryw/pinboard'
16
+ s.required_ruby_version = '>= 3.0'
26
17
  end
data/spec/helper.rb CHANGED
@@ -2,11 +2,6 @@ require 'pinboard'
2
2
  require 'rspec'
3
3
  require 'webmock/rspec'
4
4
 
5
- def auth_params
6
- { :username => 'user',
7
- :password => 'pass' }
8
- end
9
-
10
5
  def a_get(path)
11
6
  a_request(:get, Pinboard.endpoint + path)
12
7
  end
@@ -20,7 +15,7 @@ def stub_post(path)
20
15
  end
21
16
 
22
17
  def uri(path)
23
- "https://#{auth_params[:username]}:#{auth_params[:password]}@api.pinboard.in/v1/#{path}"
18
+ "https://api.pinboard.in/v1/#{path}"
24
19
  end
25
20
 
26
21
  def fixture_path
@@ -2,7 +2,7 @@ require 'helper'
2
2
 
3
3
  describe Pinboard::Client do
4
4
  describe "#posts" do
5
- let(:client) { Pinboard::Client.new(auth_params) }
5
+ let(:client) { Pinboard::Client.new }
6
6
 
7
7
  context "when there are many posts" do
8
8
  before do
@@ -30,7 +30,7 @@ describe Pinboard::Client do
30
30
  :time => Time.parse("2011-07-26T17:52:04Z")),
31
31
  ]
32
32
 
33
- client.posts.should == expected
33
+ expect(client.posts).to eq(expected)
34
34
  end
35
35
  end
36
36
 
@@ -42,7 +42,7 @@ describe Pinboard::Client do
42
42
  end
43
43
 
44
44
  it "still returns an array" do
45
- client.posts.class.should == Array
45
+ expect(client.posts.class).to eq(Array)
46
46
  end
47
47
  end
48
48
 
@@ -54,13 +54,13 @@ describe Pinboard::Client do
54
54
  end
55
55
 
56
56
  it "returns an empty array" do
57
- client.posts.should == []
57
+ expect(client.posts).to eq([])
58
58
  end
59
59
  end
60
60
  end
61
61
 
62
62
  describe "#delete" do
63
- let(:client) { Pinboard::Client.new(auth_params) }
63
+ let(:client) { Pinboard::Client.new }
64
64
 
65
65
  context "when there are many posts" do
66
66
  before do
@@ -89,7 +89,7 @@ describe Pinboard::Client do
89
89
 
90
90
  describe "#add" do
91
91
  let(:client) do
92
- Pinboard::Client.new(auth_params)
92
+ Pinboard::Client.new
93
93
  end
94
94
 
95
95
  context "where the post does not exist yet" do
@@ -237,7 +237,7 @@ describe Pinboard::Client do
237
237
  end
238
238
 
239
239
  describe "#update" do
240
- let(:client) { Pinboard::Client.new(auth_params) }
240
+ let(:client) { Pinboard::Client.new }
241
241
 
242
242
  before do
243
243
  stub_get("posts/update?").
@@ -248,12 +248,12 @@ describe Pinboard::Client do
248
248
  it "returns the time of last update" do
249
249
  expected = Time.parse "2013-04-20 13:58:56 +0200"
250
250
 
251
- client.update.should == expected
251
+ expect(client.update).to eq(expected)
252
252
  end
253
253
  end
254
254
 
255
255
  describe "#recent" do
256
- let(:client) { Pinboard::Client.new(auth_params) }
256
+ let(:client) { Pinboard::Client.new }
257
257
 
258
258
  before do
259
259
  stub_get("posts/recent?").
@@ -279,12 +279,12 @@ describe Pinboard::Client do
279
279
  :time => Time.parse("2011-07-26T17:52:04Z")),
280
280
  ]
281
281
 
282
- client.recent.should == expected
282
+ expect(client.recent).to eq(expected)
283
283
  end
284
284
  end
285
285
 
286
286
  describe "#dates" do
287
- let(:client) { Pinboard::Client.new(auth_params) }
287
+ let(:client) { Pinboard::Client.new }
288
288
 
289
289
  context "unfiltered" do
290
290
  before do
@@ -301,7 +301,7 @@ describe Pinboard::Client do
301
301
  "2013-04-17" => 3
302
302
  }
303
303
 
304
- client.dates.should == expected
304
+ expect(client.dates).to eq(expected)
305
305
  end
306
306
  end
307
307
 
@@ -320,13 +320,13 @@ describe Pinboard::Client do
320
320
  "2013-04-17" => 3
321
321
  }
322
322
 
323
- client.dates("tag").should == expected
323
+ expect(client.dates("tag")).to eq(expected)
324
324
  end
325
325
  end
326
326
  end
327
327
 
328
328
  describe "#notes_list" do
329
- let(:client) { Pinboard::Client.new(auth_params) }
329
+ let(:client) { Pinboard::Client.new }
330
330
  before do
331
331
  stub_get("notes/list?").
332
332
  to_return(:body => fixture("notes_list.xml"),
@@ -335,13 +335,13 @@ describe Pinboard::Client do
335
335
 
336
336
  it "returns a list of notes" do
337
337
  notes = client.notes_list
338
- notes.size.should == 2
339
- notes.first.title.should == "Paul Graham on Hirin' The Ladies"
338
+ expect(notes.size).to eq(2)
339
+ expect(notes.first.title).to eq("Paul Graham on Hirin' The Ladies")
340
340
  end
341
341
  end
342
342
 
343
343
  describe "#user_secret" do
344
- let(:client) { Pinboard::Client.new(auth_params) }
344
+ let(:client) { Pinboard::Client.new }
345
345
  before do
346
346
  stub_get("user/secret?").
347
347
  to_return(:body => fixture("user_secret.xml"),
@@ -350,12 +350,12 @@ describe Pinboard::Client do
350
350
 
351
351
  it "returns the user's secret RSS key" do
352
352
  secret = client.user_secret
353
- secret.should == "6493a84f72d86e7de130"
353
+ expect(secret).to eq("6493a84f72d86e7de130")
354
354
  end
355
355
  end
356
356
 
357
357
  describe "#user_api_token" do
358
- let(:client) { Pinboard::Client.new(auth_params) }
358
+ let(:client) { Pinboard::Client.new }
359
359
  before do
360
360
  stub_get("user/api_token?").
361
361
  to_return(:body => fixture("user_api_token.xml"),
@@ -364,12 +364,12 @@ describe Pinboard::Client do
364
364
 
365
365
  it "returns the user's API token" do
366
366
  token = client.user_api_token
367
- token.should == "XOG86E7JIYMI"
367
+ expect(token).to eq("XOG86E7JIYMI")
368
368
  end
369
369
  end
370
370
 
371
371
  describe "#get" do
372
- let(:client) { Pinboard::Client.new(auth_params) }
372
+ let(:client) { Pinboard::Client.new }
373
373
 
374
374
  context "when there are many posts" do
375
375
  before do
@@ -397,7 +397,7 @@ describe Pinboard::Client do
397
397
  :time => Time.parse("2011-07-26T17:52:04Z")),
398
398
  ]
399
399
 
400
- client.get.should == expected
400
+ expect(client.get).to eq(expected)
401
401
  end
402
402
  end
403
403
 
@@ -409,7 +409,7 @@ describe Pinboard::Client do
409
409
  end
410
410
 
411
411
  it "still returns an array" do
412
- client.get.class.should == Array
412
+ expect(client.get.class).to eq(Array)
413
413
  end
414
414
  end
415
415
 
@@ -421,13 +421,13 @@ describe Pinboard::Client do
421
421
  end
422
422
 
423
423
  it "returns an empty array" do
424
- client.get.should == []
424
+ expect(client.get).to eq([])
425
425
  end
426
426
  end
427
427
  end
428
428
 
429
429
  describe "#suggest" do
430
- let(:client) { Pinboard::Client.new(auth_params) }
430
+ let(:client) { Pinboard::Client.new }
431
431
  let(:url) { 'http://example.com' }
432
432
 
433
433
  context "when there are many popular and recommended tags" do
@@ -440,8 +440,8 @@ describe Pinboard::Client do
440
440
 
441
441
  it "returns a collections of tags" do
442
442
  suggest = client.suggest(url)
443
- suggest[:popular].should == %w[blog blogs]
444
- suggest[:recommended].should == %w[writing weblog]
443
+ expect(suggest[:popular]).to eq(%w[blog blogs])
444
+ expect(suggest[:recommended]).to eq(%w[writing weblog])
445
445
  end
446
446
  end
447
447
 
@@ -455,8 +455,8 @@ describe Pinboard::Client do
455
455
 
456
456
  it "still returns an array" do
457
457
  suggest = client.suggest(url)
458
- suggest[:popular].class.should == Array
459
- suggest[:recommended].class.should == Array
458
+ expect(suggest[:popular].class).to eq(Array)
459
+ expect(suggest[:recommended].class).to eq(Array)
460
460
  end
461
461
  end
462
462
 
@@ -470,8 +470,8 @@ describe Pinboard::Client do
470
470
 
471
471
  it "returns an empty array" do
472
472
  suggest = client.suggest(url)
473
- suggest[:popular].should == []
474
- suggest[:recommended].should == []
473
+ expect(suggest[:popular]).to eq([])
474
+ expect(suggest[:recommended]).to eq([])
475
475
  end
476
476
  end
477
477
  end
@@ -3,7 +3,7 @@ require 'helper'
3
3
  describe Pinboard::Post do
4
4
 
5
5
  describe ".all" do
6
- let(:posts) { Pinboard::Post.all(auth_params) }
6
+ let(:posts) { Pinboard::Post.all }
7
7
 
8
8
  before do
9
9
  stub_get("posts/all").
@@ -12,16 +12,16 @@ describe Pinboard::Post do
12
12
  end
13
13
 
14
14
  it "returns a collection" do
15
- posts.count.should == 2
15
+ expect(posts.count).to eq(2)
16
16
  end
17
17
 
18
18
  it "loads posts with valid attributes" do
19
19
  post = posts.first
20
- post.href.should == "http://foo.com/"
21
- post.description.should == "Foo!"
22
- post.extended.should == "long description Foo"
23
- post.tag.should == ["foo", "bar"]
24
- post.time.should == Time.parse('Tue Jul 26 17:52:04 UTC 2011')
20
+ expect(post.href).to eq("http://foo.com/")
21
+ expect(post.description).to eq("Foo!")
22
+ expect(post.extended).to eq("long description Foo")
23
+ expect(post.tag).to eq(["foo", "bar"])
24
+ expect(post.time).to eq(Time.parse('Tue Jul 26 17:52:04 UTC 2011'))
25
25
  end
26
26
  end
27
27
 
@@ -36,12 +36,11 @@ describe Pinboard::Post do
36
36
  }
37
37
 
38
38
  it "initializes attributes" do
39
- post.href.should == 'http://foo.com'
40
- post.description.should == 'Foo!'
41
- post.extended.should == "long description Foo"
42
- post.tag.should == %w{rspec pinboard}
43
- post.time.should == Time.mktime(2011, 1, 1)
39
+ expect(post.href).to eq('http://foo.com')
40
+ expect(post.description).to eq('Foo!')
41
+ expect(post.extended).to eq("long description Foo")
42
+ expect(post.tag).to eq(%w{rspec pinboard})
43
+ expect(post.time).to eq(Time.mktime(2011, 1, 1))
44
44
  end
45
45
  end
46
46
  end
47
-
@@ -5,7 +5,7 @@ describe Pinboard do
5
5
  describe ".new" do
6
6
 
7
7
  it "returns a Pinboard client" do
8
- Pinboard.new.should be_a Pinboard::Client
8
+ expect(Pinboard.new).to be_a Pinboard::Client
9
9
  end
10
10
 
11
11
  end
@@ -13,7 +13,7 @@ describe Pinboard do
13
13
  describe ".endpoint" do
14
14
 
15
15
  it "sets the endpoint" do
16
- Pinboard.endpoint.should == 'https://api.pinboard.in:443/v1'
16
+ expect(Pinboard.endpoint).to eq('https://api.pinboard.in:443/v1')
17
17
  end
18
18
 
19
19
  end
metadata CHANGED
@@ -1,88 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pinboard
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2026.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ry Waker
8
8
  - Jan-Erik Rediger
9
- autorequire:
9
+ - Nicholas E. Rabenau
10
+ autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2016-01-05 00:00:00.000000000 Z
13
+ date: 2026-02-22 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: yard
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - "~>"
19
- - !ruby/object:Gem::Version
20
- version: '0.7'
21
- type: :development
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - "~>"
26
- - !ruby/object:Gem::Version
27
- version: '0.7'
28
- - !ruby/object:Gem::Dependency
29
- name: rake
30
- requirement: !ruby/object:Gem::Requirement
31
- requirements:
32
- - - "~>"
33
- - !ruby/object:Gem::Version
34
- version: '0.9'
35
- type: :development
36
- prerelease: false
37
- version_requirements: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - "~>"
40
- - !ruby/object:Gem::Version
41
- version: '0.9'
42
- - !ruby/object:Gem::Dependency
43
- name: rspec
44
- requirement: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - "~>"
47
- - !ruby/object:Gem::Version
48
- version: '2.6'
49
- type: :development
50
- prerelease: false
51
- version_requirements: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - "~>"
54
- - !ruby/object:Gem::Version
55
- version: '2.6'
56
- - !ruby/object:Gem::Dependency
57
- name: webmock
58
- requirement: !ruby/object:Gem::Requirement
59
- requirements:
60
- - - "~>"
61
- - !ruby/object:Gem::Version
62
- version: '1.6'
63
- type: :development
64
- prerelease: false
65
- version_requirements: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - "~>"
68
- - !ruby/object:Gem::Version
69
- version: '1.6'
70
- - !ruby/object:Gem::Dependency
71
- name: guard-rspec
72
- requirement: !ruby/object:Gem::Requirement
73
- requirements:
74
- - - "~>"
75
- - !ruby/object:Gem::Version
76
- version: '0.5'
77
- type: :development
78
- prerelease: false
79
- version_requirements: !ruby/object:Gem::Requirement
80
- requirements:
81
- - - "~>"
82
- - !ruby/object:Gem::Version
83
- version: '0.5'
84
- - !ruby/object:Gem::Dependency
85
- name: guard-bundler
86
17
  requirement: !ruby/object:Gem::Requirement
87
18
  requirements:
88
19
  - - ">="
@@ -96,21 +27,7 @@ dependencies:
96
27
  - !ruby/object:Gem::Version
97
28
  version: '0'
98
29
  - !ruby/object:Gem::Dependency
99
- name: libnotify
100
- requirement: !ruby/object:Gem::Requirement
101
- requirements:
102
- - - ">="
103
- - !ruby/object:Gem::Version
104
- version: '0'
105
- type: :development
106
- prerelease: false
107
- version_requirements: !ruby/object:Gem::Requirement
108
- requirements:
109
- - - ">="
110
- - !ruby/object:Gem::Version
111
- version: '0'
112
- - !ruby/object:Gem::Dependency
113
- name: rb-inotify
30
+ name: rake
114
31
  requirement: !ruby/object:Gem::Requirement
115
32
  requirements:
116
33
  - - ">="
@@ -124,7 +41,7 @@ dependencies:
124
41
  - !ruby/object:Gem::Version
125
42
  version: '0'
126
43
  - !ruby/object:Gem::Dependency
127
- name: rb-fsevent
44
+ name: rspec
128
45
  requirement: !ruby/object:Gem::Requirement
129
46
  requirements:
130
47
  - - ">="
@@ -138,7 +55,7 @@ dependencies:
138
55
  - !ruby/object:Gem::Version
139
56
  version: '0'
140
57
  - !ruby/object:Gem::Dependency
141
- name: terminal-notifier-guard
58
+ name: webmock
142
59
  requirement: !ruby/object:Gem::Requirement
143
60
  requirements:
144
61
  - - ">="
@@ -151,32 +68,17 @@ dependencies:
151
68
  - - ">="
152
69
  - !ruby/object:Gem::Version
153
70
  version: '0'
154
- - !ruby/object:Gem::Dependency
155
- name: httparty
156
- requirement: !ruby/object:Gem::Requirement
157
- requirements:
158
- - - '='
159
- - !ruby/object:Gem::Version
160
- version: 0.11.0
161
- type: :runtime
162
- prerelease: false
163
- version_requirements: !ruby/object:Gem::Requirement
164
- requirements:
165
- - - '='
166
- - !ruby/object:Gem::Version
167
- version: 0.11.0
168
71
  description: Ruby wrapper for the Pinboard API
169
72
  email: ry@rywalker.com
170
73
  executables: []
171
74
  extensions: []
172
75
  extra_rdoc_files: []
173
76
  files:
174
- - ".autotest"
77
+ - ".github/workflows/ci.yml"
175
78
  - ".gitignore"
176
79
  - ".rspec"
177
- - ".travis.yml"
80
+ - ".ruby-version"
178
81
  - Gemfile
179
- - Guardfile
180
82
  - MIT-LICENSE
181
83
  - README.md
182
84
  - Rakefile
@@ -186,6 +88,7 @@ files:
186
88
  - lib/pinboard/post.rb
187
89
  - lib/pinboard/tag.rb
188
90
  - lib/pinboard/util.rb
91
+ - lib/pinboard/xml_parser.rb
189
92
  - pinboard.gemspec
190
93
  - spec/fixtures/created.xml
191
94
  - spec/fixtures/dates.xml
@@ -208,10 +111,10 @@ files:
208
111
  - spec/pinboard/client_spec.rb
209
112
  - spec/pinboard/post_spec.rb
210
113
  - spec/pinboard_spec.rb
211
- homepage: http://github.com/ryw/pinboard
114
+ homepage: https://github.com/ryw/pinboard
212
115
  licenses: []
213
116
  metadata: {}
214
- post_install_message:
117
+ post_install_message:
215
118
  rdoc_options: []
216
119
  require_paths:
217
120
  - lib
@@ -219,38 +122,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
219
122
  requirements:
220
123
  - - ">="
221
124
  - !ruby/object:Gem::Version
222
- version: '0'
125
+ version: '3.0'
223
126
  required_rubygems_version: !ruby/object:Gem::Requirement
224
127
  requirements:
225
128
  - - ">="
226
129
  - !ruby/object:Gem::Version
227
- version: 1.3.6
130
+ version: '0'
228
131
  requirements: []
229
- rubyforge_project:
230
- rubygems_version: 2.5.1
231
- signing_key:
132
+ rubygems_version: 3.5.22
133
+ signing_key:
232
134
  specification_version: 4
233
135
  summary: Ruby wrapper for the Pinboard API
234
- test_files:
235
- - spec/fixtures/created.xml
236
- - spec/fixtures/dates.xml
237
- - spec/fixtures/dates_filtered.xml
238
- - spec/fixtures/deleted.xml
239
- - spec/fixtures/missing_description.xml
240
- - spec/fixtures/missing_url.xml
241
- - spec/fixtures/multiple_posts.xml
242
- - spec/fixtures/multiple_suggest.xml
243
- - spec/fixtures/no_posts.xml
244
- - spec/fixtures/no_suggest.xml
245
- - spec/fixtures/not_found.xml
246
- - spec/fixtures/notes_list.xml
247
- - spec/fixtures/post_update.xml
248
- - spec/fixtures/single_post.xml
249
- - spec/fixtures/single_suggest.xml
250
- - spec/fixtures/user_api_token.xml
251
- - spec/fixtures/user_secret.xml
252
- - spec/helper.rb
253
- - spec/pinboard/client_spec.rb
254
- - spec/pinboard/post_spec.rb
255
- - spec/pinboard_spec.rb
256
- has_rdoc:
136
+ test_files: []
data/.autotest DELETED
@@ -1 +0,0 @@
1
- require 'autotest/bundler'
data/.travis.yml DELETED
@@ -1,7 +0,0 @@
1
- language: ruby
2
- sudo: false
3
- rvm:
4
- - 2.1
5
- - 2.2
6
- - 1.9.3
7
- - jruby
data/Guardfile DELETED
@@ -1,10 +0,0 @@
1
- guard 'bundler' do
2
- watch('Gemfile')
3
- watch(%r|^.*\.gemspec|)
4
- end
5
-
6
- guard 'rspec', :version => 2 do
7
- watch(%r{^spec/.+_spec\.rb$})
8
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
9
- watch('spec/helper.rb') { "spec" }
10
- end