ruby_mint 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f35663ac4c4455968a43c43629104347ac097356
4
- data.tar.gz: c00b9cd9cf3e4eb9c54450a730cf039f3996b706
3
+ metadata.gz: 0669bb9e0106c090f125a7b2347ec0a9328cad25
4
+ data.tar.gz: 3e9ad2ca1e6eee3c10a724f67eae1faca8b3a7b5
5
5
  SHA512:
6
- metadata.gz: 13692c620ee097e5368b4bcf0ab96cc6dd7229d3ef4f38f768e42f1c634fd871d881c6e1ef5a8f043d5ecc8b77930564700a8b46c388ed1f661abd9001294637
7
- data.tar.gz: de2f372cdf31d425fb64eeac56db6e9caca6d366dcb526952a07b3468ecf834cc786fe71cc44171f15ed800bf91ca962ee60a99bfcbb675253fc1bf796c78a14
6
+ metadata.gz: a1df96b9d242217ed2ef82d9db254cf134c10c2462f7305acaabb91013978a0493f7cd7c51a62f2ab8c479dd71ef13b6050bee69e03fa9cbcb285602d689807d
7
+ data.tar.gz: fb6dba46232e82db20b155ccffdb5ae99487fa84f785719b9b9bdc70ce1476708208a8c4f83ff39bb26ba70eceedfc87e38e63cd050b272f0585aa11a62e52fb
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Gem Version](https://badge.fury.io/rb/ruby_mint.svg)](http://badge.fury.io/rb/ruby_mint)
2
+
1
3
  # RubyMint
2
4
 
3
5
  RubyMint is a gem to assist you with getting information from Mint.com's API.
@@ -63,10 +65,32 @@ accounts = ruby_mint.accounts
63
65
 
64
66
  # Transaction Data
65
67
 
66
- Mint.com returns transactions as CSV.
68
+ Transactions can be obtained as either CSV or JSON data.
69
+
70
+ CSV is a list of all transactions as a CSV dump.
71
+
72
+ NOTE: Breaking change from v0.1 Old transactions method is now transactions_csv
73
+
74
+ ```ruby
75
+ transactions_csv = ruby_mint.transactions_csv
76
+ ```
77
+
78
+ JSON data must specify a date range and has the option to include pending transactions
79
+ or to include a search term. Mint only returns a transaction date without a time. Date
80
+ range is inclusive.
67
81
 
68
82
  ```ruby
69
- transactions = ruby_mint.transactions
83
+ # Get all transactions from May 1, 2015 until now
84
+ transactions = ruby_mint.transactions Time.parse("2015-05-01")
85
+
86
+ # Get all transactions for the month of May
87
+ transactions = ruby_mint.transactions Time.parse("2015-05-01"), Time.parse("2015-05-31")
88
+
89
+ # Include pending transactions
90
+ transactions = ruby_mint.transactions Time.parse("2015-05-01"), Time.parse("2015-05-31"), 'include_pending' => true
91
+
92
+ # Include a search term
93
+ transactions = ruby_mint.transactions Time.parse("2015-05-01"), Time.parse("2015-05-31"), 'search_term' => 'coffee'
70
94
  ```
71
95
 
72
96
  ## Contributing
data/bin/mint_download.rb CHANGED
@@ -61,7 +61,7 @@ ruby_mint.initiate_account_refresh do
61
61
 
62
62
  if transactions_file
63
63
  puts "Downloading transactions..."
64
- transactions = ruby_mint.transactions
64
+ transactions = ruby_mint.transactions_csv
65
65
  end
66
66
  end
67
67
 
data/lib/ruby_mint.rb CHANGED
@@ -32,7 +32,11 @@ class RubyMint
32
32
  end
33
33
 
34
34
  # Login retrieves a user token from Mint.com
35
- def login
35
+ #
36
+ # @param use_token [String] Use an existing token
37
+ def login(use_token = nil)
38
+ @token = use_token and return if use_token
39
+
36
40
  response = agent.get("https://wwws.mint.com/login.event?task=L")
37
41
  raise RubyMintError.new("Unable to GET Mint login page.") if response.code != "200"
38
42
 
@@ -72,9 +76,9 @@ class RubyMint
72
76
  #
73
77
  # @param sleep_time [Integer] Num of seconds to wait between calls to refreshing? when block is passed
74
78
  # @param block [Block] Code to execute upon completion of of refreshing
75
- def initiate_account_refresh(sleep_time = 3, &block)
79
+ def initiate_account_refresh(sleep_time = 3)
76
80
  agent.post("https://wwws.mint.com/refreshFILogins.xevent", { "token" => @token }, JSON_HEADERS)
77
- if block
81
+ if block_given?
78
82
  loop{ sleep sleep_time; break if !refreshing? }
79
83
  yield
80
84
  end
@@ -112,6 +116,8 @@ class RubyMint
112
116
  results = agent.post("https://wwws.mint.com/bundledServiceController.xevent?legacy=false&token=#{@token}", account_query, JSON_HEADERS)
113
117
  raise RubyMintError.new("Unable to obtain account information. Response code: #{results.code}") if results.code != "200"
114
118
 
119
+ raise RubyMintError.new("Not logged in.") if results.body.include?('Session has expired.')
120
+
115
121
  account_body = JSON.load(results.body)
116
122
  if !account_body || !account_body["response"] || !account_body["response"][@request_id.to_s] || !account_body["response"][@request_id.to_s]["response"]
117
123
  raise RubyMintError.new("Unable to obtain account information (no account information in response).")
@@ -124,14 +130,55 @@ class RubyMint
124
130
  # the transactions available
125
131
  #
126
132
  # @return [String] CSV of all transactions
127
- def transactions
133
+ def transactions_csv
128
134
  results = agent.get("https://wwws.mint.com/transactionDownload.event", JSON_HEADERS)
129
- raise RubyMintError.new("Unable to obtain transations.") if results.code != "200"
135
+ raise RubyMintError.new("Unable to obtain transactions.") if results.code != "200"
130
136
  raise RubyMintError.new("Non-CSV content returned.") if !results.header["content-type"].include?("text/csv")
131
137
 
132
138
  results.body
133
139
  end
134
140
 
141
+ # Get transactions from mint. Returned as JSON. Paginate
142
+ #
143
+ # Options:
144
+ # include_pending [Boolean] default false
145
+ # search_term [String] default ""
146
+ #
147
+ # @param start_date [Time] get all transactions on or after this date
148
+ # @param end_date [Time] get all transactions up to and including this date
149
+ # @param options [Hash] options hash
150
+ # @returns [Array<Hash>] array of transactions
151
+ def transactions(start_date, end_date = Time.now, options = {})
152
+ include_pending = options.fetch('include_pending', false)
153
+ search_term = options.fetch('search_term', '')
154
+ offset = 0
155
+ results = []
156
+
157
+ # Convert start and end dates
158
+ start_date = Time.local(start_date.year, start_date.month, start_date.day)
159
+ end_date = Time.local(end_date.year, end_date.month, end_date.day)
160
+
161
+ loop do
162
+ next_page = transaction_page(offset, search_term)
163
+ break if next_page.empty?
164
+
165
+ # Filter out pending transactions
166
+ if !include_pending
167
+ next_page.reject!{ |t| t['isPending'] }
168
+ end
169
+
170
+ results.concat next_page
171
+ break if earliest_mint_date(next_page) < start_date
172
+
173
+ offset += next_page.count
174
+ end
175
+
176
+ # Filter by date
177
+ results.select do |t|
178
+ t['date'] >= start_date && t['date'] <= end_date
179
+ end
180
+ end
181
+
135
182
 
136
183
  private
137
184
 
@@ -140,4 +187,49 @@ class RubyMint
140
187
  agent.user_agent_alias = 'Linux Firefox'
141
188
  }
142
189
  end
190
+
191
+ # Get a single page of transaction data. Mint always returns 50 transactions per page.
192
+ def transaction_page(offset, search_term)
193
+ # Example query: https://wwws.mint.com/app/getJsonData.xevent?queryNew=&offset=0&filterType=cash&acctChanged=T&task=transactions&rnd=1436026512488
194
+ base_url = "https://wwws.mint.com/app/getJsonData.xevent"
195
+ search_query = "?queryNew=#{URI.encode(search_term)}"
196
+ offset_query = "&offset=#{offset}"
197
+ transaction_query = "&filterType=cash&comparableType=8&task=transactions&rnd=#{random_number}"
198
+
199
+ json_results = agent.get("#{base_url}#{search_query}#{offset_query}#{transaction_query}", JSON_HEADERS)
200
+ raise RubyMintError.new("Unable to obtain transactions.") if json_results.code != "200"
201
+ raise RubyMintError.new("Non-JSON content returned.") if !json_results.header["content-type"].include?("text/json")
202
+
203
+ transform_transaction_times JSON.parse(json_results.body)['set'][0]['data']
204
+ end
205
+
206
+ # Mint returns transactions in two formats: "Mar 8" for this year, "10/08/14" for previous years (month/day/year).
207
+ # Transform dates into ruby time objects.
208
+ #
209
+ # NOTE: Mint only returns the date of the transaction, there is no time
210
+ #
211
+ # @param transactions [Array<Hash>] array of transactions
212
+ def transform_transaction_times(transactions)
213
+ transactions.map do |t|
214
+ t['date'] = (t['date'] =~ /\d+\/\d+\/\d+/ ? Time.strptime(t['date'], "%D") : Time.parse(t['date']))
215
+ t
216
+ end
217
+ end
218
+
219
+ # Get the earliest date from this set of transactions. Assumes they are in reverse order.
220
+ #
221
+ # @params transactions [Array<Hash>]
222
+ # @returns [Time]
223
+ def earliest_mint_date(transactions)
224
+ transactions.last['date']
225
+ end
226
+
227
+ # Queries require a 12-digit random number
228
+ def random_number
229
+ # They are starting with 14, so I won't break the mold. Get 10 more.
230
+ nums = (0..9).to_a
231
+ result = "14"
232
+ 10.times{ result << nums.sample.to_s }
233
+ result
234
+ end
143
235
  end
@@ -1,3 +1,3 @@
1
1
  class RubyMint
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
data/ruby_mint.gemspec CHANGED
@@ -25,4 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "bundler", "~> 1.8"
26
26
  spec.add_development_dependency "rake", "~> 10.0"
27
27
  spec.add_development_dependency "pry", "~> 0.10"
28
+ spec.add_development_dependency "rspec", "~> 3.3"
29
+ spec.add_development_dependency "vcr", "~> 2.9"
30
+ spec.add_development_dependency "webmock", "~> 1.21"
28
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_mint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Marrone
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-03-09 00:00:00.000000000 Z
11
+ date: 2015-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mechanize
@@ -80,6 +80,48 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0.10'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: vcr
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '2.9'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '2.9'
111
+ - !ruby/object:Gem::Dependency
112
+ name: webmock
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.21'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.21'
83
125
  description: Gem to allow you to incorporate Mint.com into your ruby applications.
84
126
  email:
85
127
  - nickmarrone@gmail.com
@@ -88,6 +130,7 @@ extensions: []
88
130
  extra_rdoc_files: []
89
131
  files:
90
132
  - ".gitignore"
133
+ - ".rspec"
91
134
  - ".travis.yml"
92
135
  - CODE_OF_CONDUCT.md
93
136
  - Gemfile
@@ -118,9 +161,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
161
  version: '0'
119
162
  requirements: []
120
163
  rubyforge_project:
121
- rubygems_version: 2.2.2
164
+ rubygems_version: 2.2.3
122
165
  signing_key:
123
166
  specification_version: 4
124
167
  summary: Retrieve your Mint.com transaction and account information.
125
168
  test_files: []
126
- has_rdoc: