kaspay 0.0.5 → 0.1.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 +4 -4
- data/kaspay.gemspec +1 -1
- data/lib/kaspay.rb +252 -87
- data/lib/kaspay/money.rb +37 -0
- data/lib/kaspay/transaction.rb +87 -0
- data/lib/kaspay/transaction_collection.rb +5 -0
- data/lib/kaspay/version.rb +1 -1
- data/lib/meta_stuff.rb +10 -14
- metadata +5 -3
- data/lib/kernel_patch.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1105d0ccb68652d0db5be5c66b6700156941019f
|
4
|
+
data.tar.gz: 3ff3ba33823323e647a0f0c61c78fac65379807b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56525bb0c6852c73eeaa59b12f20f1c7aaf38e420c6f7b1d4e18cb7ff1a6dabaa657d5fc4ca89d3000ea9adee0f4199de50255edd28b1b79affed3d9c270ecd5
|
7
|
+
data.tar.gz: dbf60d5327aab90aa84d4c8692803de8dc004545d9f4713f5d2d370ebf8ae7eedb364a3f688614a6ce10c6d64963200b808e60091886e9cb3c580ae87fac5bfc
|
data/kaspay.gemspec
CHANGED
data/lib/kaspay.rb
CHANGED
@@ -6,19 +6,21 @@ require 'pstore'
|
|
6
6
|
require 'watir'
|
7
7
|
require 'headless'
|
8
8
|
require_relative 'meta_stuff'
|
9
|
-
require_relative '
|
9
|
+
require_relative 'kaspay/money'
|
10
|
+
require_relative 'kaspay/transaction'
|
10
11
|
|
11
12
|
class KasPay
|
12
|
-
#
|
13
|
+
# Assigns methods from MetaStuff module as KasPay class methods
|
13
14
|
extend MetaStuff
|
14
15
|
|
15
|
-
# A bunch of constants
|
16
|
+
# A bunch of KasPay constants.
|
16
17
|
BASE_URL = "https://www.kaspay.com"
|
17
18
|
LOGIN_URL = BASE_URL + "/login"
|
18
|
-
|
19
|
-
|
19
|
+
TRANSACTION_URL = BASE_URL + "/account/transactiondetails/"
|
20
|
+
TRANSACTION_HISTORY_URL = BASE_URL + "/account/history/"
|
20
21
|
DATA_DIR = ENV['HOME'] + "/.kaspay"
|
21
|
-
|
22
|
+
LOGIN_PATH = DATA_DIR + "/login.dat"
|
23
|
+
COOKIE_PATH = DATA_DIR + "/cookie.dat"
|
22
24
|
|
23
25
|
# Opening KasPay class singleton scope
|
24
26
|
class << self
|
@@ -27,7 +29,7 @@ class KasPay
|
|
27
29
|
# the information.
|
28
30
|
static_pages = %w(about term) # more will come
|
29
31
|
|
30
|
-
#
|
32
|
+
# Iterates through static pages list to make methods named the
|
31
33
|
# the same as the member of the list. These methods will be
|
32
34
|
# the class methods of KasPay.
|
33
35
|
# Example usage:
|
@@ -57,6 +59,65 @@ class KasPay
|
|
57
59
|
alias_method :login, :new
|
58
60
|
# Hidden to force the use of `login` as the class method
|
59
61
|
# for instantiation.
|
62
|
+
|
63
|
+
def all_get_methods
|
64
|
+
instance_methods.grep /^get_/
|
65
|
+
end
|
66
|
+
|
67
|
+
def things_to_get
|
68
|
+
all_get_methods.map{|m| m.id2name.sub("get_","")}
|
69
|
+
end
|
70
|
+
|
71
|
+
def data_scope(path, &block)
|
72
|
+
kasdb = PStore.new(path)
|
73
|
+
kasdb.transaction do
|
74
|
+
yield(kasdb)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def login_scope(&block)
|
79
|
+
data_scope(LOGIN_PATH, &block)
|
80
|
+
end
|
81
|
+
|
82
|
+
def login_data_exists? login_name
|
83
|
+
data = nil
|
84
|
+
begin
|
85
|
+
login_scope {|login| data = login.roots}
|
86
|
+
return data.include? login_name
|
87
|
+
rescue NameError
|
88
|
+
return false
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def clear_login login_name = nil
|
93
|
+
login_scope do |login|
|
94
|
+
if !login_name.nil?
|
95
|
+
login.delete login_name
|
96
|
+
elsif login_name.nil?
|
97
|
+
login.roots.each do |name|
|
98
|
+
login.delete name
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def load_login login_name
|
105
|
+
raise LoadLoginError,
|
106
|
+
"login data \"#{login_name}\" cannot be found" \
|
107
|
+
unless login_data_exists? login_name
|
108
|
+
email, password = nil
|
109
|
+
login_scope do |login|
|
110
|
+
email = login[login_name][:email]
|
111
|
+
password = login[login_name][:password]
|
112
|
+
end
|
113
|
+
login email: email, password: password
|
114
|
+
end
|
115
|
+
|
116
|
+
def cookies_scope(&block)
|
117
|
+
data_scope(COOKIE_PATH, &block)
|
118
|
+
end
|
119
|
+
|
120
|
+
|
60
121
|
private :new
|
61
122
|
end
|
62
123
|
|
@@ -69,6 +130,8 @@ class KasPay
|
|
69
130
|
attr_reader :password
|
70
131
|
|
71
132
|
# Some methods need to be inaccessible
|
133
|
+
private :browser
|
134
|
+
private :browser=
|
72
135
|
private :headless
|
73
136
|
private :headless=
|
74
137
|
private :password
|
@@ -83,18 +146,34 @@ class KasPay
|
|
83
146
|
end
|
84
147
|
|
85
148
|
# Actually starts the login process after email and password
|
86
|
-
# provided. This is
|
87
|
-
#
|
88
|
-
#
|
149
|
+
# provided. This is different from the class method `login`
|
150
|
+
# that only creates KasPay object and compounding the data
|
151
|
+
# for login.
|
89
152
|
def login
|
90
153
|
headless = Headless.new
|
91
154
|
headless.start
|
92
155
|
|
93
156
|
@browser = Watir::Browser.start LOGIN_URL
|
94
157
|
|
95
|
-
|
96
|
-
|
97
|
-
|
158
|
+
# Delete all expired cookies
|
159
|
+
delete_cookies_if_expire
|
160
|
+
# Use unexpired cookies that match the given email and password
|
161
|
+
the_cookies = use_cookies
|
162
|
+
|
163
|
+
# Fresh login
|
164
|
+
if the_cookies.nil?
|
165
|
+
browser.text_field(id: 'username').set email
|
166
|
+
browser.text_field(id: 'password').set password
|
167
|
+
browser.button(name: 'button').click
|
168
|
+
save_cookies
|
169
|
+
# Cookies still exist
|
170
|
+
else
|
171
|
+
browser.cookies.clear
|
172
|
+
the_cookies.each do |cookies|
|
173
|
+
browser.cookies.add(cookies[:name], cookies[:value])
|
174
|
+
end
|
175
|
+
browser.goto BASE_URL
|
176
|
+
end
|
98
177
|
end
|
99
178
|
|
100
179
|
# Sets email input
|
@@ -107,6 +186,7 @@ class KasPay
|
|
107
186
|
def password= pass
|
108
187
|
@password = pass
|
109
188
|
login if user_data_complete?
|
189
|
+
return nil
|
110
190
|
end
|
111
191
|
|
112
192
|
def current_url
|
@@ -117,26 +197,117 @@ class KasPay
|
|
117
197
|
url = (path[0] == "/" ? (BASE_URL + path) : path)
|
118
198
|
browser.goto url
|
119
199
|
end
|
120
|
-
|
200
|
+
|
121
201
|
def get_name
|
122
202
|
browser.span(class: "user-name").text
|
123
203
|
end
|
124
204
|
|
125
205
|
def get_balance
|
126
|
-
Money.new browser.div(class: "kaspay-balance")
|
127
|
-
.span.text.sub("Rp ","").sub(".","").to_i
|
206
|
+
Money.new browser.div(class: "kaspay-balance").span.text
|
128
207
|
end
|
129
208
|
|
130
209
|
def get_acc_num
|
131
210
|
browser.span(class: "kaspay-id").text.sub("KasPay Account: ", "").to_i
|
132
211
|
end
|
133
|
-
|
212
|
+
|
213
|
+
def get_cookies_expire_time
|
214
|
+
current_cookies_scope do |cookies, cookies_name|
|
215
|
+
cookies[cookies_name][:cookies].each do |el|
|
216
|
+
if el[:name] == "kaspay_csrf_cookie"
|
217
|
+
return DateTime.parse(el[:expires].to_s)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def trx_type_to_num val_in_sym
|
224
|
+
num = case val_in_sym
|
225
|
+
when :all_trx then 0
|
226
|
+
when :top_up then 1
|
227
|
+
when :payment_to then 2
|
228
|
+
when :payment_from then 3
|
229
|
+
when :redeem then 4
|
230
|
+
when :refund then 5
|
231
|
+
when :trx_fee then 6
|
232
|
+
else 0
|
233
|
+
end
|
234
|
+
return num
|
235
|
+
end
|
236
|
+
|
237
|
+
def get_transaction options = {}
|
238
|
+
default_options = {
|
239
|
+
latest: 5,
|
240
|
+
type: :all_trx,
|
241
|
+
oldest_only: false
|
242
|
+
}
|
243
|
+
options = default_options.merge(options)
|
244
|
+
unless options[:oldest_only]
|
245
|
+
no_of_trx = options[:latest]
|
246
|
+
get_latest_transactions no_of_trx, trx_type_to_num(options[:type])
|
247
|
+
else
|
248
|
+
trx_no = options[:latest] - 1
|
249
|
+
get_transaction_number trx_no, trx_type_to_num(options[:type])
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def get_latest_transactions no_of_trx, type = 0
|
254
|
+
trx_ids = []
|
255
|
+
while no_of_trx - trx_ids.length > 0
|
256
|
+
browser.goto(TRANSACTION_HISTORY_URL \
|
257
|
+
+ trx_ids.length.to_s \
|
258
|
+
+ "?f=01/01/2009&t=" \
|
259
|
+
+ Time.now.strftime("%d/%m/%Y") \
|
260
|
+
+ "&transactiontype=" \
|
261
|
+
+ type.to_s)
|
262
|
+
|
263
|
+
browser.tds(class: "trxid").each do |td|
|
264
|
+
trx_ids << td.link.href.sub(/.*\/(.*)$/, '\1')
|
265
|
+
break if trx_ids.length == no_of_trx
|
266
|
+
end
|
267
|
+
break if trx_ids.length == 0 \
|
268
|
+
|| trx_ids.length >= no_of_trx
|
269
|
+
end
|
270
|
+
trx_ids.each_with_index do |trx_id, i|
|
271
|
+
trx_ids[i] = Transaction.new trx_id, browser
|
272
|
+
end
|
273
|
+
browser.goto(BASE_URL)
|
274
|
+
return trx_ids
|
275
|
+
end
|
276
|
+
|
277
|
+
def get_transaction_number trx_no, type = 0
|
278
|
+
row_number = trx_no % 5
|
279
|
+
browser.goto(TRANSACTION_HISTORY_URL \
|
280
|
+
+ (trx_no - row_number).to_s \
|
281
|
+
+ "?f=01/01/2009&t=" \
|
282
|
+
+ Time.now.strftime("%d/%m/%Y") \
|
283
|
+
+ "&transactiontype=" \
|
284
|
+
+ type.to_s)
|
285
|
+
|
286
|
+
trx_id = Transaction.new(browser.tds(class: "trxid")[row_number] \
|
287
|
+
.link.href.sub(/.*\/(.*)$/, '\1'), browser)
|
288
|
+
browser.goto(BASE_URL)
|
289
|
+
return trx_id
|
290
|
+
end
|
291
|
+
|
292
|
+
def links
|
293
|
+
links = []
|
294
|
+
browser.tds(class: "trxid").each{|td| links << td.link.href.to_s}
|
295
|
+
links
|
296
|
+
end
|
297
|
+
|
134
298
|
def home
|
135
299
|
goto "/"
|
136
300
|
end
|
137
|
-
|
301
|
+
|
138
302
|
def logout!
|
303
|
+
calling_method = caller[0][/(?<=`).*(?=')/]
|
139
304
|
logout_link.click
|
305
|
+
delete_cookies unless calling_method == "delete_cookies"
|
306
|
+
end
|
307
|
+
|
308
|
+
# Silently logs out
|
309
|
+
def logout
|
310
|
+
logout! if logged_in?
|
140
311
|
end
|
141
312
|
|
142
313
|
def logged_in?
|
@@ -154,96 +325,90 @@ class KasPay
|
|
154
325
|
|
155
326
|
def save_login login_name
|
156
327
|
Dir.mkdir(DATA_DIR) unless Dir.exists?(DATA_DIR)
|
157
|
-
|
158
|
-
|
159
|
-
kasdb[login_name] = {email: email, password: password}
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
def load_login login_name
|
164
|
-
kasdb = PStore.new(DATA_PATH)
|
165
|
-
kasdb.transaction do
|
166
|
-
@email = kasdb[login_name][:email]
|
167
|
-
@password = kasdb[login_name][:password]
|
168
|
-
return kasdb[login_name]
|
328
|
+
KasPay.login_scope do |login|
|
329
|
+
login[login_name] = {email: email, password: password}
|
169
330
|
end
|
331
|
+
return nil
|
170
332
|
end
|
171
|
-
|
172
|
-
def inspect
|
173
|
-
"#<#{self.class}:0x#{(object_id << 1).to_s(16)} logged_in=#{logged_in?}>"
|
174
|
-
end
|
175
|
-
|
176
|
-
def method_missing(m, *args, &block)
|
177
|
-
if THINGS_TO_GET.include? m
|
178
|
-
send("get_#{m}")
|
179
|
-
else
|
180
|
-
super
|
181
|
-
end
|
182
|
-
end
|
183
333
|
|
184
334
|
def check_login
|
185
335
|
raise LoginError, "you are not logged in" unless logged_in?
|
186
336
|
end
|
337
|
+
|
338
|
+
def inspect
|
339
|
+
"#<#{self.class}:0x#{(object_id << 1).to_s(16)} logged_in=#{logged_in?}>"
|
340
|
+
end
|
187
341
|
|
188
|
-
before(
|
189
|
-
|
190
|
-
alias_method :logout, :logout!
|
342
|
+
before( all_get_methods + [:logout!] ){ :check_login }
|
191
343
|
alias_method :url, :current_url
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
def login_data_exists?
|
196
|
-
data = nil
|
197
|
-
begin
|
198
|
-
PStore.new("kaspay.dat").tap{|x| x.transaction{ data = x.roots}}
|
199
|
-
return (data != [])
|
200
|
-
rescue NameError
|
201
|
-
return false
|
202
|
-
end
|
344
|
+
KasPay.things_to_get.each do |m|
|
345
|
+
alias_method m, "get_#{m}"
|
203
346
|
end
|
204
|
-
|
205
|
-
|
206
|
-
|
347
|
+
|
348
|
+
private
|
349
|
+
|
350
|
+
def get_cookies
|
351
|
+
browser.cookies.to_a
|
207
352
|
end
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
new_methods.each do |m|
|
218
|
-
define_method(m) do |arg, &block|
|
219
|
-
arg = arg.to_i # to convert string or Money object to Integer
|
220
|
-
self.value = value.send(m, arg)
|
221
|
-
return self
|
353
|
+
|
354
|
+
def current_cookies_scope
|
355
|
+
KasPay.cookies_scope do |cookies|
|
356
|
+
cookies.roots.reverse.each do |cookies_name|
|
357
|
+
if cookies[cookies_name][:email] == email \
|
358
|
+
&& cookies[cookies_name][:password] == password
|
359
|
+
yield(cookies, cookies_name)
|
360
|
+
end
|
222
361
|
end
|
223
362
|
end
|
224
|
-
|
225
|
-
|
226
|
-
|
363
|
+
end
|
364
|
+
|
365
|
+
def delete_cookies_if_expire
|
366
|
+
current_cookies_scope do |cookies, cookies_name|
|
367
|
+
cookies[cookies_name][:cookies].each do |el|
|
368
|
+
if el[:name] == "kaspay_csrf_cookie" \
|
369
|
+
&& DateTime.parse(el[:expires].to_s) < DateTime.now
|
370
|
+
cookies.delete(cookies_name)
|
371
|
+
end
|
372
|
+
end
|
227
373
|
end
|
228
|
-
|
229
|
-
|
230
|
-
|
374
|
+
end
|
375
|
+
|
376
|
+
def delete_cookies
|
377
|
+
current_cookies_scope do |cookies, cookies_name|
|
378
|
+
cookies.delete(cookies_name)
|
231
379
|
end
|
232
|
-
|
233
|
-
|
234
|
-
|
380
|
+
logout! if logged_in?
|
381
|
+
return nil
|
382
|
+
end
|
383
|
+
|
384
|
+
def save_cookies
|
385
|
+
time = Time.now
|
386
|
+
cookies_name = time.strftime("%y%m%d%H%M%S").to_i.to_s(36)
|
387
|
+
Dir.mkdir(DATA_DIR) unless Dir.exists?(DATA_DIR)
|
388
|
+
KasPay.cookies_scope do |cookies|
|
389
|
+
cookies[cookies_name] = {email: email, password: password, cookies: get_cookies}
|
235
390
|
end
|
391
|
+
end
|
236
392
|
|
237
|
-
|
238
|
-
|
393
|
+
def use_cookies
|
394
|
+
the_cookie = nil
|
395
|
+
current_cookies_scope do |cookies, cookies_name|
|
396
|
+
the_cookie = cookies[cookies_name][:cookies]
|
239
397
|
end
|
240
|
-
|
241
|
-
|
398
|
+
return the_cookie
|
399
|
+
end
|
400
|
+
|
401
|
+
def logout_link
|
402
|
+
logout_link = browser.a(href: "https://www.kaspay.com/account/logout")
|
242
403
|
end
|
243
404
|
end
|
244
405
|
|
406
|
+
# Aliases for 'KasPay' class
|
407
|
+
Kaspay = KasPay
|
408
|
+
KASPAY = KasPay
|
409
|
+
|
245
410
|
class LoginError < StandardError
|
246
411
|
end
|
247
412
|
|
248
|
-
class
|
413
|
+
class LoadLoginError < StandardError
|
249
414
|
end
|
data/lib/kaspay/money.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
class KasPay
|
2
|
+
# Inner class Money
|
3
|
+
class Money
|
4
|
+
attr_accessor :value
|
5
|
+
|
6
|
+
fixnum_methods_to_discard = %w(inspect -@ abs magnitude to_s dclone ~ & | ^ [] << >> size bit_length to_f).map(&:to_sym)
|
7
|
+
new_methods = Fixnum.instance_methods(false) \
|
8
|
+
.delete_if{|m| fixnum_methods_to_discard.include? m}
|
9
|
+
|
10
|
+
# Inheriting some methods from Fixnum
|
11
|
+
new_methods.each do |m|
|
12
|
+
define_method(m) do |arg, &block|
|
13
|
+
arg = arg.to_i # to convert string or Money object to Integer
|
14
|
+
self.value = value.send(m, arg)
|
15
|
+
return self
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize value = 0
|
20
|
+
@value = value.gsub(/\s/, '').sub(/[\.\,]00$/, "").sub(/^Rp\s*(.*)$/, '\1').gsub(/[\.\,]/, '').to_i
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_f
|
24
|
+
value * 1.0
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
"Rp " + value.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse + ".00"
|
29
|
+
end
|
30
|
+
|
31
|
+
def inspect
|
32
|
+
"#<#{self.class}:0x#{(object_id << 1).to_s(16)} value=#{value}>"
|
33
|
+
end
|
34
|
+
|
35
|
+
alias_method :to_i, :value
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
class KasPay
|
2
|
+
# Inner class Transaction
|
3
|
+
class Transaction
|
4
|
+
def initialize trx_id, browser
|
5
|
+
@trx_id = trx_id
|
6
|
+
@browser = browser
|
7
|
+
end
|
8
|
+
|
9
|
+
def data_available?
|
10
|
+
respond_to? :amount
|
11
|
+
end
|
12
|
+
|
13
|
+
# To be called only when needed
|
14
|
+
def data_build
|
15
|
+
@browser.goto(KasPay::TRANSACTION_URL + @trx_id)
|
16
|
+
data = []
|
17
|
+
@browser.tds.each_slice(3){|a, b, c| data << c.text}
|
18
|
+
@date = DateTime.parse(data[0] + "T" \
|
19
|
+
+ data[1] + "+07:00")
|
20
|
+
@trx_id = data[2]
|
21
|
+
@trx_type = data[3]
|
22
|
+
@remark = data[4]
|
23
|
+
@status = data[5]
|
24
|
+
m1_in_sym = []
|
25
|
+
(instance_variables - [:@browser]).each do |v|
|
26
|
+
m1_in_sym << v.to_s.sub(/@/, '').to_sym
|
27
|
+
end
|
28
|
+
m1_in_sym.each do |m|
|
29
|
+
define_singleton_method m do
|
30
|
+
eval "@#{m.to_s}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
non_payment_type = ["Transaction correction", "Topup"]
|
35
|
+
unless non_payment_type.include? @trx_type
|
36
|
+
@seller = data[6]
|
37
|
+
@merchant_trx_id = data[7]
|
38
|
+
@product_id = data[8]
|
39
|
+
@product_name = data[9]
|
40
|
+
@quantity = data[10].gsub(/[^0-9]/, '').to_i
|
41
|
+
@description = data[11]
|
42
|
+
m2_in_sym = []
|
43
|
+
(instance_variables - [:@browser]).each do |v|
|
44
|
+
m2_in_sym << v.to_s.sub(/@/, '').to_sym
|
45
|
+
end
|
46
|
+
m2_in_sym = m2_in_sym - m1_in_sym
|
47
|
+
m2_in_sym.each do |m|
|
48
|
+
define_singleton_method m do
|
49
|
+
eval "@#{m.to_s}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
@amount = Money.new data[12]
|
53
|
+
else
|
54
|
+
@amount = Money.new data[6]
|
55
|
+
end
|
56
|
+
|
57
|
+
define_singleton_method :amount do
|
58
|
+
@amount
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_h
|
63
|
+
h = {}
|
64
|
+
instance_variables.each do |v|
|
65
|
+
m_in_sym = v.to_s.sub(/@/, '').to_sym
|
66
|
+
h[m_in_sym] = send m_in_sym
|
67
|
+
end
|
68
|
+
return h
|
69
|
+
end
|
70
|
+
|
71
|
+
def inspect
|
72
|
+
"#<#{self.class}:0x#{(object_id << 1).to_s(16)} id=#{@trx_id} browser=#{@browser}>"
|
73
|
+
end
|
74
|
+
|
75
|
+
def method_missing(name, *args, &block)
|
76
|
+
if data_available?
|
77
|
+
super
|
78
|
+
else
|
79
|
+
data_build
|
80
|
+
send(name, *args, &block)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
alias_method :to_s, :to_h
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
data/lib/kaspay/version.rb
CHANGED
data/lib/meta_stuff.rb
CHANGED
@@ -1,17 +1,13 @@
|
|
1
1
|
module MetaStuff
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
define_method(name) do
|
11
|
-
n.bind(self).call
|
12
|
-
m.bind(self).call
|
2
|
+
def before(names)
|
3
|
+
names.each do |name|
|
4
|
+
m = instance_method(name)
|
5
|
+
n = instance_method(yield)
|
6
|
+
define_method(name) do |*args, &block|
|
7
|
+
n.bind(self)
|
8
|
+
m.bind(self).(*args, &block)
|
9
|
+
end
|
13
10
|
end
|
14
|
-
|
15
|
-
|
16
|
-
end
|
11
|
+
private yield
|
12
|
+
end
|
17
13
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kaspay
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrian Setyadi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: watir
|
@@ -62,8 +62,10 @@ files:
|
|
62
62
|
- README.md
|
63
63
|
- kaspay.gemspec
|
64
64
|
- lib/kaspay.rb
|
65
|
+
- lib/kaspay/money.rb
|
66
|
+
- lib/kaspay/transaction.rb
|
67
|
+
- lib/kaspay/transaction_collection.rb
|
65
68
|
- lib/kaspay/version.rb
|
66
|
-
- lib/kernel_patch.rb
|
67
69
|
- lib/meta_stuff.rb
|
68
70
|
homepage: https://github.com/styd/kaspay
|
69
71
|
licenses:
|