pinup 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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