goodwill 0.1.4 → 0.4.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 +5 -13
- data/.rubocop.yml +17 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -2
- data/Gemfile +5 -0
- data/README.md +18 -4
- data/Rakefile +7 -3
- data/bin/console +4 -3
- data/bin/goodwill +2 -0
- data/goodwill.gemspec +17 -21
- data/lib/goodwill.rb +6 -1
- data/lib/goodwill/account.rb +58 -25
- data/lib/goodwill/auction.rb +60 -15
- data/lib/goodwill/biddingauction.rb +5 -15
- data/lib/goodwill/cli.rb +5 -1
- data/lib/goodwill/csspaths.rb +13 -5
- data/lib/goodwill/logger.rb +2 -0
- data/lib/goodwill/mechanize.rb +8 -7
- data/lib/goodwill/urlpaths.rb +8 -4
- data/lib/goodwill/version.rb +3 -1
- metadata +102 -60
- data/Gemfile.old +0 -5
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
M2E3NWNkYjFmZTQ4NGRiNmZjZjk5NjI3NDAxMWY4N2ZhMDliNWNiMA==
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4067be1f98e0d4de75e6b2880f35d671d8d88b3d939aaa64b1e85c5448775759
|
4
|
+
data.tar.gz: e5eedc6e6208cbf1b9706349bf7485934c1b2c4d91f07a8d655775134dcf151c
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
NjE3NTUzMDNiZWRjNTUzOGU5OGRkMGYxYmVjYjFmNTIyMWIwMjZkZGM5ZTJk
|
11
|
-
OTQ5ZWQzMGIzNmY5Y2Q2NWNmYjY0ZDEwMTU3YzUyZGU2ZjZkMGQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ODBmZWUyMzNlOGY5ZWUxM2I1NTc2NGFhMTgxNmJiMDVmMDkyMzJmZjY1MTRm
|
14
|
-
MzE3YmQ2NzEyNWFkOTQyNDAzNDE4ODI5ODNlNTA4MDdjZTgxMzMxNzJjMDQy
|
15
|
-
YmMxY2IzNDJiMTU5NDgwNjA3MmM5NGZmMmFmYTE1ZGYyYjc2MDk=
|
6
|
+
metadata.gz: a5351d1a764cf460f4e0850da86ae0f95da9608ead60742f25e42477d71bfbdf9a8fe2c78e7a28037060088b85c00f66db637dc0fa6ee193a51e7880a9f34dde
|
7
|
+
data.tar.gz: d1b3b90c793943446a2e0ac4b676b3785d2e4eb2d85ef997f59dbd8c030c170707b5049c06cc2867ddeb63f19077049c80a3fec22f1aa41f867e5ee2131dac0d
|
data/.rubocop.yml
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.7.1
|
data/.travis.yml
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.
|
4
|
-
|
3
|
+
- 2.5.0
|
4
|
+
- 2.6.0
|
5
|
+
- 2.7.0
|
6
|
+
before_install: gem install bundler
|
7
|
+
script:
|
8
|
+
- bundle exec rspec
|
9
|
+
- bundle exec rubocop ./lib
|
5
10
|
deploy:
|
6
11
|
provider: rubygems
|
7
12
|
api_key:
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
[](http://inch-ci.org/github/dudemcbacon/goodwill)
|
5
5
|
# Goodwill
|
6
6
|
|
7
|
-
|
7
|
+
Goodwill is a simple web scraper for ShopGoodwill.com. You can query login to your account, view your currently in progress auction, search for items, and even bid on new options. It also includes a small CLI for interacting with ShopGoodwill.com from the command-line.
|
8
8
|
|
9
9
|
TODO: Delete this and the text above, and describe your gem
|
10
10
|
|
@@ -26,7 +26,22 @@ Or install it yourself as:
|
|
26
26
|
|
27
27
|
## Usage
|
28
28
|
|
29
|
-
|
29
|
+
```ruby
|
30
|
+
gem 'goodwill'
|
31
|
+
|
32
|
+
account = Goodwill::Account.new('username', 'password')
|
33
|
+
|
34
|
+
pp account.search('famicom')
|
35
|
+
[#<Goodwill::Auction:0x007fbf50ec0c18
|
36
|
+
@bidding=false,
|
37
|
+
@bids="8",
|
38
|
+
@current="$66.00",
|
39
|
+
@end="",
|
40
|
+
@href="http://www.shopgoodwill.com/viewItem.asp?itemID=25576979",
|
41
|
+
@item="Two Nintendo Super Famicom Game Consoles 020",
|
42
|
+
@itemid="25576979",
|
43
|
+
@seller="Columbia Goodwill">]
|
44
|
+
```
|
30
45
|
|
31
46
|
## Development
|
32
47
|
|
@@ -36,5 +51,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
36
51
|
|
37
52
|
## Contributing
|
38
53
|
|
39
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
40
|
-
|
54
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/dudemcbacon/goodwill.
|
data/Rakefile
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'rubocop/rake_task'
|
3
6
|
|
4
7
|
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
RuboCop::RakeTask.new
|
5
9
|
|
6
|
-
task :
|
10
|
+
task default: :spec
|
data/bin/console
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
-
require
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'goodwill'
|
5
6
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +11,5 @@ require "goodwill"
|
|
10
11
|
# require "pry"
|
11
12
|
# Pry.start
|
12
13
|
|
13
|
-
require
|
14
|
+
require 'irb'
|
14
15
|
IRB.start
|
data/bin/goodwill
CHANGED
data/goodwill.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'goodwill/version'
|
5
6
|
|
@@ -14,28 +15,23 @@ Gem::Specification.new do |spec|
|
|
14
15
|
spec.description = 'Allows you to perform basic auction management, bidding, and searching from ruby.'
|
15
16
|
spec.homepage = 'https://github.com/dudemcbacon/goodwill'
|
16
17
|
|
17
|
-
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
|
-
# delete this section to allow pushing this gem to any host.
|
19
|
-
if spec.respond_to?(:metadata)
|
20
|
-
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
21
|
-
else
|
22
|
-
fail 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
|
23
|
-
end
|
24
|
-
|
25
18
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
19
|
spec.bindir = 'exe'
|
27
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
21
|
spec.require_paths = ['lib']
|
29
22
|
|
30
|
-
spec.add_development_dependency '
|
31
|
-
spec.add_development_dependency '
|
32
|
-
spec.add_development_dependency '
|
33
|
-
spec.add_development_dependency '
|
34
|
-
spec.add_development_dependency '
|
35
|
-
spec.add_development_dependency '
|
36
|
-
spec.
|
37
|
-
spec.
|
38
|
-
spec.
|
39
|
-
spec.add_dependency '
|
40
|
-
spec.add_dependency '
|
23
|
+
spec.add_development_dependency 'gem-release'
|
24
|
+
spec.add_development_dependency 'pry'
|
25
|
+
spec.add_development_dependency 'rake'
|
26
|
+
spec.add_development_dependency 'rspec'
|
27
|
+
spec.add_development_dependency 'rubocop'
|
28
|
+
spec.add_development_dependency 'simplecov'
|
29
|
+
spec.add_development_dependency 'travis'
|
30
|
+
spec.add_development_dependency 'vcr'
|
31
|
+
spec.add_development_dependency 'webmock'
|
32
|
+
spec.add_dependency 'highline'
|
33
|
+
spec.add_dependency 'mechanize'
|
34
|
+
spec.add_dependency 'parallel'
|
35
|
+
spec.add_dependency 'table_print'
|
36
|
+
spec.add_dependency 'thor'
|
41
37
|
end
|
data/lib/goodwill.rb
CHANGED
data/lib/goodwill/account.rb
CHANGED
@@ -1,16 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'goodwill/auction'
|
2
4
|
require 'goodwill/mechanize'
|
3
5
|
require 'goodwill/urlpaths'
|
6
|
+
require 'goodwill/csspaths'
|
4
7
|
|
8
|
+
require 'json'
|
5
9
|
require 'mechanize'
|
6
10
|
require 'parallel'
|
7
11
|
|
8
12
|
module Goodwill
|
13
|
+
#
|
14
|
+
# Allows for basic account interaction
|
15
|
+
#
|
9
16
|
class Account
|
10
17
|
include Goodwill::Mechanize
|
11
18
|
include URLPaths
|
19
|
+
include CSSPaths
|
12
20
|
|
13
|
-
IN_PROG = 'https://www.shopgoodwill.com/buyers/myShop/AuctionsInProgress.asp'
|
14
21
|
PER_PAGE = 25
|
15
22
|
|
16
23
|
attr_reader :username, :password, :threads
|
@@ -24,51 +31,77 @@ module Goodwill
|
|
24
31
|
end
|
25
32
|
|
26
33
|
def in_progress
|
27
|
-
in_progress_page = mechanize.get(
|
28
|
-
Parallel.map(in_progress_page.search(
|
34
|
+
in_progress_page = mechanize.get(OPEN_ORDERS_URL)
|
35
|
+
Parallel.map(in_progress_page.search(IN_PROGRESS_ROWS), in_threads: @threads) do |row|
|
29
36
|
Goodwill::BiddingAuction.new(itemid_from_open_order_row(row), mechanize)
|
30
37
|
end
|
31
38
|
end
|
32
39
|
|
33
|
-
def search(
|
34
|
-
search_page = mechanize.get(SEARCH_URL +
|
35
|
-
pages(total_items(search_page))
|
36
|
-
search_page = search_page.link_with(text: '
|
37
|
-
Parallel.map(search_page.search(
|
40
|
+
def search(item_title)
|
41
|
+
search_page = mechanize.get(SEARCH_URL + item_title)
|
42
|
+
Array.new(pages(total_items(search_page))) do |i|
|
43
|
+
search_page = search_page.link_with(text: '>').click unless i.zero?
|
44
|
+
Parallel.map(search_page.search(SEARCH_ROWS), in_threads: @threads) do |row|
|
38
45
|
Goodwill::Auction.new(itemid_from_search_row(row))
|
39
46
|
end
|
40
47
|
end.flatten
|
41
48
|
end
|
42
49
|
|
43
50
|
def bid(itemid, bid)
|
44
|
-
mechanize.get(ITEM_SEARCH_URL + itemid.to_s)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
item = mechanize.get(ITEM_SEARCH_URL + itemid.to_s)
|
52
|
+
href = item.search(SELLER_ID_LINK).attribute('href').value
|
53
|
+
seller_id = href.split('/').last
|
54
|
+
|
55
|
+
params = {
|
56
|
+
itemId: itemid,
|
57
|
+
bidAmount: bid,
|
58
|
+
quantity: 1,
|
59
|
+
sellerId: seller_id
|
60
|
+
}
|
61
|
+
|
62
|
+
# bidresult
|
63
|
+
# 1 - success (check message for 'Bid Received!')
|
64
|
+
# 1 - outbid (check message for 'You have already been outbid.')
|
65
|
+
# -5 - bid less than minimum
|
66
|
+
mechanize.get(BID_URL, params) do |page|
|
67
|
+
res = JSON.parse(page.body)
|
68
|
+
case res['BidResult']
|
69
|
+
when 1
|
70
|
+
return true if res['BidResultMessage'].include?('Bid Received')
|
71
|
+
|
72
|
+
return false if res['BidResultMessage'].include?('You have already been outbid.')
|
73
|
+
|
74
|
+
raise Goodwill::BidError, res['BidResultMessage']
|
75
|
+
when -5
|
76
|
+
raise Goodwill::BidError, res['BidResultMessage']
|
77
|
+
end
|
53
78
|
end
|
54
79
|
end
|
55
80
|
|
56
81
|
private
|
57
82
|
|
58
|
-
def
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
def total_items(page)
|
63
|
-
page.search('div h1').text.split.first.to_i
|
83
|
+
def buyer_token
|
84
|
+
mechanize.cookies.select { |c| c.name == 'AuthenticatedBuyerToken' }.first.value
|
64
85
|
end
|
65
86
|
|
66
87
|
def itemid_from_open_order_row(row)
|
67
|
-
row.search('a').
|
88
|
+
row.search('a').text
|
68
89
|
end
|
69
90
|
|
70
91
|
def itemid_from_search_row(row)
|
71
|
-
row.search('
|
92
|
+
row.search('a').first.attributes['href'].value.split('/').last
|
93
|
+
end
|
94
|
+
|
95
|
+
def pages(items)
|
96
|
+
(items / 40.to_f).ceil
|
97
|
+
end
|
98
|
+
|
99
|
+
def request_token
|
100
|
+
mechanize.cookies.select { |c| c.name == '__RequestVerificationToken' }.first.value
|
101
|
+
end
|
102
|
+
|
103
|
+
def total_items(page)
|
104
|
+
page.search('//*[@id="search-results"]/div/div[1]/nav[1]/p').first.text.split(' of ')[1].split(' ').first.to_i
|
72
105
|
end
|
73
106
|
end
|
74
107
|
end
|
data/lib/goodwill/auction.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'mechanize'
|
2
4
|
|
3
5
|
require 'goodwill/csspaths'
|
@@ -5,33 +7,76 @@ require 'goodwill/urlpaths'
|
|
5
7
|
require 'goodwill/mechanize'
|
6
8
|
|
7
9
|
module Goodwill
|
10
|
+
#
|
11
|
+
# A ShopGoodwill Auction
|
12
|
+
#
|
8
13
|
class Auction
|
9
14
|
include Goodwill::Mechanize
|
10
15
|
include CSSPaths
|
11
16
|
include URLPaths
|
12
17
|
|
13
|
-
attr_reader :bids
|
14
|
-
attr_reader :current
|
15
|
-
attr_reader :end
|
16
|
-
attr_reader :href
|
17
|
-
attr_reader :item
|
18
|
-
attr_reader :itemid
|
19
|
-
attr_reader :seller
|
18
|
+
attr_reader :item_page, :bids, :current, :end, :href, :item, :itemid, :seller, :shipping, :type
|
20
19
|
|
21
|
-
def initialize(itemid =
|
22
|
-
@href = ITEM_SEARCH_URL + itemid.to_s
|
20
|
+
def initialize(itemid, zipcode = '97222', state = 'OR', country = 'US')
|
23
21
|
@itemid = itemid
|
24
|
-
|
25
|
-
@
|
26
|
-
@
|
27
|
-
|
22
|
+
@zipcode = zipcode
|
23
|
+
@state = state
|
24
|
+
@country = country
|
25
|
+
|
26
|
+
@href = ITEM_SEARCH_URL + itemid.to_s
|
27
|
+
@item_page = mechanize.get(@href)
|
28
|
+
|
29
|
+
@type = parse_type
|
30
|
+
@bids = item_page.search(BIDS_PATH).text[/\d+/].to_i
|
31
|
+
@current = item_page.search(CURRENT_PRICE_PATH).text.tr('$', '').to_f
|
32
|
+
@end = parse_end_time
|
28
33
|
@item = item_page.search(ITEM_TITLE_PATH).text
|
29
34
|
@seller = item_page.search(SELLER_PATH).text
|
30
35
|
@bidding = false
|
36
|
+
@shipping = calculate_shipping(@itemid, @zipcode, @country)
|
37
|
+
end
|
38
|
+
|
39
|
+
def ==(other)
|
40
|
+
itemid == other.itemid
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_hash
|
44
|
+
hash = {}
|
45
|
+
instance_variables.each do |var|
|
46
|
+
next if var == :@item_page
|
47
|
+
|
48
|
+
hash[var.to_s.delete('@')] = if var == :@end
|
49
|
+
instance_variable_get(var).to_s
|
50
|
+
else
|
51
|
+
instance_variable_get(var)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
hash
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def calculate_shipping(itemid, zipcode, country)
|
60
|
+
params = "?ZipCode=#{zipcode}&Country=#{country}&ItemId=#{itemid}&Quantity=1&_=#{DateTime.now.strftime('%s')}"
|
61
|
+
page = mechanize.get(SHIPPING_URL + params)
|
62
|
+
page.search(SHIPPING_PATH).text.split(': ').last.tr('$', '').to_f
|
63
|
+
rescue StandardError
|
64
|
+
puts "Timeout (#{e}), retrying in 1 second..."
|
65
|
+
retry
|
66
|
+
end
|
67
|
+
|
68
|
+
def parse_end_time
|
69
|
+
search_path = type == :auction ? END_TIME_PATH : BIN_END_TIME_PATH
|
70
|
+
time = item_page.search(search_path).text.split(': ')[1]
|
71
|
+
return nil if time.nil?
|
72
|
+
|
73
|
+
DateTime.strptime(time, '%m/%d/%Y %l:%M:%S %p %Z')
|
74
|
+
rescue Date::Error
|
75
|
+
nil
|
31
76
|
end
|
32
77
|
|
33
|
-
def
|
34
|
-
|
78
|
+
def parse_type
|
79
|
+
item_page.search(BUY_IT_NOW_PATH).empty? ? :auction : :buyitnow
|
35
80
|
end
|
36
81
|
end
|
37
82
|
end
|
@@ -1,21 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'goodwill/urlpaths'
|
2
4
|
|
3
5
|
module Goodwill
|
4
6
|
class BiddingAuction < Auction
|
5
7
|
include URLPaths
|
6
8
|
|
7
|
-
attr_reader :bidding
|
8
|
-
attr_reader :winning
|
9
|
-
attr_reader :max
|
9
|
+
attr_reader :bidding, :winning, :max, :current, :end, :href, :item, :itemid, :seller, :shipping
|
10
10
|
|
11
11
|
# TODO: why do i need this?
|
12
12
|
attr_reader :bids
|
13
|
-
attr_reader :current
|
14
|
-
attr_reader :end
|
15
|
-
attr_reader :href
|
16
|
-
attr_reader :item
|
17
|
-
attr_reader :itemid
|
18
|
-
attr_reader :seller
|
19
13
|
|
20
14
|
def initialize(itemid, mechanize)
|
21
15
|
super(itemid)
|
@@ -23,8 +17,8 @@ module Goodwill
|
|
23
17
|
if order_page.link_with(text: regqt(itemid.to_s))
|
24
18
|
@bidding = true
|
25
19
|
row = order_page.link_with(text: regqt(itemid.to_s)).node.parent.parent
|
26
|
-
@winning =
|
27
|
-
@max = row.search('td:nth-child(5)').text
|
20
|
+
@winning = !row.search('td:nth-child(5) > i').empty?
|
21
|
+
@max = row.search('td:nth-child(5)').text.tr("\r\n", '').tr(' ', '').tr('$', '')
|
28
22
|
else
|
29
23
|
@bidding = false
|
30
24
|
@winning = false
|
@@ -37,9 +31,5 @@ module Goodwill
|
|
37
31
|
def regqt(itemid)
|
38
32
|
/#{Regexp.quote(itemid.to_s)}/
|
39
33
|
end
|
40
|
-
|
41
|
-
def happy?(src)
|
42
|
-
src.include?('happy')
|
43
|
-
end
|
44
34
|
end
|
45
35
|
end
|
data/lib/goodwill/cli.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'thor'
|
2
4
|
|
3
5
|
module Goodwill
|
@@ -5,6 +7,7 @@ module Goodwill
|
|
5
7
|
class_option :verbose, type: :boolean
|
6
8
|
class_option :username
|
7
9
|
class_option :password
|
10
|
+
class_option :threads
|
8
11
|
|
9
12
|
def initialize(*args)
|
10
13
|
super
|
@@ -12,7 +15,8 @@ module Goodwill
|
|
12
15
|
|
13
16
|
username = options[:username] || ask('Username:')
|
14
17
|
password = options[:password] || ask('Password:') { |q| q.echo = false }
|
15
|
-
|
18
|
+
threads = options[:threads].to_i || 10
|
19
|
+
@account = Goodwill::Account.new(username, password, threads)
|
16
20
|
end
|
17
21
|
|
18
22
|
desc 'auctions', "List all auctions you're currently bidding on"
|
data/lib/goodwill/csspaths.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Goodwill
|
2
4
|
module CSSPaths
|
3
5
|
# Auction Page
|
4
6
|
# http://www.shopgoodwill.com/viewItem.asp?itemID=<itemID>
|
5
|
-
BIDS_PATH = '
|
6
|
-
|
7
|
-
|
7
|
+
BIDS_PATH = 'body > section > div.container > div:nth-child(3) > div:nth-child(2) > ul.product-data > li:nth-child(3) > span.num-bids'
|
8
|
+
BIN_END_TIME_PATH = '/html/body/section/div[2]/div[3]/div[2]/ul[2]/li[7]'
|
9
|
+
BUY_IT_NOW_PATH = '/html/body/section/div[2]/div[3]/div[2]/div[2]/div[1]/div/div/div/button'
|
10
|
+
CURRENT_PRICE_PATH = 'body > section > div.container > div:nth-child(3) > div:nth-child(2) > ul.product-data > li:nth-child(4) > span'
|
11
|
+
END_TIME_PATH = '/html/body/section/div[2]/div[3]/div[2]/ul[2]/li[10]'
|
12
|
+
IN_PROGRESS_ROWS = '#my-auctions-table > tbody > tr'
|
8
13
|
ITEMID_PATH = 'body > span > div.itemdetail > div:nth-child(2) > div:nth-child(2) > div > table > tbody > tr:nth-child(3) > td'
|
9
|
-
ITEM_TITLE_PATH = '
|
10
|
-
|
14
|
+
ITEM_TITLE_PATH = 'body > section > div.container > div:nth-child(3) > div:nth-child(2) > h1'
|
15
|
+
SEARCH_ROWS = '#search-results > div > section > ul.products > li'
|
16
|
+
SELLER_ID_LINK = '/html/body/section/div[2]/div[4]/div/section/div/ul/li[4]/a'
|
17
|
+
SELLER_PATH = 'body > section > div.container > div:nth-child(3) > div:nth-child(2) > ul.product-data > li:nth-child(8) > a'
|
18
|
+
SHIPPING_PATH = 'body > p:nth-child(7) > b'
|
11
19
|
end
|
12
20
|
end
|
data/lib/goodwill/logger.rb
CHANGED
data/lib/goodwill/mechanize.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'mechanize'
|
2
4
|
|
3
5
|
require 'goodwill/urlpaths'
|
@@ -15,14 +17,12 @@ module Goodwill
|
|
15
17
|
@username ||= nil
|
16
18
|
end
|
17
19
|
|
18
|
-
attr_writer :username
|
20
|
+
attr_writer :username, :password
|
19
21
|
|
20
22
|
def password
|
21
23
|
@password ||= nil
|
22
24
|
end
|
23
25
|
|
24
|
-
attr_writer :password
|
25
|
-
|
26
26
|
def logged_in?
|
27
27
|
@logged_in ||= false
|
28
28
|
end
|
@@ -35,12 +35,13 @@ module Goodwill
|
|
35
35
|
|
36
36
|
def login
|
37
37
|
return true if logged_in?
|
38
|
+
|
38
39
|
@mechanize.get(LOGIN_URL) do |page|
|
39
|
-
my_page = page.form_with(action: '
|
40
|
-
f.
|
41
|
-
f.
|
40
|
+
my_page = page.form_with(action: '/SignIn') do |f|
|
41
|
+
f.Username = @username
|
42
|
+
f.Password = @password
|
42
43
|
end.click_button
|
43
|
-
@logged_in = my_page.links.map(&:to_s).include? 'My
|
44
|
+
@logged_in = my_page.links.map(&:to_s).include? 'My Shopgoodwill '
|
44
45
|
end
|
45
46
|
end
|
46
47
|
end
|
data/lib/goodwill/urlpaths.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Goodwill
|
2
4
|
module URLPaths
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
BID_URL = 'https://www.shopgoodwill.com/Bid/PlaceBid'
|
6
|
+
ITEM_SEARCH_URL = 'https://www.shopgoodwill.com/viewItem.asp?itemID='
|
7
|
+
LOGIN_URL = 'https://www.shopgoodwill.com/SignIn'
|
8
|
+
OPEN_ORDERS_URL = 'https://www.shopgoodwill.com/MyShopgoodwill/AuctionsInProgress'
|
9
|
+
SEARCH_URL = 'https://www.shopgoodwill.com/Listings?sg=&c=&s=&lp=0&hp=999999&sbn=false&spo=false&snpo=false&socs=false&sd=false&sca=false&cadb=7&scs=false&sis=false&col=0&p=1&ps=40&desc=false&ss=0&UseBuyerPrefs=true&st='
|
10
|
+
SHIPPING_URL = 'https://www.shopgoodwill.com/CalculateShipping'
|
7
11
|
end
|
8
12
|
end
|
data/lib/goodwill/version.rb
CHANGED
metadata
CHANGED
@@ -1,169 +1,211 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: goodwill
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandon Burnett
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: gem-release
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: rake
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
16
44
|
requirements:
|
17
|
-
- -
|
45
|
+
- - ">="
|
18
46
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
47
|
+
version: '0'
|
20
48
|
type: :development
|
21
49
|
prerelease: false
|
22
50
|
version_requirements: !ruby/object:Gem::Requirement
|
23
51
|
requirements:
|
24
|
-
- -
|
52
|
+
- - ">="
|
25
53
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
54
|
+
version: '0'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: rspec
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
|
-
- -
|
59
|
+
- - ">="
|
32
60
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
61
|
+
version: '0'
|
34
62
|
type: :development
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
|
-
- -
|
66
|
+
- - ">="
|
39
67
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
68
|
+
version: '0'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: rubocop
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
44
72
|
requirements:
|
45
|
-
- -
|
73
|
+
- - ">="
|
46
74
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0
|
75
|
+
version: '0'
|
48
76
|
type: :development
|
49
77
|
prerelease: false
|
50
78
|
version_requirements: !ruby/object:Gem::Requirement
|
51
79
|
requirements:
|
52
|
-
- -
|
80
|
+
- - ">="
|
53
81
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0
|
82
|
+
version: '0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
84
|
+
name: simplecov
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
|
-
- -
|
87
|
+
- - ">="
|
60
88
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0
|
89
|
+
version: '0'
|
62
90
|
type: :development
|
63
91
|
prerelease: false
|
64
92
|
version_requirements: !ruby/object:Gem::Requirement
|
65
93
|
requirements:
|
66
|
-
- -
|
94
|
+
- - ">="
|
67
95
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0
|
96
|
+
version: '0'
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: travis
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
72
100
|
requirements:
|
73
|
-
- -
|
101
|
+
- - ">="
|
74
102
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
103
|
+
version: '0'
|
76
104
|
type: :development
|
77
105
|
prerelease: false
|
78
106
|
version_requirements: !ruby/object:Gem::Requirement
|
79
107
|
requirements:
|
80
|
-
- -
|
108
|
+
- - ">="
|
81
109
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
110
|
+
version: '0'
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
112
|
+
name: vcr
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
86
114
|
requirements:
|
87
|
-
- -
|
115
|
+
- - ">="
|
88
116
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0
|
117
|
+
version: '0'
|
90
118
|
type: :development
|
91
119
|
prerelease: false
|
92
120
|
version_requirements: !ruby/object:Gem::Requirement
|
93
121
|
requirements:
|
94
|
-
- -
|
122
|
+
- - ">="
|
95
123
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0
|
124
|
+
version: '0'
|
97
125
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
126
|
+
name: webmock
|
99
127
|
requirement: !ruby/object:Gem::Requirement
|
100
128
|
requirements:
|
101
|
-
- -
|
129
|
+
- - ">="
|
102
130
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
104
|
-
type: :
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
105
133
|
prerelease: false
|
106
134
|
version_requirements: !ruby/object:Gem::Requirement
|
107
135
|
requirements:
|
108
|
-
- -
|
136
|
+
- - ">="
|
109
137
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
138
|
+
version: '0'
|
111
139
|
- !ruby/object:Gem::Dependency
|
112
140
|
name: highline
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
114
142
|
requirements:
|
115
|
-
- -
|
143
|
+
- - ">="
|
116
144
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
145
|
+
version: '0'
|
118
146
|
type: :runtime
|
119
147
|
prerelease: false
|
120
148
|
version_requirements: !ruby/object:Gem::Requirement
|
121
149
|
requirements:
|
122
|
-
- -
|
150
|
+
- - ">="
|
123
151
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
152
|
+
version: '0'
|
125
153
|
- !ruby/object:Gem::Dependency
|
126
154
|
name: mechanize
|
127
155
|
requirement: !ruby/object:Gem::Requirement
|
128
156
|
requirements:
|
129
|
-
- -
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: parallel
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
130
172
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
173
|
+
version: '0'
|
132
174
|
type: :runtime
|
133
175
|
prerelease: false
|
134
176
|
version_requirements: !ruby/object:Gem::Requirement
|
135
177
|
requirements:
|
136
|
-
- -
|
178
|
+
- - ">="
|
137
179
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
180
|
+
version: '0'
|
139
181
|
- !ruby/object:Gem::Dependency
|
140
182
|
name: table_print
|
141
183
|
requirement: !ruby/object:Gem::Requirement
|
142
184
|
requirements:
|
143
|
-
- -
|
185
|
+
- - ">="
|
144
186
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
187
|
+
version: '0'
|
146
188
|
type: :runtime
|
147
189
|
prerelease: false
|
148
190
|
version_requirements: !ruby/object:Gem::Requirement
|
149
191
|
requirements:
|
150
|
-
- -
|
192
|
+
- - ">="
|
151
193
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
194
|
+
version: '0'
|
153
195
|
- !ruby/object:Gem::Dependency
|
154
196
|
name: thor
|
155
197
|
requirement: !ruby/object:Gem::Requirement
|
156
198
|
requirements:
|
157
|
-
- -
|
199
|
+
- - ">="
|
158
200
|
- !ruby/object:Gem::Version
|
159
|
-
version: '0
|
201
|
+
version: '0'
|
160
202
|
type: :runtime
|
161
203
|
prerelease: false
|
162
204
|
version_requirements: !ruby/object:Gem::Requirement
|
163
205
|
requirements:
|
164
|
-
- -
|
206
|
+
- - ">="
|
165
207
|
- !ruby/object:Gem::Version
|
166
|
-
version: '0
|
208
|
+
version: '0'
|
167
209
|
description: Allows you to perform basic auction management, bidding, and searching
|
168
210
|
from ruby.
|
169
211
|
email:
|
@@ -172,12 +214,13 @@ executables: []
|
|
172
214
|
extensions: []
|
173
215
|
extra_rdoc_files: []
|
174
216
|
files:
|
175
|
-
- .env
|
176
|
-
- .gitignore
|
177
|
-
- .rspec
|
178
|
-
- .
|
217
|
+
- ".env"
|
218
|
+
- ".gitignore"
|
219
|
+
- ".rspec"
|
220
|
+
- ".rubocop.yml"
|
221
|
+
- ".ruby-version"
|
222
|
+
- ".travis.yml"
|
179
223
|
- Gemfile
|
180
|
-
- Gemfile.old
|
181
224
|
- LICENSE.txt
|
182
225
|
- README.md
|
183
226
|
- Rakefile
|
@@ -198,25 +241,24 @@ files:
|
|
198
241
|
homepage: https://github.com/dudemcbacon/goodwill
|
199
242
|
licenses:
|
200
243
|
- MIT
|
201
|
-
metadata:
|
202
|
-
allowed_push_host: https://rubygems.org
|
244
|
+
metadata: {}
|
203
245
|
post_install_message:
|
204
246
|
rdoc_options: []
|
205
247
|
require_paths:
|
206
248
|
- lib
|
207
249
|
required_ruby_version: !ruby/object:Gem::Requirement
|
208
250
|
requirements:
|
209
|
-
- -
|
251
|
+
- - ">="
|
210
252
|
- !ruby/object:Gem::Version
|
211
253
|
version: '0'
|
212
254
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
213
255
|
requirements:
|
214
|
-
- -
|
256
|
+
- - ">="
|
215
257
|
- !ruby/object:Gem::Version
|
216
258
|
version: '0'
|
217
259
|
requirements: []
|
218
260
|
rubyforge_project:
|
219
|
-
rubygems_version: 2.
|
261
|
+
rubygems_version: 2.7.7
|
220
262
|
signing_key:
|
221
263
|
specification_version: 4
|
222
264
|
summary: Basic auction management for ShopGoodwil.com
|