line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Finance::CaVirtex::API; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
26223
|
use 5.014002; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
37
|
|
4
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
27
|
|
5
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
49
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.03'; |
8
|
|
|
|
|
|
|
|
9
|
1
|
|
|
1
|
|
5
|
use base qw(Finance::CaVirtex::API::DefaultPackage); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
569
|
|
10
|
|
|
|
|
|
|
|
11
|
1
|
|
|
1
|
|
6
|
use constant DEBUG => 0; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
48
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
# you can use a lower version, but then you are responsible for SSL cert verification code... |
14
|
1
|
|
|
1
|
|
1088
|
use LWP::UserAgent 6; |
|
1
|
|
|
|
|
65212
|
|
|
1
|
|
|
|
|
35
|
|
15
|
1
|
|
|
1
|
|
10
|
use URI; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
23
|
|
16
|
1
|
|
|
1
|
|
6268
|
use CGI; |
|
1
|
|
|
|
|
16962
|
|
|
1
|
|
|
|
|
8
|
|
17
|
1
|
|
|
1
|
|
2013
|
use JSON; |
|
1
|
|
|
|
|
18756
|
|
|
1
|
|
|
|
|
6
|
|
18
|
1
|
|
|
1
|
|
923
|
use MIME::Base64; |
|
1
|
|
|
|
|
756
|
|
|
1
|
|
|
|
|
66
|
|
19
|
1
|
|
|
1
|
|
864
|
use Time::HiRes qw(gettimeofday); |
|
1
|
|
|
|
|
2032
|
|
|
1
|
|
|
|
|
4
|
|
20
|
1
|
|
|
1
|
|
1087
|
use Digest::SHA qw(hmac_sha256_hex); |
|
1
|
|
|
|
|
4270
|
|
|
1
|
|
|
|
|
160
|
|
21
|
1
|
|
|
1
|
|
982
|
use Data::Dumper; |
|
1
|
|
|
|
|
7634
|
|
|
1
|
|
|
|
|
96
|
|
22
|
|
|
|
|
|
|
|
23
|
1
|
|
|
1
|
|
636
|
use Finance::CaVirtex::API::Request::OrderBook; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
30
|
|
24
|
1
|
|
|
1
|
|
572
|
use Finance::CaVirtex::API::Request::TradeBook; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
30
|
|
25
|
1
|
|
|
1
|
|
688
|
use Finance::CaVirtex::API::Request::Ticker; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
64
|
|
26
|
1
|
|
|
1
|
|
607
|
use Finance::CaVirtex::API::Request::Balance; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
25
|
|
27
|
1
|
|
|
1
|
|
488
|
use Finance::CaVirtex::API::Request::Transactions; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
21
|
|
28
|
1
|
|
|
1
|
|
915
|
use Finance::CaVirtex::API::Request::TradeHistory; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
19
|
|
29
|
1
|
|
|
1
|
|
495
|
use Finance::CaVirtex::API::Request::OrderHistory; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
20
|
|
30
|
1
|
|
|
1
|
|
603
|
use Finance::CaVirtex::API::Request::Order; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
22
|
|
31
|
1
|
|
|
1
|
|
524
|
use Finance::CaVirtex::API::Request::OrderCancel; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
25
|
|
32
|
1
|
|
|
1
|
|
541
|
use Finance::CaVirtex::API::Request::Withdraw; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
31
|
|
33
|
|
|
|
|
|
|
|
34
|
1
|
|
|
1
|
|
5
|
use constant COMPANY => 'CaVirtex'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
41
|
|
35
|
1
|
|
|
1
|
|
5
|
use constant ERROR_NO_REQUEST => 'No request object to send'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
35
|
|
36
|
1
|
|
|
1
|
|
5
|
use constant ERROR_NOT_READY => 'Not enough information to send a %s request'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
43
|
|
37
|
1
|
|
|
1
|
|
5
|
use constant ERROR_IS_IT_READY => "The request is%s READY to send\n"; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
61
|
|
38
|
1
|
|
|
1
|
|
6
|
use constant ERROR_CAVIRTEX => COMPANY . " error: '%s'\n"; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
62
|
|
39
|
1
|
|
|
1
|
|
5
|
use constant ERROR_UNKNOWN_STATUS => COMPANY . " returned an unknown status\n"; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
60
|
|
40
|
|
|
|
|
|
|
|
41
|
1
|
|
|
1
|
|
5
|
use constant ATTRIBUTES => qw(token secret); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
65
|
|
42
|
|
|
|
|
|
|
|
43
|
1
|
|
|
|
|
1685
|
use constant CLASS_ACTION_MAP => { |
44
|
|
|
|
|
|
|
orderbook => 'Finance::CaVirtex::API::Request::OrderBook', |
45
|
|
|
|
|
|
|
tradebook => 'Finance::CaVirtex::API::Request::TradeBook', |
46
|
|
|
|
|
|
|
ticker => 'Finance::CaVirtex::API::Request::Ticker', |
47
|
|
|
|
|
|
|
balance => 'Finance::CaVirtex::API::Request::Balance', |
48
|
|
|
|
|
|
|
transactions => 'Finance::CaVirtex::API::Request::Transactions', |
49
|
|
|
|
|
|
|
trade_history => 'Finance::CaVirtex::API::Request::TradeHistory', |
50
|
|
|
|
|
|
|
order_history => 'Finance::CaVirtex::API::Request::OrderHistory', |
51
|
|
|
|
|
|
|
order => 'Finance::CaVirtex::API::Request::Order', |
52
|
|
|
|
|
|
|
order_cancel => 'Finance::CaVirtex::API::Request::OrderCancel', |
53
|
|
|
|
|
|
|
withdraw => 'Finance::CaVirtex::API::Request::Withdraw', |
54
|
1
|
|
|
1
|
|
5
|
}; |
|
1
|
|
|
|
|
1
|
|
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub is_ready_to_send { |
57
|
3
|
|
|
3
|
0
|
6
|
my $self = shift; |
58
|
3
|
|
|
|
|
6
|
my $ready = 0; |
59
|
|
|
|
|
|
|
# here we are checking whether or not to default to '0' (not ready to send) based on this objects settings. |
60
|
|
|
|
|
|
|
# the settings in here are the token and the secret provided to you by CaVirtex. |
61
|
|
|
|
|
|
|
# if we dont have to add a nonce, then just check if its ready... |
62
|
3
|
50
|
0
|
|
|
10
|
if (not $self->private or defined $self->token && defined $self->secret) { |
|
|
|
33
|
|
|
|
|
63
|
3
|
|
|
|
|
9
|
$ready = $self->request->is_ready_to_send; |
64
|
|
|
|
|
|
|
} |
65
|
3
|
|
|
|
|
7
|
warn sprintf ERROR_IS_IT_READY, ($ready ? '' : ' NOT') if DEBUG; |
66
|
|
|
|
|
|
|
|
67
|
3
|
|
|
|
|
11
|
return $ready; |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub send { |
71
|
3
|
|
|
3
|
0
|
6
|
my $self = shift; |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
# clear any previous response values... because if you wan it, you shoulda put a variable on it. |
74
|
3
|
|
|
|
|
8
|
$self->response(undef); |
75
|
3
|
|
|
|
|
8
|
$self->error(undef); |
76
|
3
|
|
|
|
|
9
|
$self->new_nonce; |
77
|
|
|
|
|
|
|
|
78
|
3
|
50
|
|
|
|
9
|
unless ($self->request) { |
79
|
0
|
|
|
|
|
0
|
$self->error({ |
80
|
|
|
|
|
|
|
type => __PACKAGE__, |
81
|
|
|
|
|
|
|
message => ERROR_NO_REQUEST, |
82
|
|
|
|
|
|
|
}); |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
else { |
85
|
|
|
|
|
|
|
# validate that the minimum required request attributes are set here. |
86
|
3
|
50
|
|
|
|
10
|
if (not $self->is_ready_to_send) { |
87
|
0
|
|
|
|
|
0
|
$self->error({ |
88
|
|
|
|
|
|
|
type => __PACKAGE__, |
89
|
|
|
|
|
|
|
message => sprintf(ERROR_NOT_READY, ref $self->request), |
90
|
|
|
|
|
|
|
}); |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
else { |
93
|
|
|
|
|
|
|
# make sure we have an request to send... |
94
|
3
|
|
|
|
|
22
|
my $request = $self->http_request(HTTP::Request->new); |
95
|
3
|
|
|
|
|
14
|
$request->method($self->request->request_type); |
96
|
3
|
|
|
|
|
31
|
$request->uri($self->request->url); |
97
|
3
|
|
|
|
|
11310
|
my %query_form = %{$self->request_content}; |
|
3
|
|
|
|
|
15
|
|
98
|
|
|
|
|
|
|
# |
99
|
|
|
|
|
|
|
# This block will be removed once we have basic testing completed. |
100
|
|
|
|
|
|
|
# ...because printing these variables on a live system is not a good idea... |
101
|
|
|
|
|
|
|
# |
102
|
|
|
|
|
|
|
#if ($self->private) { |
103
|
|
|
|
|
|
|
# print Data::Dumper->Dump([\%query_form],['Query Form']); |
104
|
|
|
|
|
|
|
# printf "sorted request values: %s\n", join(', ', $self->sorted_request_values); |
105
|
|
|
|
|
|
|
# printf "Nonce: %s\n", $self->nonce; |
106
|
|
|
|
|
|
|
# printf "Token: %s\n", $self->token; |
107
|
|
|
|
|
|
|
# printf "Path: %s\n", $self->path; |
108
|
|
|
|
|
|
|
#} |
109
|
|
|
|
|
|
|
# |
110
|
3
|
50
|
|
|
|
14
|
if ($self->private) { |
111
|
0
|
|
|
|
|
0
|
$query_form{nonce } = $self->nonce; |
112
|
0
|
|
|
|
|
0
|
$query_form{token } = $self->token; |
113
|
0
|
|
|
|
|
0
|
$query_form{signature} = $self->signature; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
3
|
|
|
|
|
12
|
my $uri = URI->new; |
117
|
3
|
|
|
|
|
136
|
$uri->query_form(%query_form); |
118
|
3
|
50
|
66
|
|
|
304
|
if ($self->request->request_type eq 'POST') { |
|
|
100
|
|
|
|
|
|
119
|
0
|
|
|
|
|
0
|
$request->content($uri->query); |
120
|
0
|
|
|
|
|
0
|
$request->content_type($self->request->content_type); |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
elsif ($self->request->request_type eq 'GET' and $uri->query) { |
123
|
2
|
|
|
|
|
30
|
$request->uri($request->uri . '?' . $uri->query); |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
|
126
|
3
|
|
|
|
|
238
|
$request->header(Accept => 'application/json'); |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
# create a new user_agent each time... |
129
|
3
|
|
|
|
|
222
|
$self->user_agent(LWP::UserAgent->new); |
130
|
3
|
|
|
|
|
9
|
$self->user_agent->agent('Mozilla/8.0'); |
131
|
3
|
|
|
|
|
171
|
$self->user_agent->ssl_opts(verify_hostname => 1); |
132
|
|
|
|
|
|
|
|
133
|
3
|
|
|
|
|
69
|
warn Data::Dumper->Dump([$self->user_agent, $request],[qw(UserAgent Request)]) if DEBUG; |
134
|
|
|
|
|
|
|
|
135
|
3
|
|
|
|
|
8
|
$self->http_response($self->user_agent->request($request)); |
136
|
3
|
|
|
|
|
12
|
$self->process_response; |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
} |
139
|
3
|
|
|
|
|
9
|
return $self->is_success; |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
sub process_response { |
143
|
3
|
|
|
3
|
0
|
5
|
my $self = shift; |
144
|
|
|
|
|
|
|
|
145
|
3
|
|
|
|
|
4
|
warn sprintf "Content: %s\n", $self->http_response->content if DEBUG; |
146
|
|
|
|
|
|
|
|
147
|
3
|
|
|
|
|
4
|
my $content; |
148
|
|
|
|
|
|
|
eval { |
149
|
3
|
|
|
|
|
4
|
warn Data::Dumper->Dump([$self->http_response],['Response']) if DEBUG; |
150
|
3
|
|
|
|
|
9
|
$content = $self->json->decode($self->http_response->content); |
151
|
0
|
|
|
|
|
0
|
1; |
152
|
3
|
50
|
|
|
|
7
|
} or do { |
153
|
3
|
|
|
|
|
87
|
$content = {}; |
154
|
3
|
|
|
|
|
283
|
warn "error: $@\n"; |
155
|
|
|
|
|
|
|
}; |
156
|
3
|
50
|
|
|
|
15
|
if (exists $content->{status}) { |
157
|
0
|
0
|
|
|
|
0
|
if (lc $content->{status} eq 'ok') { |
|
|
0
|
|
|
|
|
|
158
|
0
|
0
|
|
|
|
0
|
$self->apirate($content->{apirate}) if exists $content->{apirate}; |
159
|
0
|
0
|
|
|
|
0
|
if ($self->request->data_key) { |
160
|
|
|
|
|
|
|
# crutch: there is a call to tradebook that returns the json data keyed on either |
161
|
|
|
|
|
|
|
# 'orders' or 'trades'. As a result we have to allow this to be a hash or potential |
162
|
|
|
|
|
|
|
# keys to search. |
163
|
|
|
|
|
|
|
# once this is standardized on Cavirtex, we will remove these conditions... |
164
|
|
|
|
|
|
|
# |
165
|
|
|
|
|
|
|
# TODO: watch for such a change and then reduce the code below and change Request/TrasdeBook.pm |
166
|
0
|
0
|
|
|
|
0
|
if (ref $self->request->data_key) { |
167
|
0
|
|
|
|
|
0
|
foreach my $key (@{$self->request->data_key}) { |
|
0
|
|
|
|
|
0
|
|
168
|
0
|
0
|
|
|
|
0
|
if (exists $content->{$key}) { |
169
|
0
|
|
|
|
|
0
|
$self->response($content->{$key}); |
170
|
0
|
|
|
|
|
0
|
last; |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
# end crutch, but also, remove the 'else' below... |
175
|
|
|
|
|
|
|
else { |
176
|
0
|
|
|
|
|
0
|
$self->response($content->{$self->request->data_key}); |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
else { |
180
|
0
|
|
|
|
|
0
|
$self->response($content); |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
elsif ($content->{status} eq 'error') { |
184
|
0
|
|
|
|
|
0
|
warn sprintf ERROR_CAVIRTEX, Dumper $content->{message} if DEBUG; |
185
|
0
|
|
|
|
|
0
|
$self->error($content->{message}); |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
else { |
188
|
|
|
|
|
|
|
# we got a response but the result was not 'success' and did not contain an 'error' key... |
189
|
|
|
|
|
|
|
# note: your code should never get here, so I am forcing a warning and Dump of the content... |
190
|
0
|
|
|
|
|
0
|
warn ERROR_UNKNOWN_STATUS; |
191
|
0
|
|
|
|
|
0
|
warn Data::Dumper->Dump([$content],[sprintf 'Invalid %s Response Content', COMPANY]); |
192
|
0
|
|
|
|
|
0
|
$self->error('unknown status'); |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
else { |
196
|
|
|
|
|
|
|
# we did not get valid content from their server. Assume an unknown HTTP error occurred... |
197
|
3
|
|
|
|
|
19
|
$self->error({ |
198
|
|
|
|
|
|
|
type => __PACKAGE__, |
199
|
|
|
|
|
|
|
message => 'no status', |
200
|
|
|
|
|
|
|
}); |
201
|
|
|
|
|
|
|
} |
202
|
3
|
|
|
|
|
10
|
return $self->is_success; |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
# the code below is only here to explain the code above |
207
|
0
|
|
|
0
|
0
|
0
|
sub sorted_request_values { @{$_[0]->request_content}{sort {lc($a) cmp lc($b)} keys $_[0]->request_content} } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
208
|
|
|
|
|
|
|
#sub sorted_request_values { |
209
|
|
|
|
|
|
|
#my $self = shift; |
210
|
|
|
|
|
|
|
#my %content = %{$self->request_content}; |
211
|
|
|
|
|
|
|
#return @content{sort {lc($a) cmp lc($b)} keys %content}; |
212
|
|
|
|
|
|
|
#} |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
# signature : is a HMAC-SHA256 Hex encoded hash containing the string data input: |
215
|
|
|
|
|
|
|
# nonce, API token, relative API, request path and alphabetically sorted post parameters. |
216
|
|
|
|
|
|
|
# The message must be generated using the Secret Key that was created with your API token. |
217
|
|
|
|
|
|
|
#sub signature { hmac_sha256_hex(map($_[0]->$_, qw(nonce token path sorted_request_values secret))) } |
218
|
|
|
|
|
|
|
sub signature { |
219
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
220
|
0
|
|
|
|
|
0
|
return hmac_sha256_hex($self->nonce, $self->token, $self->path, $self->sorted_request_values, $self->secret); |
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
|
223
|
3
|
|
|
3
|
0
|
33
|
sub new_nonce { shift->nonce(sprintf '%d%06d' => gettimeofday) } |
224
|
0
|
|
|
0
|
0
|
0
|
sub path { URI->new(shift->http_request->uri)->path } |
225
|
3
|
|
|
3
|
0
|
10
|
sub request_content { shift->request->request_content } |
226
|
3
|
|
66
|
3
|
0
|
42
|
sub json { shift->{json} ||= JSON->new } |
227
|
6
|
|
|
6
|
0
|
16
|
sub private { shift->request->is_private } |
228
|
6
|
|
|
6
|
0
|
16
|
sub is_success { defined shift->response } |
229
|
0
|
|
|
0
|
0
|
0
|
sub public { not shift->private } |
230
|
2
|
|
|
2
|
0
|
9
|
sub attributes { ATTRIBUTES } |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
# this method makes the action call routines simpler... |
233
|
|
|
|
|
|
|
sub class_action { |
234
|
3
|
|
|
3
|
0
|
6
|
my $self = shift; |
235
|
3
|
|
|
|
|
31
|
my $class = CLASS_ACTION_MAP->{((caller(1))[3] =~ /::(\w+)$/)[0]}; |
236
|
3
|
|
|
|
|
50
|
$self->request($class->new(@_)); |
237
|
3
|
50
|
|
|
|
10
|
return $self->send ? $self->response : undef; |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
|
240
|
1
|
|
|
1
|
0
|
1190
|
sub orderbook { class_action(@_) } |
241
|
1
|
|
|
1
|
0
|
1509
|
sub tradebook { class_action(@_) } |
242
|
1
|
|
|
1
|
0
|
529
|
sub ticker { class_action(@_) } |
243
|
0
|
|
|
0
|
0
|
0
|
sub balance { class_action(@_) } |
244
|
0
|
|
|
0
|
0
|
0
|
sub transactions { class_action(@_) } |
245
|
0
|
|
|
0
|
0
|
0
|
sub trade_history { class_action(@_) } |
246
|
0
|
|
|
0
|
0
|
0
|
sub order_history { class_action(@_) } |
247
|
0
|
|
|
0
|
0
|
0
|
sub order { class_action(@_) } |
248
|
0
|
|
|
0
|
0
|
0
|
sub order_cancel { class_action(@_) } |
249
|
0
|
|
|
0
|
0
|
0
|
sub withdraw { class_action(@_) } |
250
|
|
|
|
|
|
|
|
251
|
1
|
|
|
1
|
1
|
3
|
sub token { my $self = shift; $self->get_set(@_) } |
|
1
|
|
|
|
|
5
|
|
252
|
1
|
|
|
1
|
1
|
3
|
sub secret { my $self = shift; $self->get_set(@_) } |
|
1
|
|
|
|
|
5
|
|
253
|
3
|
|
|
3
|
0
|
5
|
sub nonce { my $self = shift; $self->get_set(@_) } |
|
3
|
|
|
|
|
31
|
|
254
|
9
|
|
|
9
|
1
|
15
|
sub error { my $self = shift; $self->get_set(@_) } |
|
9
|
|
|
|
|
30
|
|
255
|
6
|
|
|
6
|
0
|
4685
|
sub http_response { my $self = shift; $self->get_set(@_) } |
|
6
|
|
|
|
|
20
|
|
256
|
30
|
|
|
30
|
1
|
42
|
sub request { my $self = shift; $self->get_set(@_) } |
|
30
|
|
|
|
|
90
|
|
257
|
9
|
|
|
9
|
0
|
15
|
sub response { my $self = shift; $self->get_set(@_) } |
|
9
|
|
|
|
|
24
|
|
258
|
3
|
|
|
3
|
0
|
190
|
sub http_request { my $self = shift; $self->get_set(@_) } |
|
3
|
|
|
|
|
10
|
|
259
|
12
|
|
|
12
|
1
|
3861
|
sub user_agent { my $self = shift; $self->get_set(@_) } |
|
12
|
|
|
|
|
40
|
|
260
|
0
|
|
|
0
|
0
|
|
sub apirate { my $self = shift; $self->get_set(@_) } |
|
0
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
1; |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
__END__ |