blib/lib/HTTP/QuickBase.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 69 | 825 | 8.3 |
branch | 14 | 364 | 3.8 |
condition | 3 | 28 | 10.7 |
subroutine | 10 | 73 | 13.7 |
pod | 32 | 70 | 45.7 |
total | 128 | 1360 | 9.4 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package HTTP::QuickBase; | ||||||
2 | |||||||
3 | #Version $Id: QuickBase.pm,v 1.55 2013/08/09 15:29:23 cvonroes Exp $ | ||||||
4 | |||||||
5 | ( $VERSION ) = '$Revision: 1.55 $ ' =~ /\$Revision:\s+([^\s]+)/; | ||||||
6 | |||||||
7 | 1 | 1 | 725 | use strict; | |||
1 | 1 | ||||||
1 | 32 | ||||||
8 | 1 | 1 | 2726 | use LWP::UserAgent; | |||
1 | 73643 | ||||||
1 | 36 | ||||||
9 | 1 | 1 | 907 | use MIME::Base64 qw(encode_base64); | |||
1 | 797 | ||||||
1 | 11635 | ||||||
10 | |||||||
11 | =pod | ||||||
12 | |||||||
13 | =head1 NAME | ||||||
14 | |||||||
15 | HTTP::QuickBase - Create a web shareable database in under a minute | ||||||
16 | |||||||
17 | =head1 VERSION | ||||||
18 | |||||||
19 | $Revision: 1.54 $ | ||||||
20 | |||||||
21 | =head1 SYNOPSIS | ||||||
22 | |||||||
23 | # see https://www.quickbase.com/up/6mztyxu8/g/rc7/en/ for details of the underlying API. | ||||||
24 | |||||||
25 | use HTTP::QuickBase; | ||||||
26 | $qdb = HTTP::QuickBase->new(); | ||||||
27 | |||||||
28 | #If you don't want to use HTTPS or your Perl installation doesn't support HTTPS then | ||||||
29 | #make sure you have the "Allow non-SSL access (normally OFF)" checkbox checked on your | ||||||
30 | #QuickBase database info page. You can get to this page by going to the database "MAIN" | ||||||
31 | #page and then clicking on "Administration" under "SHORTCUTS". Then click on "Basic Properties". | ||||||
32 | #To use this module in non-SSL mode invoke the QuickBase object like this: | ||||||
33 | |||||||
34 | #$qdb = HTTP::QuickBase->new('http://www.quickbase.com/db'); | ||||||
35 | |||||||
36 | $username="fred"; | ||||||
37 | $password="flinstone"; | ||||||
38 | |||||||
39 | $qdb->authenticate($username, $password); | ||||||
40 | $database_name= "GuestBook Template"; | ||||||
41 | |||||||
42 | #I don't recommend using the getIDbyName method because there are many tables with the same name. | ||||||
43 | #Instead you can discover the database_id of your table empirically. | ||||||
44 | #Read the follwing article to find out how: | ||||||
45 | #https://www.quickbase.com/db/6mztyxu8?a=dr&r=w | ||||||
46 | |||||||
47 | $database_id = "9mztyxu8"; | ||||||
48 | $clone_name = "My Guest Book"; | ||||||
49 | $database_clone_id = $qdb->cloneDatabase($database_id, $clone_name, "Description of my new database."); | ||||||
50 | |||||||
51 | |||||||
52 | #Let's put something into the new guest book | ||||||
53 | $Name = "Fred Flinstone"; | ||||||
54 | $dphone = "978-533-2189"; | ||||||
55 | $ephone = "781-839-1555"; | ||||||
56 | $email = "fred\@bedrock.com"; | ||||||
57 | $address1 = "Rubble Court"; | ||||||
58 | $address2 = "Pre Historic Route 1"; | ||||||
59 | $city = "Bedrock"; | ||||||
60 | $state = "Stonia"; | ||||||
61 | $zip = "99999-1234"; | ||||||
62 | $comments = "Hanna Barbara the king of Saturday morning cartoons."; | ||||||
63 | #if you want to attach a file you need to create an array with the first member of the array set to the literal string "file" and the second | ||||||
64 | #member of the array set to the full path of the file. | ||||||
65 | $attached_file = ["file", "c:\\my documents\\bedrock.txt"]; | ||||||
66 | %record_data=("Name" => $Name,"Daytime Phone" => $dphone, "Evening Phone" =>$ephone,"Email Address" => $email, "Street Address 1" => $address1,"Street Address 2" => $address2,"City" => $city,"State"=>$state,"Zip Code"=>$zip, "Comments" => $comments , "Attached File" => $attached_file ); | ||||||
67 | |||||||
68 | $record_id = $qdb->AddRecord($database_clone_id, %record_data); | ||||||
69 | |||||||
70 | #Let's get that information back out again | ||||||
71 | %new_record=$qdb->GetRecord($database_clone_id, $record_id); | ||||||
72 | #Now let's edit that record! | ||||||
73 | $new_record{"Daytime Phone"} = "978-275-2189"; | ||||||
74 | $qdb->EditRecord($database_clone_id, $record_id, %new_record); | ||||||
75 | |||||||
76 | #Let's print out all records in the database. | ||||||
77 | |||||||
78 | @records = $qdb->doQuery($database_clone_id, "{0.CT.''}"); | ||||||
79 | foreach $record (@records){ | ||||||
80 | foreach $field (keys %$record){ | ||||||
81 | print "$field -> $record->{$field}\n"; | ||||||
82 | } | ||||||
83 | } | ||||||
84 | |||||||
85 | #Let's save the entire database to a local comma separated values (CSV) file. | ||||||
86 | |||||||
87 | open( CSV, ">my_qbd_snapshot.csv"); | ||||||
88 | print CSV $qdb->getCompleteCSV($database_clone_id); | ||||||
89 | close CSV; | ||||||
90 | |||||||
91 | #Where field number 10 contains Wilma (the query) | ||||||
92 | #let's print out fields 10, 11, 12 and 15 (the clist) | ||||||
93 | #sorted by field 14 (the slist) | ||||||
94 | #in descending order (the options) | ||||||
95 | |||||||
96 | @records = $qdb->doQuery($database_clone_id, "{10.CT.'Wilma'}", "10.11.12.15", "14", "sortorder-D"); | ||||||
97 | foreach $record (@records){ | ||||||
98 | foreach $field (keys %$record){ | ||||||
99 | print "$field -> $record->{$field}\n"; | ||||||
100 | } | ||||||
101 | } | ||||||
102 | |||||||
103 | #You can find out what you need in terms of the query, clist, slist and options by | ||||||
104 | #going to the View design page of your QuickBase database and filling in the form. Hit the "Display" button and | ||||||
105 | #look at the URL in the browser "Address" window. The View design page is accessible from any database home | ||||||
106 | #page by clicking on VIEWS at the top left and then clicking on "New View..." in the lower left. | ||||||
107 | |||||||
108 | =head1 REQUIRES | ||||||
109 | |||||||
110 | Perl5.005, LWP::UserAgent, Crypt::SSLeay (optional unless you want to talk to QuickBase via HTTPS) | ||||||
111 | |||||||
112 | =head1 SEE ALSO | ||||||
113 | |||||||
114 | https://www.quickbase.com/up/6mztyxu8/g/rc7/en/ for details of the underlying QuickBase HTTP API | ||||||
115 | |||||||
116 | =head1 EXPORTS | ||||||
117 | |||||||
118 | Nothing | ||||||
119 | |||||||
120 | =head1 DESCRIPTION | ||||||
121 | |||||||
122 | HTTP::QuickBase allows you to manipulate QuickBase databases. | ||||||
123 | Methods are provided for cloning databases, adding records, editing records, deleting records and retrieving records. | ||||||
124 | All you need is a valid QuickBase account, although with anonymous access you can read from publically accessible QuickBase | ||||||
125 | databases. To learn more about QuickBase please visit http://www.quickbase.com/ | ||||||
126 | This module supports a single object that retains login state. You call the authenticate method only once. | ||||||
127 | |||||||
128 | =head1 METHODS | ||||||
129 | |||||||
130 | =head2 Creation | ||||||
131 | |||||||
132 | =over 4 | ||||||
133 | |||||||
134 | =item $qdb = new HTTP::QuickBase($URLprefix) | ||||||
135 | |||||||
136 | Creates and returns a | ||||||
137 | new HTTP::QuickBase object. | ||||||
138 | Use the optional $URLprefix to connect to QuickBase via HTTP instead of HTTPS. | ||||||
139 | call the constructor with a URLprefix parameter of "http://www.quickbase.com/db/". | ||||||
140 | QuickBase databases are by default not accessible via HTTP. To allow HTTP access to a | ||||||
141 | QuickBase database go to its main page and click on "Administration" under "SHORTCUTS". | ||||||
142 | Then click on "Basic Properties". Next to "Options" you'll see a checkbox labeled | ||||||
143 | "Allow non-SSL access (normally unchecked)". You'll need to check this box to allow HTTP | ||||||
144 | access to the database. | ||||||
145 | |||||||
146 | =back | ||||||
147 | |||||||
148 | =head2 Authentication/Permissions | ||||||
149 | |||||||
150 | =over 4 | ||||||
151 | |||||||
152 | =item $qdb->authenticate($username, $password) | ||||||
153 | |||||||
154 | Sets the username and password used for subsequent method invocations | ||||||
155 | |||||||
156 | =back | ||||||
157 | |||||||
158 | =head2 Finding IDs | ||||||
159 | |||||||
160 | =over 4 | ||||||
161 | |||||||
162 | =item $qdb->getIDbyName($dbName) | ||||||
163 | |||||||
164 | Returns the database ID of the database whose full name matches $dbName. | ||||||
165 | I don't recommend using the getIDbyName method because there are many tables with the same name. | ||||||
166 | Instead you can discover the database_id of your table empirically. | ||||||
167 | Read the follwing article to find out how: | ||||||
168 | https://www.quickbase.com/db/6mztyxu8?a=dr&r=w | ||||||
169 | |||||||
170 | =item $qdb->GetRIDs ($QuickBaseID) | ||||||
171 | |||||||
172 | Returns an array of all record IDs in the database identified by database ID $QuickBaseID. | ||||||
173 | |||||||
174 | =back | ||||||
175 | |||||||
176 | =head2 Cloning and Creating from Scratch | ||||||
177 | |||||||
178 | =over 4 | ||||||
179 | |||||||
180 | |||||||
181 | =item $qdb->cloneDatabase($QuickBaseID, $Name, $Description) | ||||||
182 | |||||||
183 | Clones the database identified by $QuickBaseID and gives the clone the name $Name and description $Description | ||||||
184 | |||||||
185 | Returns the dbid of the new database. | ||||||
186 | |||||||
187 | =back | ||||||
188 | |||||||
189 | =over 4 | ||||||
190 | |||||||
191 | =item $qdb->createDatabase($Name, $Description) | ||||||
192 | |||||||
193 | Creates a database with the name $Name and description $Description | ||||||
194 | |||||||
195 | Returns the dbid of the new database. | ||||||
196 | |||||||
197 | =back | ||||||
198 | |||||||
199 | =over 4 | ||||||
200 | |||||||
201 | =item $qdb->addField($QuickBaseID, $label, $type, $mode) | ||||||
202 | |||||||
203 | Creates a field with the label $label of label, a type of $type and if the field is to be a formula field then set $mode to 'virtual' otherwise set it to the empty string. | ||||||
204 | |||||||
205 | Returns the fid of the new field. | ||||||
206 | |||||||
207 | =back | ||||||
208 | |||||||
209 | =over 4 | ||||||
210 | |||||||
211 | =item $qdb->deleteField($QuickBaseID, $fid) | ||||||
212 | |||||||
213 | Deletes the field with the field identifier of $fid. | ||||||
214 | |||||||
215 | Returns nothing. | ||||||
216 | |||||||
217 | =back | ||||||
218 | |||||||
219 | =over 4 | ||||||
220 | |||||||
221 | =item $qdb->setFieldProperties($QuickBaseID, $fid, %properties) | ||||||
222 | |||||||
223 | Modifies the field with the field identifier of $fid using the name-value pairs in %properties. Please see the QuickBase HTTP API document for more details. | ||||||
224 | |||||||
225 | Returns nothing. | ||||||
226 | |||||||
227 | =back | ||||||
228 | |||||||
229 | |||||||
230 | =head2 Adding Information | ||||||
231 | |||||||
232 | =over 4 | ||||||
233 | |||||||
234 | |||||||
235 | =item $qdb->AddRecord($QuickBaseID, %recorddata) | ||||||
236 | |||||||
237 | Returns the record id of the new record. The keys of the associative array %recorddata are scanned for matches with the | ||||||
238 | field names of the database. If the key begins with the number one through nine and contains only numbers | ||||||
239 | then the field identifiers are scanned for a match instead. | ||||||
240 | If a particular key matches then the corresponding field in the new record is set to the value associated with the key. | ||||||
241 | If you want to attach a file you need to create an array with the first member of the array set to the string literal 'file' and the second | ||||||
242 | member of the array set to the full path of the file. Then the value of the key corresponding to the file attachment field | ||||||
243 | should be set to a reference which points to this two member array. | ||||||
244 | |||||||
245 | =back | ||||||
246 | |||||||
247 | =head2 Deleting Information | ||||||
248 | |||||||
249 | =over 4 | ||||||
250 | |||||||
251 | =item $qdb->DeleteRecord($QuickBaseID, $rid) | ||||||
252 | |||||||
253 | Deletes the record identified by the record identifier $rid. | ||||||
254 | |||||||
255 | =back | ||||||
256 | |||||||
257 | =over 4 | ||||||
258 | |||||||
259 | =item $qdb->PurgeRecords($QuickBaseID, $query) | ||||||
260 | |||||||
261 | Deletes the records identified by the query, qname or qid in $query. Use the qid of '1' to delete all the records in a database. | ||||||
262 | |||||||
263 | Please refer to https://www.quickbase.com/db/6mztyxu8?a=dr&r=2 for more details on the query parameter. | ||||||
264 | |||||||
265 | =back | ||||||
266 | |||||||
267 | |||||||
268 | |||||||
269 | =head2 Editing Information | ||||||
270 | |||||||
271 | =over 4 | ||||||
272 | |||||||
273 | =item $qdb->EditRecord($QuickBaseID, $rid, %recorddata) | ||||||
274 | |||||||
275 | Modifies the record defined by record id $rid in the database defined by database ID $QuickBaseID. | ||||||
276 | |||||||
277 | Any field in the database that can be modified and that has its field label or field identifer as a key in the associative array | ||||||
278 | %recorddata will be modified to the value associated with the key. The keys of the associative array %recorddata are scanned for matches with the | ||||||
279 | field names of the database. If the key begins with the number one through nine and contains only numbers | ||||||
280 | then the field identifiers are scanned for a match instead. | ||||||
281 | If a particular key matches then the corresponding field in the record is set to the value associated with the key. | ||||||
282 | If you want to modify a file attachment field, you need to create an array with the first member of the array set to the string literal 'file' and the second | ||||||
283 | member of the array set to the full path of the file. Then the value of the key corresponding to the file attachment field | ||||||
284 | should be set to a reference which points to this two member array. | ||||||
285 | |||||||
286 | |||||||
287 | Use $qdb->EditRecordWithUpdateID($QuickBaseID, $rid, $update_id, %recorddata) to take advantage of conflict detection. | ||||||
288 | If $update_id is supplied then the edit will only succeed if the record's current update_id matches. | ||||||
289 | |||||||
290 | Returns the XML response from QuickBase after modifying every valid field refered to in %recorddata. | ||||||
291 | |||||||
292 | Not all fields can be modified. Built-in and formula (virtual) fields cannot be modified. If you attempt to | ||||||
293 | modify them with EditRecord you will get an error and no part of the record will have been modified. | ||||||
294 | |||||||
295 | =back | ||||||
296 | |||||||
297 | =head2 Retrieving Information | ||||||
298 | |||||||
299 | =over 4 | ||||||
300 | |||||||
301 | =item $qdb->GetRecord($QuickBaseID, $rid) | ||||||
302 | |||||||
303 | From the database identified by $QuickBaseID, returns an associative array of field names and values of the record identified by $rid. | ||||||
304 | |||||||
305 | =back | ||||||
306 | |||||||
307 | =over 4 | ||||||
308 | |||||||
309 | =item $qdb->doQuery($QuickBaseID, $query, $clist, $slist, $options) | ||||||
310 | |||||||
311 | From the database identified by $QuickBaseID, returns an array of | ||||||
312 | associative arrays of field names and values of the records selected by | ||||||
313 | $query, which can either be an actual query in QuickBase's query | ||||||
314 | language, or a view name or number (qid or qname). | ||||||
315 | |||||||
316 | The columns (fields) returned are determined by $clist, a period delimited list of field identifiers. | ||||||
317 | |||||||
318 | The sorting of the records is determined by $slist, a period delimited list of field identifiers. | ||||||
319 | |||||||
320 | Ascending or descending order of the sorts defined by $slist is controlled by $options. | ||||||
321 | |||||||
322 | Please refer to https://www.quickbase.com/db/6mztyxu8?a=dr&r=2 for more details on the parameters for API_DoQuery. | ||||||
323 | |||||||
324 | =back | ||||||
325 | |||||||
326 | =over 4 | ||||||
327 | |||||||
328 | =item $qdb->getCompleteCSV($QuickBaseID) | ||||||
329 | |||||||
330 | From the database identified by $QuickBaseID, returns a scalar containing the comma separated values of all fields including built in fields. | ||||||
331 | |||||||
332 | The first row of the comma separated values (CSV) contains the field labels. | ||||||
333 | |||||||
334 | =back | ||||||
335 | |||||||
336 | =over 4 | ||||||
337 | |||||||
338 | =item $qdb->GetFile($QuickBaseDBid, $filename, $rid, $fid) | ||||||
339 | |||||||
340 | From the database identified by $QuickBaseID, returns an array where the first element is the contents of the file $filename uploaded to | ||||||
341 | the record identified by record ID $rid in the field identified by field indentifier $fid. | ||||||
342 | |||||||
343 | The second element of the returned array is return value from the headers method of the corresponding LWP::UserAgent object. | ||||||
344 | |||||||
345 | =back | ||||||
346 | |||||||
347 | |||||||
348 | |||||||
349 | |||||||
350 | =head2 Errors | ||||||
351 | |||||||
352 | =over 4 | ||||||
353 | |||||||
354 | =item $qdb->error() | ||||||
355 | |||||||
356 | Retrieve the error code returned from QuickBase. | ||||||
357 | Please refer to the | ||||||
358 | |||||||
359 | Appendix A for error code details. | ||||||
360 | |||||||
361 | =item $qdb->errortext() | ||||||
362 | |||||||
363 | Retrieve the error text returned from QuickBase. | ||||||
364 | Please refer to | ||||||
365 | |||||||
366 | Appendix A for all possible error messages. | ||||||
367 | |||||||
368 | |||||||
369 | =back | ||||||
370 | |||||||
371 | |||||||
372 | =head2 New API calls added in 2008 | ||||||
373 | |||||||
374 | |||||||
375 | |||||||
376 | |||||||
377 | =over 4 | ||||||
378 | |||||||
379 | =item CreateTable($QuickBaseDBid, $pnoun) | ||||||
380 | |||||||
381 | Add a table to an existing application. | ||||||
382 | |||||||
383 | Returns the dbid of the new table. | ||||||
384 | |||||||
385 | =back | ||||||
386 | |||||||
387 | |||||||
388 | |||||||
389 | =over 4 | ||||||
390 | |||||||
391 | =item AddUserToRole($QuickBaseDBid, $userid, $roleid) | ||||||
392 | |||||||
393 | Add a user to a role in an application. | ||||||
394 | |||||||
395 | =back | ||||||
396 | |||||||
397 | |||||||
398 | |||||||
399 | =over 4 | ||||||
400 | |||||||
401 | =item ChangeUserRole($QuickBaseDBid, $userid, $roleid, $newroleid) | ||||||
402 | |||||||
403 | Change the role of a user in an application. | ||||||
404 | |||||||
405 | =back | ||||||
406 | |||||||
407 | |||||||
408 | |||||||
409 | =over 4 | ||||||
410 | |||||||
411 | =item GetDBvar($QuickBaseDBid, $varname) | ||||||
412 | |||||||
413 | Retrieve the value of an application variable. | ||||||
414 | |||||||
415 | =back | ||||||
416 | |||||||
417 | =over 4 | ||||||
418 | |||||||
419 | =item GetRoleInfo($QuickBaseDBid) | ||||||
420 | |||||||
421 | Retrieve the list of Roles defined for an application. | ||||||
422 | |||||||
423 | =back | ||||||
424 | |||||||
425 | =over 4 | ||||||
426 | |||||||
427 | =item GetUserInfo($email) | ||||||
428 | |||||||
429 | Retrieve a hash containing the login, name, and id of a user, given the user's email address. | ||||||
430 | |||||||
431 | =back | ||||||
432 | |||||||
433 | |||||||
434 | =over 4 | ||||||
435 | |||||||
436 | =item GetUserRole($QuickBaseDBid,$userid) | ||||||
437 | |||||||
438 | Retrieve the Role information for a user | ||||||
439 | |||||||
440 | =back | ||||||
441 | |||||||
442 | =over 4 | ||||||
443 | |||||||
444 | =item ProvisionUser($QuickBaseDBid,$roleid, $email, $fname, $lname) | ||||||
445 | |||||||
446 | Add the user information to QuickBase in preparation for inviting the user for the first time to view a QuickBase application. | ||||||
447 | |||||||
448 | =back | ||||||
449 | |||||||
450 | |||||||
451 | =over 4 | ||||||
452 | |||||||
453 | =item GetOneTimeTicket | ||||||
454 | |||||||
455 | Retrieve a ticket valid for the next 5 minutes only. Designed for uploading files. | ||||||
456 | |||||||
457 | =back | ||||||
458 | |||||||
459 | =over 4 | ||||||
460 | |||||||
461 | =item RemoveUserFromRole($QuickBaseDBid, $userid, $roleid) | ||||||
462 | |||||||
463 | Remove a user from a role in an application. | ||||||
464 | |||||||
465 | =back | ||||||
466 | |||||||
467 | |||||||
468 | =over 4 | ||||||
469 | |||||||
470 | =item RenameApp($QuickBaseDBid,$newappname) | ||||||
471 | |||||||
472 | Change the name of an application. | ||||||
473 | |||||||
474 | =back | ||||||
475 | |||||||
476 | |||||||
477 | =over 4 | ||||||
478 | |||||||
479 | =item SetDBvar($QuickBaseDBid, $varname, $value) | ||||||
480 | |||||||
481 | Set the value of an application variable. | ||||||
482 | |||||||
483 | =back | ||||||
484 | |||||||
485 | |||||||
486 | =over 4 | ||||||
487 | |||||||
488 | =item SendInvitation($QuickBaseDBid, $userid) | ||||||
489 | |||||||
490 | Send an email from QuickBase inviting a user to an application. | ||||||
491 | |||||||
492 | =back | ||||||
493 | |||||||
494 | |||||||
495 | =over 4 | ||||||
496 | |||||||
497 | =item UserRoles($QuickBaseDBid) | ||||||
498 | |||||||
499 | Returns an Xml Document of information about the roles defined for an application. | ||||||
500 | |||||||
501 | =back | ||||||
502 | |||||||
503 | |||||||
504 | |||||||
505 | =head1 CLASS VARIABLES | ||||||
506 | |||||||
507 | None | ||||||
508 | |||||||
509 | =head1 DIAGNOSTICS | ||||||
510 | |||||||
511 | All errors are reported by the methods error and errortext. For a | ||||||
512 | complete list of errors, please visit | ||||||
513 | https://www.quickbase.com/up/6mztyxu8/g/rc7/en/ and scroll | ||||||
514 | down to Appendix A. | ||||||
515 | |||||||
516 | =head1 AUTHOR | ||||||
517 | |||||||
518 | Claude von Roesgen, claude_von_roesgen@intuit.com | ||||||
519 | |||||||
520 | =head1 COPYRIGHT | ||||||
521 | |||||||
522 | Copyright (c) 1999-2008 Intuit, Inc. All rights reserved. | ||||||
523 | This program is free software; you can redistribute it and/or | ||||||
524 | modify it under the same terms as Perl itself. | ||||||
525 | |||||||
526 | |||||||
527 | =cut | ||||||
528 | |||||||
529 | my %XMLescapes; | ||||||
530 | |||||||
531 | sub new | ||||||
532 | { | ||||||
533 | 1 | 1 | 1 | 14 | my $class = shift; | ||
534 | 1 | 2 | my $prefix = shift; | ||||
535 | 1 | 2 | my $self; | ||||
536 | |||||||
537 | 1 | 4 | for (0..255) { | ||||
538 | 256 | 938 | $XMLescapes{chr($_)} = sprintf("%03d;", $_); | ||||
539 | } | ||||||
540 | |||||||
541 | 1 | 50 | 21 | $self = bless { | |||
542 | 'URLprefix' => $prefix || "https://www.quickbase.com/db" , | ||||||
543 | 'ticket' => undef, | ||||||
544 | 'apptoken' => "", | ||||||
545 | 'error' => undef, | ||||||
546 | 'errortext' => undef, | ||||||
547 | 'username' => undef, | ||||||
548 | 'password' => undef, | ||||||
549 | 'credentials' => undef, | ||||||
550 | 'proxy' => undef, | ||||||
551 | 'realmhost' => undef | ||||||
552 | }, $class; | ||||||
553 | |||||||
554 | } | ||||||
555 | |||||||
556 | sub authenticate ($$) | ||||||
557 | { | ||||||
558 | 1 | 1 | 1 | 13 | my($self, $username, $password) = @_; | ||
559 | 1 | 7 | $self->{'username'} = $username; | ||||
560 | 1 | 4 | $self->{'password'} = $password; | ||||
561 | 1 | 6 | $username = $self->xml_escape($username); | ||||
562 | 1 | 11 | $password = $self->xml_escape($password); | ||||
563 | 1 | 5 | $self->{'credentials'} = " |
||||
564 | 1 | 3 | $self->{'ticket'}=""; | ||||
565 | 1 | 2 | return ""; | ||||
566 | } | ||||||
567 | |||||||
568 | sub setAppToken($) | ||||||
569 | { | ||||||
570 | 0 | 0 | 0 | 0 | my($self,$apptoken) = @_; | ||
571 | 0 | 0 | $self->{'apptoken'} = $apptoken; | ||||
572 | } | ||||||
573 | |||||||
574 | sub getTicket() | ||||||
575 | { | ||||||
576 | 0 | 0 | 0 | 0 | my($self) = @_; | ||
577 | #First we have to get the authorization ticket | ||||||
578 | #We do this by posting the QuickBase username and password to QuickBase | ||||||
579 | #This is where we post the QuickBase username and password | ||||||
580 | 0 | 0 | my $res = $self->PostAPIURL ("main", "API_Authenticate", | ||||
581 | " |
||||||
582 | $self->{'credentials'}. | ||||||
583 | ""); | ||||||
584 | 0 | 0 | 0 | if ($res->content =~ / |
|||
585 | { | ||||||
586 | 0 | 0 | $self->{'error'} = $1; | ||||
587 | 0 | 0 | $self->{'errortext'} = $2; | ||||
588 | } | ||||||
589 | 0 | 0 | 0 | if ($res->content =~ / |
|||
590 | { | ||||||
591 | 0 | 0 | $self->{'errortext'} = $1; | ||||
592 | } | ||||||
593 | 0 | 0 | 0 | if ($self->{'error'} eq '0') | |||
594 | { | ||||||
595 | 0 | 0 | $res->content =~ / |
||||
596 | 0 | 0 | $self->{'ticket'} = $1; | ||||
597 | 0 | 0 | $self->{'credentials'} = " |
||||
598 | } | ||||||
599 | else | ||||||
600 | { | ||||||
601 | 0 | 0 | return ""; | ||||
602 | } | ||||||
603 | 0 | 0 | return $self->{'ticket'}; | ||||
604 | } | ||||||
605 | |||||||
606 | sub URLprefix() | ||||||
607 | { | ||||||
608 | 1 | 1 | 0 | 3 | my($self) = shift; | ||
609 | 1 | 50 | 5 | if (@_) | |||
610 | { | ||||||
611 | 0 | 0 | $self->{'URLprefix'}=shift; | ||||
612 | 0 | 0 | $self->{'URLprefix'} =~ s/cgi\/sb.exe/db/; | ||||
613 | 0 | 0 | return $self->{'URLprefix'}; | ||||
614 | } | ||||||
615 | else | ||||||
616 | { | ||||||
617 | 1 | 10 | return $self->{'URLprefix'}; | ||||
618 | } | ||||||
619 | } | ||||||
620 | |||||||
621 | sub setProxy($) | ||||||
622 | { | ||||||
623 | 0 | 0 | 0 | 0 | my($self, $proxyserver) = @_; | ||
624 | 0 | 0 | $self->{'proxy'} = $proxyserver; | ||||
625 | 0 | 0 | return $self->{'proxy'}; | ||||
626 | } | ||||||
627 | |||||||
628 | sub setRealmHost($) | ||||||
629 | { | ||||||
630 | 0 | 0 | 0 | 0 | my($self, $realmhost) = @_; | ||
631 | 0 | 0 | $self->{'realmhost'} = $realmhost; | ||||
632 | 0 | 0 | return $self->{'realmhost'}; | ||||
633 | } | ||||||
634 | |||||||
635 | sub errortext() | ||||||
636 | { | ||||||
637 | 1 | 1 | 1 | 37 | my($self) = shift; | ||
638 | 1 | 0 | return $self->{'errortext'}; | ||||
639 | } | ||||||
640 | |||||||
641 | sub error() | ||||||
642 | { | ||||||
643 | 0 | 0 | 1 | 0 | my($self) = shift; | ||
644 | 0 | 0 | return $self->{'error'}; | ||||
645 | } | ||||||
646 | |||||||
647 | sub AddRecord($%) | ||||||
648 | { | ||||||
649 | 0 | 0 | 1 | 0 | my($self, $QuickBaseDBid, %recorddata) = @_; | ||
650 | 0 | 0 | my $name; | ||||
651 | my $content; | ||||||
652 | 0 | 0 | my $filecontents; | ||||
653 | 0 | 0 | my $filebuffer; | ||||
654 | 0 | 0 | my $tag; | ||||
655 | |||||||
656 | 0 | 0 | $content = " |
||||
657 | 0 | 0 | foreach $name (keys(%recorddata)) | ||||
658 | { | ||||||
659 | 0 | 0 | $tag=$name; | ||||
660 | 0 | 0 | $tag =~tr/A-Z/a-z/; | ||||
661 | 0 | 0 | $tag=~s/[^a-z0-9]/_/g; | ||||
662 | 0 | 0 | $content .= $self->createFieldXML($tag, $recorddata{$name}); | ||||
663 | } | ||||||
664 | |||||||
665 | 0 | 0 | $content .= ""; | ||||
666 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseDBid, "API_AddRecord", $content); | ||||
667 | 0 | 0 | my $xml = $res->content; | ||||
668 | |||||||
669 | 0 | 0 | 0 | if ($xml =~ / |
|||
670 | { | ||||||
671 | 0 | 0 | return $1; | ||||
672 | } | ||||||
673 | 0 | 0 | return ""; | ||||
674 | } | ||||||
675 | |||||||
676 | sub AddReplaceDBPage($$$$$) | ||||||
677 | { | ||||||
678 | 0 | 0 | 0 | 0 | my($self,$QuickBaseDBid, $pageid, $pagename, $pagetype, $pagebody) = @_; | ||
679 | |||||||
680 | 0 | 0 | my $content = " |
||||
681 | 0 | 0 | 0 | $content .= " |
|||
682 | 0 | 0 | 0 | $content .= " |
|||
683 | 0 | 0 | $content .= " |
||||
684 | |||||||
685 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseDBid, "API_AddReplaceDBPage", $content)->content; | ||||
686 | |||||||
687 | 0 | 0 | 0 | if($res =~ / |
|||
0 | |||||||
688 | 0 | 0 | return $1; | ||||
689 | } | ||||||
690 | elsif($res =~ / |
||||||
691 | 0 | 0 | return $1; | ||||
692 | } | ||||||
693 | else | ||||||
694 | { | ||||||
695 | 0 | 0 | return ""; | ||||
696 | } | ||||||
697 | } | ||||||
698 | |||||||
699 | sub AddUserToRole($$$) | ||||||
700 | { | ||||||
701 | 0 | 0 | 1 | 0 | my($self,$QuickBaseDBid, $userid, $roleid) = @_; | ||
702 | 0 | 0 | my $content = " |
||||
703 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_AddUserToRole", $content); | ||||
704 | 0 | 0 | return ""; | ||||
705 | } | ||||||
706 | |||||||
707 | sub ChangeUserRole($$$$) | ||||||
708 | { | ||||||
709 | 0 | 0 | 1 | 0 | my($self,$QuickBaseDBid, $userid, $roleid, $newroleid) = @_; | ||
710 | 0 | 0 | my $content = " |
||||
711 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_AddUserToRole", $content); | ||||
712 | 0 | 0 | return ""; | ||||
713 | } | ||||||
714 | |||||||
715 | sub ChangeRecordOwner($$$) | ||||||
716 | { | ||||||
717 | 0 | 0 | 0 | 0 | my($self, $QuickBaseDBid, $rid, $newowner); | ||
718 | |||||||
719 | 0 | 0 | my $content = " |
||||
720 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_ChangeRecordOwner", $content); | ||||
721 | 0 | 0 | return""; | ||||
722 | } | ||||||
723 | |||||||
724 | sub CreateTable($$) | ||||||
725 | { | ||||||
726 | 0 | 0 | 1 | 0 | my($self,$QuickBaseDBid, $pnoun) = @_; | ||
727 | 0 | 0 | my $content = " |
||||
728 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseDBid, "API_CreateTable", $content)->content; | ||||
729 | 0 | 0 | 0 | if($res =~ / |
|||
0 | |||||||
730 | 0 | 0 | return $1; | ||||
731 | } | ||||||
732 | elsif($res =~ / |
||||||
733 | 0 | 0 | return $1; | ||||
734 | } | ||||||
735 | else | ||||||
736 | { | ||||||
737 | 0 | 0 | return ""; | ||||
738 | } | ||||||
739 | } | ||||||
740 | |||||||
741 | sub DeleteDatabase($) | ||||||
742 | { | ||||||
743 | 0 | 0 | 0 | 0 | my($self,$QuickBaseDBid) = @_; | ||
744 | 0 | 0 | $self->PostAPIURL($QuickBaseDBid, "API_DeleteDatabase", ""); | ||||
745 | 0 | 0 | return ""; | ||||
746 | } | ||||||
747 | |||||||
748 | sub DeleteRecord($$) | ||||||
749 | { | ||||||
750 | 0 | 0 | 1 | 0 | my($self, $QuickBaseDBid, $rid) = @_; | ||
751 | |||||||
752 | 0 | 0 | my $content = " |
||||
753 | " |
||||||
754 | ""; | ||||||
755 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_DeleteRecord", $content)->content; | ||||
756 | } | ||||||
757 | |||||||
758 | sub FieldAddChoices($$@) | ||||||
759 | { | ||||||
760 | 0 | 0 | 0 | 0 | my($self,$QuickBaseDBid, $fid, @choices) = @_; | ||
761 | |||||||
762 | 0 | 0 | my $content = " |
||||
763 | 0 | 0 | my $choice; | ||||
764 | 0 | 0 | foreach $choice (@choices) | ||||
765 | { | ||||||
766 | 0 | 0 | $content .= " |
||||
767 | } | ||||||
768 | 0 | 0 | $content .= ""; | ||||
769 | |||||||
770 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseDBid, "API_FieldAddChoices", $content)->content; | ||||
771 | |||||||
772 | 0 | 0 | 0 | if($res =~ / |
|||
773 | 0 | 0 | return $1; | ||||
774 | } | ||||||
775 | else | ||||||
776 | { | ||||||
777 | 0 | 0 | return ""; | ||||
778 | } | ||||||
779 | } | ||||||
780 | |||||||
781 | sub FieldRemoveChoices($$@) | ||||||
782 | { | ||||||
783 | 0 | 0 | 0 | 0 | my($self,$QuickBaseDBid, $fid, @choices) = @_; | ||
784 | |||||||
785 | 0 | 0 | my $content = " |
||||
786 | 0 | 0 | my $choice; | ||||
787 | 0 | 0 | foreach $choice (@choices) | ||||
788 | { | ||||||
789 | 0 | 0 | $content .= " |
||||
790 | } | ||||||
791 | 0 | 0 | $content .= ""; | ||||
792 | |||||||
793 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseDBid, "API_FieldRemoveChoices", $content)->content; | ||||
794 | |||||||
795 | 0 | 0 | 0 | if($res =~ / |
|||
796 | 0 | 0 | return $1; | ||||
797 | } | ||||||
798 | else | ||||||
799 | { | ||||||
800 | 0 | 0 | return ""; | ||||
801 | } | ||||||
802 | } | ||||||
803 | |||||||
804 | sub GenAddRecordForm($%) | ||||||
805 | { | ||||||
806 | 0 | 0 | 0 | 0 | my($self,$QuickBaseDBid,%fields) = @_; | ||
807 | 0 | 0 | my $content = " |
||||
808 | 0 | 0 | my $field; | ||||
809 | 0 | 0 | foreach $field (keys %fields) | ||||
810 | { | ||||||
811 | 0 | 0 | $content .= " |
||||
812 | } | ||||||
813 | 0 | 0 | $content .= ""; | ||||
814 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_GenAddRecordForm", $content)->content; | ||||
815 | } | ||||||
816 | |||||||
817 | sub GenResultsTable($$$$$$$) | ||||||
818 | { | ||||||
819 | 0 | 0 | 0 | 0 | my($self, $QuickBaseDBid, $query, $clist, $slist, $jht, $jsa, $options) = @_; | ||
820 | 0 | 0 | my $content = " |
||||
821 | 0 | 0 | 0 | $content .= " |
|||
822 | 0 | 0 | 0 | $content .= " |
|||
823 | 0 | 0 | 0 | $content .= " |
|||
824 | 0 | 0 | 0 | $content .= " |
|||
825 | 0 | 0 | 0 | $content .= " |
|||
826 | 0 | 0 | 0 | $content .= " |
|||
827 | 0 | 0 | $content .= ""; | ||||
828 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_GenAddRecordForm", $content)->content; | ||||
829 | } | ||||||
830 | |||||||
831 | sub GetDBInfo($) | ||||||
832 | { | ||||||
833 | 0 | 0 | 0 | 0 | my($self,$QuickBaseDBid) = @_; | ||
834 | |||||||
835 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseDBid, "API_GetDBInfo", "")->content; | ||||
836 | |||||||
837 | 0 | 0 | my %dbInfo; | ||||
838 | 0 | 0 | 0 | if($res =~ / |
|||
839 | 0 | 0 | $dbInfo{"dbname"} = $1; | ||||
840 | } | ||||||
841 | 0 | 0 | 0 | if($res =~ / |
|||
842 | 0 | 0 | $dbInfo{"version"} = $1; | ||||
843 | } | ||||||
844 | 0 | 0 | 0 | if($res =~ / |
|||
845 | 0 | 0 | $dbInfo{"lastRecModTime"} = $1; | ||||
846 | } | ||||||
847 | 0 | 0 | 0 | if($res =~ / |
|||
848 | 0 | 0 | $dbInfo{"lastModifiedTime"} = $1; | ||||
849 | } | ||||||
850 | 0 | 0 | 0 | if($res =~ / |
|||
851 | 0 | 0 | $dbInfo{"createdTime"} = $1; | ||||
852 | } | ||||||
853 | 0 | 0 | 0 | if($res =~ / |
|||
854 | 0 | 0 | $dbInfo{"lastAccessTime"} = $1; | ||||
855 | } | ||||||
856 | 0 | 0 | 0 | if($res =~ / |
|||
857 | 0 | 0 | $dbInfo{"numRecords"} = $1; | ||||
858 | } | ||||||
859 | 0 | 0 | 0 | if($res =~ / |
|||
860 | 0 | 0 | $dbInfo{"mgrID"} = $1; | ||||
861 | } | ||||||
862 | 0 | 0 | 0 | if($res =~ / |
|||
863 | 0 | 0 | $dbInfo{"mgrName"} = $1; | ||||
864 | } | ||||||
865 | 0 | 0 | return %dbInfo; | ||||
866 | } | ||||||
867 | |||||||
868 | sub GetDBPage($$$) | ||||||
869 | { | ||||||
870 | 0 | 0 | 0 | 0 | my($self, $QuickBaseDBid, $pageid, $pagename) = @_; | ||
871 | |||||||
872 | 0 | 0 | my $content = " |
||||
873 | 0 | 0 | 0 | $content .= " |
|||
874 | 0 | 0 | 0 | $content .= " |
|||
875 | 0 | 0 | $content .= ""; | ||||
876 | |||||||
877 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_GetDBPage", $content)->content; | ||||
878 | } | ||||||
879 | |||||||
880 | sub GetDBvar($$) | ||||||
881 | { | ||||||
882 | 0 | 0 | 1 | 0 | my($self,$QuickBaseDBid, $varname) = @_; | ||
883 | 0 | 0 | my $content = " |
||||
884 | 0 | 0 | my $res = $self->PostAPIURL($QuickBaseDBid, "API_GetDBvar", $content)->content; | ||||
885 | 0 | 0 | 0 | if($res =~ / |
|||
886 | 0 | 0 | return $1; | ||||
887 | } | ||||||
888 | else | ||||||
889 | { | ||||||
890 | 0 | 0 | return ""; | ||||
891 | } | ||||||
892 | } | ||||||
893 | |||||||
894 | sub GetNumRecords($) | ||||||
895 | { | ||||||
896 | 0 | 0 | 0 | 0 | my($self,$QuickBaseDBid) = @_; | ||
897 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseDBid, "API_GetNumRecords", "")->content; | ||||
898 | 0 | 0 | 0 | if($res =~ / |
|||
899 | 0 | 0 | return $1; | ||||
900 | } | ||||||
901 | else | ||||||
902 | { | ||||||
903 | 0 | 0 | return ""; | ||||
904 | } | ||||||
905 | } | ||||||
906 | |||||||
907 | sub GetOneTimeTicket() | ||||||
908 | { | ||||||
909 | 0 | 0 | 1 | 0 | my($self) = @_; | ||
910 | 0 | 0 | my $res = $self->PostAPIURL ("main", "API_GetOneTimeTicket", "")->content; | ||||
911 | 0 | 0 | 0 | if($res =~ / |
|||
912 | 0 | 0 | return $1; | ||||
913 | } | ||||||
914 | else | ||||||
915 | { | ||||||
916 | 0 | 0 | return ""; | ||||
917 | } | ||||||
918 | } | ||||||
919 | |||||||
920 | sub GetRecord($$) | ||||||
921 | { | ||||||
922 | 0 | 0 | 1 | 0 | my($self, $QuickBaseDBid, $rid) = @_; | ||
923 | 0 | 0 | my $content; | ||||
924 | my @record; | ||||||
925 | 0 | 0 | my %record; | ||||
926 | 0 | 0 | my $true=1; | ||||
927 | 0 | 0 | my $false=0; | ||||
928 | 0 | 0 | my $isFieldname = $false; | ||||
929 | 0 | 0 | my $isFieldvalue = $false; | ||||
930 | 0 | 0 | my $isFieldprintable = $false; | ||||
931 | 0 | 0 | my ($fieldname, $fieldvalue, $fieldprintable) = ("","",""); | ||||
932 | |||||||
933 | 0 | 0 | $content = " |
||||
934 | " |
||||||
935 | ""; | ||||||
936 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseDBid, "API_GetRecordInfo", $content); | ||||
937 | 0 | 0 | my $recordXML = $res->content; | ||||
938 | 0 | 0 | $recordXML =~ s/ /\n/ig; |
||||
939 | 0 | 0 | @record = $recordXML =~ /<([A-Z\-\.0-9]+)>([^<]*)<\/\1>/isg; | ||||
940 | 0 | 0 | my $count = 0; | ||||
941 | 0 | 0 | my $record; | ||||
942 | |||||||
943 | 0 | 0 | foreach $record(@record){ | ||||
944 | 0 | 0 | 0 | unless ($count % 2) | |||
945 | { | ||||||
946 | 0 | 0 | 0 | if($record=~/^name$/) | |||
0 | |||||||
0 | |||||||
947 | { | ||||||
948 | 0 | 0 | $isFieldname = $true; | ||||
949 | 0 | 0 | 0 | if ($fieldname) | |||
950 | { | ||||||
951 | 0 | 0 | $fieldname = $self->xml_unescape($fieldname); | ||||
952 | 0 | 0 | 0 | if($fieldprintable){ | |||
0 | |||||||
953 | 0 | 0 | $record{$fieldname} = $self->xml_unescape($fieldprintable); | ||||
954 | }elsif($fieldvalue){ | ||||||
955 | 0 | 0 | $record{$fieldname} = $self->xml_unescape($fieldvalue); | ||||
956 | } | ||||||
957 | } | ||||||
958 | 0 | 0 | $fieldname=""; $fieldvalue=""; $fieldprintable=""; | ||||
0 | 0 | ||||||
0 | 0 | ||||||
959 | } | ||||||
960 | elsif($record=~/^value$/) | ||||||
961 | { | ||||||
962 | 0 | 0 | $isFieldvalue = $true; | ||||
963 | } | ||||||
964 | elsif($record=~/^printable$/) | ||||||
965 | { | ||||||
966 | 0 | 0 | $isFieldprintable = $true; | ||||
967 | } | ||||||
968 | } | ||||||
969 | else | ||||||
970 | { | ||||||
971 | 0 | 0 | 0 | if($isFieldname) | |||
0 | |||||||
0 | |||||||
972 | { | ||||||
973 | 0 | 0 | $fieldname = $record; | ||||
974 | 0 | 0 | $isFieldname = $false; | ||||
975 | } | ||||||
976 | elsif($isFieldvalue) | ||||||
977 | { | ||||||
978 | 0 | 0 | $fieldvalue = $record; | ||||
979 | 0 | 0 | $isFieldvalue = $false; | ||||
980 | } | ||||||
981 | elsif($isFieldprintable) | ||||||
982 | { | ||||||
983 | 0 | 0 | $fieldprintable = $record; | ||||
984 | 0 | 0 | $isFieldprintable = $false; | ||||
985 | } | ||||||
986 | } | ||||||
987 | 0 | 0 | $count++; | ||||
988 | } | ||||||
989 | 0 | 0 | 0 | if ($fieldname) | |||
990 | { | ||||||
991 | 0 | 0 | $fieldname = $self->xml_unescape($fieldname); | ||||
992 | 0 | 0 | 0 | if($fieldprintable){ | |||
0 | |||||||
993 | 0 | 0 | $record{$fieldname} = $self->xml_unescape($fieldprintable); | ||||
994 | }elsif($fieldvalue){ | ||||||
995 | 0 | 0 | $record{$fieldname} = $self->xml_unescape($fieldvalue); | ||||
996 | } | ||||||
997 | } | ||||||
998 | |||||||
999 | 0 | 0 | return %record; | ||||
1000 | } | ||||||
1001 | |||||||
1002 | sub GetRecordAsHTML($$$) | ||||||
1003 | { | ||||||
1004 | 0 | 0 | 0 | 0 | my($self, $QuickBaseDBid, $rid, $jht) = @_; | ||
1005 | 0 | 0 | my $content = " |
||||
1006 | 0 | 0 | 0 | $content .= " |
|||
1007 | 0 | 0 | $content .= ""; | ||||
1008 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_GetRecordAsHTML", $content)->content; | ||||
1009 | } | ||||||
1010 | |||||||
1011 | sub GetRecordInfo($$) | ||||||
1012 | { | ||||||
1013 | 0 | 0 | 0 | 0 | my($self, $QuickBaseDBid, $rid) = @_; | ||
1014 | 0 | 0 | my $content = " |
||||
1015 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_GetRecordInfo", $content)->content; | ||||
1016 | } | ||||||
1017 | |||||||
1018 | sub GetRoleInfo($) | ||||||
1019 | { | ||||||
1020 | 0 | 0 | 1 | 0 | my($self, $QuickBaseDBid) = @_; | ||
1021 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_GetRoleInfo", "")->content; | ||||
1022 | } | ||||||
1023 | |||||||
1024 | sub GetSchema | ||||||
1025 | { | ||||||
1026 | 0 | 0 | 0 | 0 | my($self,$QuickBaseDBid) = @_; | ||
1027 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_GetSchema", "")->content; | ||||
1028 | } | ||||||
1029 | |||||||
1030 | sub GetUserInfo($) | ||||||
1031 | { | ||||||
1032 | 0 | 0 | 1 | 0 | my($self,$email) = @_; | ||
1033 | |||||||
1034 | 0 | 0 | my $content = " |
||||
1035 | |||||||
1036 | 0 | 0 | my $res = $self->PostAPIURL ("main", "API_GetUserInfo", $content)->content; | ||||
1037 | |||||||
1038 | 0 | 0 | my %userInfo; | ||||
1039 | 0 | 0 | 0 | if($res =~ / |
|||
1040 | 0 | 0 | $userInfo{"login"} = $1 | ||||
1041 | } | ||||||
1042 | 0 | 0 | 0 | if($res =~ / |
|||
1043 | 0 | 0 | $userInfo{"name"} = $1 | ||||
1044 | } | ||||||
1045 | 0 | 0 | 0 | if($res =~ / |
|||
1046 | 0 | 0 | $userInfo{"firstName"} = $1 | ||||
1047 | } | ||||||
1048 | 0 | 0 | 0 | if($res =~ / |
|||
1049 | 0 | 0 | $userInfo{"lastName"} = $1 | ||||
1050 | } | ||||||
1051 | 0 | 0 | 0 | if($res =~ /id=\"(.*)\"/ ){ | |||
1052 | 0 | 0 | $userInfo{"id"} = $1 | ||||
1053 | } | ||||||
1054 | 0 | 0 | return %userInfo; | ||||
1055 | } | ||||||
1056 | |||||||
1057 | sub GetUserRole($$) | ||||||
1058 | { | ||||||
1059 | 0 | 0 | 1 | 0 | my($self,$QuickBaseDBid,$userid) = @_; | ||
1060 | 0 | 0 | my $content = " |
||||
1061 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_GetUserRole", $content)->content; | ||||
1062 | } | ||||||
1063 | |||||||
1064 | sub GrantedDBs() | ||||||
1065 | { | ||||||
1066 | 0 | 0 | 0 | 0 | my($self) = @_; | ||
1067 | 0 | 0 | $self->PostAPIURL ("main", "API_GrantedDBs", "")->content; | ||||
1068 | } | ||||||
1069 | |||||||
1070 | sub ProvisionUser($$$$$) | ||||||
1071 | { | ||||||
1072 | 0 | 0 | 1 | 0 | my($self, $QuickBaseDBid,$roleid, $email, $fname, $lname) = @_; | ||
1073 | 0 | 0 | my $content = " |
||||
1074 | 0 | 0 | $content .= " |
||||
1075 | 0 | 0 | $content .= " |
||||
1076 | 0 | 0 | $content .= " |
||||
1077 | 0 | 0 | $content .= " |
||||
1078 | 0 | 0 | $content .= ""; | ||||
1079 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseDBid, "API_ProvisionUser", $content)->content; | ||||
1080 | 0 | 0 | 0 | if($res =~ / |
|||
1081 | 0 | 0 | return $1; | ||||
1082 | } | ||||||
1083 | else | ||||||
1084 | { | ||||||
1085 | 0 | 0 | return ""; | ||||
1086 | } | ||||||
1087 | } | ||||||
1088 | |||||||
1089 | sub RemoveUserFromRole($$$) | ||||||
1090 | { | ||||||
1091 | 0 | 0 | 1 | 0 | my($self, $QuickBaseDBid, $userid, $roleid) = @_; | ||
1092 | 0 | 0 | my $content = " |
||||
1093 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_RemoveUserFromRole", $content); | ||||
1094 | 0 | 0 | return ""; | ||||
1095 | } | ||||||
1096 | |||||||
1097 | sub RenameApp($$) | ||||||
1098 | { | ||||||
1099 | 0 | 0 | 1 | 0 | my($self,$QuickBaseDBid,$newappname) = @_; | ||
1100 | 0 | 0 | my $content = " |
||||
1101 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_RenameApp", $content); | ||||
1102 | 0 | 0 | return ""; | ||||
1103 | } | ||||||
1104 | |||||||
1105 | sub SendInvitation($$) | ||||||
1106 | { | ||||||
1107 | 0 | 0 | 1 | 0 | my($self, $QuickBaseDBid, $userid) = @_; | ||
1108 | 0 | 0 | my $content = " |
||||
1109 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_SendInvitation", $content); | ||||
1110 | 0 | 0 | return ""; | ||||
1111 | } | ||||||
1112 | |||||||
1113 | sub SetDBvar($$$) | ||||||
1114 | { | ||||||
1115 | 0 | 0 | 1 | 0 | my($self, $QuickBaseDBid, $varname, $value) = @_; | ||
1116 | 0 | 0 | my $content = " |
||||
1117 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_SetDBvar", $content); | ||||
1118 | 0 | 0 | return ""; | ||||
1119 | } | ||||||
1120 | |||||||
1121 | sub UserRoles($) | ||||||
1122 | { | ||||||
1123 | 0 | 0 | 1 | 0 | my($self,$QuickBaseDBid) = @_; | ||
1124 | 0 | 0 | $self->PostAPIURL ($QuickBaseDBid, "API_UserRoles", "")->content; | ||||
1125 | } | ||||||
1126 | |||||||
1127 | sub GetURL($$) | ||||||
1128 | { | ||||||
1129 | 0 | 0 | 0 | 0 | my($self, $QuickBaseDBid, $action) = @_; | ||
1130 | 0 | 0 | my $error; | ||||
1131 | |||||||
1132 | 0 | 0 | 0 | unless( $action =~ /^act=API_|\&act=API_/i) | |||
1133 | { | ||||||
1134 | 0 | 0 | $self->{'error'} = "1"; | ||||
1135 | 0 | 0 | $self->{'errortext'} = "Error: You're using a QuickBase URL that is not part of the HTTP API. ". $action . "\n" | ||||
1136 | . "Please use only actions that start with 'API_' i.e. act=API_GetNumRecords.\n" | ||||||
1137 | . "Please refer to the QuickBase HTTP API documentation."; | ||||||
1138 | 0 | 0 | return $self->{'errortext'}; | ||||
1139 | } | ||||||
1140 | |||||||
1141 | |||||||
1142 | 0 | 0 | my $ua = new LWP::UserAgent; | ||||
1143 | 0 | 0 | $ua->agent("QuickBasePerlAPI/2.0"); | ||||
1144 | 0 | 0 | 0 | if ($self->{'proxy'}){ | |||
1145 | 0 | 0 | $ua->proxy(['http','https'], $self->{'proxy'}); | ||||
1146 | } | ||||||
1147 | 0 | 0 | my $req = new HTTP::Request; | ||||
1148 | 0 | 0 | $req->method("GET"); | ||||
1149 | 0 | 0 | $req->uri($self->URLprefix()."/$QuickBaseDBid?$action"); | ||||
1150 | 0 | 0 | 0 | unless ($self->{'ticket'}) | |||
1151 | { | ||||||
1152 | 0 | 0 | $self->{'ticket'}=$self->getTicket($self->{'username'},$self->{'password'}); | ||||
1153 | } | ||||||
1154 | 0 | 0 | $req->header('Cookie' => "TICKET=$self->{'ticket'};"); | ||||
1155 | 0 | 0 | $req->header('Accept' => 'text/html'); | ||||
1156 | # send request | ||||||
1157 | 0 | 0 | my $res = $ua->request($req); | ||||
1158 | |||||||
1159 | |||||||
1160 | # check the outcome | ||||||
1161 | 0 | 0 | 0 | if ($res->is_error) { | |||
1162 | 0 | 0 | $self->{'error'} = $res->code; | ||||
1163 | 0 | 0 | $self->{'errortext'} =$res->message; | ||||
1164 | 0 | 0 | return "Error: " . $res->code . " " . $res->message; | ||||
1165 | } | ||||||
1166 | 0 | 0 | return $res->content; | ||||
1167 | } | ||||||
1168 | |||||||
1169 | sub GetFile($$$$) | ||||||
1170 | { | ||||||
1171 | 0 | 0 | 1 | 0 | my($self, $QuickBaseDBid, $filename, $rid, $fid) = @_; | ||
1172 | 0 | 0 | my $error; | ||||
1173 | 0 | 0 | my $prefix= $self->URLprefix(); | ||||
1174 | 0 | 0 | $prefix =~ s/\/db$/\/up/; | ||||
1175 | 0 | 0 | my $ua = new LWP::UserAgent; | ||||
1176 | 0 | 0 | $ua->agent("QuickBasePerlAPI/1.0"); | ||||
1177 | 0 | 0 | 0 | if ($self->{'proxy'}){ | |||
1178 | 0 | 0 | $ua->proxy(['http','https'], $self->{'proxy'}); | ||||
1179 | } | ||||||
1180 | 0 | 0 | my $req = new HTTP::Request; | ||||
1181 | 0 | 0 | $req->method("GET"); | ||||
1182 | |||||||
1183 | 0 | 0 | $req->uri($prefix."/$QuickBaseDBid/g/r".$self->encode32($rid)."/e".$self->encode32($fid)."/"); | ||||
1184 | |||||||
1185 | |||||||
1186 | 0 | 0 | 0 | unless ($self->{'ticket'}) | |||
1187 | { | ||||||
1188 | 0 | 0 | $self->{'ticket'}=$self->getTicket($self->{'username'},$self->{'password'}); | ||||
1189 | } | ||||||
1190 | 0 | 0 | $req->header('Accept' => '*/*'); | ||||
1191 | 0 | 0 | $req->header('Cookie' => "TICKET=$self->{'ticket'};"); | ||||
1192 | |||||||
1193 | # send request | ||||||
1194 | 0 | 0 | my $res = $ua->request($req); | ||||
1195 | |||||||
1196 | # check the outcome | ||||||
1197 | 0 | 0 | 0 | if ($res->is_error) { | |||
1198 | 0 | 0 | $self->{'error'} = $res->code; | ||||
1199 | 0 | 0 | $self->{'errortext'} =$res->message; | ||||
1200 | 0 | 0 | return ("Error: " . $res->code . " " . $res->message, $res->headers); | ||||
1201 | } | ||||||
1202 | 0 | 0 | return ($res->content, $res->headers); | ||||
1203 | } | ||||||
1204 | |||||||
1205 | sub PostURL($$$$) | ||||||
1206 | { | ||||||
1207 | 0 | 0 | 0 | 0 | my $self = shift; | ||
1208 | 0 | 0 | my $QuickBaseDBid = shift; | ||||
1209 | 0 | 0 | my $action = shift; | ||||
1210 | 0 | 0 | my $content = shift; | ||||
1211 | 0 | 0 | 0 | my $content_type = shift || 'application/x-www-form-urlencoded'; | |||
1212 | |||||||
1213 | 0 | 0 | my $ua = new LWP::UserAgent; | ||||
1214 | 0 | 0 | 0 | if ($self->{'proxy'}){ | |||
1215 | 0 | 0 | $ua->proxy(['http','https'], $self->{'proxy'}); | ||||
1216 | } | ||||||
1217 | 0 | 0 | $ua->agent("QuickBasePerlAPI/1.0"); | ||||
1218 | 0 | 0 | my $req = new HTTP::Request; | ||||
1219 | 0 | 0 | $req->method("POST"); | ||||
1220 | 0 | 0 | $req->uri($self->URLprefix."/$QuickBaseDBid?$action"); | ||||
1221 | 0 | 0 | 0 | unless ($self->{'ticket'}) | |||
1222 | { | ||||||
1223 | 0 | 0 | $self->{'ticket'}=$self->getTicket($self->{'username'},$self->{'password'}); | ||||
1224 | } | ||||||
1225 | 0 | 0 | $req->header('Cookie' => "TICKET=$self->{'ticket'};"); | ||||
1226 | 0 | 0 | $req->content_type($content_type); | ||||
1227 | |||||||
1228 | #This is where we post the info for the new record | ||||||
1229 | |||||||
1230 | 0 | 0 | $req->content($content); | ||||
1231 | 0 | 0 | my $res = $ua->request($req); | ||||
1232 | 0 | 0 | 0 | if($res->is_error()){ | |||
1233 | 0 | 0 | $self->{'error'} = $res->code; | ||||
1234 | 0 | 0 | $self->{'errortext'} =$res->message; | ||||
1235 | 0 | 0 | return $res; | ||||
1236 | } | ||||||
1237 | 0 | 0 | $res->content =~ / |
||||
1238 | 0 | 0 | $self->{'error'} = $1; | ||||
1239 | 0 | 0 | $self->{'errortext'} = $2; | ||||
1240 | 0 | 0 | 0 | if ($res->content =~ / |
|||
1241 | { | ||||||
1242 | 0 | 0 | $self->{'errortext'} = $1; | ||||
1243 | } | ||||||
1244 | 0 | 0 | return $res; | ||||
1245 | } | ||||||
1246 | |||||||
1247 | sub PostAPIURL($$$) | ||||||
1248 | { | ||||||
1249 | 1 | 1 | 0 | 3 | my($self, $QuickBaseDBid, $action, $content) = @_; | ||
1250 | 1 | 8 | my $ua = new LWP::UserAgent; | ||||
1251 | 1 | 4737 | $ua->agent("QuickBasePerlAPI/2.0"); | ||||
1252 | 1 | 50 | 85 | if ($self->{'proxy'}){ | |||
1253 | 0 | 0 | $ua->proxy(['http','https'], $self->{'proxy'}); | ||||
1254 | } | ||||||
1255 | 1 | 11 | my $req = new HTTP::Request; | ||||
1256 | 1 | 73 | $req->method('POST'); | ||||
1257 | 1 | 50 | 12 | if($self->{'realmhost'}) | |||
1258 | { | ||||||
1259 | 0 | 0 | $req->uri($self->URLprefix()."/$QuickBaseDBid?realmhost=$self->{'realmhost'}"); | ||||
1260 | } | ||||||
1261 | else | ||||||
1262 | { | ||||||
1263 | 1 | 6 | $req->uri($self->URLprefix()."/$QuickBaseDBid"); | ||||
1264 | } | ||||||
1265 | |||||||
1266 | 1 | 28545 | $req->content_type('text/xml'); | ||||
1267 | 1 | 61 | $req->header('QUICKBASE-ACTION' => "$action"); | ||||
1268 | |||||||
1269 | 1 | 50 | 33 | 98 | if ($self->{'apptoken'} ne "" && $self->{'credentials'} !~ / |
||
1270 | { | ||||||
1271 | 0 | 0 | $self->{'credentials'} .= " |
||||
1272 | } | ||||||
1273 | |||||||
1274 | 1 | 50 | 0 | 8 | if($content =~ /^ |
||
0 | |||||||
1275 | { | ||||||
1276 | 1 | 9 | $content =~s/^ |
||||
1277 | } | ||||||
1278 | elsif($content eq "" || !defined($content)) | ||||||
1279 | { | ||||||
1280 | 0 | 0 | $content =" |
||||
1281 | } | ||||||
1282 | 1 | 50 | 7 | if($content =~ /^ |
|||
1283 | { | ||||||
1284 | 1 | 4 | $content = "" . $content; | ||||
1285 | } | ||||||
1286 | 1 | 2 | my $res; | ||||
1287 | 1 | 50 | 5 | if ($self->{'ticket'}) | |||
1288 | { | ||||||
1289 | 0 | 0 | $req->header('Cookie' => "TICKET=$self->{'ticket'};"); | ||||
1290 | } | ||||||
1291 | |||||||
1292 | 1 | 9 | $req->content($content); | ||||
1293 | 1 | 28 | $res = $ua->request($req); | ||||
1294 | 1 | 50 | 1226087 | if($res->is_error()){ | |||
1295 | 0 | 0 | $self->{'error'} = $res->code; | ||||
1296 | 0 | 0 | $self->{'errortext'} =$res->message; | ||||
1297 | 0 | 0 | return $res; | ||||
1298 | } | ||||||
1299 | 1 | 50 | 33 | 23 | if (defined ($res->header('Set-Cookie')) && $res->header('Set-Cookie') =~ /TICKET=(.+?);/) | ||
50 | |||||||
1300 | { | ||||||
1301 | 0 | 0 | $self->{'ticket'} = $1; | ||||
1302 | 0 | 0 | $self->{'credentials'} = " |
||||
1303 | } | ||||||
1304 | elsif ($res->content =~ / |
||||||
1305 | { | ||||||
1306 | 0 | 0 | $self->{'ticket'} = $1; | ||||
1307 | 0 | 0 | $self->{'credentials'} = " |
||||
1308 | } | ||||||
1309 | |||||||
1310 | 1 | 125 | $res->content =~ / |
||||
1311 | 1 | 57 | $self->{'error'} = $1; | ||||
1312 | 1 | 5 | $self->{'errortext'} = $2; | ||||
1313 | 1 | 50 | 6 | if ($res->content =~ / |
|||
1314 | { | ||||||
1315 | 1 | 20 | $self->{'errortext'} = $1; | ||||
1316 | } | ||||||
1317 | 1 | 50 | 5 | if($self->{'error'} eq '11') | |||
1318 | { | ||||||
1319 | 0 | 0 | $self->{'errortext'} .= "\nXML request:\n" . $content; | ||||
1320 | } | ||||||
1321 | 1 | 644 | return $res; | ||||
1322 | } | ||||||
1323 | |||||||
1324 | sub getoneBaseIDbyName($) | ||||||
1325 | { | ||||||
1326 | 0 | 0 | 0 | 0 | my ($self, $dbName)= @_; | ||
1327 | 0 | 0 | return $self->getIDbyName($dbName); | ||||
1328 | } | ||||||
1329 | |||||||
1330 | sub getIDbyName($) | ||||||
1331 | { | ||||||
1332 | 1 | 1 | 1 | 9 | my ($self, $dbName)= @_; | ||
1333 | 1 | 2 | my $content; | ||||
1334 | 1 | 3 | $content = " |
||||
1335 | 1 | 5 | my $res = $self->PostAPIURL ("main", "API_FindDBByName", $content); | ||||
1336 | |||||||
1337 | 1 | 50 | 8 | if($res->content =~ / |
|||
1338 | 0 | 0 | return $1; | ||||
1339 | } | ||||||
1340 | else | ||||||
1341 | { | ||||||
1342 | 1 | 68 | return ""; | ||||
1343 | } | ||||||
1344 | } | ||||||
1345 | |||||||
1346 | sub FindDBByName($) | ||||||
1347 | { | ||||||
1348 | 0 | 0 | 0 | 0 | my ($self, $dbName)= @_; | ||
1349 | 0 | 0 | $self->getIDbyName($dbName); | ||||
1350 | } | ||||||
1351 | |||||||
1352 | sub cloneDatabase ($$$) | ||||||
1353 | { | ||||||
1354 | 0 | 0 | 1 | 0 | my ($self, $QuickBaseID, $Name, $Description)=@_; | ||
1355 | 0 | 0 | my $content; | ||||
1356 | 0 | 0 | $content = " |
||||
1357 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseID, "API_CloneDatabase", $content); | ||||
1358 | 0 | 0 | 0 | if($res->content =~ / |
|||
1359 | 0 | 0 | return $1; | ||||
1360 | } | ||||||
1361 | else | ||||||
1362 | { | ||||||
1363 | 0 | 0 | return ""; | ||||
1364 | } | ||||||
1365 | } | ||||||
1366 | |||||||
1367 | sub createDatabase ($$) | ||||||
1368 | { | ||||||
1369 | 0 | 0 | 1 | 0 | my ($self, $Name, $Description)=@_; | ||
1370 | 0 | 0 | my $content; | ||||
1371 | 0 | 0 | $content = " |
||||
1372 | 0 | 0 | my $res = $self->PostAPIURL ("main", "API_CreateDatabase", $content); | ||||
1373 | 0 | 0 | 0 | if($res->content =~ / |
|||
1374 | 0 | 0 | my $dbid = $1; | ||||
1375 | 0 | 0 | 0 | if($res->content =~ / |
|||
1376 | 0 | 0 | return ($dbid,$1); | ||||
1377 | } | ||||||
1378 | else | ||||||
1379 | { | ||||||
1380 | 0 | 0 | return $1; | ||||
1381 | } | ||||||
1382 | } | ||||||
1383 | else | ||||||
1384 | { | ||||||
1385 | 0 | 0 | return ""; | ||||
1386 | } | ||||||
1387 | } | ||||||
1388 | |||||||
1389 | sub addField ($$$$) | ||||||
1390 | { | ||||||
1391 | 0 | 0 | 1 | 0 | my ($self, $QuickBaseID, $label, $type, $mode)=@_; | ||
1392 | 0 | 0 | my $content; | ||||
1393 | 0 | 0 | $content = " |
||||
1394 | 0 | 0 | 0 | if ($mode) | |||
1395 | { | ||||||
1396 | 0 | 0 | $content .= " |
||||
1397 | } | ||||||
1398 | else | ||||||
1399 | { | ||||||
1400 | 0 | 0 | $content .= ""; | ||||
1401 | } | ||||||
1402 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseID, "API_AddField", $content); | ||||
1403 | 0 | 0 | 0 | if($res->content =~ / |
|||
1404 | 0 | 0 | return $1; | ||||
1405 | } | ||||||
1406 | else | ||||||
1407 | { | ||||||
1408 | 0 | 0 | return ""; | ||||
1409 | } | ||||||
1410 | } | ||||||
1411 | |||||||
1412 | sub deleteField ($$) | ||||||
1413 | { | ||||||
1414 | 0 | 0 | 1 | 0 | my ($self, $QuickBaseID, $fid)=@_; | ||
1415 | 0 | 0 | my $content; | ||||
1416 | 0 | 0 | $content = " |
||||
1417 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseID, "API_DeleteField", $content); | ||||
1418 | } | ||||||
1419 | |||||||
1420 | sub setFieldProperties ($$%) | ||||||
1421 | { | ||||||
1422 | 0 | 0 | 1 | 0 | my ($self, $QuickBaseID, $fid, %properties)=@_; | ||
1423 | 0 | 0 | my $content; | ||||
1424 | my $property; | ||||||
1425 | 0 | 0 | my $value; | ||||
1426 | 0 | 0 | $content = " |
||||
1427 | 0 | 0 | foreach $property (keys %properties) | ||||
1428 | { | ||||||
1429 | 0 | 0 | $content .= "<$property>".$self->xml_escape($properties{$property})."$property>"; | ||||
1430 | } | ||||||
1431 | 0 | 0 | $content .= ""; | ||||
1432 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseID, "API_SetFieldProperties", $content); | ||||
1433 | 0 | 0 | 0 | if($res->content =~ / |
|||
1434 | 0 | 0 | return $1; | ||||
1435 | } | ||||||
1436 | else | ||||||
1437 | { | ||||||
1438 | 0 | 0 | return ""; | ||||
1439 | } | ||||||
1440 | } | ||||||
1441 | |||||||
1442 | |||||||
1443 | sub purgeRecords ($$) | ||||||
1444 | { | ||||||
1445 | 0 | 0 | 0 | 0 | my ($self, $QuickBaseID, $query)=@_; | ||
1446 | |||||||
1447 | 0 | 0 | my $content; | ||||
1448 | 0 | 0 | 0 | if ($query =~ /^\{.*\}$/) | |||
0 | |||||||
1449 | { | ||||||
1450 | 0 | 0 | $content = " |
||||
1451 | } | ||||||
1452 | elsif ($query =~ /^\d+$/) | ||||||
1453 | { | ||||||
1454 | 0 | 0 | $content = " |
||||
1455 | } | ||||||
1456 | else | ||||||
1457 | { | ||||||
1458 | 0 | 0 | $content = " |
||||
1459 | } | ||||||
1460 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseID, "API_PurgeRecords", $content); | ||||
1461 | 0 | 0 | 0 | if($res->content =~ / |
|||
1462 | 0 | 0 | return $1; | ||||
1463 | } | ||||||
1464 | else | ||||||
1465 | { | ||||||
1466 | 0 | 0 | return ""; | ||||
1467 | } | ||||||
1468 | } | ||||||
1469 | |||||||
1470 | sub DoQuery ($$$$$) | ||||||
1471 | { | ||||||
1472 | 0 | 0 | 0 | 0 | my ($self, $QuickBaseID, $query, $clist, $slist, $options)=@_; | ||
1473 | 0 | 0 | return $self->doQuery ($QuickBaseID, $query, $clist, $slist, $options); | ||||
1474 | } | ||||||
1475 | |||||||
1476 | sub doQuery ($$$$$) | ||||||
1477 | { | ||||||
1478 | 0 | 0 | 1 | 0 | my ($self, $QuickBaseID, $query, $clist, $slist, $options)=@_; | ||
1479 | |||||||
1480 | 0 | 0 | my $content; | ||||
1481 | my $result; | ||||||
1482 | 0 | 0 | my @result; | ||||
1483 | 0 | 0 | my $record={}; | ||||
1484 | 0 | 0 | my $field; | ||||
1485 | my @labels; | ||||||
1486 | 0 | 0 | my $fieldvalue; | ||||
1487 | 0 | 0 | my $counter = 0; | ||||
1488 | 0 | 0 | my $numfields; | ||||
1489 | my $i; | ||||||
1490 | |||||||
1491 | 0 | 0 | 0 | if ($query =~ /^\{.*\}$/) | |||
0 | |||||||
1492 | { | ||||||
1493 | 0 | 0 | $content = " |
||||
1494 | } | ||||||
1495 | elsif ($query =~ /^\d+$/) | ||||||
1496 | { | ||||||
1497 | 0 | 0 | $content = " |
||||
1498 | } | ||||||
1499 | else | ||||||
1500 | { | ||||||
1501 | 0 | 0 | $content = " |
||||
1502 | } | ||||||
1503 | |||||||
1504 | 0 | 0 | $content .= " |
||||
1505 | 0 | 0 | $result = $self->PostAPIURL ($QuickBaseID, "API_DoQuery", $content)->content; | ||||
1506 | 0 | 0 | @labels = $result =~ / | ||||
1507 | 0 | 0 | $numfields = @labels; | ||||
1508 | 0 | 0 | for $i (0 .. $numfields) | ||||
1509 | { | ||||||
1510 | 0 | 0 | $labels[$i] = $self->xml_unescape($labels[$i]); | ||||
1511 | } | ||||||
1512 | 0 | 0 | foreach $fieldvalue ( $result =~ / |
||||
1513 | { | ||||||
1514 | 0 | 0 | 0 | unless ($counter % $numfields) | |||
1515 | { | ||||||
1516 | 0 | 0 | 0 | if ($counter > 0) | |||
1517 | { | ||||||
1518 | 0 | 0 | push (@result, $record); | ||||
1519 | } | ||||||
1520 | 0 | 0 | $record={}; | ||||
1521 | } | ||||||
1522 | 0 | 0 | $record->{$labels[$counter % $numfields]}=$self->xml_unescape($fieldvalue); | ||||
1523 | 0 | 0 | $counter++; | ||||
1524 | } | ||||||
1525 | 0 | 0 | 0 | if ($counter) | |||
1526 | { | ||||||
1527 | 0 | 0 | push (@result, $record); | ||||
1528 | } | ||||||
1529 | 0 | 0 | return @result; | ||||
1530 | } | ||||||
1531 | |||||||
1532 | sub getCompleteCSV ($) | ||||||
1533 | { | ||||||
1534 | 0 | 0 | 1 | 0 | my ($self, $QuickBaseID)=@_; | ||
1535 | 0 | 0 | my $content; | ||||
1536 | 0 | 0 | my $clist=""; | ||||
1537 | 0 | 0 | my $fid; | ||||
1538 | my @ids; | ||||||
1539 | 0 | 0 | my $result; | ||||
1540 | 0 | 0 | $result = $self->PostAPIURL ($QuickBaseID, "API_GetSchema", " |
||||
1541 | 0 | 0 | @ids = $result =~ / |
||||
1542 | 0 | 0 | foreach $fid (@ids){ | ||||
1543 | 0 | 0 | $clist .= "$fid."; | ||||
1544 | } | ||||||
1545 | 0 | 0 | $content .= " |
||||
1546 | 0 | 0 | return $self->PostAPIURL ($QuickBaseID, "API_GenResultsTable", $content)->content; | ||||
1547 | } | ||||||
1548 | |||||||
1549 | sub GetRIDs ($) | ||||||
1550 | { | ||||||
1551 | 0 | 0 | 1 | 0 | my ($self, $QuickBaseID) = @_; | ||
1552 | 0 | 0 | my $content=" |
||||
1553 | 0 | 0 | my $fid; | ||||
1554 | 0 | 0 | $self->PostAPIURL($QuickBaseID,"API_GetSchema",$content)->content =~ / | ||||
1555 | 0 | 0 | $fid = $1; | ||||
1556 | 0 | 0 | $content = " |
||||
1557 | 0 | 0 | my @rids = $self->PostAPIURL($QuickBaseID,"API_DoQuery",$content)->content =~ / |
||||
1558 | 0 | 0 | return @rids; | ||||
1559 | } | ||||||
1560 | |||||||
1561 | sub EditRecord ($$%) | ||||||
1562 | { | ||||||
1563 | 0 | 0 | 1 | 0 | my ($self, $QuickBaseID, $rid, %recorddata) = @_; | ||
1564 | 0 | 0 | my $name; | ||||
1565 | 0 | 0 | my $content = " |
||||
1566 | 0 | 0 | my $tag; | ||||
1567 | |||||||
1568 | 0 | 0 | foreach $name (keys(%recorddata)) | ||||
1569 | { | ||||||
1570 | 0 | 0 | $tag=$name; | ||||
1571 | 0 | 0 | $tag =~tr/A-Z/a-z/; | ||||
1572 | 0 | 0 | $tag=~s/[^a-z0-9]/_/g; | ||||
1573 | 0 | 0 | $content .= $self->createFieldXML($tag, $recorddata{$name}); | ||||
1574 | } | ||||||
1575 | 0 | 0 | $content .= ""; | ||||
1576 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseID, "API_EditRecord", $content); | ||||
1577 | 0 | 0 | return $res->content; | ||||
1578 | } | ||||||
1579 | |||||||
1580 | sub EditRecordWithUpdateID ($$$%) | ||||||
1581 | { | ||||||
1582 | 0 | 0 | 0 | 0 | my ($self, $QuickBaseID, $rid, $update_id, %recorddata) = @_; | ||
1583 | 0 | 0 | my $name; | ||||
1584 | 0 | 0 | my $content = " |
||||
1585 | 0 | 0 | my ($value, $tag); | ||||
1586 | 0 | 0 | $content .= " |
||||
1587 | |||||||
1588 | |||||||
1589 | 0 | 0 | foreach $name (keys(%recorddata)) | ||||
1590 | { | ||||||
1591 | 0 | 0 | $value = $recorddata{$name}; | ||||
1592 | 0 | 0 | $value = $self->xml_escape($value); | ||||
1593 | 0 | 0 | $tag=$name; | ||||
1594 | 0 | 0 | $tag =~tr/A-Z/a-z/; | ||||
1595 | 0 | 0 | $tag=~s/[^a-z0-9]/_/g; | ||||
1596 | |||||||
1597 | 0 | 0 | $content .= $self->createFieldXML($tag, $recorddata{$name}); | ||||
1598 | } | ||||||
1599 | |||||||
1600 | 0 | 0 | $content .= ""; | ||||
1601 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseID, "API_EditRecord", $content); | ||||
1602 | 0 | 0 | return $res->content; | ||||
1603 | } | ||||||
1604 | |||||||
1605 | |||||||
1606 | sub ImportFromCSV ($$$$) | ||||||
1607 | { | ||||||
1608 | 0 | 0 | 0 | 0 | my ($self, $QuickBaseID, $CSVData, $clist, $skipfirst) = @_; | ||
1609 | 0 | 0 | my $content = " |
||||
1610 | |||||||
1611 | 0 | 0 | $content .= " |
||||
1612 | 0 | 0 | 0 | if($skipfirst) | |||
1613 | { | ||||||
1614 | 0 | 0 | $content .= " |
||||
1615 | } | ||||||
1616 | 0 | 0 | $content .= ""; | ||||
1617 | 0 | 0 | my $res = $self->PostAPIURL ($QuickBaseID, "API_ImportFromCSV", $content); | ||||
1618 | 0 | 0 | return $res->content; | ||||
1619 | } | ||||||
1620 | |||||||
1621 | |||||||
1622 | sub GetNextField ($$$$) | ||||||
1623 | { | ||||||
1624 | 0 | 0 | 0 | 0 | my ($self, $datapointer, $delim, $offsetpointer, $fieldpointer)=@_; | ||
1625 | 0 | 0 | my $BEFORE_FIELD=0; | ||||
1626 | 0 | 0 | my $IN_QUOTED_FIELD=1; | ||||
1627 | 0 | 0 | my $IN_UNQUOTED_FIELD=2; | ||||
1628 | 0 | 0 | my $DOUBLE_QUOTE_TEST=3; | ||||
1629 | 0 | 0 | my $c=""; | ||||
1630 | 0 | 0 | my $state = $BEFORE_FIELD; | ||||
1631 | 0 | 0 | my $p = $$offsetpointer; | ||||
1632 | 0 | 0 | my $endofdata = length($$datapointer); | ||||
1633 | 0 | 0 | my $false=0; | ||||
1634 | 0 | 0 | my $true=1; | ||||
1635 | |||||||
1636 | |||||||
1637 | 0 | 0 | $$fieldpointer = ""; | ||||
1638 | |||||||
1639 | 0 | 0 | while ($true) | ||||
1640 | { | ||||||
1641 | 0 | 0 | 0 | if ($p >= $endofdata) | |||
1642 | { | ||||||
1643 | # File, line and field are done | ||||||
1644 | 0 | 0 | $$offsetpointer = $p; | ||||
1645 | 0 | 0 | return $false; | ||||
1646 | } | ||||||
1647 | |||||||
1648 | 0 | 0 | $c = substr($$datapointer, $p, 1); | ||||
1649 | |||||||
1650 | 0 | 0 | 0 | if($state == $DOUBLE_QUOTE_TEST) | |||
0 | |||||||
0 | |||||||
0 | |||||||
1651 | { | ||||||
1652 | # These checks are ordered by likelihood */ | ||||||
1653 | 0 | 0 | 0 | 0 | if ($c eq $delim) | ||
0 | |||||||
0 | |||||||
1654 | { | ||||||
1655 | # Field is done; delimiter means more to come | ||||||
1656 | 0 | 0 | $$offsetpointer = $p + 1; | ||||
1657 | 0 | 0 | return $true; | ||||
1658 | } | ||||||
1659 | elsif ($c eq "\n" || $c eq "\r") | ||||||
1660 | { | ||||||
1661 | # Line and field are done | ||||||
1662 | 0 | 0 | $$offsetpointer = $p + 1; | ||||
1663 | 0 | 0 | return $false; | ||||
1664 | } | ||||||
1665 | elsif ($c eq '"') | ||||||
1666 | { | ||||||
1667 | # It is doubled, so append one quote | ||||||
1668 | 0 | 0 | $$fieldpointer .= '"'; | ||||
1669 | 0 | 0 | $p++; | ||||
1670 | 0 | 0 | $state = $IN_QUOTED_FIELD; | ||||
1671 | } | ||||||
1672 | else | ||||||
1673 | { | ||||||
1674 | # !!! Shouldn't have anything else after an end quote! | ||||||
1675 | # But do something reasonable to recover: go into unquoted mode | ||||||
1676 | 0 | 0 | $$fieldpointer .= $c; | ||||
1677 | 0 | 0 | $p++; | ||||
1678 | 0 | 0 | $state = $IN_UNQUOTED_FIELD; | ||||
1679 | } | ||||||
1680 | } | ||||||
1681 | elsif($state == $BEFORE_FIELD) | ||||||
1682 | { | ||||||
1683 | # These checks are ordered by likelihood */ | ||||||
1684 | 0 | 0 | 0 | 0 | if ($c eq $delim) | ||
0 | |||||||
0 | |||||||
0 | |||||||
1685 | { | ||||||
1686 | # Field is blank; delimiter means more to come | ||||||
1687 | 0 | 0 | $$offsetpointer = $p + 1; | ||||
1688 | 0 | 0 | return $true; | ||||
1689 | } | ||||||
1690 | elsif ($c eq '"') | ||||||
1691 | { | ||||||
1692 | # Found the beginning of a quoted field | ||||||
1693 | 0 | 0 | $p++; | ||||
1694 | 0 | 0 | $state = $IN_QUOTED_FIELD; | ||||
1695 | } | ||||||
1696 | elsif ($c eq "\n" || $c eq "\r") | ||||||
1697 | { | ||||||
1698 | # Field is blank and line is done | ||||||
1699 | 0 | 0 | $$offsetpointer = $p + 1; | ||||
1700 | 0 | 0 | return $false; | ||||
1701 | } | ||||||
1702 | elsif ($c eq ' ') | ||||||
1703 | { | ||||||
1704 | # Ignore leading spaces | ||||||
1705 | 0 | 0 | $p++; | ||||
1706 | } | ||||||
1707 | else | ||||||
1708 | { | ||||||
1709 | # Found some other character, beginning an unquoted field | ||||||
1710 | 0 | 0 | $$fieldpointer.=$c; | ||||
1711 | 0 | 0 | $p++; | ||||
1712 | 0 | 0 | $state = $IN_UNQUOTED_FIELD; | ||||
1713 | } | ||||||
1714 | } | ||||||
1715 | elsif ($state == $IN_UNQUOTED_FIELD) | ||||||
1716 | { | ||||||
1717 | # These checks are ordered by likelihood */ | ||||||
1718 | 0 | 0 | 0 | 0 | if ($c eq $delim) | ||
0 | |||||||
1719 | { | ||||||
1720 | # Field is done; delimiter means more to come | ||||||
1721 | 0 | 0 | $$offsetpointer = $p + 1; | ||||
1722 | 0 | 0 | return $true; | ||||
1723 | } | ||||||
1724 | elsif ($c eq "\n" || $c eq "\r") | ||||||
1725 | { | ||||||
1726 | # Line and field are done | ||||||
1727 | 0 | 0 | $$offsetpointer = $p + 1; | ||||
1728 | 0 | 0 | return $false; | ||||
1729 | } | ||||||
1730 | else | ||||||
1731 | { | ||||||
1732 | # Found some other character, add it to the field | ||||||
1733 | 0 | 0 | $$fieldpointer.=$c; | ||||
1734 | 0 | 0 | $p++; | ||||
1735 | } | ||||||
1736 | } | ||||||
1737 | elsif($state == $IN_QUOTED_FIELD) | ||||||
1738 | { | ||||||
1739 | 0 | 0 | 0 | if ($c eq '"') | |||
1740 | { | ||||||
1741 | 0 | 0 | $p++; | ||||
1742 | 0 | 0 | $state = $DOUBLE_QUOTE_TEST; | ||||
1743 | } | ||||||
1744 | else | ||||||
1745 | { | ||||||
1746 | # Found some other character, add it to the field | ||||||
1747 | 0 | 0 | $$fieldpointer.=$c; | ||||
1748 | 0 | 0 | $p++; | ||||
1749 | } | ||||||
1750 | } | ||||||
1751 | } | ||||||
1752 | } | ||||||
1753 | |||||||
1754 | sub GetNextLine ($$$$$$) | ||||||
1755 | { | ||||||
1756 | 0 | 0 | 0 | 0 | my ($self, $data, $delim, $offsetpointer, $fieldpointer, $line, $lineIsEmptyPtr)=@_; | ||
1757 | 0 | 0 | my $false=0; | ||||
1758 | 0 | 0 | my $true=1; | ||||
1759 | |||||||
1760 | 0 | 0 | undef(@$line); | ||||
1761 | # skip any empty lines | ||||||
1762 | 0 | 0 | 0 | while ($$offsetpointer < length($$data) && ((substr($$data, $$offsetpointer, 1) eq "\r") || (substr($$data, $$offsetpointer, 1) eq "\n"))) | |||
0 | |||||||
1763 | { | ||||||
1764 | 0 | 0 | $$offsetpointer++; | ||||
1765 | } | ||||||
1766 | |||||||
1767 | 0 | 0 | 0 | if ($$offsetpointer >= length($$data)) | |||
1768 | { | ||||||
1769 | 0 | 0 | return $false; | ||||
1770 | } | ||||||
1771 | |||||||
1772 | 0 | 0 | $$lineIsEmptyPtr = $true; | ||||
1773 | 0 | 0 | my $moreToCome; | ||||
1774 | 0 | 0 | do { | ||||
1775 | 0 | 0 | $moreToCome = $self->GetNextField ($data, $delim, $offsetpointer, $fieldpointer); | ||||
1776 | 0 | 0 | push (@$line, $$fieldpointer); | ||||
1777 | 0 | 0 | 0 | if ($$fieldpointer) | |||
1778 | { | ||||||
1779 | 0 | 0 | $$lineIsEmptyPtr = $false; | ||||
1780 | } | ||||||
1781 | } | ||||||
1782 | while ($moreToCome); | ||||||
1783 | |||||||
1784 | 0 | 0 | return $true; | ||||
1785 | } | ||||||
1786 | |||||||
1787 | |||||||
1788 | sub ParseDelimited ($$) | ||||||
1789 | { | ||||||
1790 | 0 | 0 | 0 | 0 | my ($self, $data, $delim)=@_; | ||
1791 | 0 | 0 | my @output; | ||||
1792 | my @line; | ||||||
1793 | 0 | 0 | my $offset =0; | ||||
1794 | |||||||
1795 | 0 | 0 | my $field=""; | ||||
1796 | 0 | 0 | my $lineEmpty=1; | ||||
1797 | 0 | 0 | my $maxsize = 0; | ||||
1798 | 0 | 0 | my $numfields=0; | ||||
1799 | 0 | 0 | my $i; | ||||
1800 | |||||||
1801 | # Parse lines until the eof is hit | ||||||
1802 | 0 | 0 | while ($self->GetNextLine (\$data, $delim, \$offset, \$field, \@line, \$lineEmpty)) | ||||
1803 | { | ||||||
1804 | 0 | 0 | 0 | unless($lineEmpty) | |||
1805 | { | ||||||
1806 | 0 | 0 | push (@output, [@line]); | ||||
1807 | 0 | 0 | $numfields=@line; | ||||
1808 | 0 | 0 | 0 | if ($numfields > $maxsize) | |||
1809 | { | ||||||
1810 | 0 | 0 | $maxsize = $numfields; | ||||
1811 | } | ||||||
1812 | } | ||||||
1813 | } | ||||||
1814 | |||||||
1815 | |||||||
1816 | # If there are any lines which are shorter than the longest | ||||||
1817 | # lines, fill them out with "" entries here. This simplifies | ||||||
1818 | # checking later. | ||||||
1819 | 0 | 0 | foreach $i(@output) | ||||
1820 | { | ||||||
1821 | 0 | 0 | while (@$i < $maxsize) | ||||
1822 | { | ||||||
1823 | 0 | 0 | push (@$i, ""); | ||||
1824 | } | ||||||
1825 | } | ||||||
1826 | |||||||
1827 | 0 | 0 | return @output; | ||||
1828 | |||||||
1829 | } | ||||||
1830 | sub xml_escape ($) { | ||||||
1831 | 3 | 3 | 0 | 5 | my ($self, $rest) = @_; | ||
1832 | 3 | 50 | 7 | unless(defined($rest)){return "";} | |||
0 | 0 | ||||||
1833 | 3 | 8 | $rest =~ s/&/&/g; | ||||
1834 | 3 | 4 | $rest =~ s/</g; | ||||
1835 | 3 | 6 | $rest =~ s/>/>/g; | ||||
1836 | 3 | 6 | $rest =~ s/([^;\/?:@&=+\$,A-Za-z0-9\-_.!~*'()# ])/$XMLescapes{$1}/g; | ||||
1837 | 3 | 9 | return $rest; | ||||
1838 | } | ||||||
1839 | |||||||
1840 | sub xml_unescape ($) { | ||||||
1841 | 0 | 0 | 0 | my ($self, $rest) = @_; | |||
1842 | 0 | 0 | unless(defined($rest)){return "";} | ||||
0 | |||||||
1843 | 0 | $rest =~ s/ /\n/ig; |
|||||
1844 | 0 | $rest =~ s/</ | |||||
1845 | 0 | $rest =~ s/>/>/g; | |||||
1846 | 0 | $rest =~ s/&/&/g; | |||||
1847 | 0 | $rest =~ s/'/'/g; | |||||
1848 | 0 | $rest =~ s/"/"/g; | |||||
1849 | 0 | $rest =~ s/([0-9]{2,3});/chr($1)/eg; | |||||
0 | |||||||
1850 | 0 | return $rest; | |||||
1851 | } | ||||||
1852 | |||||||
1853 | sub encode32 ($){ | ||||||
1854 | 0 | 0 | 0 | my ($self, $number) = @_; | |||
1855 | 0 | my $result = ""; | |||||
1856 | 0 | while ($number > 0){ | |||||
1857 | 0 | my $remainder = $number % 32; | |||||
1858 | 0 | $number = ($number - $remainder)/32; | |||||
1859 | 0 | $result = $self->hash32($remainder) . $result; | |||||
1860 | } | ||||||
1861 | 0 | return $result; | |||||
1862 | } | ||||||
1863 | |||||||
1864 | sub hash32 ($){ | ||||||
1865 | 0 | 0 | 0 | my ($self, $number) = @_; | |||
1866 | 0 | 0 | if($number == 0) {return 'a';} | ||||
0 | |||||||
1867 | 0 | 0 | if($number == 1) {return 'b';} | ||||
0 | |||||||
1868 | 0 | 0 | if($number == 2) {return 'c';} | ||||
0 | |||||||
1869 | 0 | 0 | if($number == 3) {return 'd';} | ||||
0 | |||||||
1870 | 0 | 0 | if($number == 4) {return 'e';} | ||||
0 | |||||||
1871 | 0 | 0 | if($number == 5) {return 'f';} | ||||
0 | |||||||
1872 | 0 | 0 | if($number == 6) {return 'g';} | ||||
0 | |||||||
1873 | 0 | 0 | if($number == 7) {return 'h';} | ||||
0 | |||||||
1874 | 0 | 0 | if($number == 8) {return 'i';} | ||||
0 | |||||||
1875 | 0 | 0 | if($number == 9) {return 'j';} | ||||
0 | |||||||
1876 | 0 | 0 | if($number == 10) {return 'k';} | ||||
0 | |||||||
1877 | 0 | 0 | if($number == 11) {return 'm';} | ||||
0 | |||||||
1878 | 0 | 0 | if($number == 12) {return 'n';} | ||||
0 | |||||||
1879 | 0 | 0 | if($number == 13) {return 'p';} | ||||
0 | |||||||
1880 | 0 | 0 | if($number == 14) {return 'q';} | ||||
0 | |||||||
1881 | 0 | 0 | if($number == 15) {return 'r';} | ||||
0 | |||||||
1882 | 0 | 0 | if($number == 16) {return 's';} | ||||
0 | |||||||
1883 | 0 | 0 | if($number == 17) {return 't';} | ||||
0 | |||||||
1884 | 0 | 0 | if($number == 18) {return 'u';} | ||||
0 | |||||||
1885 | 0 | 0 | if($number == 19) {return 'v';} | ||||
0 | |||||||
1886 | 0 | 0 | if($number == 20) {return 'w';} | ||||
0 | |||||||
1887 | 0 | 0 | if($number == 21) {return 'x';} | ||||
0 | |||||||
1888 | 0 | 0 | if($number == 22) {return 'y';} | ||||
0 | |||||||
1889 | 0 | 0 | if($number == 23) {return 'z';} | ||||
0 | |||||||
1890 | 0 | 0 | if($number == 24) {return '2';} | ||||
0 | |||||||
1891 | 0 | 0 | if($number == 25) {return '3';} | ||||
0 | |||||||
1892 | 0 | 0 | if($number == 26) {return '4';} | ||||
0 | |||||||
1893 | 0 | 0 | if($number == 27) {return '5';} | ||||
0 | |||||||
1894 | 0 | 0 | if($number == 28) {return '6';} | ||||
0 | |||||||
1895 | 0 | 0 | if($number == 29) {return '7';} | ||||
0 | |||||||
1896 | 0 | 0 | if($number == 30) {return '8';} | ||||
0 | |||||||
1897 | 0 | 0 | if($number == 31) {return '9';} | ||||
0 | |||||||
1898 | } | ||||||
1899 | |||||||
1900 | |||||||
1901 | |||||||
1902 | sub unencode32 ($){ | ||||||
1903 | 0 | 0 | 0 | my ($self, $number) = @_; | |||
1904 | 0 | my $result = 0; | |||||
1905 | 0 | while ($number ne ""){ | |||||
1906 | 0 | my $l = length($number); | |||||
1907 | 0 | my $firstchar = substr($number, 0, 1); | |||||
1908 | 0 | $result = ($result * 32) + $self->unhash32($firstchar); | |||||
1909 | 0 | $number = substr($number, 1, $l-1); | |||||
1910 | } | ||||||
1911 | 0 | return $result; | |||||
1912 | } | ||||||
1913 | |||||||
1914 | |||||||
1915 | |||||||
1916 | sub unhash32 ($) { | ||||||
1917 | 0 | 0 | 0 | my ($self, $number) = @_; | |||
1918 | 0 | 0 | if($number eq 'a') {return 0;} | ||||
0 | |||||||
1919 | 0 | 0 | if($number eq 'b') {return 1;} | ||||
0 | |||||||
1920 | 0 | 0 | if($number eq 'c') {return 2;} | ||||
0 | |||||||
1921 | 0 | 0 | if($number eq 'd') {return 3;} | ||||
0 | |||||||
1922 | 0 | 0 | if($number eq 'e') {return 4;} | ||||
0 | |||||||
1923 | 0 | 0 | if($number eq 'f') {return 5;} | ||||
0 | |||||||
1924 | 0 | 0 | if($number eq 'g') {return 6;} | ||||
0 | |||||||
1925 | 0 | 0 | if($number eq 'h') {return 7;} | ||||
0 | |||||||
1926 | 0 | 0 | if($number eq 'i') {return 8;} | ||||
0 | |||||||
1927 | 0 | 0 | if($number eq 'j') {return 9;} | ||||
0 | |||||||
1928 | 0 | 0 | if($number eq 'k') {return 10;} | ||||
0 | |||||||
1929 | 0 | 0 | if($number eq 'm') {return 11;} | ||||
0 | |||||||
1930 | 0 | 0 | if($number eq 'n') {return 12;} | ||||
0 | |||||||
1931 | 0 | 0 | if($number eq 'p') {return 13;} | ||||
0 | |||||||
1932 | 0 | 0 | if($number eq 'q') {return 14;} | ||||
0 | |||||||
1933 | 0 | 0 | if($number eq 'r') {return 15;} | ||||
0 | |||||||
1934 | 0 | 0 | if($number eq 's') {return 16;} | ||||
0 | |||||||
1935 | 0 | 0 | if($number eq 't') {return 17;} | ||||
0 | |||||||
1936 | 0 | 0 | if($number eq 'u') {return 18;} | ||||
0 | |||||||
1937 | 0 | 0 | if($number eq 'v') {return 19;} | ||||
0 | |||||||
1938 | 0 | 0 | if($number eq 'w') {return 20;} | ||||
0 | |||||||
1939 | 0 | 0 | if($number eq 'x') {return 21;} | ||||
0 | |||||||
1940 | 0 | 0 | if($number eq 'y') {return 22;} | ||||
0 | |||||||
1941 | 0 | 0 | if($number eq 'z') {return 23;} | ||||
0 | |||||||
1942 | 0 | 0 | if($number eq '2') {return 24;} | ||||
0 | |||||||
1943 | 0 | 0 | if($number eq '3') {return 25;} | ||||
0 | |||||||
1944 | 0 | 0 | if($number eq '4') {return 26;} | ||||
0 | |||||||
1945 | 0 | 0 | if($number eq '5') {return 27;} | ||||
0 | |||||||
1946 | 0 | 0 | if($number eq '6') {return 28;} | ||||
0 | |||||||
1947 | 0 | 0 | if($number eq '7') {return 29;} | ||||
0 | |||||||
1948 | 0 | 0 | if($number eq '8') {return 30;} | ||||
0 | |||||||
1949 | 0 | 0 | if($number eq '9') {return 31;} | ||||
0 | |||||||
1950 | } | ||||||
1951 | |||||||
1952 | sub createFieldXML($$) | ||||||
1953 | { | ||||||
1954 | 0 | 0 | 0 | my($self, $tag, $value) = @_; | |||
1955 | 0 | my $nameattribute; | |||||
1956 | 0 | 0 | if($tag =~ /^[1-9]\d*$/) | ||||
1957 | { | ||||||
1958 | 0 | $nameattribute = "fid"; | |||||
1959 | } | ||||||
1960 | else | ||||||
1961 | { | ||||||
1962 | 0 | $nameattribute = "name"; | |||||
1963 | } | ||||||
1964 | 0 | 0 | if(ref($value) eq "ARRAY") | ||||
1965 | { | ||||||
1966 | 0 | 0 | if($$value[0] =~ /^file/i) | ||||
1967 | { | ||||||
1968 | #This is a file attachment! | ||||||
1969 | 0 | my $filename = ""; | |||||
1970 | 0 | my $buffer = ""; | |||||
1971 | 0 | my $filecontents = ""; | |||||
1972 | 0 | 0 | if($$value[1] =~ /[\\\/]([^\/\\]+)$/) | ||||
1973 | { | ||||||
1974 | 0 | $filename = $1; | |||||
1975 | } | ||||||
1976 | else | ||||||
1977 | { | ||||||
1978 | 0 | $filename = $$value[1]; | |||||
1979 | } | ||||||
1980 | 0 | 0 | unless(open(FORUPLOADTOQUICKBASE, "<$$value[1]")) | ||||
1981 | { | ||||||
1982 | 0 | $filecontents = encode_base64("Sorry QuickBase could not open the file '$$value[1]' for input, for upload to this field in this record.", ""); | |||||
1983 | } | ||||||
1984 | 0 | binmode FORUPLOADTOQUICKBASE; | |||||
1985 | 0 | while (read(FORUPLOADTOQUICKBASE, $buffer, 60*57)) | |||||
1986 | { | ||||||
1987 | 0 | $filecontents .= encode_base64($buffer, ""); | |||||
1988 | } | ||||||
1989 | 0 | close FORUPLOADTOQUICKBASE; | |||||
1990 | 0 | return " |
|||||
1991 | } | ||||||
1992 | } | ||||||
1993 | else | ||||||
1994 | { | ||||||
1995 | 0 | $value = $self->xml_escape($value); | |||||
1996 | 0 | return " |
|||||
1997 | } | ||||||
1998 | } | ||||||
1999 | |||||||
2000 | |||||||
2001 | 1; |