pinup 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NmE3YzhkNTM1NjZiY2E4OWUxOTI2M2NmYzI1ZjE1N2M5ZGVhOTk5OQ==
4
+ NTkzZDNhMzg3MDFhNGMxZTI5NmY4MGEwMGE0OGNlOGJkNTIyODBhNg==
5
5
  data.tar.gz: !binary |-
6
- YzA2MzQxNjBiNmE1OWM5YjIwZDM3ZWFlMjZjMDViODAwOTkxOGM5Mw==
6
+ NzVmYTUxZjJlY2E2MDlmN2MzYTg4ZGI3YzhjMDgzMmQyOTEzNDUyMA==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- Y2Q3ODFlNTAxNzk3NGQ2MzUwNDRhNjU3ZTAyMzFkYzE4OGJlZTMyNTdiZTky
10
- Nzc3ZTE3Y2JmZWFjNzMxYzEwNTI2NGY0ZDlhNWE5ODVhYmVjMzBmMWU0YTYx
11
- ZmQ3NjEyZTg4ZWVmMmQyYmMzYWRmMDZiMThmM2M5NTFkMWI2MGQ=
9
+ YjQyMGUyNmEyYzY5N2I3NGJjNmUzZDY2OWZhNjUzZDBhNGFkMmY4YWE5NTVj
10
+ OGI3NDNlOGI3YWQ4NDU0MzAwYjk4MjEwOGI1OWM5ZDg2ODIyYzM5YmRlZmMz
11
+ YThhZTUzNWE4MTA4OTgwMjhmNmJhYWNkMTBjN2VkMmVjODQ0ZjQ=
12
12
  data.tar.gz: !binary |-
13
- OWY4NDNmOWMzZDBkYjY3ZjE3YjY3MzdlNDdjODJjNzgzMjlmYTdkYzYxOWZk
14
- YmMxZTE4NDZjM2E0N2IzZDZhNTU3MzE1ZDJhNmE4ZTI2OTc0OGE4ODAzMTc1
15
- MWM3ZjY0ZDRlYzc3MTFiOTFmYzVhNmE5MWQ5ZTA1OTVhN2IyOTY=
13
+ YTkwMjlkMDY2ZDMxNTgyMTM0ZTE2ZDg4MThmMDhlMjBiNjYwZWVhOWQyOGQ5
14
+ MzIyNWU4ZTVjZjdhM2MzNmUxOTZjOWYwMmMxZjUxZGQ2MTI0ZjAwYWMzMzQx
15
+ NGQ0ZmQ0MDQ3M2NiMWM4NWE4MDg5ZjhmMWVlODI3MjEyNjM0MjQ=
data/README.md CHANGED
@@ -3,6 +3,8 @@
3
3
  Pinup is a [RubyGem](http://rubygems.org/) for quickly getting through your [Pinboard](https://pinboard.in) bookmarks. It allows you to open or list your bookmarks and delete them afterwards (if you'd like).
4
4
 
5
5
  [![Build Status](https://travis-ci.org/Keithbsmiley/pinup.png?branch=master)](https://travis-ci.org/Keithbsmiley/pinup)
6
+ [![Code Climate](https://codeclimate.com/github/Keithbsmiley/pinup.png)](https://codeclimate.com/github/Keithbsmiley/pinup)
7
+ [![Coverage Status](https://coveralls.io/repos/Keithbsmiley/pinup/badge.png?branch=master)](https://coveralls.io/r/Keithbsmiley/pinup)
6
8
  [![Dependency Status](https://gemnasium.com/Keithbsmiley/pinup.png)](https://gemnasium.com/Keithbsmiley/pinup)
7
9
 
8
10
  ## Authorization
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require 'rspec/core/rake_task'
3
3
 
4
4
  # NOTE CI does not run all tests, some tests require valid Pinboard credentials in the netrc file
5
5
  RSpec::Core::RakeTask.new do |t|
6
- t.pattern = FileList['spec/**/*.rb'].exclude(/authorize|queries/)
6
+ t.pattern = FileList['spec/**/*.rb'].exclude(/authorize|command|queries/)
7
7
  end
8
8
 
9
9
  task :default => :spec
@@ -17,9 +17,7 @@ module Pinup
17
17
 
18
18
  def self.authorize_netrc(options = {})
19
19
  path = DEFAULT_NETRC
20
- if options[:path]
21
- path = File.expand_path(options[:path])
22
- end
20
+ path = File.expand_path(options[:path]) if options[:path]
23
21
 
24
22
  netrc = Netrc.read(path)
25
23
  username, password = netrc[PINBOARD_URL]
@@ -40,10 +38,11 @@ module Pinup
40
38
  parameters[:auth_token] = token
41
39
  response = authorize({ params: parameters })
42
40
 
43
- if response.code != '200'
44
- puts "Invalid user credentials in #{ path }".red
41
+ if !valid_credentials(response.code)
45
42
  return nil
46
- elsif !path.nil? && DEFAULT_NETRC != path
43
+ end
44
+
45
+ if path && DEFAULT_NETRC != path
47
46
  Pinup::Settings.write_settings({ path: path })
48
47
  else
49
48
  Pinup::Settings.clear_settings
@@ -55,21 +54,17 @@ module Pinup
55
54
  def self.authorize_credentials(options = {})
56
55
  # Ask for user and pass, save to passed or default netrc location
57
56
  # Reading from options hash for testing
58
- username = options[:username] || ask('Enter your username')
57
+ print 'Enter your username: ' if options[:username].nil?
58
+ username = options[:username] || gets.chomp
59
59
  print 'Enter your password (not saved): ' if options[:password].nil?
60
60
  password = options[:password] || STDIN.noecho(&:gets).chomp
61
61
 
62
62
  parameters = { params: JSON_PARAMS.dup, username: username, password: password }
63
63
  response = authorize(parameters)
64
64
 
65
- if response.code != '200'
66
- puts 'Invalid user credentials'.red
67
- return nil
68
- else
65
+ if valid_credentials(response.code)
69
66
  path = DEFAULT_NETRC
70
- if options[:path]
71
- path = File.expand_path(options[:path])
72
- end
67
+ path = File.expand_path(options[:path]) if options[:path]
73
68
 
74
69
  json = JSON.parse(response.body)
75
70
  digits = json['result']
@@ -81,20 +76,17 @@ module Pinup
81
76
  Pinup::Settings.save_token(options)
82
77
 
83
78
  return true
79
+ else
80
+ return nil
84
81
  end
85
82
  end
86
83
 
87
- def self.ask(string)
88
- print "#{ string }: "
89
- gets.chomp
90
- end
91
-
92
84
  private
93
85
 
94
86
  def self.authorize(options = {})
95
- parameters = options[:params] || {}
96
- username = options[:username] || {}
97
- password = options[:password] || {}
87
+ parameters = options[:params] || {}
88
+ username = options[:username]
89
+ password = options[:password]
98
90
 
99
91
  uri = URI.parse("#{ API_URL }/user/api_token")
100
92
  uri.query = URI.encode_www_form(parameters)
@@ -104,11 +96,20 @@ module Pinup
104
96
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
105
97
 
106
98
  request = Net::HTTP::Get.new(uri.request_uri)
107
- if !username.nil? && !username.empty? && !password.nil? && !password.empty?
99
+ if username && password
108
100
  request.basic_auth(username, password)
109
101
  end
110
102
 
111
103
  http.request(request)
112
104
  end
105
+
106
+ def self.valid_credentials(code)
107
+ if code == '200' || code == 200
108
+ return true
109
+ end
110
+
111
+ puts 'Invalid user credentials'.red
112
+ return false
113
+ end
113
114
  end
114
115
  end
@@ -1,10 +1,10 @@
1
1
  module Pinup
2
2
  class List
3
3
  def self.list_pins(options = {})
4
- unread = options[:unread] unless options[:unread].nil?
5
- untagged = options[:untagged] unless options[:untagged].nil?
6
- count = options[:number].to_i unless options[:number].nil?
7
- delete = options[:delete] unless options[:delete].nil?
4
+ unread = options[:unread]
5
+ untagged = options[:untagged]
6
+ count = options[:number].to_i
7
+ delete = options[:delete]
8
8
 
9
9
  items = Pinup::Queries.list_items
10
10
  filtered = Pinup::Queries.filter_items(items, unread, untagged, count)
@@ -3,18 +3,22 @@ require 'launchy'
3
3
  module Pinup
4
4
  class Open
5
5
  def self.open_pins(options = {})
6
- unread = options[:unread] unless options[:unread].nil?
7
- untagged = options[:untagged] unless options[:untagged].nil?
8
- count = options[:number].to_i unless options[:number].nil?
9
- delete = options[:delete] unless options[:delete].nil?
6
+ unread = options[:unread]
7
+ untagged = options[:untagged]
8
+ count = options[:number].to_i
9
+ delete = options[:delete]
10
10
 
11
11
  items = Pinup::Queries.list_items
12
12
  filtered = Pinup::Queries.filter_items(items, unread, untagged, count)
13
13
  items_string = Pinup::Queries.item_string(filtered)
14
14
  urls = items_string.split(/\n/)
15
15
 
16
- urls.each do |url|
17
- Launchy.open(url)
16
+ if count > 0 # For testing
17
+ urls.each do |url|
18
+ Launchy.open(url)
19
+ end
20
+ else
21
+ puts "You must specify more than #{ count } items"
18
22
  end
19
23
 
20
24
  if delete
data/lib/pinup/queries.rb CHANGED
@@ -13,7 +13,7 @@ module Pinup
13
13
  parameters = JSON_PARAMS.dup
14
14
  parameters[:auth_token] = token
15
15
 
16
- response = list_query(parameters)
16
+ response = pinboard_query(LIST_PATH, parameters)
17
17
  if response.code != '200'
18
18
  puts "Error getting bookmarks: #{ response.body }"
19
19
  return nil
@@ -36,22 +36,8 @@ module Pinup
36
36
  json.each do |item|
37
37
  bookmark = Bookmark.new(item)
38
38
 
39
- if unread && untagged
40
- if bookmark.unread || bookmark.untagged
41
- new_items << bookmark
42
- end
43
- elsif unread
44
- if bookmark.unread && !bookmark.untagged
45
- new_items << bookmark
46
- end
47
- elsif untagged
48
- if bookmark.untagged && !bookmark.unread
49
- new_items << bookmark
50
- end
51
- else
52
- if !bookmark.unread && !bookmark.untagged
53
- new_items << bookmark
54
- end
39
+ if should_show(bookmark, unread, untagged)
40
+ new_items << bookmark
55
41
  end
56
42
 
57
43
  if new_items.count >= count
@@ -74,10 +60,33 @@ module Pinup
74
60
  urls.each do |url|
75
61
  url_params = parameters.dup
76
62
  url_params[:url] = url
63
+ pinboard_query(DELETE_PATH, url_params)
77
64
  delete_query(url_params)
78
65
  end
79
66
  end
80
67
 
68
+ def self.should_show(bookmark, unread, untagged)
69
+ if unread && untagged
70
+ if bookmark.unread || bookmark.untagged
71
+ return true
72
+ end
73
+ elsif unread
74
+ if bookmark.unread && !bookmark.untagged
75
+ return true
76
+ end
77
+ elsif untagged
78
+ if bookmark.untagged && !bookmark.unread
79
+ return true
80
+ end
81
+ else
82
+ if !bookmark.unread && !bookmark.untagged
83
+ return true
84
+ end
85
+ end
86
+
87
+ return false
88
+ end
89
+
81
90
  def self.item_string(items)
82
91
  item_output = ""
83
92
  items.each do |item|
@@ -88,21 +97,9 @@ module Pinup
88
97
  end
89
98
 
90
99
  private
91
-
92
- def self.list_query(parameters)
93
- uri = URI.parse("#{ API_URL }/posts/all")
94
- uri.query = URI.encode_www_form(parameters)
95
-
96
- http = Net::HTTP.new(uri.host, uri.port)
97
- http.use_ssl = true
98
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
99
-
100
- request = Net::HTTP::Get.new(uri.request_uri)
101
- http.request(request)
102
- end
103
100
 
104
- def self.delete_query(parameters)
105
- uri = URI.parse("#{ API_URL }/posts/delete")
101
+ def self.pinboard_query(path, parameters)
102
+ uri = URI.parse("#{ API_URL }/#{ path }")
106
103
  uri.query = URI.encode_www_form(parameters)
107
104
 
108
105
  http = Net::HTTP.new(uri.host, uri.port)
@@ -11,11 +11,11 @@ module Pinup
11
11
  end
12
12
 
13
13
  def self.read_settings
14
- if !File.exists? SETTINGS
15
- return nil
14
+ settings = nil
15
+ if File.exists?(SETTINGS)
16
+ settings = YAML::load_file(SETTINGS)
16
17
  end
17
18
 
18
- settings = YAML::load_file(SETTINGS)
19
19
  if !settings || settings.empty?
20
20
  return nil
21
21
  end
@@ -46,7 +46,7 @@ module Pinup
46
46
  password = token_split.last
47
47
 
48
48
  netrc = Netrc.read(path)
49
- netrc.new_item_prefix = "\n# This Entry was added automatically\n"
49
+ netrc.new_item_prefix = "\n\n# This Entry was added automatically\n"
50
50
  netrc[PINBOARD_URL] = username, password
51
51
  netrc.save
52
52
 
data/lib/pinup/version.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  module Pinup
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  SETTINGS = File.expand_path('~/.pinup')
4
4
  PINBOARD_URL = 'pinboard.in'
5
5
  API_URL = 'https://api.pinboard.in/v1'
6
6
  JSON_PARAMS = { format: 'json' }
7
7
  DEFAULT_NETRC = File.expand_path('~/.netrc')
8
+ DELETE_PATH = 'posts/delete'
9
+ LIST_PATH = 'posts/all'
8
10
  end
data/pinup.gemspec CHANGED
@@ -19,6 +19,7 @@ spec = Gem::Specification.new do |s|
19
19
  s.add_dependency('netrc', '~> 0.7.7')
20
20
  s.add_dependency('launchy', '~> 2.3.0')
21
21
  s.add_development_dependency('rake')
22
+ s.add_development_dependency('coveralls')
22
23
  s.add_development_dependency('rspec', '~> 2.13.0')
23
24
  s.add_runtime_dependency('gli','2.5.6')
24
25
  end
@@ -2,7 +2,25 @@ require_relative '../spec_helper'
2
2
 
3
3
  describe Pinup::Authorize do
4
4
  before do
5
- @netrc_path = File.expand_path('~/foobar')
5
+ @netrc_path = File.expand_path('~/foobarbaz')
6
+ end
7
+
8
+ describe 'authorize_command' do
9
+ describe 'when netrc is true' do
10
+ it 'should call the correct method' do
11
+ options = { netrc: true }
12
+ Pinup::Authorize.should_receive(:authorize_netrc)
13
+ Pinup::Authorize.authorize_command(options)
14
+ end
15
+ end
16
+
17
+ describe 'when netrc is false' do
18
+ it 'should call the correct method' do
19
+ options = { netrc: false }
20
+ Pinup::Authorize.should_receive(:authorize_credentials)
21
+ Pinup::Authorize.authorize_command(options)
22
+ end
23
+ end
6
24
  end
7
25
 
8
26
  describe 'authorize_netrc' do
@@ -18,6 +36,43 @@ describe Pinup::Authorize do
18
36
  expect(Pinup::Authorize.authorize_netrc).to be_true
19
37
  end
20
38
  end
39
+
40
+ describe 'invalid credentials' do
41
+ before do
42
+ @path = File.expand_path('~/foobar')
43
+ Pinup::Settings.write_settings({ path: @path })
44
+ end
45
+
46
+ after do
47
+ File.delete(@path) if File.exists?(@path)
48
+ Pinup::Settings.clear_settings
49
+ end
50
+
51
+ describe 'invalid token' do
52
+ before do
53
+ Pinup::Settings.save_token({ token: 'foo:bar', path: @path })
54
+ end
55
+
56
+ it 'should return nil' do
57
+ expect(Pinup::Authorize.authorize_netrc({ path: @path })).to be_nil
58
+ end
59
+ end
60
+ end
61
+
62
+ describe 'valid credentials with custom path' do
63
+ before do
64
+ token = Pinup::Settings.get_token
65
+ @path = File.expand_path('~/foobar')
66
+ Pinup::Settings.save_token({ token: token, path: @path })
67
+ end
68
+
69
+ it 'should write the settings' do
70
+ Pinup::Authorize.authorize_netrc({ path: @path })
71
+ settings = Pinup::Settings.read_settings
72
+ result = settings[:path] == @path
73
+ expect(result).to be_true
74
+ end
75
+ end
21
76
  end
22
77
 
23
78
  describe 'authorize_credentials' do
@@ -0,0 +1,29 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Pinup::List do
4
+ describe 'cli usage' do
5
+ before do
6
+ Pinup::List.list_pins
7
+ @response = %x[bundle exec bin/pinup list]
8
+ end
9
+
10
+ it 'should print some URLs' do
11
+ expect(@response).to match(/http/)
12
+ expect(@response).to match(/com/)
13
+ end
14
+ end
15
+ end
16
+
17
+ describe Pinup::Open do
18
+ describe 'cli usage' do
19
+ before do
20
+ Pinup::Open.open_pins({ number: 0 })
21
+ @output = %x[bundle exec bin/pinup open -n 0]
22
+ end
23
+
24
+ it 'should get called from the open command' do
25
+ expect(@output).to match(/0/)
26
+ expect(@output).to match(/specify/)
27
+ end
28
+ end
29
+ end
@@ -7,10 +7,38 @@ describe Pinup::Queries do
7
7
  @posts = JSON.parse(items)
8
8
  end
9
9
 
10
- it 'shoud return some number of items' do
10
+ it 'should return some number of items' do
11
11
  result = @posts.count > 0
12
12
  expect(result).to be_true
13
13
  end
14
+
15
+ describe 'token issues' do
16
+ before(:each) do
17
+ @path = File.expand_path('~/foobar')
18
+ Pinup::Settings.write_settings({ path: @path })
19
+ end
20
+
21
+ after(:each) do
22
+ File.delete(@path) if File.exists?(@path)
23
+ Pinup::Settings.clear_settings
24
+ end
25
+
26
+ describe 'no token' do
27
+ it 'should return nil' do
28
+ expect(Pinup::Queries.list_items).to be_nil
29
+ end
30
+ end
31
+
32
+ describe 'invalid token' do
33
+ before do
34
+ Pinup::Settings.save_token({ token: 'foo:bar', path: @path })
35
+ end
36
+
37
+ it 'should return nil' do
38
+ expect(Pinup::Queries.list_items).to be_nil
39
+ end
40
+ end
41
+ end
14
42
  end
15
43
 
16
44
  describe 'filter_items' do
@@ -113,6 +141,16 @@ describe Pinup::Queries do
113
141
  end
114
142
  end
115
143
  end
144
+
145
+ describe 'improper JSON' do
146
+ it 'should exit' do
147
+ begin
148
+ Pinup::Queries.filter_items('foobar', true, true, 10)
149
+ rescue SystemExit => e
150
+ expect(e).not_to be_nil
151
+ end
152
+ end
153
+ end
116
154
  end
117
155
 
118
156
  describe 'item_string' do
@@ -112,10 +112,14 @@ describe Pinup::Settings do
112
112
 
113
113
  describe 'if there is no token' do
114
114
  before do
115
- @local_path = File.expand_path('~/foobar')
115
+ @local_path = File.expand_path('~/foobarquux')
116
116
  Pinup::Settings.write_settings({ path: @local_path })
117
117
  end
118
118
 
119
+ after do
120
+ File.delete(@local_path) if File.exists?(@local_path)
121
+ end
122
+
119
123
  it 'should return nil' do
120
124
  token = Pinup::Settings.get_token
121
125
  expect(token).to be_nil
data/spec/spec_helper.rb CHANGED
@@ -6,6 +6,11 @@
6
6
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
7
  #
8
8
 
9
+ if ENV['COVERALLS_RUN_LOCALLY']
10
+ require 'coveralls'
11
+ Coveralls.wear!
12
+ end
13
+
9
14
  require 'pinup'
10
15
  require 'pinup/version.rb'
11
16
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pinup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Smiley
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ! '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: coveralls
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -120,6 +134,7 @@ files:
120
134
  - pinup.gemspec
121
135
  - spec/integration/authorize_spec.rb
122
136
  - spec/integration/bookmark_spec.rb
137
+ - spec/integration/commands_spec.rb
123
138
  - spec/integration/queries_spec.rb
124
139
  - spec/integration/settings_spec.rb
125
140
  - spec/spec_helper.rb
@@ -150,6 +165,7 @@ summary: Digest your Pinboard bookmarks in bulk
150
165
  test_files:
151
166
  - spec/integration/authorize_spec.rb
152
167
  - spec/integration/bookmark_spec.rb
168
+ - spec/integration/commands_spec.rb
153
169
  - spec/integration/queries_spec.rb
154
170
  - spec/integration/settings_spec.rb
155
171
  - spec/spec_helper.rb