amex 0.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.
@@ -0,0 +1,5 @@
1
+ require 'amex/card_account'
2
+ require 'amex/client'
3
+ require 'amex/loyalty_programme'
4
+ require 'amex/utils'
5
+ require 'amex/version'
@@ -0,0 +1,77 @@
1
+ module Amex
2
+ class CardAccount
3
+ attr_accessor :card_product, :card_number_suffix,
4
+ :lending_type, :card_member_name, :past_due, :cancelled, :is_basic,
5
+ :is_centurion, :is_platinum, :is_premium, :market, :card_art,
6
+ :loyalty_indicator, :stmt_balance, :payment_credits, :recent_charges,
7
+ :total_balance, :payment_due, :payment_due_date, :loyalty_programmes
8
+
9
+ def initialize(options)
10
+ options.each do |key, value|
11
+ method = key.underscore + "="
12
+ send(key.underscore + "=", value) if respond_to? method.to_sym
13
+ end
14
+ @loyalty_programmes = []
15
+ end
16
+
17
+ def statement_balance
18
+ @stmt_balance
19
+ end
20
+
21
+ def product
22
+ @card_product
23
+ end
24
+
25
+ def cancelled?
26
+ @cancelled
27
+ end
28
+
29
+ def payment_due_date
30
+ # Overrides attr_accessor so it actually returns a DateTime, not String
31
+ DateTime.parse(@payment_due_date)
32
+ end
33
+
34
+ def type
35
+ return :basic if @is_basic
36
+ return :platinum if @is_platinum
37
+ return :centurion if @is_centurion
38
+ return :premium if @is_premium
39
+ :unknown
40
+ end
41
+
42
+ def is_credit_card?
43
+ return true if @lending_type == "Credit"
44
+ false
45
+ end
46
+
47
+ def is_charge_card?
48
+ return true if @lending_type == "Charge"
49
+ false
50
+ end
51
+
52
+ def overdue?
53
+ return true if @past_due
54
+ false
55
+ end
56
+
57
+ def due?
58
+ return true if @payment_due.to_f > 0
59
+ false
60
+ end
61
+
62
+ def loyalty_enabled?
63
+ @loyalty_indicator
64
+ end
65
+
66
+ def loyalty_balances
67
+ result = {}
68
+ @loyalty_programmes.each do |programme|
69
+ result[programme.name] = programme.balance
70
+ end
71
+ result
72
+ end
73
+
74
+
75
+
76
+ end
77
+ end
@@ -0,0 +1,63 @@
1
+ require 'erb'
2
+ require 'httparty'
3
+
4
+ module Amex
5
+ class Client
6
+ include HTTParty
7
+ base_uri 'https://global.americanexpress.com/'
8
+
9
+ def initialize(username, password)
10
+ @username = username
11
+ @password = password
12
+ end
13
+
14
+ def request_xml
15
+ xml = File.read(
16
+ File.expand_path(File.dirname(__FILE__) + '/data/request.xml')
17
+ )
18
+
19
+ username = @username
20
+ password = @password
21
+ timestamp = Time.now.to_i
22
+
23
+ ERB.new(xml).result(binding)
24
+ end
25
+
26
+ def account
27
+ # This only supports one account for now, because I'm lazy and I
28
+ # hate traversing XML...
29
+ options = { :body => { "PayLoadText" => request_xml }}
30
+ response = self.class.post(
31
+ '/myca/intl/moblclient/emea/ws.do?Face=en_GB', options
32
+ )
33
+
34
+ xml = MultiXml.parse(response)['XMLResponse']
35
+
36
+ if xml['ServiceResponse']['Status'] != "success"
37
+ raise "There was a problem logging in to American Express."
38
+ else
39
+ account_details = {}
40
+ xml["CardAccounts"]["CardAccount"]["CardData"]["param"].each do |item|
41
+ account_details[item['name']] = item['__content__']
42
+ end
43
+
44
+ xml["CardAccounts"]["CardAccount"]["AccountSummaryData"]["SummaryElement"].each do |item|
45
+ account_details[item['name']] = item['value'] ? item['value'].to_f : item['formattedValue']
46
+ end
47
+
48
+ account = Amex::CardAccount.new(account_details)
49
+
50
+ xml["CardAccounts"]["CardAccount"]["LoyaltyProgramData"].each do |item|
51
+ item.each do |part|
52
+ next if part.class == String
53
+ account.loyalty_programmes << Amex::LoyaltyProgramme.new(part['label'], part['formattedValue'].gsub(",", "").to_i)
54
+ end
55
+ end
56
+
57
+ account
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <XMLRequest>
3
+ <ClientType>iPhone</ClientType>
4
+ <ClientVersion>1.8</ClientVersion>
5
+ <ServiceVersion>1.0</ServiceVersion>
6
+ <Locale>en_GB</Locale>
7
+ <ServiceName>AccountSummaryService</ServiceName>
8
+ <DeviceInfo><HardwareId>dummy_hardware_id</HardwareId><OSBuild>iPhone OS 6.0.1</OSBuild><DeviceModel>iPhone</DeviceModel><Timestamp><%= timestamp %></Timestamp><TimeZoneOffset>0</TimeZoneOffset></DeviceInfo>
9
+ <LoginCredentials><UserID><%= username %></UserID><Password><%= password %></Password><RememberMeUIFlagSelected>false</RememberMeUIFlagSelected><ProfileDataContent></ProfileDataContent></LoginCredentials>
10
+ </XMLRequest>
@@ -0,0 +1,10 @@
1
+ module Amex
2
+ class LoyaltyProgramme
3
+ attr_accessor :name, :balance
4
+
5
+ def initialize(name, balance)
6
+ @name = name
7
+ @balance = balance
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ class String
2
+ def underscore
3
+ self.gsub(/::/, '/').
4
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
5
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
6
+ tr("-", "_").
7
+ downcase
8
+ end
9
+
10
+ def to_bool
11
+ return true if self == true || self =~ (/(true|t|yes|y|1)$/i)
12
+ return false if self == false || self.blank? || self =~ (/(false|f|no|n|0)$/i)
13
+ raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
14
+ end
15
+
16
+ end
@@ -0,0 +1,3 @@
1
+ module Amex
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: amex
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tim Rogers
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description:
31
+ email:
32
+ - tim@tim-rogers.co.uk
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - lib/amex.rb
38
+ - lib/amex/card_account.rb
39
+ - lib/amex/client.rb
40
+ - lib/amex/loyalty_programme.rb
41
+ - lib/amex/utils.rb
42
+ - lib/amex/version.rb
43
+ - lib/amex/data/request.xml
44
+ homepage: https://github.com/timrogers/amex
45
+ licenses: []
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 1.8.24
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: A library for accessing data on an American Express account
68
+ test_files: []
69
+ has_rdoc: