Class: QuickBase::CommandLineClient
- Defined in:
- lib/QuickBaseCommandLineClient.rb
Overview
This implements an extensible command line interface to QuickBase.
Use setCommand() and setCommandAlias() to extend or modify the interface.
Call run() to use the command line interactively.
Call run( filename ) to run the commands in a file.
Commands entered during an interactive session can be recorded to a file.
In addition to the @commands loaded in initialize(), any public method
from class Client can be used as a command, and any line of Ruby code
can be executed.
Run a command line client session interactively, or using the commands in a file. e.g.:
* ruby QuickBaseCommandLineClient.rb run
* ruby QuickBaseCommandLineClient.rb run dailyTasks.qbc
* ruby -e "require 'quickbasecommandlineclient';QuickBase::CommandLineClient.new.run"
Direct Known Subclasses
Defined Under Namespace
Classes: Command
Instance Attribute Summary collapse
-
#aliases ⇒ Object
readonly
Returns the value of attribute aliases.
-
#availableCommands ⇒ Object
readonly
Returns the value of attribute availableCommands.
-
#commands ⇒ Object
readonly
Returns the value of attribute commands.
-
#usage ⇒ Object
readonly
Returns the value of attribute usage.
Attributes inherited from Client
#HTML, #access, #accessid, #accountLimit, #accountUsage, #action, #admin, #adminOnly, #ancestorappid, #app, #appdata, #appdbid, #applicationLimit, #applicationUsage, #apptoken, #authenticationXML, #cacheSchemas, #cachedSchemas, #chdbids, #choice, #clist, #create, #createapptoken, #createdTime, #databases, #dbdesc, #dbid, #dbidForRequestURL, #dbname, #delete, #disprec, #domain, #downLoadFileURL, #email, #encoding, #errcode, #errdetail, #errtext, #escapeBR, #eventSubscribers, #excludeparents, #externalAuth, #fform, #fid, #fids, #field, #fieldTypeLabelMap, #fieldValue, #field_data, #field_data_list, #fields, #fileContents, #fileUploadToken, #firstName, #fmt, #fname, #fnames, #fvlist, #hours, #httpConnection, #id, #ignoreCR, #ignoreError, #ignoreLF, #ignoreTAB, #includeancestors, #jht, #jsa, #keepData, #key_fid, #label, #lastAccessTime, #lastError, #lastModifiedTime, #lastName, #lastPaymentDate, #lastRecModTime, #logger, #login, #mgrID, #mgrName, #mode, #modify, #name, #newappname, #newdbdesc, #newdbid, #newdbname, #newowner, #numMatches, #numRecords, #num_fields, #num_records, #num_recs_added, #num_recs_deleted, #num_recs_input, #num_recs_updated, #numadded, #numremoved, #oldestancestorappid, #options, #org, #page, #pagebody, #pageid, #pagename, #pagetype, #password, #permissions, #printRequestsAndResponses, #properties, #qarancestorappid, #qbhost, #qdbapi, #qid, #qname, #queries, #query, #rdr, #record, #records, #records_csv, #requestHeaders, #requestNextAllowedTime, #requestSucceeded, #requestTime, #requestURL, #requestXML, #responseElement, #responseElementText, #responseElements, #responseXML, #responseXMLdoc, #rid, #rids, #role, #roleid, #rolename, #saveviews, #screenName, #serverDatabases, #serverGroups, #serverStatus, #serverUpdays, #serverUptime, #serverUsers, #serverVersion, #showAppData, #skipfirst, #slist, #standardRequestHeaders, #status, #stopOnError, #table, #tables, #ticket, #type, #udata, #uname, #update_id, #user, #userid, #username, #users, #validFieldProperties, #validFieldTypes, #value, #variables, #varname, #version, #vid, #view, #withembeddedtables, #xsl
Instance Method Summary collapse
-
#cmdString(command, include_desc = true) ⇒ Object
Make a string to display a command to the user.
-
#evalAvailableCommands ⇒ Object
Get a list of commands that are valid now.
-
#initialize ⇒ CommandLineClient
constructor
Set up some basic commands and their abbreviations.
-
#prompt(promptString) ⇒ Object
Prompt the user if a command requires an ‘Are you sure?’ type of response.
-
#run(filename = nil) ⇒ Object
The main command entry and processing loop.
-
#setCommand(name, desc, prerequisite, args, code, prompt = nil) ⇒ Object
Add a command to the list of available commands.
-
#setCommandAlias(anAlias, cmd) ⇒ Object
Set the alias, or abbreviation, for a command.
-
#showAvailableCommands ⇒ Object
Display the commands currently available.
-
#showUsage ⇒ Object
Display a message telling the user what to do.
Methods inherited from Client
#_addField, #_addRecord, #_addReplaceDBPage, #_addUserToRole, #_changePermission, #_changeRecordOwner, #_changeUserRole, #_cloneDatabase, #_deleteDatabase, #_deleteField, #_deleteFieldName, #_deleteRecord, #_doQuery, #_doQueryCount, #_doQueryHash, #_doQueryName, #_downLoadFile, #_editRecord, #_fieldAddChoices, #_fieldNameAddChoices, #_fieldNameRemoveChoices, #_fieldRemoveChoices, #_genAddRecordForm, #_genResultsTable, #_getAncestorInfo, #_getAppDTMInfo, #_getBillingStatus, #_getDBInfo, #_getDBPage, #_getDBvar, #_getEntitlementValues, #_getFileAttachmentUsage, #_getNumRecords, #_getRecordAsHTML, #_getRecordInfo, #_getRoleInfo, #_getSchema, #_getUserRole, #_importFromCSV, #_importFromExcel, #_listDBPages, #_printChildElements, #_provisionUser, #_purgeRecords, #_removeUserFromRole, #_renameApp, #_runImport, #_sendInvitation, #_setActiveRecord, #_setAppData, #_setDBvar, #_setFieldProperties, #_setKeyField, #_updateFile, #_uploadFile, #_userRoles, #addField, #addFieldValuePair, #addOrEditRecord, #addRecord, #addReplaceDBPage, #addUserToRole, #alias_methods, #applyDeviationToRecords, #applyPercentToRecords, #authenticate, #average, #chainAPIcallsBlock, #changePermission, #changeRecordOwner, #changeRecords, #changeUserRole, #clearFieldValuePairList, #clientMethods, #cloneDatabase, #copyRecord, #count, #createDatabase, #createTable, #dateToMS, #debugHTTPConnection, #decodeXML, #deleteDatabase, #deleteDuplicateRecords, #deleteField, #deleteRecord, #deleteRecords, #deviation, #doQuery, #doQueryCount, #doSQLInsert, #doSQLQuery, #doSQLUpdate, #downLoadFile, #eachField, #eachRecord, #editRecord, #editRecords, #encodeXML, #encodingStrings, #escapeXML, #fieldAddChoices, #fieldRemoveChoices, #fieldTypeForLabel, #findDBByname, #findDuplicateRecordIDs, #findElementByAttributeValue, #findElementsByAttributeName, #findElementsByAttributeValue, #formatChdbidName, #formatCurrency, #formatDate, #formatDuration, #formatFieldValue, #formatImportCSV, #formatPercent, #formatTimeOfDay, #genAddRecordForm, #genResultsTable, #getAllRecordIDs, #getAllValuesForFields, #getAllValuesForFieldsAsArray, #getAllValuesForFieldsAsJSON, #getAllValuesForFieldsAsPrettyJSON, #getAncestorInfo, #getAppDTMInfo, #getApplicationVariable, #getApplicationVariables, #getAttributeString, #getAuthenticationXMLforRequest, #getBillingStatus, #getColumnListForQuery, #getDBInfo, #getDBPage, #getDBPagesAsArray, #getDBforRequestURL, #getDBvar, #getEntitlementValues, #getErrorInfoFromResponse, #getFieldChoices, #getFieldDataPrintableValue, #getFieldDataValue, #getFieldIDs, #getFieldNames, #getFileAttachmentUsage, #getFileUploadToken, #getFilteredRecords, #getJoinRecords, #getNumRecords, #getNumTables, #getOneTimeTicket, #getQueryRequestXML, #getRecord, #getRecordAsHTML, #getRecordInfo, #getReportNames, #getResponseElement, #getResponseElements, #getResponsePathValue, #getResponsePathValues, #getResponseValue, #getRoleInfo, #getSchema, #getServerStatus, #getSortListForQuery, #getSummaryRecords, #getTableIDs, #getTableName, #getTableNames, #getUnionRecords, #getUserInfo, #getUserRole, #grantedDBs, #importCSVFile, #importFromCSV, #importFromExcel, #importSVFile, #importTSVFile, init, #isAverageField?, #isBuiltInField?, #isHTMLRequest?, #isRecordidField?, #isTotalField?, #isValidFieldProperty?, #isValidFieldType?, #iterateDBPages, #iterateFilteredRecords, #iterateJoinRecords, #iterateRecordInfos, #iterateRecords, #iterateSummaryRecords, #iterateUnionRecords, #listDBPages, #logToFile, #lookupBaseFieldTypeByName, #lookupChdbid, #lookupField, #lookupFieldData, #lookupFieldIDByName, #lookupFieldName, #lookupFieldNameFromID, #lookupFieldPropertyByName, #lookupFieldType, #lookupFieldTypeByName, #lookupFieldsByType, #lookupQuery, #lookupQueryByName, #lookupRecord, #makeSVFile, #max, #method_missing, #min, #obStatus, #onChangedDbid, #parseResponseXML, #percent, #prependAPI?, #printChildElements, #printLastError, #printRequest, #printResponse, #processChildElements, processDatabase, #processRESTFieldNameOrRecordKeyRequest, #processRESTRequest, #processResponse, #provisionUser, #purgeRecords, #removeUserFromRole, #renameApp, #replaceFieldValuePair, #resetErrorInfo, #resetfid, #resetrid, #runImport, #sendInvitation, #sendRequest, #setActiveRecord, #setActiveTable, #setAppData, #setDBvar, #setFieldProperties, #setFieldValue, #setFieldValues, #setHTTPConnection, #setHTTPConnectionAndqbhost, #setKeyField, #setLogger, #setqbhost, #signOut, #splitString, #subscribe, #sum, #toXML, #toggleTraceInfo, #updateFile, #uploadFile, #userRoles, #verifyFieldList, #verifyQueryOperator
Constructor Details
#initialize ⇒ CommandLineClient
Set up some basic commands and their abbreviations
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/QuickBaseCommandLineClient.rb', line 67 def initialize super # the main purpose of commands and aliases loaded here is reduce the # steps, typing and clicking needed to get simple things done in QuickBase setCommand( "signin", "Sign into QuickBase", "@ticket.nil?", [ "username", "password" ], [ :authenticate ] ) setCommand( "create", "Create an application", "@ticket", [ "application name", "description" ], [ :createDatabase, :onChangedDbid ] ) setCommand( "copy", "Copy an application, with/out data", "@ticket and @dbid", [ "name", "desc", "keep data?" ], [ :_cloneDatabase, :onChangedDbid ] ) setCommand( "open", "Open an application", "@ticket", [ "application name" ], [ :findDBByname, :onChangedDbid ] ) setCommand( "use", "Use a table from the current application","@ticket and @dbid and @chdbids", [ "table name" ], [ :lookupChdbid, :onChangedDbid ] ) setCommand( "select", "Select records using a query name", "@ticket and @dbid", [ "query name" ], [ :_doQueryName, :resetrid ] ) setCommand( "setrecord", "Set the active record", "@ticket and @dbid", [ "record number" ], [ :_setActiveRecord ] ) setCommand( "changerecords", "Conditionally set field value", "@ticket and @dbid and @fields", [ "field", "value", "testfld", "test", "testval" ], [ :changeRecords ], "Are you sure?" ) setCommand( "deleterecords", "Conditionally delete records", "@ticket and @dbid and @fields", [ "test field", "test", "test value" ], [ :deleteRecords ], "Are you sure?" ) setCommand( "deleteallrecords", "Delete all records", "@ticket and @dbid", nil, [ :deleteRecords, :resetrid ], "Are you sure?" ) setCommand( "addrecord","Add a record to the active table", "@ticket and @dbid", nil, [ :_addRecord, :_getRecordInfo ] ) setCommand( "setfield", "Set a field value in the active record", "@ticket and @dbid and @rid", [ "field name", "value"], [ :setFieldValue ] ) setCommand( "addfield", "Add a field to the active table", "@ticket and @dbid", [ "field name" , "field type" ], [ :_addField ] ) setCommand( "addfieldchoices", "Add value choices for a field", "@ticket and @dbid", [ "field name" , "[choice1,choice2]" ], [ :_fieldNameAddChoices ] ) setCommand( "importfile","Import records from a CSV file", "@ticket and @dbid", [ "file name" ], [ :importCSVFile, :resetrid ] ) setCommand( "importexcelfile","Import records from Excel", "@ticket and @dbid", [ "Excel(.xls) file name", "last import column" ], [ :_importFromExcel, :resetrid ] ) setCommand( "exportfile","Export records to a CSV file", "@ticket and @dbid", [ "file name" ], [ :makeSVFile ] ) setCommand( "uploadfile", "Upload a file into a new record", "@ticket and @dbid", [ "file name", "file attachment field name" ], [:_uploadFile] ) setCommand( "updatefile", "Update the file attachment in a record","@ticket and @dbid and @rid", [ "file name", "file attachment field name" ], [:_updateFile] ) setCommand( "deletefield", "Delete a field from the active table", "@ticket and @dbid", [ "field name" ], [:_deleteFieldName], "Are you sure?" ) setCommand( "deletetable", "Delete the active table", "@ticket and @dbid", nil, [ :_deleteDatabase, :resetrid ], "Are you sure?" ) setCommand( "print", "Prints the results of the last command", "@ticket", nil, [ :_printChildElements ] ) setCommand( "listapps", "Lists the applications you can access", "@ticket", nil, [ :grantedDBs, :_printChildElements ] ) setCommand( "uselog", "Logs requests and responses to a file", "true", [ "log file" ], [ :logToFile ] ) setCommand( "signout", "Sign out of QuickBase", "@ticket", nil, [ :signOut ] ) @aliases = { "si" => "signin", "la" => "listapps", "o" => "open", "p" => "print", "so" => "signout", "af" => "addfield", "sel" => "select", "ar" => "addrecord", "sf" => "setfield", "sr" => "setrecord", "q" => "quit", "if" => "importfile", "ef" => "exportfile", "ulf" => "uploadfile", "udf" => "updatefile", "r" => "run", "ul" => "uselog" } end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class QuickBase::Client
Instance Attribute Details
#aliases ⇒ Object (readonly)
Returns the value of attribute aliases.
38 39 40 |
# File 'lib/QuickBaseCommandLineClient.rb', line 38 def aliases @aliases end |
#availableCommands ⇒ Object (readonly)
Returns the value of attribute availableCommands.
38 39 40 |
# File 'lib/QuickBaseCommandLineClient.rb', line 38 def availableCommands @availableCommands end |
#commands ⇒ Object (readonly)
Returns the value of attribute commands.
38 39 40 |
# File 'lib/QuickBaseCommandLineClient.rb', line 38 def commands @commands end |
#usage ⇒ Object (readonly)
Returns the value of attribute usage.
38 39 40 |
# File 'lib/QuickBaseCommandLineClient.rb', line 38 def usage @usage end |
Instance Method Details
#cmdString(command, include_desc = true) ⇒ Object
Make a string to display a command to the user
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/QuickBaseCommandLineClient.rb', line 141 def cmdString( command, include_desc = true ) ret = "" cmd = @commands[command] if cmd cmdalias = "" if @aliases and @aliases.has_value?( cmd.name ) @aliases.each{ |k,v| cmdalias << "#{k}," if v == cmd.name } cmdalias[-1] = "" cmdalias = "(#{cmdalias})" end if cmd.args if include_desc ret = "#{cmd.name}#{cmdalias} '#{cmd.args.join( ',' )}': #{cmd.desc}" else ret = "#{cmd.name}#{cmdalias} '#{cmd.args.join( ',' )}'" end else if include_desc ret = "#{cmd.name}#{cmdalias} : #{cmd.desc}" else ret = "#{cmd.name}#{cmdalias}" end end end ret end |
#evalAvailableCommands ⇒ Object
Get a list of commands that are valid now
133 134 135 136 137 138 |
# File 'lib/QuickBaseCommandLineClient.rb', line 133 def evalAvailableCommands @availableCommands = Array.new @commands.each{ |name,cmd| @availableCommands << name if eval( cmd.prerequisite ) } end |
#prompt(promptString) ⇒ Object
Prompt the user if a command requires an ‘Are you sure?’ type of response
187 188 189 190 191 192 193 194 195 |
# File 'lib/QuickBaseCommandLineClient.rb', line 187 def prompt( promptString ) if promptString print "#{promptString} (Press 'y' if Yes): " yn = gets yn.chop! return false if yn != "y" end true end |
#run(filename = nil) ⇒ Object
The main command entry and processing loop
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
# File 'lib/QuickBaseCommandLineClient.rb', line 198 def run( filename = nil ) begin if filename file = File.new( filename ) else showUsage end recordedCommandsFile = nil loop { resetErrorInfo if filename.nil? showAvailableCommands print "Enter a command: " inputLine = gets else evalAvailableCommands inputLine = file.gets break if inputLine.nil? end if inputLine.index( '\t' ) separator = "\t" elsif inputLine.index( "," ) separator = "," else separator = " " end args = inputLine.split inputcommand = args[0] if filename.nil? and recordedCommandsFile and inputcommand != "record" recordedCommandsFile.write( inputLine ) end input = splitString( inputLine, separator ) if input and input.length > 0 (0..input.length-1).each{ |i| input[i].strip!;input[i].gsub!( "\"", "") } if @aliases and @aliases.include?( inputcommand ) command = @aliases[ inputcommand ] else command = inputcommand end break if command == "quit" if command == "usage" showUsage elsif command == "record" if input.length == 2 recordedCommandsFile.close if recordedCommandsFile recordedCommandsFile = File.open( input[ 1 ], "w" ) puts "Unable to open file '#{input[ 1 ]}' for writing." if recordedCommandsFile.nil? elsif input.length < 2 puts "Command file name is missing. Enter 'record filename'" end elsif command == "run" if input.length == 2 and FileTest.readable?( input[ 1 ] ) run( input[ 1 ] ) elsif input.length < 2 puts "Command file name is missing. Enter 'run filename'" else puts "'#{input[1]}' is not a readable file" end elsif command == "ruby" begin inputLine.sub!( "ruby", "" ) puts inputLine eval( inputLine ) rescue StandardError => e puts "Error: #{e}" end elsif command == "?" showAvailableCommands puts "API commands:\n#{clientMethods().sort().join(', ')}\n" elsif @commands and @commands.include?( command ) and @availableCommands.include?( command ) cmd = @commands[ command ] input.shift if cmd.args and cmd.args.length == 1 inputLine.sub!( inputcommand, "" ) inputLine.strip! input = [ inputLine ] end if prompt( cmd.prompt ) begin if cmd.args and input.length == cmd.args.length case input.length when 1 puts "#{cmd.code[0]}( #{input[0]} )" send( cmd.code[0], input[0] ) when 2 puts "#{cmd.code[0]}( #{input[0]}, #{input[1]} )" send( cmd.code[0], input[0], input[1] ) when 3 puts "#{cmd.code[0]}( #{input[0]}, #{input[1]}, #{input[2]} )" send( cmd.code[0], input[0], input[1], input[2] ) when 4 puts "#{cmd.code[0]}( #{input[0]}, #{input[1]}, #{input[2]} , #{input[3]})" send( cmd.code[0], input[0], input[1], input[2], input[3] ) when 5 puts "#{cmd.code[0]}( #{input[0]}, #{input[1]}, #{input[2]} , #{input[3]}, #{input[4]})" send( cmd.code[0], input[0], input[1], input[2], input[3], input[4] ) end (1..cmd.code.length-1).each{ |c| puts "#{cmd.code[c]}" send( cmd.code[c] ) } elsif cmd.args.nil? cmd.code.each{ |c| puts "#{c}" send( c ) } else puts "Information missing: #{cmdString( command, false )}" end rescue StandardError => e puts "Error: #{e}" end end elsif clientMethods().include?( command ) puts inputLine begin eval( inputLine ) rescue StandardError => e puts "Error: #{e}" end else puts "Invalid command '#{inputcommand}'" end if (!@requestSucceeded.nil?) and @requestSucceeded == false puts "\n#{@lastError}" end if filename.nil? print "\nPress Enter to continue..." gets end end } rescue StandardError => e puts "Error: #{e}" ensure signOut if @ticket and filename.nil? recordedCommandsFile.close if recordedCommandsFile end end |
#setCommand(name, desc, prerequisite, args, code, prompt = nil) ⇒ Object
Add a command to the list of available commands
120 121 122 123 124 |
# File 'lib/QuickBaseCommandLineClient.rb', line 120 def setCommand( name, desc, prerequisite, args, code, prompt = nil ) @commands = Hash.new if @commands.nil? cmd = Command.new( name, desc, prerequisite, args, code, prompt ) @commands[ name ] = cmd end |
#setCommandAlias(anAlias, cmd) ⇒ Object
Set the alias, or abbreviation, for a command
127 128 129 130 |
# File 'lib/QuickBaseCommandLineClient.rb', line 127 def setCommandAlias( anAlias, cmd ) @aliases = Hash.new if @aliases.nil? @aliases[ anAlias ] = cmd end |
#showAvailableCommands ⇒ Object
Display the commands currently available
173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/QuickBaseCommandLineClient.rb', line 173 def showAvailableCommands evalAvailableCommands puts "\nCommands available:" puts puts " quit(q): End this command session" puts " usage: Show how to use this program" puts " ruby 'rubycode': run a line of ruby language code" puts " run(r) 'filename': run the commands in a file" puts " record 'filename': records your commands in a file" @availableCommands.sort().each { |cmd| puts " #{cmdString( cmd )}" } puts "\n" end |
#showUsage ⇒ Object
Display a message telling the user what to do.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/QuickBaseCommandLineClient.rb', line 49 def showUsage if @usage.nil? @usage = <<USAGE Enter a command from the list of available commands. The list of commands may change after each command. Type TABs, commas, or spaces between parts of a command. Use double-quotes if your commands contain TABs, commas or spaces. e.g. addfield "my text field" text USAGE end puts @usage end |