burglar 0.0.1 → 0.0.2

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: ad15042c4c2a1593be0e0fed11ce0a41d0d944f8
4
- data.tar.gz: 6220d4e9cfc3b9e8b00838d0a074877da2f89d0b
3
+ metadata.gz: 81787646ec2d922aea291dfaf4de5fcb7d08eb01
4
+ data.tar.gz: a329034499aa42ad0ef1a8ec79459d1cf89fa50e
5
5
  SHA512:
6
- metadata.gz: ab4cfcd6e4b02078c03d52f1516280b330a49a2e55c46cfb54ec695541e796c35ea7c88992653f54abe5334b7febfceb4457507b2ee0378830120e501d7fc5af
7
- data.tar.gz: 60304bd5cedb001bbad65625f9140270bb3fa7e6efe923342d146eaf2f45164765fd39410a30896b384734586949b3e8cf525ed0cd32ebe1c0d803071464379c
6
+ metadata.gz: 4d9e2cc34ec13edf2daa8e1ea132061ef0bd660b43991ddac1cbdd175d9d3fca126510c79542ed9bb92545b1c9867828d1fb9bb3f66074e31a661ddaa7aead81
7
+ data.tar.gz: 6b236a999b709735b7bfc130dd57ad321c391d478cd4004beebc14585b5056c8b18a6dca41fae9e74fcb701e9cf201595b190c92742d773f48cf3eaf57175172
data/.circle-ruby ADDED
@@ -0,0 +1,3 @@
1
+ 2.4.2
2
+ 2.3.5
3
+ 2.2.8
data/.prospectus CHANGED
@@ -1,11 +1,25 @@
1
+ Prospectus.extra_dep('file', 'prospectus_circleci')
2
+
3
+ my_slug = 'akerl/burglar'
4
+
1
5
  item do
2
- expected do
3
- static
4
- set 'green'
5
- end
6
+ noop
6
7
 
7
- actual do
8
- gemnasium
9
- slug 'akerl/burglar'
8
+ deps do
9
+ item do
10
+ name 'gems'
11
+
12
+ expected do
13
+ static
14
+ set 'green'
15
+ end
16
+
17
+ actual do
18
+ gemnasium
19
+ slug my_slug
20
+ end
21
+ end
10
22
  end
23
+
24
+ extend ProspectusCircleci::Build.new(my_slug)
11
25
  end
data/.rubocop.yml CHANGED
@@ -1,2 +1,5 @@
1
- Encoding:
2
- Enabled: false
1
+ inherit_gem:
2
+ goodcop: .rubocop.yml
3
+ AllCops:
4
+ Include:
5
+ - 'bin/*'
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
-
data/README.md CHANGED
@@ -3,15 +3,76 @@ burglar
3
3
 
4
4
  [![Gem Version](https://img.shields.io/gem/v/burglar.svg)](https://rubygems.org/gems/burglar)
5
5
  [![Dependency Status](https://img.shields.io/gemnasium/akerl/burglar.svg)](https://gemnasium.com/akerl/burglar)
6
- [![Build Status](https://img.shields.io/circleci/project/akerl/burglar.svg)](https://circleci.com/gh/akerl/burglar)
6
+ [![Build Status](https://img.shields.io/circleci/project/akerl/burglar/master.svg)](https://circleci.com/gh/akerl/burglar)
7
7
  [![Coverage Status](https://img.shields.io/codecov/c/github/akerl/burglar.svg)](https://codecov.io/github/akerl/burglar)
8
- [![Code Quality](https://img.shields.io/codacy/.svg)](https://www.codacy.com/app/akerl/burglar)
8
+ [![Code Quality](https://img.shields.io/codacy/940f3f131d724124a68a0be7d21f951b.svg)](https://www.codacy.com/app/akerl/burglar)
9
9
  [![MIT Licensed](https://img.shields.io/badge/license-MIT-green.svg)](https://tldrlegal.com/license/mit-license)
10
10
 
11
- Tool for parsing data from bank websites
11
+ Tool for parsing data from bank websites into the format of [ledger](http://ledger-cli.org/)
12
12
 
13
13
  ## Usage
14
14
 
15
+ Burglar operates on the concept of `modules` for each bank's site. The module does the heavy lifting to hit the API or scrape the site for data.
16
+
17
+ ### Running burglar
18
+
19
+ Burglar supports a couple of command line flags, each with a sane default:
20
+
21
+ ```
22
+ -c FILE, --config FILE Config file to load
23
+ -b DATE, --begin DATE Beginning of date range
24
+ -e DATE, --end DATE End of date range
25
+ ```
26
+
27
+ The config file will default to `~/.burglar.yml`, begin defaults to 30 days ago, and end defaults to today.
28
+
29
+ ### Configuration file
30
+
31
+ Here's an initial example, which should be mostly self explanatory.
32
+
33
+ ```
34
+ banks:
35
+ amex:
36
+ type: american_express
37
+ user: akerl
38
+ account: Liabilities:Credit:amex
39
+ ```
40
+
41
+ The banks object is a hash of named hashes, each one is an account that will be polled. Each account *must* have a `type`, which is the name of the module to use. You can also pass an `account`, which sets the account name for the ledger output (if not set, modules can attempt to provide a default). Other configuration depends on the module.
42
+
43
+ ### Modules
44
+
45
+ #### American Express
46
+
47
+ This pulls from the American Express site by scraping a CSV.
48
+
49
+ Configuration:
50
+
51
+ * [required] user: your American Express username
52
+
53
+ #### Ally
54
+
55
+ This pulls from the Ally site by scraping a CSV.
56
+
57
+ * [required] user: your Ally username
58
+ * [required] name: the nickname of the specific account
59
+
60
+ ### Helpers
61
+
62
+ Helpers exist to centralize common activity that modules can rely on.
63
+
64
+ #### Creds
65
+
66
+ This uses [keylime](https://github.com/akerl/keylime) to pull creds from an OSX keychain
67
+
68
+ #### Ledger
69
+
70
+ This helps convert transactions into ledger entries using [libledger](https://github.com/akerl/libledger)
71
+
72
+ #### Mechanize
73
+
74
+ This provides a [Mechanize](https://github.com/sparklemotion/mechanize) client for modules that want to scrape the bank website
75
+
15
76
  ## Installation
16
77
 
17
78
  gem install burglar
data/Rakefile CHANGED
@@ -7,8 +7,7 @@ RSpec::Core::RakeTask.new(:spec)
7
7
 
8
8
  desc 'Run Rubocop on the gem'
9
9
  RuboCop::RakeTask.new(:rubocop) do |task|
10
- task.patterns = ['lib/**/*.rb', 'spec/**/*.rb']
11
10
  task.fail_on_error = true
12
11
  end
13
12
 
14
- task default: [:spec, :rubocop, :build, :install]
13
+ task default: %i[spec rubocop build install]
data/bin/burglar ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'burglar'
4
+ require 'mercenary'
5
+ require 'cymbal'
6
+ require 'yaml'
7
+
8
+ def add_common_opts(c)
9
+ c.option :config, '-c FILE', '--config FILE', 'Config file to load'
10
+ c.option :begin, '-b DATE', '--begin DATE', 'Beginning of date range'
11
+ c.option :end, '-e DATE', '--end DATE', 'End of date range'
12
+ end
13
+
14
+ def load_config(file)
15
+ file ||= '~/.burglar.yml'
16
+ file = File.expand_path file
17
+ Cymbal.symbolize YAML.safe_load(File.read(file))
18
+ end
19
+
20
+ Mercenary.program(:burglar) do |p|
21
+ p.version Burglar::VERSION
22
+ p.description 'Load data from banks'
23
+ p.syntax 'burglar [options]'
24
+
25
+ add_common_opts(p)
26
+
27
+ p.action do |_, options|
28
+ options[:end] ||= Date.today
29
+ options[:begin] ||= options[:end] - 30
30
+ config = load_config(options[:config]).merge(options)
31
+ puts Burglar.new(config).transactions
32
+ end
33
+ end
data/burglar.gemspec CHANGED
@@ -1,10 +1,14 @@
1
+ require 'English'
2
+ $LOAD_PATH.unshift File.expand_path('../lib/', __FILE__)
3
+ require 'burglar/version'
4
+
1
5
  Gem::Specification.new do |s|
2
6
  s.name = 'burglar'
3
- s.version = '0.0.1'
7
+ s.version = Burglar::VERSION
4
8
  s.date = Time.now.strftime('%Y-%m-%d')
5
9
 
6
10
  s.summary = 'Tool for parsing data from bank websites'
7
- s.description = "Tool for parsing data from bank websites"
11
+ s.description = 'Tool for parsing data from bank websites'
8
12
  s.authors = ['Les Aker']
9
13
  s.email = 'me@lesaker.org'
10
14
  s.homepage = 'https://github.com/akerl/burglar'
@@ -12,10 +16,17 @@ Gem::Specification.new do |s|
12
16
 
13
17
  s.files = `git ls-files`.split
14
18
  s.test_files = `git ls-files spec/*`.split
19
+ s.executables = ['burglar']
20
+
21
+ s.add_dependency 'cymbal', '~> 1.0.0'
22
+ s.add_dependency 'libledger', '~> 0.0.3'
23
+ s.add_dependency 'logcabin', '~> 0.1.3'
24
+ s.add_dependency 'mercenary', '~> 0.3.4'
15
25
 
16
- s.add_development_dependency 'rubocop', '~> 0.35.0'
17
- s.add_development_dependency 'rake', '~> 10.4.0'
18
26
  s.add_development_dependency 'codecov', '~> 0.1.1'
19
- s.add_development_dependency 'rspec', '~> 3.4.0'
20
- s.add_development_dependency 'fuubar', '~> 2.0.0'
27
+ s.add_development_dependency 'fuubar', '~> 2.2.0'
28
+ s.add_development_dependency 'goodcop', '~> 0.1.0'
29
+ s.add_development_dependency 'rake', '~> 12.3.0'
30
+ s.add_development_dependency 'rspec', '~> 3.7.0'
31
+ s.add_development_dependency 'rubocop', '~> 0.51.0'
21
32
  end
data/circle.yml CHANGED
@@ -1,12 +1,7 @@
1
1
  dependencies:
2
2
  override:
3
- - 'rvm-exec 2.0.0-p645 bundle install'
4
- - 'rvm-exec 2.1.6 bundle install'
5
- - 'rvm-exec 2.2.2 bundle install'
6
- - 'rvm-exec 2.3.1 bundle install'
3
+ - 'for i in $(cat .circle-ruby) ; do rvm-exec $i gem update --system --no-doc || exit 1 ; done'
4
+ - 'for i in $(cat .circle-ruby) ; do rvm-exec $i bundle install || exit 1 ; done'
7
5
  test:
8
6
  override:
9
- - 'rvm-exec 2.0.0-p645 bundle exec rake'
10
- - 'rvm-exec 2.1.6 bundle exec rake'
11
- - 'rvm-exec 2.2.2 bundle exec rake'
12
- - 'rvm-exec 2.3.1 bundle exec rake'
7
+ - 'for i in $(cat .circle-ruby) ; do rvm-exec $i bundle exec rake || exit 1 ; done'
data/lib/burglar.rb CHANGED
@@ -0,0 +1,43 @@
1
+ require 'logcabin'
2
+ require 'libledger'
3
+
4
+ ##
5
+ # This module provides a unified interface for pulling accountig transactions
6
+ module Burglar
7
+ class << self
8
+ ##
9
+ # Insert a helper .new() method for creating a new Heist object
10
+
11
+ def new(*args)
12
+ self::Heist.new(*args)
13
+ end
14
+
15
+ def modules
16
+ @modules ||= LogCabin.new(load_path: load_path(:modules))
17
+ end
18
+
19
+ def helpers
20
+ @helpers ||= LogCabin.new(load_path: load_path(:helpers))
21
+ end
22
+
23
+ def extra_dep(name, dep)
24
+ require dep
25
+ rescue LoadError
26
+ raise("The #{name} module requires the #{dep} gem")
27
+ end
28
+
29
+ private
30
+
31
+ def gem_dir
32
+ Gem::Specification.find_by_name('burglar').gem_dir
33
+ end
34
+
35
+ def load_path(type)
36
+ File.join(gem_dir, 'lib', 'burglar', type.to_s)
37
+ end
38
+ end
39
+ end
40
+
41
+ require 'burglar/version'
42
+ require 'burglar/heist'
43
+ require 'burglar/bank'
@@ -0,0 +1,40 @@
1
+ module Burglar
2
+ ##
3
+ # Single bank's information
4
+ class Bank
5
+ def initialize(params = {})
6
+ @options = params
7
+ extend module_obj
8
+ end
9
+
10
+ def transactions
11
+ Ledger.new(entries: raw_transactions)
12
+ end
13
+
14
+ def begin_date
15
+ @begin_date ||= @options[:begin]
16
+ end
17
+
18
+ def end_date
19
+ @end_date ||= @options[:end]
20
+ end
21
+
22
+ private
23
+
24
+ def account_name
25
+ @account_name ||= @options[:account] || default_account_name
26
+ end
27
+
28
+ def default_account_name
29
+ raise('Module failed to override default_account_name')
30
+ end
31
+
32
+ def type
33
+ @type ||= @options[:type] || raise('Must supply an account type')
34
+ end
35
+
36
+ def module_obj
37
+ @module_obj ||= Burglar.modules.find(type) || raise("No module: #{type}")
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,21 @@
1
+ module Burglar
2
+ ##
3
+ # Collection of banks
4
+ class Heist
5
+ def initialize(params = {})
6
+ @options = params
7
+ end
8
+
9
+ def banks
10
+ @banks ||= @options[:banks].map do |k, v|
11
+ [k, Burglar::Bank.new(@options.merge(v))]
12
+ end.to_h
13
+ end
14
+
15
+ def transactions
16
+ @transactions ||= Ledger.new(
17
+ entries: banks.map { |_, v| v.transactions.entries }.flatten.sort
18
+ )
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ Burglar.extra_dep('creds', 'keylime')
2
+
3
+ module LogCabin
4
+ module Modules
5
+ ##
6
+ # Provide a helper to access OSX keychain credentials
7
+ module Creds
8
+ def creds(server, account)
9
+ credential = Keylime.new(server: server, account: account)
10
+ credential.get!("Enter password for #{server} (#{account})").password
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ module LogCabin
2
+ module Modules
3
+ ##
4
+ # Provide a helper to create simple Ledger objects
5
+ module Ledger
6
+ def simple_ledger(date, name, amount)
7
+ ::Ledger::Entry.new(
8
+ name: name,
9
+ state: date > Date.today ? :pending : :cleared,
10
+ date: date.strftime('%Y/%m/%d'),
11
+ actions: [
12
+ { name: guess_action(name), amount: amount },
13
+ { name: account_name }
14
+ ]
15
+ )
16
+ end
17
+
18
+ def guess_action(name)
19
+ guess = `ledger xact '#{name.delete("'")}' 2>/dev/null`.split("\n")[1]
20
+ guess ? guess.split.first : 'Expenses:generic'
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ Burglar.extra_dep('mechanize', 'mechanize')
2
+
3
+ module LogCabin
4
+ module Modules
5
+ ##
6
+ # Provide a helper to scrape websites
7
+ module Mechanize
8
+ def mech
9
+ return @mech if @mech
10
+ @mech = ::Mechanize.new
11
+ setup_mech if respond_to? :setup_mech, true
12
+ @mech
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,156 @@
1
+ require 'json'
2
+ require 'csv'
3
+ require 'date'
4
+ require 'digest/sha1'
5
+
6
+ module LogCabin
7
+ module Modules
8
+ ##
9
+ # Ally
10
+ module Ally # rubocop:disable Metrics/ModuleLength
11
+ include Burglar.helpers.find(:creds)
12
+ include Burglar.helpers.find(:mechanize)
13
+ include Burglar.helpers.find(:ledger)
14
+
15
+ ALLY_DOMAIN = 'https://secure.ally.com'.freeze
16
+ ALLY_CSRF_URL = ALLY_DOMAIN + '/capi-gw/session/status/olbWeb'
17
+ ALLY_AUTH_URL = ALLY_DOMAIN + '/capi-gw/customer/authentication'
18
+ ALLY_AUTH_PATCH_URL = ALLY_AUTH_URL + '?_method=PATCH'
19
+ ALLY_MFA_URL = ALLY_DOMAIN + '/capi-gw/notification'
20
+ ALLY_DEVICE_URL = ALLY_DOMAIN + '/capi-gw/customer/device'
21
+ ALLY_DEVICE_PATCH_URL = ALLY_DEVICE_URL + '?_method=PATCH'
22
+ ALLY_ACCOUNT_URL = ALLY_DOMAIN + '/capi-gw/accounts'
23
+
24
+ def raw_transactions
25
+ csv.map do |x|
26
+ amount = format('$%.2f', x[:amount] * -1)
27
+ simple_ledger(x[:date], x[:description], amount)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def default_account_name
34
+ 'Assets:' + @options[:name].gsub(/\s/, '')
35
+ end
36
+
37
+ def raw_csv_url
38
+ ALLY_DOMAIN + "/capi-gw/accounts/#{account_id}/transactions.csv"
39
+ end
40
+
41
+ def raw_csv
42
+ csv_headers = headers('text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8') # rubocop:disable Metrics/LineLength
43
+ @raw_csv ||= mech.get(raw_csv_url, csv_data, nil, csv_headers)
44
+ end
45
+
46
+ def csv
47
+ @csv ||= CSV.new(
48
+ raw_csv.body,
49
+ headers: true,
50
+ header_converters: :symbol,
51
+ converters: %i[date float]
52
+ ).map(&:to_h)
53
+ end
54
+
55
+ def csv_data
56
+ @csv_data ||= {
57
+ 'fromDate' => begin_date.strftime('%Y-%m-%d'),
58
+ 'toDate' => end_date.strftime('%Y-%m-%d'),
59
+ 'status' => 'Posted'
60
+ }
61
+ end
62
+
63
+ def user
64
+ @user ||= @options[:user]
65
+ end
66
+
67
+ def password
68
+ @password ||= creds(ALLY_DOMAIN, user)
69
+ end
70
+
71
+ def csrf_token
72
+ mech
73
+ @csrf_token ||= mech.get(ALLY_CSRF_URL).response['csrfchallengetoken']
74
+ end
75
+
76
+ def device_token
77
+ return @device_token if @device_token
78
+ res = `system_profiler SPHardwareDataType`
79
+ raw_token = res.lines.grep(/Serial Number/).first.split.last
80
+ @device_token = Digest::SHA1.hexdigest raw_token
81
+ end
82
+
83
+ def headers(accept, spname = nil)
84
+ {
85
+ 'CSRFChallengeToken' => csrf_token,
86
+ 'ApplicationName' => 'AOB',
87
+ 'ApplicationId' => 'ALLYUSBOLB',
88
+ 'ApplicationVersion' => '1.0',
89
+ 'Accept' => accept,
90
+ 'spname' => spname
91
+ }.reject { |_, v| v.nil? }
92
+ end
93
+
94
+ def auth_headers
95
+ @auth_headers ||= headers('application/v1+json', 'auth')
96
+ end
97
+
98
+ def common_data
99
+ @common_data = {
100
+ 'channelType' => 'OLB',
101
+ 'devicePrintRSA' => device_token
102
+ }
103
+ end
104
+
105
+ def auth_data
106
+ @auth_data = common_data.merge(
107
+ 'userNamePvtEncrypt' => user,
108
+ 'passwordPvtBlock' => password,
109
+ 'rememberMeFlag' => 'false'
110
+ )
111
+ end
112
+
113
+ def setup_mech
114
+ auth = mech.post(ALLY_AUTH_URL, auth_data, auth_headers)
115
+ auth_res = JSON.parse(auth.body)
116
+ mfa(auth_res) if auth_res['authentication']['mfa']
117
+ end
118
+
119
+ def mfa_data(payload)
120
+ mfa_methods = payload['authentication']['mfa']['mfaDeliveryMethods']
121
+ mfa_id = mfa_methods.first['deliveryMethodId']
122
+ common_data.merge('deliveryMethodId' => mfa_id)
123
+ end
124
+
125
+ def mfa_token
126
+ UserInput.new(message: 'MFA token', validation: /^\d+$/).ask
127
+ end
128
+
129
+ def mfa(payload)
130
+ mech.post(ALLY_MFA_URL, mfa_data(payload), auth_headers)
131
+ data = common_data.merge('otpCodePvtBlock' => mfa_token)
132
+ mech.post(ALLY_AUTH_PATCH_URL, data, auth_headers)
133
+ mech.post(ALLY_DEVICE_PATCH_URL, common_data, auth_headers)
134
+ end
135
+
136
+ def accounts
137
+ account_headers = headers('application/vnd.api+json', 'common-api')
138
+ @accounts ||= JSON.parse(
139
+ mech.get(ALLY_ACCOUNT_URL, [], nil, account_headers).body
140
+ )
141
+ end
142
+
143
+ def account
144
+ return @account if @account
145
+ list = accounts['accounts']['deposit']['accountSummary']
146
+ match = list.find { |x| x['accountNickname'].match @options[:name] }
147
+ raise('No matching account found') unless match
148
+ @account = match
149
+ end
150
+
151
+ def account_id
152
+ @account_id ||= account['accountId']
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,79 @@
1
+ require 'csv'
2
+ require 'date'
3
+
4
+ module LogCabin
5
+ module Modules
6
+ ##
7
+ # American Express
8
+ module AmericanExpress
9
+ include Burglar.helpers.find(:creds)
10
+ include Burglar.helpers.find(:ledger)
11
+ include Burglar.helpers.find(:mechanize)
12
+
13
+ # rubocop:disable Metrics/LineLength
14
+ AMEX_DOMAIN = 'https://online.americanexpress.com'.freeze
15
+ AMEX_LOGIN_PATH = '/myca/logon/us/action/LogonHandler?request_type=LogonHandler&Face=en_US'.freeze
16
+ AMEX_LOGIN_FORM = 'lilo_formLogon'.freeze
17
+ AMEX_CSV_PATH = '/myca/estmt/us/downloadTxn.do'.freeze
18
+ # rubocop:enable Metrics/LineLength
19
+
20
+ def raw_transactions
21
+ @raw_transactions ||= csv.map do |row|
22
+ raw_date, raw_amount, raw_name = row.values_at(0, 7, 11)
23
+ date = Date.strptime(raw_date, '%m/%d/%Y %a')
24
+ amount = format('$%.2f', raw_amount)
25
+ name = raw_name.empty? ? 'Amex Payment' : raw_name.downcase
26
+ simple_ledger(date, name, amount)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def default_account_name
33
+ 'Liabilities:Credit:american_express'.freeze
34
+ end
35
+
36
+ def user
37
+ @user ||= @options[:user]
38
+ end
39
+
40
+ def password
41
+ @password ||= creds(AMEX_DOMAIN, user)
42
+ end
43
+
44
+ def setup_mech
45
+ mech.user_agent = 'chrome'
46
+ page = mech.get(AMEX_DOMAIN + AMEX_LOGIN_PATH)
47
+ form = page.form_with(id: AMEX_LOGIN_FORM) do |f|
48
+ f.UserID = user
49
+ f.Password = password
50
+ end
51
+ form.submit
52
+ end
53
+
54
+ def csv
55
+ CSV.parse(csv_page.body)
56
+ end
57
+
58
+ def csv_page
59
+ params = static_fields.merge(
60
+ 'startDate' => begin_date.strftime('%m%d%Y'),
61
+ 'endDate' => end_date.strftime('%m%d%Y')
62
+ )
63
+ mech.post(AMEX_DOMAIN + AMEX_CSV_PATH, params)
64
+ end
65
+
66
+ def static_fields
67
+ @static_fields ||= {
68
+ 'request_type' => 'authreg_Statement',
69
+ 'downloadType' => 'C',
70
+ 'downloadView' => 'C',
71
+ 'downloadWithETDTool' => 'true',
72
+ 'viewType' => 'L',
73
+ 'reportType' => '1',
74
+ 'BPIndex' => '-99'
75
+ }.freeze
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # Set the version (needed for Mercenary -v)
5
+ module Burglar
6
+ VERSION = '0.0.2'.freeze
7
+ end
data/spec/burglar_spec.rb CHANGED
@@ -1,2 +1 @@
1
1
  require 'spec_helper'
2
-
metadata CHANGED
@@ -1,43 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: burglar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Les Aker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-24 00:00:00.000000000 Z
11
+ date: 2017-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rubocop
14
+ name: cymbal
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.35.0
20
- type: :development
19
+ version: 1.0.0
20
+ type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.35.0
26
+ version: 1.0.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: libledger
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 10.4.0
34
- type: :development
33
+ version: 0.0.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: logcabin
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.1.3
48
+ type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: 10.4.0
54
+ version: 0.1.3
55
+ - !ruby/object:Gem::Dependency
56
+ name: mercenary
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.3.4
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.3.4
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: codecov
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -52,40 +80,84 @@ dependencies:
52
80
  - - "~>"
53
81
  - !ruby/object:Gem::Version
54
82
  version: 0.1.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: fuubar
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 2.2.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 2.2.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: goodcop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.1.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.1.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 12.3.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 12.3.0
55
125
  - !ruby/object:Gem::Dependency
56
126
  name: rspec
57
127
  requirement: !ruby/object:Gem::Requirement
58
128
  requirements:
59
129
  - - "~>"
60
130
  - !ruby/object:Gem::Version
61
- version: 3.4.0
131
+ version: 3.7.0
62
132
  type: :development
63
133
  prerelease: false
64
134
  version_requirements: !ruby/object:Gem::Requirement
65
135
  requirements:
66
136
  - - "~>"
67
137
  - !ruby/object:Gem::Version
68
- version: 3.4.0
138
+ version: 3.7.0
69
139
  - !ruby/object:Gem::Dependency
70
- name: fuubar
140
+ name: rubocop
71
141
  requirement: !ruby/object:Gem::Requirement
72
142
  requirements:
73
143
  - - "~>"
74
144
  - !ruby/object:Gem::Version
75
- version: 2.0.0
145
+ version: 0.51.0
76
146
  type: :development
77
147
  prerelease: false
78
148
  version_requirements: !ruby/object:Gem::Requirement
79
149
  requirements:
80
150
  - - "~>"
81
151
  - !ruby/object:Gem::Version
82
- version: 2.0.0
152
+ version: 0.51.0
83
153
  description: Tool for parsing data from bank websites
84
154
  email: me@lesaker.org
85
- executables: []
155
+ executables:
156
+ - burglar
86
157
  extensions: []
87
158
  extra_rdoc_files: []
88
159
  files:
160
+ - ".circle-ruby"
89
161
  - ".gitignore"
90
162
  - ".prospectus"
91
163
  - ".rspec"
@@ -94,9 +166,18 @@ files:
94
166
  - LICENSE
95
167
  - README.md
96
168
  - Rakefile
169
+ - bin/burglar
97
170
  - burglar.gemspec
98
171
  - circle.yml
99
172
  - lib/burglar.rb
173
+ - lib/burglar/bank.rb
174
+ - lib/burglar/heist.rb
175
+ - lib/burglar/helpers/creds.rb
176
+ - lib/burglar/helpers/ledger.rb
177
+ - lib/burglar/helpers/mechanize.rb
178
+ - lib/burglar/modules/ally.rb
179
+ - lib/burglar/modules/american_express.rb
180
+ - lib/burglar/version.rb
100
181
  - spec/burglar_spec.rb
101
182
  - spec/spec_helper.rb
102
183
  homepage: https://github.com/akerl/burglar
@@ -119,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
200
  version: '0'
120
201
  requirements: []
121
202
  rubyforge_project:
122
- rubygems_version: 2.5.1
203
+ rubygems_version: 2.6.14
123
204
  signing_key:
124
205
  specification_version: 4
125
206
  summary: Tool for parsing data from bank websites