| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Google::OAuth::Install ; |
|
2
|
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
3638
|
use 5.008009; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
31
|
|
|
4
|
1
|
|
|
1
|
|
5
|
use strict; |
|
|
1
|
|
|
|
|
6
|
|
|
|
1
|
|
|
|
|
28
|
|
|
5
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
26
|
|
|
6
|
1
|
|
|
1
|
|
5
|
use vars qw( %INC ) ; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
54
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
1
|
|
|
1
|
|
46
|
use Google::OAuth ; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
use File::Copy ; |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
require Exporter; |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our @ISA = qw( Exporter ) ; |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# Items to export into callers namespace by default. Note: do not export |
|
16
|
|
|
|
|
|
|
# names by default without a very good reason. Use EXPORT_OK instead. |
|
17
|
|
|
|
|
|
|
# Do not simply export all your public functions/methods/constants. |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
# This allows declaration use Google::OAuth ':all'; |
|
20
|
|
|
|
|
|
|
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK |
|
21
|
|
|
|
|
|
|
# will save memory. |
|
22
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( 'all' => [ qw() ] ); |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ) ; |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
our @EXPORT = qw( config settings grantcode test install ) ; |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
our $VERSION = '0.01'; |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
my $config ; |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
sub testdb { |
|
33
|
|
|
|
|
|
|
Google::OAuth->setclient ; |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
my @ok = () ; |
|
36
|
|
|
|
|
|
|
eval { |
|
37
|
|
|
|
|
|
|
## Probably not generic enough |
|
38
|
|
|
|
|
|
|
@ok = Google::OAuth->dsn->rows_array( |
|
39
|
|
|
|
|
|
|
'SELECT COUNT(*) FROM %s' ) ; |
|
40
|
|
|
|
|
|
|
} ; |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
return @ok ; |
|
43
|
|
|
|
|
|
|
} |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub config { |
|
46
|
|
|
|
|
|
|
return print STDERR <<'eof' unless @ARGV ; |
|
47
|
|
|
|
|
|
|
Usage: perl -MGoogle::OAuth::Install -e config outputfile |
|
48
|
|
|
|
|
|
|
eof |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
my $configfile = shift @ARGV ; |
|
51
|
|
|
|
|
|
|
my $fh ; |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
return print STDERR < $configfile" ; |
|
54
|
|
|
|
|
|
|
Cannot open $configfile for writing |
|
55
|
|
|
|
|
|
|
eof |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
print $fh $config ; |
|
58
|
|
|
|
|
|
|
printf <
|
|
59
|
|
|
|
|
|
|
Please edit $configfile |
|
60
|
|
|
|
|
|
|
Installation instructions are described within |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
Then run |
|
63
|
|
|
|
|
|
|
perl -MGoogle::OAuth::Install -e settings $configfile |
|
64
|
|
|
|
|
|
|
eof |
|
65
|
|
|
|
|
|
|
} |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub init { |
|
68
|
|
|
|
|
|
|
my $function = shift ; |
|
69
|
|
|
|
|
|
|
return 0 & print STDERR <
|
|
70
|
|
|
|
|
|
|
Usage: perl -MGoogle::OAuth::Install -e $function configfile |
|
71
|
|
|
|
|
|
|
eof |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
my $configfile = shift @ARGV ; |
|
74
|
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
my $error = <
|
|
76
|
|
|
|
|
|
|
Missing or invalid configfile: $configfile |
|
77
|
|
|
|
|
|
|
Run: perl -MGoogle::OAuth::Install -e config $configfile |
|
78
|
|
|
|
|
|
|
eof |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
return 0 & print STDERR $error unless -f $configfile ; |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
do $configfile or return 0 & print STDERR $error ; |
|
83
|
|
|
|
|
|
|
return 0 & print STDERR $error |
|
84
|
|
|
|
|
|
|
unless $Google::OAuth::Config::VERSION eq '1.00' ; |
|
85
|
|
|
|
|
|
|
return $configfile ; |
|
86
|
|
|
|
|
|
|
} |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub settings { |
|
89
|
|
|
|
|
|
|
return unless @_ || init('settings') ; |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
my %client = Google::OAuth::Config->setclient ; |
|
92
|
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
print join( "\n ", 'Settings:', %client ), "\n\n" unless @_ ; |
|
94
|
|
|
|
|
|
|
$client{client_secret} ||= 'undefined' ; |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
my @client = grep $_, %client ; |
|
97
|
|
|
|
|
|
|
return print STDERR <<'eof' unless @client == 8 ; |
|
98
|
|
|
|
|
|
|
Configuration is incomplete- run settings |
|
99
|
|
|
|
|
|
|
eof |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
Google::OAuth->setclient ; |
|
102
|
|
|
|
|
|
|
my $dsn = Google::OAuth->dsn ; |
|
103
|
|
|
|
|
|
|
my $ok = ref $dsn && $dsn->[0] && $dsn->dbconnected ; |
|
104
|
|
|
|
|
|
|
return print STDERR <<'eof' unless $ok ; |
|
105
|
|
|
|
|
|
|
Missing data source |
|
106
|
|
|
|
|
|
|
eof |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
return 0 ; |
|
109
|
|
|
|
|
|
|
} |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub grantcode { |
|
112
|
|
|
|
|
|
|
return unless init('grantcode') ; |
|
113
|
|
|
|
|
|
|
return if settings(1) ; |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
Google::OAuth->setclient ; |
|
116
|
|
|
|
|
|
|
my $link = Google::OAuth::Client->new->scope( |
|
117
|
|
|
|
|
|
|
'calendar.readonly' )->token_request ; |
|
118
|
|
|
|
|
|
|
printf 'Get Grant Code%s', $link, "\n" ; |
|
119
|
|
|
|
|
|
|
} |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
sub test { |
|
122
|
|
|
|
|
|
|
init('test') unless @_ ; |
|
123
|
|
|
|
|
|
|
return if settings(1) ; |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
my $code = $Google::OAuth::Config::test{grantcode} ; |
|
126
|
|
|
|
|
|
|
return print STDERR <<'eof' unless $code ; |
|
127
|
|
|
|
|
|
|
Generate a URL to acquire Grant Code from Google |
|
128
|
|
|
|
|
|
|
perl -MGoogle::OAuth::Install -e grantcode configfile |
|
129
|
|
|
|
|
|
|
eof |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
my %client = Google::OAuth::Config->setclient ; |
|
132
|
|
|
|
|
|
|
$client{dsn}->loadschema unless &testdb ; |
|
133
|
|
|
|
|
|
|
return print STDERR <<'eof' unless &testdb ; |
|
134
|
|
|
|
|
|
|
Unable to open database dsn |
|
135
|
|
|
|
|
|
|
eof |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
Google::OAuth->setclient ; |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
my @ok = Google::OAuth->token_list ; |
|
140
|
|
|
|
|
|
|
return print join( "\n ", "Successfully found tokens:", @ok ), "\n" |
|
141
|
|
|
|
|
|
|
if @ok ; |
|
142
|
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
my $response = Google::OAuth->grant_code( $code ) ; |
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
return 0 & printf "Token successfully generated for %s\n", |
|
146
|
|
|
|
|
|
|
$response->{emailkey} if $response->{emailkey} ; |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
print "Unknown Error. Here's what Google has to say:\n" ; |
|
149
|
|
|
|
|
|
|
print ref $response? join( "\n ", '', %$response ): " $response" ; |
|
150
|
|
|
|
|
|
|
return print "\n" ; |
|
151
|
|
|
|
|
|
|
} |
|
152
|
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
sub install { |
|
154
|
|
|
|
|
|
|
return unless my $ok = init('install') ; |
|
155
|
|
|
|
|
|
|
Google::OAuth->setclient ; |
|
156
|
|
|
|
|
|
|
return if Google::OAuth->token_list == 0 && test( 1 ) ; |
|
157
|
|
|
|
|
|
|
copy( $ok, $INC{'Google/OAuth/Config.pm'} ) ; |
|
158
|
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
printf "Updated %s\n", $INC{'Google/OAuth/Config.pm'} ; |
|
160
|
|
|
|
|
|
|
} |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
$config = <<'eof' ; |
|
163
|
|
|
|
|
|
|
package Google::OAuth::Config ; |
|
164
|
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
my %client ; |
|
166
|
|
|
|
|
|
|
our %test ; |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
############################################################################### |
|
169
|
|
|
|
|
|
|
# # |
|
170
|
|
|
|
|
|
|
# Step 1 - Specify a NoSQL::PL2SQL database driver # |
|
171
|
|
|
|
|
|
|
# # |
|
172
|
|
|
|
|
|
|
# NoSQL::PL2SQL is ideal for the amorphous data structures used in # |
|
173
|
|
|
|
|
|
|
# Google API's and other web services. In order to use NoSQL::PL2SQL, # |
|
174
|
|
|
|
|
|
|
# you must install one of the NoSQL::PL2SQL::DBI drivers appropriate for # |
|
175
|
|
|
|
|
|
|
# your installation. Specify the driver below. # |
|
176
|
|
|
|
|
|
|
# # |
|
177
|
|
|
|
|
|
|
# The only driver currently available is NoSQL::PL2SQL::DBI::MySQL. Please # |
|
178
|
|
|
|
|
|
|
# contact jim@tqis.com for information about other drivers. # |
|
179
|
|
|
|
|
|
|
# # |
|
180
|
|
|
|
|
|
|
############################################################################### |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
## Step 1 - Specify a NoSQL::PL2SQL database driver |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
# use NoSQL::PL2SQL::DBI::MySQL ; ## Uncomment |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
############################################################################### |
|
188
|
|
|
|
|
|
|
# # |
|
189
|
|
|
|
|
|
|
# Step 2 - Specify Google API credentials # |
|
190
|
|
|
|
|
|
|
# # |
|
191
|
|
|
|
|
|
|
# If you haven't already, you must register an application to access the # |
|
192
|
|
|
|
|
|
|
# Google API. Here is the link to register: # |
|
193
|
|
|
|
|
|
|
# https://code.google.com/apis/console/ # |
|
194
|
|
|
|
|
|
|
# # |
|
195
|
|
|
|
|
|
|
# Once you've registered, the values required below can be displayed by # |
|
196
|
|
|
|
|
|
|
# clicking the "API Access" tab in the upper left navigation. # |
|
197
|
|
|
|
|
|
|
# # |
|
198
|
|
|
|
|
|
|
# Warning: The client_secret and dsn access will be available to # |
|
199
|
|
|
|
|
|
|
# everyone in a shared environment. Refer to "SECURE INSTALLATION" |
|
200
|
|
|
|
|
|
|
# in the manual. # |
|
201
|
|
|
|
|
|
|
# # |
|
202
|
|
|
|
|
|
|
############################################################################### |
|
203
|
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
## Step 2 - Specify Google API credentials |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
$client{redirect_uri} = '' ; |
|
207
|
|
|
|
|
|
|
$client{client_id} = '' ; |
|
208
|
|
|
|
|
|
|
$client{client_secret} = '' ; ## May be left blank |
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
############################################################################### |
|
212
|
|
|
|
|
|
|
# # |
|
213
|
|
|
|
|
|
|
# Step 3 - Define the NoSQL::PLSQL dsn # |
|
214
|
|
|
|
|
|
|
# # |
|
215
|
|
|
|
|
|
|
# A NoSQL:PL2SQL data source (DSN) is defined as a single table. Perldoc # |
|
216
|
|
|
|
|
|
|
# NoSQL::PL2SQL:DBI: # |
|
217
|
|
|
|
|
|
|
# http://search.cpan.org/~tqisjim/NoSQL-PL2SQL-1.20/lib/NoSQL/PL2SQL/DBI.pm # |
|
218
|
|
|
|
|
|
|
# # |
|
219
|
|
|
|
|
|
|
# The table will be built as part of this installation process. # |
|
220
|
|
|
|
|
|
|
# # |
|
221
|
|
|
|
|
|
|
############################################################################### |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
## Step 3 - Define the NoSQL::PLSQL dsn |
|
224
|
|
|
|
|
|
|
## Refer to "SECURE INSTALLATION" before connecting the database |
|
225
|
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
# $client{dsn} = NoSQL::PL2SQL::DBI::MySQL->new( $tablename ) ; |
|
227
|
|
|
|
|
|
|
# $client{dsn}->connect( 'DBI:mysql:'.$dbname, @login ) ; |
|
228
|
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
############################################################################### |
|
231
|
|
|
|
|
|
|
# # |
|
232
|
|
|
|
|
|
|
# Step 4 - Acquire a Grant Code # |
|
233
|
|
|
|
|
|
|
# # |
|
234
|
|
|
|
|
|
|
# Before proceeding, you may test your settings as follows: # |
|
235
|
|
|
|
|
|
|
# perl -MGoogle::OAuth::Install settings configfile # |
|
236
|
|
|
|
|
|
|
# # |
|
237
|
|
|
|
|
|
|
# In order to test your settings, you'll need to acquire a "Grant Code" # |
|
238
|
|
|
|
|
|
|
# from Google using a web browser. The link is dynamically generated # |
|
239
|
|
|
|
|
|
|
# using Google::OAuth. The easiest way to access this link is by email # |
|
240
|
|
|
|
|
|
|
# as follows: # |
|
241
|
|
|
|
|
|
|
# # |
|
242
|
|
|
|
|
|
|
# perl -MGoogle::OAuth::Install grantcode configfile | mail you@yours.com # |
|
243
|
|
|
|
|
|
|
# # |
|
244
|
|
|
|
|
|
|
# This process is effectively the same as what your users will experience. # |
|
245
|
|
|
|
|
|
|
# # |
|
246
|
|
|
|
|
|
|
# 1. Use the Google::OAuth library to generate a link # |
|
247
|
|
|
|
|
|
|
# 2. The link will prompt users to log in and authorize your app # |
|
248
|
|
|
|
|
|
|
# 3. After authorization, the user is redirected to your specified # |
|
249
|
|
|
|
|
|
|
# redirect_uri # |
|
250
|
|
|
|
|
|
|
# 4. Google will append a grant code to your url as a query_string # |
|
251
|
|
|
|
|
|
|
# argument. # |
|
252
|
|
|
|
|
|
|
# # |
|
253
|
|
|
|
|
|
|
# You'll need to capture the grant code and enter it below: # |
|
254
|
|
|
|
|
|
|
# # |
|
255
|
|
|
|
|
|
|
############################################################################### |
|
256
|
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
## Step 4 - Acquire a Grant Code |
|
258
|
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
$test{grantcode} = '' ; |
|
260
|
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
############################################################################### |
|
263
|
|
|
|
|
|
|
# # |
|
264
|
|
|
|
|
|
|
# Step 5 - Test your configuration # |
|
265
|
|
|
|
|
|
|
# # |
|
266
|
|
|
|
|
|
|
# perl -MGoogle::OAuth::Install test configfile # |
|
267
|
|
|
|
|
|
|
# # |
|
268
|
|
|
|
|
|
|
# Google::OAuth effectively performs two tests: First it uses the # |
|
269
|
|
|
|
|
|
|
# Grant Code to create an Access Token and Refresh Token. Second, # |
|
270
|
|
|
|
|
|
|
# it uses the Access Token to query Google for a user id. # |
|
271
|
|
|
|
|
|
|
# # |
|
272
|
|
|
|
|
|
|
# If the test succeeds, the email address used in Step 4 will print out, # |
|
273
|
|
|
|
|
|
|
# and proceed to installation: # |
|
274
|
|
|
|
|
|
|
# # |
|
275
|
|
|
|
|
|
|
# perl -MGoogle::OAuth::Install install configfile # |
|
276
|
|
|
|
|
|
|
# # |
|
277
|
|
|
|
|
|
|
# One common failure is an "Invalid Grant Code". Google may throw # |
|
278
|
|
|
|
|
|
|
# this error even though everything is configured correctly, because: # |
|
279
|
|
|
|
|
|
|
# 1. A Grant Code can only be used once # |
|
280
|
|
|
|
|
|
|
# 2. A Grant Code is invalid after another Grant Code is issued # |
|
281
|
|
|
|
|
|
|
# 3. A Grant Code is only valid for a short period of time # |
|
282
|
|
|
|
|
|
|
# 4. Google will issue invalid Grant Codes if requests are made too # |
|
283
|
|
|
|
|
|
|
# frequently. # |
|
284
|
|
|
|
|
|
|
# # |
|
285
|
|
|
|
|
|
|
# This problem may be resolved by repeating step 4 after a brief wait # |
|
286
|
|
|
|
|
|
|
# period. # |
|
287
|
|
|
|
|
|
|
# # |
|
288
|
|
|
|
|
|
|
############################################################################### |
|
289
|
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
############################################################################### |
|
291
|
|
|
|
|
|
|
# # |
|
292
|
|
|
|
|
|
|
# Facebook OAUTH # |
|
293
|
|
|
|
|
|
|
# # |
|
294
|
|
|
|
|
|
|
# Conceptually, Facebook OAUTH is similar, although the implementation is # |
|
295
|
|
|
|
|
|
|
# much simpler. So most of the same methods can be applied for Facebook. # |
|
296
|
|
|
|
|
|
|
# To utilize the overlapping functionality, as well as providing a token # |
|
297
|
|
|
|
|
|
|
# persistence solution, a sample Facebook subclass is included in this # |
|
298
|
|
|
|
|
|
|
# distro. # |
|
299
|
|
|
|
|
|
|
# # |
|
300
|
|
|
|
|
|
|
# One major difference is that Facebook uses only one token. This token # |
|
301
|
|
|
|
|
|
|
# can be renewed indefinitely unless allowed to expire. After expiration, # |
|
302
|
|
|
|
|
|
|
# however, the entire token request process must be repeated. # |
|
303
|
|
|
|
|
|
|
# # |
|
304
|
|
|
|
|
|
|
############################################################################### |
|
305
|
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
my %facebook ; |
|
307
|
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
$facebook{client_id} = '' ; |
|
309
|
|
|
|
|
|
|
$facebook{client_secret} = '' ; |
|
310
|
|
|
|
|
|
|
$facebook{redirect_uri} = '' ; |
|
311
|
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
############################# END OF INSTRUCTIONS ############################# |
|
314
|
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
BEGIN { |
|
316
|
|
|
|
|
|
|
use 5.008009; |
|
317
|
|
|
|
|
|
|
use strict; |
|
318
|
|
|
|
|
|
|
use warnings; |
|
319
|
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
require Exporter; |
|
321
|
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
our @ISA = qw( Exporter ) ; |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( 'all' => [ qw() ] ); |
|
325
|
|
|
|
|
|
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ) ; |
|
326
|
|
|
|
|
|
|
our @EXPORT = qw() ; |
|
327
|
|
|
|
|
|
|
our $VERSION = '1.01'; |
|
328
|
|
|
|
|
|
|
} |
|
329
|
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
sub setclient { |
|
331
|
|
|
|
|
|
|
return %client ; |
|
332
|
|
|
|
|
|
|
} |
|
333
|
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
sub facebookclient { |
|
335
|
|
|
|
|
|
|
return %facebook ; |
|
336
|
|
|
|
|
|
|
} |
|
337
|
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
1; |
|
339
|
|
|
|
|
|
|
eof |
|
340
|
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
1; |
|
342
|
|
|
|
|
|
|
__END__ |