Top Level Namespace

Defined Under Namespace

Modules: ActiveRecord, QuickBase Classes: QuickBaseContactsAppBuilder

Instance Method Summary collapse

Instance Method Details

#applicationObjectExampleObject

module QuickBase



511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
# File 'lib/QuickBaseObjects.rb', line 511

def applicationObjectExample
  
  qbob = QuickBase::Objects::Builder.new(ENV["quickbase_username"],ENV["quickbase_password"])
  
  cookbookApp = qbob.application("QuickBase API Cookbook v3")
  
  puts "\n\nApplication name:\n"
  puts cookbookApp.name

  puts "\n\nApplication roles:\n"
  cookbookApp.roles.each_value{|role|puts "name: #{role.name}, id: #{role.id}, access: #{role.access}"}

  puts "\n\nApplication users:\n"
  cookbookApp.users.each_value{|user|puts "id: #{user.id}"}

  puts "\n\nApplication variables:\n"
  cookbookApp.variables.each_value{|variable|puts "#{variable.name}: #{variable.value}"}

  puts "\n\nValue of application variable 'TestVariable':\n"
  puts cookbookApp.vTestVariable

  puts "\n\nApplication pages:\n"
  cookbookApp.pages.each_value{|page|puts page.name}

  puts "\n\nDefault application page:\n"
  puts cookbookApp.pDefault_Dashboard.name
  
  puts "\n\nTables from the QuickBase API Cookbook v3:\n"
  cookbookApp.tables.each_value{|table|puts table.name}
  
  puts "\n\nQueries from the Recipes table:\n"
  cookbookApp.tRecipes.queries.each_value{|query|puts query.name}

  puts "\n\nProperties of the List All query from the Recipes table:\n"
  cookbookApp.tRecipes.qList_All.properties.each_pair{|key,value|puts "#{key}: #{value}" }

  puts "\n\nRecord Titles from the List All query from the Recipes table:\n"
  records = cookbookApp.tRecipes.qList_All.run 
  records.each{|record| puts record.fTitle}

  puts "\n\nColumns of the List All query from the Recipes table:\n"
  puts cookbookApp.tRecipes.qList_All.qyclst
  
  puts "\n\nFields from the Ingredients table:\n"
  cookbookApp.tIngredients.fields.each_value{|field|puts field.name}
  
  puts "\n\nField ID of the Description field in the Ingredients table:\n"
  puts cookbookApp.tIngredients.fDescription.id

  puts "\n\nName of field 7 from the Ingredients table:\n"
  puts cookbookApp.tIngredients.fields["7"].name


end

#runFieldEntryDialog(username, password, dbid, field) ⇒ Object

Display a dialog with one text entry field, and buttons to send the text to a field in a new record in QuickBase, go to QuickBase, and to close the dialog.

  • ‘dbid’ must be a valid table id.

  • ‘field’ must be the name or id of a text field in the ‘dbid’ table.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/runFieldEntryDialog.rb', line 21

def runFieldEntryDialog(username,password,dbid,field)
      @qbc = QuickBase::Client.new(username,password)
      if @qbc and @qbc.requestSucceeded
         @qbc.getSchema(dbid)
         if @qbc.requestSucceeded
            field = field.join(' ')
            field.strip!
            fieldID = @qbc.lookupFieldIDByName(field)
            if fieldID
               fieldName = field
            else
               fieldName = lookupFieldNameFromID(field)
               fieldID = field if fieldName
            end
            tableName = @qbc.getResponseElement( "table/name" ).text
            if fieldID and fieldName
               
               fieldElement = @qbc.lookupField(fieldID)
               numTextLines = 1
               numLinesProc = proc { |element|
                  if element.is_a?(REXML::Element) and element.name == "num_lines" and element.has_text?
                     numTextLines = element.text.to_i
                  end
               }
               @qbc.processChildElements(fieldElement, true, numLinesProc)
               
               root = TkRoot.new{ title tableName }
               frame = TkFrame.new(root){
                   borderwidth 4 
                   width 60
                   pack "side" => "top"
               }
               if numTextLines == 1
                  labelText = "Enter '#{fieldName}' and press Enter or click 'Send to QuickBase':"
               else
                  labelText = "Enter '#{fieldName}' and click 'Send to QuickBase':"
               end
               fieldLabel = TkLabel.new(frame){
                   text labelText
                   font "Arial 10 bold"
                   pack "side"=>"top", "expand" => true 
               }
               
               entryField = nil
               if numTextLines == 1
                  entryField = TkEntry.new(frame){
                      font "Arial 10 bold"
                      pack "fill" => "x", "expand" => true, "side" => "top",  "padx" =>5, "pady"=>5  
                  }
                  entryField.bind('Key-Return') {|e|  
                     value = entryField.get
                     @qbc.clearFieldValuePairList
                     @qbc.addFieldValuePair(nil,fieldID,nil,value)
                     @qbc.addRecord(dbid,@qbc.fvlist)
                     entryField.value = ""
                  }
               elsif numTextLines > 1
                  entryField = TkText.new(frame){
                      height numTextLines
                      width 60
                      font "Arial 10 bold"
                      pack "fill" => "both", "expand" => true, "side" => "top",  "padx" =>5, "pady"=>5  
                      wrap "word"
                  }
               end
               entryField.focus
               
               buttonFrame = TkFrame.new(frame){
                   pack "side" => "bottom"
                   width 50 
               }
               sendButton = TkButton.new(buttonFrame){
                   text "Send To QuickBase" 
                   underline 0
                   font "Arial 10 bold"
                   pack "side"=>"left", "padx"=>5, "pady"=>5
               }
               sendButton.command {
                  if numTextLines > 1
                     value = entryField.get("1.0","end")
                  else
                     value = entryField.get
                  end
                  @qbc.clearFieldValuePairList
                  @qbc.addFieldValuePair(nil,fieldID,nil,value)
                  @qbc.addRecord(dbid,@qbc.fvlist)
                  entryField.value = ""
               }
               launchButton = TkButton.new(buttonFrame){
                   text "Go to QuickBase..." 
                   underline 0
                   font "Arial 10 bold"
                   pack "side"=>"left","padx"=>5, "pady"=>5
               }
               launchButton .command {
                  url = "http://www.quickbase.com/db/#{dbid}"
                  url = "start #{url}" if RUBY_PLATFORM.split("-")[1].include?("mswin")  
                  system(url)
               }
               closeButton = TkButton.new(buttonFrame){
                   text "Close" 
                   underline 0
                   font "Arial 10 bold"
                   pack "side"=>"right","padx"=>5, "pady"=>5
               }
               closeButton.command { Tk.exit }
   
               root.bind('Alt-KeyRelease-s') {|e| sendButton.invoke }
               root.bind('Alt-KeyRelease-l') {|e| launchButton.invoke }
               root.bind('Alt-KeyRelease-c') {|e| closeButton.invoke }
               
               Tk.mainloop
            else
               Tk.messageBox({"icon"=>"error","title"=>"Oops!", "message" => "Error finding the QuickBase field '#{fieldName}' in the '#{tableName}' table."})      
            end
         else
            Tk.messageBox({"icon"=>"error","title"=>"Oops!", "message" => "Error finding the QuickBase table with the '#{dbid}' id."})      
         end
      else
         Tk.messageBox({"icon"=>"error","title"=>"Oops!", "message" => "Error connecting to QuickBase.\nPlease check your internet connection and your username and password."})      
      end
end

#runOfflineFieldEntryDialog(username, password, dbid, field) ⇒ Object

Display a dialog with one text entry field, and buttons to send the text to a field in a new record in QuickBase, go to QuickBase, and to close the dialog.

  • ‘dbid’ must be a valid table id.

  • ‘field’ must be the name or id of a text field in the ‘dbid’ table.

If you can’t connect to QuickBase, data will be written to a file in your current working directory then sent to QuickBase next time you are able to connect. Note that you must have connected to QuickBase at least once before you can enter data offline.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/runOfflineFieldEntryDialog.rb', line 25

def runOfflineFieldEntryDialog(username,password,dbid,field)
      
   connected = false
   appendToOfflineFile = false
   
   numTextLines = 1
   tableName = ""
   fieldID = "" 
   fieldName = ""
   
   offlineDataFileName = "#{dbid}.offline.txt"
   offlineConfigFileName = "#{dbid}.offline.cfg"
      
   if FileTest.exist?(offlineConfigFileName)
      File.open(offlineConfigFileName,"r"){|f| 
         cfg = f.gets
         tableName, numTextLines, fieldID, fieldName = cfg.split(":::")
         numTextLines = numTextLines.to_i
      }
   end
      
   @qbc = QuickBase::Client.new(username,password)
   if @qbc and @qbc.requestSucceeded
      connected = true
      if FileTest.exist?(offlineDataFileName)
         QuickBase::TextData.uploadData(username,password,offlineDataFileName)
         File.delete(offlineDataFileName)
      end
   else
      appendToOfflineFile = true if FileTest.exist?(offlineDataFileName)
   end   
      
   @offlineDataFile = nil
   if connected
      @qbc.getSchema(dbid)
      if @qbc.requestSucceeded
         field = field.join(' ')
         field.strip!
         fieldID = @qbc.lookupFieldIDByName(field)
         if fieldID
            fieldName = field
         else
            fieldName = lookupFieldNameFromID(field)
            fieldID = field if fieldName
         end
         tableName = @qbc.getResponseElement( "table/name" ).text
         if fieldID and fieldName
            fieldElement = @qbc.lookupField(fieldID)
            numLinesProc = proc { |element|
               if element.is_a?(REXML::Element) and element.name == "num_lines" and element.has_text?
                  numTextLines = element.text.to_i
               end
            }
            @qbc.processChildElements(fieldElement, true, numLinesProc)
            File.open(offlineConfigFileName,"w"){|f|f.write("#{tableName}:::#{numTextLines}:::#{fieldID}:::#{fieldName}")}
         else
            Tk.messageBox({"icon"=>"error","title"=>"Oops!", "message" => "Error finding the QuickBase field '#{fieldName}' in the '#{tableName}' table."})      
         end
      else
         Tk.messageBox({"icon"=>"error","title"=>"Oops!", "message" => "Error finding the QuickBase table with the '#{dbid}' id."})      
      end
   elsif appendToOfflineFile
      @offlineDataFile = File.open(offlineDataFileName, "a")
   else   
      @offlineDataFile = File.open(offlineDataFileName, "w")
      @offlineDataFile.puts("dbid:#{dbid}")
   end
            
   root = TkRoot.new{ title tableName }
   frame = TkFrame.new(root){
       borderwidth 4 
       width 60
       pack "side" => "top"
   }
   if numTextLines == 1
      labelText = "Enter '#{fieldName}' and press Enter or click 'Send to QuickBase':"
   else
      labelText = "Enter '#{fieldName}' and click 'Send to QuickBase':"
   end
   fieldLabel = TkLabel.new(frame){
       text labelText
       font "Arial 10 bold"
       pack "side"=>"top", "expand" => true 
   }
   
   entryField = nil
   if numTextLines == 1
      entryField = TkEntry.new(frame){
          font "Arial 10 bold"
          pack "fill" => "x", "expand" => true, "side" => "top",  "padx" =>5, "pady"=>5  
      }
      entryField.bind('Key-Return') {|e|  
         value = entryField.get
         if connected
            @qbc.clearFieldValuePairList
            @qbc.addFieldValuePair(nil,fieldID,nil,value)
            @qbc.addRecord(dbid,@qbc.fvlist)
         else
            @offlineDataFile.puts("record:\n#{fieldName}:#{value}")
         end
         entryField.value = ""
      }
   elsif numTextLines > 1
      entryField = TkText.new(frame){
          height numTextLines
          width 60
          font "Arial 10 bold"
          pack "fill" => "both", "expand" => true, "side" => "top",  "padx" =>5, "pady"=>5  
          wrap "word"
      }
   end
   entryField.focus
   
   buttonFrame = TkFrame.new(frame){
       pack "side" => "bottom"
       width 50 
   }
   sendButton = TkButton.new(buttonFrame){
       text "Send To QuickBase" 
       underline 0
       font "Arial 10 bold"
       pack "side"=>"left", "padx"=>5, "pady"=>5
   }
   sendButton.command {
      if numTextLines > 1
         value = entryField.get("1.0","end")
      else
         value = entryField.get
      end
      if connected
         @qbc.clearFieldValuePairList
         @qbc.addFieldValuePair(nil,fieldID,nil,value)
         @qbc.addRecord(dbid,@qbc.fvlist)
      else
         @offlineDataFile.puts("record:\n#{fieldName}:#{value}")
      end
      entryField.value = ""
   }
    
   if connected
      launchButton = TkButton.new(buttonFrame){
          text "Go to QuickBase..." 
          underline 0
          font "Arial 10 bold"
          pack "side"=>"left","padx"=>5, "pady"=>5
      }
      launchButton.command {
         url = "http://www.quickbase.com/db/#{dbid}"
         url = "start #{url}" if RUBY_PLATFORM.split("-")[1].include?("mswin")  
         system(url)
      }
   end
   closeButton = TkButton.new(buttonFrame){
       text "Close" 
       underline 0
       font "Arial 10 bold"
       pack "side"=>"right","padx"=>5, "pady"=>5
   }
   closeButton.command { Tk.exit }
   
   root.bind('Alt-KeyRelease-s') {|e| sendButton.invoke }
   root.bind('Alt-KeyRelease-l') {|e| launchButton.invoke }
   root.bind('Alt-KeyRelease-c') {|e| closeButton.invoke }

   Tk.mainloop
end

#test(username, password) ⇒ Object

The following test code generates RSS text from recently modified records in the QuickBase Community Forum and KnowledgeBase.



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/QuickBaseRSSGenerator.rb', line 263

def test( username, password )
   
   qbc = QuickBase::Client.new( username, password )
   qbRSSgen  = QuickBase::RSSGenerator.new( qbc )
   
   qbRSSgen.unSorted
   
   qbRSSgen.setTitle( "QuickBase Forum/KnowledgeBase RSS" )
   qbRSSgen.setLink( "main" )
   qbRSSgen.setDescription( "RSS view of QuickBase Community Forum and KnowledgeBase" )
   
   qbRSSgen.addTable("8emtadvk", "Community Forum", { "title" => "6", "description" => "10" }, nil, nil, nil, 75 )
   qbRSSgen.addTable( "6mztyxu8", "KnowledgeBase", { "title" => "5", "description" => "6" }, nil, nil, nil, 50 )
   
   rssText = qbRSSgen.generateRSStext
   
   File.open( "QuickBaseInfoRSS.xml", "w" ) { |file| file.write( rssText ) }
   print "\nPlease view QuickBaseInfoRSS.xml in an RSS reader, a browser or an XML editor.\n"
   
end

#testQuickBaseCLClient(filename = nil) ⇒ Object

module QuickBase ———————————————



370
371
372
373
374
# File 'lib/QuickBaseCommandLineClient.rb', line 370

def testQuickBaseCLClient( filename = nil )
  include QuickBase
  qbCLClient = CommandLineClient.new
  qbCLClient.run( filename )
end

#testQuickBaseClient(username, password, appname, showGrantedDBs = false, showChildDBs = true, cloneappnameDB = true, createTempDB = true, showTrace = false) ⇒ Object

This does not modify any existing databases.

If the method throws an exception, you may have one or two unwanted databases
in your list of databases in www.quickbase.com.


4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
# File 'lib/QuickBaseClient.rb', line 4882

def testQuickBaseClient( username,
                         password,
                         appname,
                         showGrantedDBs = false,
                         showChildDBs = true,
                         cloneappnameDB = true,
                         createTempDB = true,
                         showTrace = false )

   include QuickBase

   begin

      qbClient = Client.new( username, password, # sign in to QuickBase as username, password
           appname, # open a DB using its name
           true, # use SSL (default)
           true, # show requests sent to QuickBase and reponses returned
           true, # throw an exception back here on the first error
           showTrace # show entire program trace
         )

      if showGrantedDBs
         # list the accessible databases for this user
         qbClient.grantedDBs() { | database| qbClient.printChildElements( database ) }
      end

      appdbid = qbClient.dbid
      qbClient.getDBInfo( appdbid )   # get description etc. of appname
      qbClient.getSchema( appdbid ) # get the schema for appname
      qbClient.doQuery( appdbid )  { |record| qbClient.printChildElements( record ) }   # print all records

      if showChildDBs and qbClient.chdbids         # if appname has child tables
         qbClient.chdbids.each { |chdbid|           # for each child table -
            chdbid = chdbid.text
            qbClient.getDBInfo( chdbid )                #  - get description etc.
            qbClient.getSchema( chdbid )              #  - get schema
            qbClient.doQuery( chdbid ) { |record| qbClient.printChildElements( record ) } # print all records
         }
      end

      if cloneappnameDB
         # make a copy of the database, with the structure but none of the data
         newdbname = newdbdesc = "#{username}'s temporary copy of #{appname} - OK to delete)"
         newdbid = qbClient.cloneDatabase( appdbid, newdbname, newdbdesc, false )

         # delete the copy of the database
         qbClient.deleteDatabase( newdbid )
      end

      if createTempDB
         # make a new database ----------------------------------------
         newdbid = qbClient.createDatabase( "#{username}'s test database.", "This is test database created using a ruby script that calls the QuickBase HTTP API." )

         # add a text field to the new database
         textfid, textlabel = qbClient.addField( newdbid, "text field", "text" )

         # add a file attachment field to the new database
         filefid, filelabel = qbClient.addField( newdbid, "file attachment field", "file" )

         # add a choice field to the new database, with some default choices
         choicefid, choicelabel = qbClient.addField( newdbid, "choice field", "text" )
         qbClient.fieldAddChoices( newdbid, choicefid, %w{ one two three four five } )

         # remove a choice field
         if qbClient.numadded == "5"
            qbClient.fieldRemoveChoices( newdbid, choicefid, "three" )
         end

         # add a record to the new database
         qbClient.addFieldValuePair( nil, textfid, nil, "#{textfid}" )
         qbClient.addFieldValuePair( nil, filefid, "aFile.txt", "Contents of aFile.txt" )
         fvlist = qbClient.addFieldValuePair( nil, choicefid, nil, "four" )
         rid, update_id = qbClient.addRecord( newdbid, fvlist )
         qbClient.getRecordInfo( newdbid, rid ) { |field| qbClient.printChildElements( field ) }

         # edit the record
         qbClient.clearFieldValuePairList
         fvlist = qbClient.addFieldValuePair( nil, choicefid, nil, "two" )
         qbClient.editRecord( newdbid, rid, fvlist )
         qbClient.getRecordInfo( newdbid, rid ) { |field| qbClient.printChildElements( field ) }

         # pass some user data through the API
         myData = "about to call changeRecordOwner"
         qbClient.udata = myData

         # change record owner
         qbClient.changeRecordOwner( newdbid, rid, username )

         # this will throw an exception if udata wasn't in the response
         qbClient.udata = nil if qbClient.udata == myData

         # turn off permission to save views
         qbClient.changePermission( newdbid, username, "any", "any", "true", "true", "false", "true" )

         # get an HTML view of the record
         html = qbClient.getRecordAsHTML( newdbid, rid )
         p html

         # download aFile.txt
         qbClient.downLoadFile( newdbid, rid, filefid )

         # delete 2 fields
         qbClient.deleteField( newdbid, textfid )
         qbClient.deleteField( newdbid, filefid )

         # get a CSV view of the database
         csv = qbClient.genResultsTable( newdbid, nil, nil, nil, nil, nil, "csv" )
         p csv

         # get an HTML form for adding records
         html = qbClient.genAddRecordForm( newdbid )
         p html

         # add an HTML page to the database
         testpage = "<HTML><HEAD><TITLE>test page</TITLE></HEAD><BODY>this is a test page</BODY></HTML>"
         qbClient.addReplaceDBPage( newdbid, nil, "test page", "1",  testpage )

         # get the Default Overview page
         qbClient.getDBPage( newdbid, nil, "Default Overview" )

         # change the label of the choice field
         qbClient.setFieldProperties( newdbid, { "label" => "The only field in this database!" }, choicefid )

         # import some records from CSV
         csvToImport = qbClient.formatImportCSV( "five\r\none\r\nfour" )
         qbClient.importFromCSV( newdbid, csvToImport, choicefid, "1" )

         # print various query results
         qbClient.doQuery( newdbid )
         qbClient.printChildElements( [ qbClient.chdbids, qbClient.queries , qbClient.records, qbClient.fields, qbClient.variables ] )

         # remove records and database
         p qbClient.getNumRecords( newdbid )
         qbClient.purgeRecords( newdbid )
         p qbClient.getNumRecords( newdbid )
         qbClient.deleteDatabase( newdbid )

      end

   rescue StandardError => exception
      puts "#{exception}"
   ensure
      qbClient.signOut # sign out of QuickBase
   end
end

#testQuickBaseTwitterConnectorObject



294
295
296
# File 'lib/QuickBaseTwitterConnector.rb', line 294

def testQuickBaseTwitterConnector()
  QuickBase::TwitterConnector.new
end