fine_ants 1.0.1 → 1.1.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
2
  SHA1:
3
- metadata.gz: c93b06df5d3a1884ffaf8a846cdff9a08c0e2c89
4
- data.tar.gz: 0b63df67da081a1ff08ac2c0596168e5de0e86d6
3
+ metadata.gz: e3697392395db65fdf59a5227adc446f7214ecf4
4
+ data.tar.gz: f838e9a2bbd3ccbf1b46e7c99bebf24c9a9380a9
5
5
  SHA512:
6
- metadata.gz: 7ed0806e9ae8464b066cd29922c471ead3d3fa1767680ae1bfcf71e21870f836a61fa21b346bd49d3b602d3002135e817d2b9f36aba5cd5daca765d7e58f284d
7
- data.tar.gz: e9573cb0dde9a9c2f686cc6c4a5febb605aaaaa906f614fd91ce2a86f9372ba10f6686958b6f74092d39be2688d2ff7c35181b4db71cd48dc1f2ae7d0342fafb
6
+ metadata.gz: 007c5ab54b95b8622afedf1d62ab83b198cde91e46cc06b55fdb24955a2b2e1eab8cc7de4d95d6001a0ed178d4a5fd038b4535c1a488b9103cf8f248a27ccd90
7
+ data.tar.gz: 5ddba5b03f1fb7a33a65d4b98eb0460757555501ab0e341a67668b5344f075c81be261142135efbecc502dd6d5ec4a6972f13e6320b880a06a4c05788e7fb50d
data/LICENSE.txt CHANGED
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
652
652
  If the program does terminal interaction, make it output a short
653
653
  notice like this when it starts in an interactive mode:
654
654
 
655
- <program> Copyright (C) <year> <name of author>
655
+ Fine Ants Copyright (C) 2016 Justin Searls
656
656
  This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657
657
  This is free software, and you are welcome to redistribute it
658
658
  under certain conditions; type `show c' for details.
data/README.md CHANGED
@@ -57,7 +57,8 @@ when a login process requires a 2FA challenge.
57
57
 
58
58
  Right now, FineAnts ships with adapters for:
59
59
 
60
- * [Vanguard personal finance](https://personal.vanguard.com/us/hnwnesc/nesc/LoginPage)
60
+ * [Vanguard Personal Investment](https://personal.vanguard.com/us/hnwnesc/nesc/LoginPage)
61
+ * [PNC Personal Banking](https://www.pnc.com/en/personal-banking.html)
61
62
 
62
63
  You can also implement your own adapter and pass it to `FineAnts.download`. The
63
64
  expected public contract of an adapter is:
@@ -0,0 +1,61 @@
1
+ require "bigdecimal"
2
+
3
+ module FineAnts
4
+ module Adapters
5
+ class Betterment
6
+ def initialize(credentials)
7
+ @user = credentials[:user]
8
+ @password = credentials[:password]
9
+ end
10
+
11
+ def login
12
+ visit "https://wwws.betterment.com/app/login"
13
+ fill_in "web_authentication[email]", :with => @user
14
+ fill_in "web_authentication[password]", :with => @password
15
+ click_button "Log in"
16
+ verify_login!
17
+ end
18
+
19
+ def download
20
+ accounts = all(".sub-account")
21
+ accounts.map do |account|
22
+ {
23
+ :adapter => :betterment,
24
+ :user => @user,
25
+ :id => id_for(account),
26
+ :name => name_for(account),
27
+ :amount => total_for(account)
28
+ }
29
+ end.tap do
30
+ find(".dropdown .user-option").click
31
+ click_button "Log Out"
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def verify_login!
38
+ find ".total-balance"
39
+ rescue
40
+ raise FineAnts::LoginFailedError.new
41
+ end
42
+
43
+ def id_for(account)
44
+ link = account.find(".donut-label a")
45
+ link[:href].match(/\/app\/goals\/(\d+)\//)[1]
46
+ end
47
+
48
+ def name_for(account)
49
+ "#{account.find(".type-and-plan").text} - #{account.find(".goal-name").text}"
50
+ end
51
+
52
+ def total_for(account)
53
+ total_string = account.find(".current-balance h3").text
54
+ BigDecimal.new(total_string.match(/\$(.*)$/)[1].gsub(/,/,''))
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+
61
+
@@ -0,0 +1,58 @@
1
+ require "bigdecimal"
2
+
3
+ module FineAnts
4
+ module Adapters
5
+ class Pnc
6
+ def initialize(credentials)
7
+ @user = credentials[:user]
8
+ @password = credentials[:password]
9
+ end
10
+
11
+ def login
12
+ visit "https://www.onlinebanking.pnc.com/alservlet/SignonInitServlet"
13
+ fill_in "userId", :with => @user
14
+ click_button "Sign On"
15
+
16
+ if all("input[name=answer").any?
17
+ return false
18
+ else
19
+ try_password!
20
+ return true
21
+ end
22
+ end
23
+
24
+ def two_factor_response(answer)
25
+ fill_in "answer", :with => answer
26
+ click_button "Continue"
27
+ try_password!
28
+ end
29
+
30
+ def download
31
+ rows = all("#depositAccountsWrapper tr.depAccount")
32
+ rows.map do |row|
33
+ cells = row.all("td")
34
+ {
35
+ :adapter => :pnc,
36
+ :user => @user,
37
+ :id => cells[2].text, # TODO - this won't be unique, only gives last 4 :-/
38
+ :name => cells[0].text,
39
+ :amount => BigDecimal.new(cells[3].text.match(/\$(.*)$/)[1].gsub(/,/,''))
40
+ }
41
+ end.tap { click_link "Sign Off" }
42
+ end
43
+
44
+ private
45
+
46
+ def try_password!
47
+ fill_in "password", :with => @password
48
+ click_button "Sign On"
49
+ find ".lastSignOn"
50
+ rescue
51
+ raise FineAnts::LoginFailedError.new
52
+ end
53
+
54
+ end
55
+ end
56
+ end
57
+
58
+
@@ -30,15 +30,15 @@ module FineAnts
30
30
  end
31
31
 
32
32
  def download
33
- rows = find(:id, "BalancesTabBoxId:balancesForm:balancesTable").all("tr")
34
- rows[0..-3].map do |row|
33
+ rows = find(".accountsList table").all("tr")
34
+ rows.map do |row|
35
35
  cells = row.all("td")
36
36
  {
37
37
  :adapter => :vanguard,
38
38
  :user => @user,
39
- :id => cells[0].find("a")[:href].match(/.*#(.*)$/)[1],
40
- :name => cells[0].find("a").text,
41
- :amount => BigDecimal.new(cells[1].text.match(/\$(.*)$/)[1].gsub(/,/,''))
39
+ :id => cells.first.find("a")[:href].match(/.*#(.*)$/)[1],
40
+ :name => cells.first.text,
41
+ :amount => BigDecimal.new(cells.last.text.match(/\$(.*)$/)[1].gsub(/,/,''))
42
42
  }
43
43
  end.tap { click_link "Log off" }
44
44
  end
@@ -46,7 +46,7 @@ module FineAnts
46
46
  private
47
47
 
48
48
  def verify_login!
49
- find "#comp-lastLogon"
49
+ find ".lastLogon"
50
50
  rescue Capybara::ElementNotFound
51
51
  raise FineAnts::LoginFailedError.new
52
52
  end
@@ -1,6 +1,8 @@
1
1
  require "capybara/dsl"
2
2
 
3
3
  require "fine_ants/adapters/vanguard"
4
+ require "fine_ants/adapters/pnc"
5
+ require "fine_ants/adapters/betterment"
4
6
 
5
7
  module FineAnts
6
8
  module Adapters
@@ -9,7 +11,6 @@ module FineAnts
9
11
  const_get(const_name).tap do |adapter|
10
12
  adapter.class_eval do
11
13
  include Capybara::DSL
12
-
13
14
  end
14
15
  end
15
16
  end
@@ -9,4 +9,4 @@ Capybara.register_driver :selenium do |app|
9
9
  Capybara::Selenium::Driver.new(app, :browser => :chrome)
10
10
  end
11
11
  Capybara.default_driver = :selenium
12
-
12
+ Capybara.default_wait_time = 5
@@ -1,3 +1,3 @@
1
1
  module FineAnts
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fine_ants
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Searls
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-08-07 00:00:00.000000000 Z
11
+ date: 2016-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capybara
@@ -97,6 +97,8 @@ files:
97
97
  - fine_ants.gemspec
98
98
  - lib/fine_ants.rb
99
99
  - lib/fine_ants/adapters.rb
100
+ - lib/fine_ants/adapters/betterment.rb
101
+ - lib/fine_ants/adapters/pnc.rb
100
102
  - lib/fine_ants/adapters/vanguard.rb
101
103
  - lib/fine_ants/capybara_setup.rb
102
104
  - lib/fine_ants/login_failed_error.rb