amex 0.1.0 → 0.2.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.
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +16 -0
- data/README.md +91 -0
- data/amex-0.1.0.gem +0 -0
- data/amex.gemspec +15 -0
- data/example.rb +10 -0
- data/lib/amex/client.rb +30 -16
- data/lib/amex/version.rb +1 -1
- metadata +27 -3
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
settings.rb
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/README.md
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
## Amex
|
2
|
+
|
3
|
+
Welcome to the last continuation of my Ruby-based assault on various online
|
4
|
+
banking systems, much like my
|
5
|
+
[Lloyds TSB screen scraper](https://github.com/timrogers/lloydstsb).
|
6
|
+
|
7
|
+
However, this one doesn't rely on nasty screen-scraping. Instead, it uses
|
8
|
+
the previous unknown internal API used by American Express for their
|
9
|
+
"Amex UK" iPhone app. I suspect it works elsewhere, but I haven't tested.
|
10
|
+
|
11
|
+
### Changelog
|
12
|
+
|
13
|
+
__v0.1.0__ - Original version
|
14
|
+
__v0.2.0__ - Support for multiple American Express cards, parsing using
|
15
|
+
Nokogiri
|
16
|
+
|
17
|
+
### Usage
|
18
|
+
|
19
|
+
The file `example.rb` provides a very simple example of how the code works, but here's a step by step:
|
20
|
+
|
21
|
+
1. Ensure the gem is installed, and then include it in your Ruby file, or in your Gemfile where appropriate:
|
22
|
+
|
23
|
+
```
|
24
|
+
$ gem install amex
|
25
|
+
`require 'amex'
|
26
|
+
```
|
27
|
+
|
28
|
+
2. You'll just need two variables, @username and @password, each unsurprisingly corresponding to different authentication details used
|
29
|
+
|
30
|
+
```
|
31
|
+
@username = "chuck_norris"
|
32
|
+
@password = "roundhousekick123"
|
33
|
+
```
|
34
|
+
|
35
|
+
3. Instantiate a new instance of the `Amex::Client` object, passing in the
|
36
|
+
username and password - this is used to perform the authentication required.
|
37
|
+
|
38
|
+
`client = Amex::Client.new(@username, @password)`
|
39
|
+
|
40
|
+
4. Call the `account` method of the object you just made - it'll take a few seconds, and will return an Amex::CardAccount object. There'll only be one, since this
|
41
|
+
only supports one card at a time right now.
|
42
|
+
|
43
|
+
```
|
44
|
+
accounts = client.accounts
|
45
|
+
puts account.first.product
|
46
|
+
puts account.first.type
|
47
|
+
```
|
48
|
+
|
49
|
+
### Data models
|
50
|
+
|
51
|
+
An `Amex::CardAccount` is created by `Amex::CardAccount.new` passing in a hash
|
52
|
+
of the parsed XML. The parsing is done by `Amex::Client`.
|
53
|
+
|
54
|
+
An __Amex::CardAccount__ instance has the following attributes:
|
55
|
+
|
56
|
+
* __product (string)__ - the type of card (e.g. "The Preferred Rewards Gold Card®")
|
57
|
+
* __card_number_suffix (string)__ - the last five digits of your card number
|
58
|
+
* __lending_type (string)__ - either "Charge" or "Credit", depending on the type of credit arrangement you have
|
59
|
+
* __card_member_name (string)__ - your name, as recorded as the account holder
|
60
|
+
* __past_due (boolean)__ - is the card past its due payment date?
|
61
|
+
* __cancelled?__ (boolean)__ - has the account been cancelled?
|
62
|
+
* __is_basic/centurion/platinum/premium] (boolean)__ - which type of account does this conform to?
|
63
|
+
* __market (string)__ - the market that your card is registered too, e.g. "en_GB"
|
64
|
+
* __card__art (string)__ - a URL for an image of your card
|
65
|
+
* __loyalty_indicator (boolean)__ - does this card have some
|
66
|
+
kind of loyalty scheme active? (e.g. Membership Rewards)
|
67
|
+
* __loyalty_programmes (array of Amex::LoyaltyProgramme objects)__ - the loyalty programmes this card belongs to
|
68
|
+
* __loyalty_balances (hash)__ - the loyalty balances on this card - the key is the name of the programme (string), and the balance is the value, as an integer
|
69
|
+
* __statement_balance (float)__ - the amount of the last statement on your account
|
70
|
+
* __payment_credits (float)__ - the combination of current payments and credits on your account
|
71
|
+
* __recent_charges (float)__ - charges since your last statement was issued (I believe)
|
72
|
+
* __total_balance (float)__ - what American Express refer to as your total balance, whatever that is!
|
73
|
+
* __payment_due (float)__ - the amount of money you need to pay before `payment_due_date`
|
74
|
+
* __payment_due_date (DateTime)__ - when the `payment_due` needs to be paid by
|
75
|
+
|
76
|
+
There are lots of extra useful methods here to make accessing
|
77
|
+
some of the various properties easier. They're very self-explanatory - check `lib/amex/card_account.rb`.
|
78
|
+
|
79
|
+
A __LloydsTSB::LoyaltyProgramme has just two attributes:
|
80
|
+
|
81
|
+
* __name (string)__ - The name of the programme, most often "Membership Rewards"
|
82
|
+
* __balance (integer)__ - The balance of the programme
|
83
|
+
|
84
|
+
### Limitations
|
85
|
+
|
86
|
+
* There's no support for viewing transactions yet - watch this space!
|
87
|
+
|
88
|
+
### License
|
89
|
+
|
90
|
+
Use this for what you will, as long as it isn't evil. If you make any changes or cool improvements, please let me know at <tim+amex@tim-rogers.co.uk>.
|
91
|
+
|
data/amex-0.1.0.gem
ADDED
Binary file
|
data/amex.gemspec
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path('../lib/amex/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.name = 'amex'
|
5
|
+
gem.version = Amex::VERSION.dup
|
6
|
+
gem.authors = ['Tim Rogers']
|
7
|
+
gem.email = ['tim@tim-rogers.co.uk']
|
8
|
+
gem.summary = 'A library for accessing data on an American Express account'
|
9
|
+
gem.homepage = 'https://github.com/timrogers/amex'
|
10
|
+
|
11
|
+
gem.add_runtime_dependency "httparty"
|
12
|
+
gem.add_runtime_dependency "nokogiri"
|
13
|
+
|
14
|
+
gem.files = `git ls-files`.split("\n")
|
15
|
+
end
|
data/example.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'amex'
|
3
|
+
|
4
|
+
# Bring in the settings.rb file - this isn't included in the repository,
|
5
|
+
# but it should just contain two class variables, `username` and `password`
|
6
|
+
require "#{File.dirname(__FILE__)}/settings.rb"
|
7
|
+
|
8
|
+
client = Amex::Client.new(@username, @password)
|
9
|
+
accounts = client.accounts
|
10
|
+
puts accounts.first.inspect
|
data/lib/amex/client.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'erb'
|
2
2
|
require 'httparty'
|
3
|
+
require 'nokogiri'
|
3
4
|
|
4
5
|
module Amex
|
5
6
|
class Client
|
@@ -23,7 +24,7 @@ module Amex
|
|
23
24
|
ERB.new(xml).result(binding)
|
24
25
|
end
|
25
26
|
|
26
|
-
def
|
27
|
+
def accounts
|
27
28
|
# This only supports one account for now, because I'm lazy and I
|
28
29
|
# hate traversing XML...
|
29
30
|
options = { :body => { "PayLoadText" => request_xml }}
|
@@ -31,30 +32,43 @@ module Amex
|
|
31
32
|
'/myca/intl/moblclient/emea/ws.do?Face=en_GB', options
|
32
33
|
)
|
33
34
|
|
34
|
-
xml =
|
35
|
+
xml = Nokogiri::XML(response.body)
|
36
|
+
xml = xml.css("XMLResponse")
|
35
37
|
|
36
|
-
if xml
|
38
|
+
if xml.css('ServiceResponse Status').text != "success"
|
37
39
|
raise "There was a problem logging in to American Express."
|
38
40
|
else
|
39
|
-
|
40
|
-
xml["CardAccounts"]["CardAccount"]["CardData"]["param"].each do |item|
|
41
|
-
account_details[item['name']] = item['__content__']
|
42
|
-
end
|
41
|
+
accounts = [] # We'll store all the accounts in here!
|
43
42
|
|
44
|
-
xml
|
45
|
-
account_details
|
46
|
-
|
43
|
+
xml.css('CardAccounts CardAccount').each do |item|
|
44
|
+
account_details = {} # All the attributes from the XML go in here
|
45
|
+
# For each of the CardAccount objects, let's first go through
|
46
|
+
# the CardData to pull out lots of nice information
|
47
|
+
item.css('CardData param').each do |attribute|
|
48
|
+
account_details[attribute.attr('name')] = attribute.text
|
49
|
+
end
|
47
50
|
|
48
|
-
|
51
|
+
# Now let's go through the AccountSummaryData to find all the
|
52
|
+
# various bits of balance information
|
53
|
+
item.css('AccountSummaryData SummaryElement').each do |attribute|
|
54
|
+
account_details[attribute.attr('name')] = attribute.attr('value') ? attribute.attr('value').to_f : attribute.attr('formattedValue')
|
55
|
+
end
|
56
|
+
|
57
|
+
# We have all the attributes ready to go, so let's make an
|
58
|
+
# Amex::CardAccount object
|
59
|
+
account = Amex::CardAccount.new(account_details)
|
49
60
|
|
50
|
-
|
51
|
-
item.each do |
|
52
|
-
|
53
|
-
|
61
|
+
# Finally, let's rip out all the loyalty balances...
|
62
|
+
item.css('LoyaltyProgramData LoyaltyElement').each do |element|
|
63
|
+
account.loyalty_programmes << Amex::LoyaltyProgramme.new(
|
64
|
+
element.attr('label'), element.attr('formattedValue').gsub(",", "").to_i
|
65
|
+
)
|
54
66
|
end
|
67
|
+
accounts << account
|
68
|
+
|
55
69
|
end
|
56
70
|
|
57
|
-
|
71
|
+
accounts
|
58
72
|
end
|
59
73
|
|
60
74
|
end
|
data/lib/amex/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-12-
|
12
|
+
date: 2012-12-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httparty
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: nokogiri
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
30
46
|
description:
|
31
47
|
email:
|
32
48
|
- tim@tim-rogers.co.uk
|
@@ -34,13 +50,21 @@ executables: []
|
|
34
50
|
extensions: []
|
35
51
|
extra_rdoc_files: []
|
36
52
|
files:
|
53
|
+
- .gitignore
|
54
|
+
- Gemfile
|
55
|
+
- Gemfile.lock
|
56
|
+
- README.md
|
57
|
+
- amex-0.1.0.gem
|
58
|
+
- amex-0.2.0.gem
|
59
|
+
- amex.gemspec
|
60
|
+
- example.rb
|
37
61
|
- lib/amex.rb
|
38
62
|
- lib/amex/card_account.rb
|
39
63
|
- lib/amex/client.rb
|
64
|
+
- lib/amex/data/request.xml
|
40
65
|
- lib/amex/loyalty_programme.rb
|
41
66
|
- lib/amex/utils.rb
|
42
67
|
- lib/amex/version.rb
|
43
|
-
- lib/amex/data/request.xml
|
44
68
|
homepage: https://github.com/timrogers/amex
|
45
69
|
licenses: []
|
46
70
|
post_install_message:
|