ipp_quickbase_devkit 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. data/LICENSE +87 -0
  2. data/README.rdoc +112 -0
  3. data/doc/QuickBaseClient.rb.htm +1896 -0
  4. data/doc/ReleaseNotes.txt +43 -0
  5. data/doc/qbc.makeCSVFile.qbc +4 -0
  6. data/doc/qbc.makeCSVFile.rb +4 -0
  7. data/doc/quickbase_adapter.rb.htm +399 -0
  8. data/examples/cookbookfiles/QuickBaseAPICookbook.html +2590 -0
  9. data/examples/cookbookfiles/addChangeRemoveUserRole.rb +21 -0
  10. data/examples/cookbookfiles/addOrEditRecord.rb +10 -0
  11. data/examples/cookbookfiles/application_object.rb +55 -0
  12. data/examples/cookbookfiles/applyRubyFormulas.rb +10 -0
  13. data/examples/cookbookfiles/average.rb +27 -0
  14. data/examples/cookbookfiles/backupApplication.rb +8 -0
  15. data/examples/cookbookfiles/cacheSchemas.rb +53 -0
  16. data/examples/cookbookfiles/calculateRunningTotals.rb +11 -0
  17. data/examples/cookbookfiles/copyrecords.rb +73 -0
  18. data/examples/cookbookfiles/count.rb +26 -0
  19. data/examples/cookbookfiles/createRecordNavigatorHTML.rb +42 -0
  20. data/examples/cookbookfiles/createReportDashboard.rb +35 -0
  21. data/examples/cookbookfiles/createTable.rb +12 -0
  22. data/examples/cookbookfiles/deviation.rb +25 -0
  23. data/examples/cookbookfiles/downloadCookbook.rb +97 -0
  24. data/examples/cookbookfiles/downloadFile.rb +10 -0
  25. data/examples/cookbookfiles/downloadFilesToFolder.rb +81 -0
  26. data/examples/cookbookfiles/downloadToTextFile.rb +64 -0
  27. data/examples/cookbookfiles/dumpSchema.rb +11 -0
  28. data/examples/cookbookfiles/duplicateRecord.rb +8 -0
  29. data/examples/cookbookfiles/dynamicMethods.rb +33 -0
  30. data/examples/cookbookfiles/editRecords.rb +15 -0
  31. data/examples/cookbookfiles/findJohnsLast10Records.rb +17 -0
  32. data/examples/cookbookfiles/findRubyRecords.rb +17 -0
  33. data/examples/cookbookfiles/formatCurrency.rb +24 -0
  34. data/examples/cookbookfiles/formatDate.rb +10 -0
  35. data/examples/cookbookfiles/formatDuration.rb +27 -0
  36. data/examples/cookbookfiles/formatPercent.rb +24 -0
  37. data/examples/cookbookfiles/getAllValuesForFields.rb +18 -0
  38. data/examples/cookbookfiles/getAppDTMInfo.rb +29 -0
  39. data/examples/cookbookfiles/getApplicationVariable.rb +5 -0
  40. data/examples/cookbookfiles/getChildTableDBID.rb +11 -0
  41. data/examples/cookbookfiles/getColumnListForReport.rb +6 -0
  42. data/examples/cookbookfiles/getFieldChoices.rb +13 -0
  43. data/examples/cookbookfiles/getFieldIDs.rb +6 -0
  44. data/examples/cookbookfiles/getFieldNames.rb +6 -0
  45. data/examples/cookbookfiles/getLastModTime.rb +8 -0
  46. data/examples/cookbookfiles/getLastRecModTime.rb +8 -0
  47. data/examples/cookbookfiles/getNumRecords.rb +8 -0
  48. data/examples/cookbookfiles/getNumTables.rb +4 -0
  49. data/examples/cookbookfiles/getRecord.rb +5 -0
  50. data/examples/cookbookfiles/getRecordDisplayURL.rb +13 -0
  51. data/examples/cookbookfiles/getRecordsAddedToday.rb +20 -0
  52. data/examples/cookbookfiles/getRecordsAsJSON.rb +6 -0
  53. data/examples/cookbookfiles/getReportNames.rb +25 -0
  54. data/examples/cookbookfiles/getRoleInfo.rb +48 -0
  55. data/examples/cookbookfiles/getServerStatus.rb +11 -0
  56. data/examples/cookbookfiles/getSortListForReport.rb +6 -0
  57. data/examples/cookbookfiles/getTableIDs.rb +6 -0
  58. data/examples/cookbookfiles/getTableName.rb +8 -0
  59. data/examples/cookbookfiles/getTableNames.rb +25 -0
  60. data/examples/cookbookfiles/getTimeCreated.rb +8 -0
  61. data/examples/cookbookfiles/getTimeInMilliseconds.rb +5 -0
  62. data/examples/cookbookfiles/getUserInfo.rb +26 -0
  63. data/examples/cookbookfiles/getUserRole.rb +15 -0
  64. data/examples/cookbookfiles/intranet.rb +101 -0
  65. data/examples/cookbookfiles/isAverageField.rb +17 -0
  66. data/examples/cookbookfiles/isDbidString.rb +8 -0
  67. data/examples/cookbookfiles/isTotalField.rb +16 -0
  68. data/examples/cookbookfiles/iterateDBPages.rb +8 -0
  69. data/examples/cookbookfiles/iterateFilteredRecords.rb +12 -0
  70. data/examples/cookbookfiles/iterateJoinRecords.rb +68 -0
  71. data/examples/cookbookfiles/iterateRecordInfos.rb +8 -0
  72. data/examples/cookbookfiles/iterateRecords.rb +23 -0
  73. data/examples/cookbookfiles/iterateSummaryRecords.rb +13 -0
  74. data/examples/cookbookfiles/iterateUnionRecords.rb +38 -0
  75. data/examples/cookbookfiles/listAccessibleApplications.rb +6 -0
  76. data/examples/cookbookfiles/logRequestAndResponseXML.rb +8 -0
  77. data/examples/cookbookfiles/lookupFieldPropertyByName.rb +62 -0
  78. data/examples/cookbookfiles/lookupFieldTypeByName.rb +10 -0
  79. data/examples/cookbookfiles/makeCSVFile.rb +4 -0
  80. data/examples/cookbookfiles/makeSlideShow.rb +42 -0
  81. data/examples/cookbookfiles/makerecs.rb +64 -0
  82. data/examples/cookbookfiles/max.rb +26 -0
  83. data/examples/cookbookfiles/min.rb +26 -0
  84. data/examples/cookbookfiles/percent.rb +29 -0
  85. data/examples/cookbookfiles/printChildElements.rb +54 -0
  86. data/examples/cookbookfiles/printNewRecords.rb +12 -0
  87. data/examples/cookbookfiles/processRESTRequest.rb +21 -0
  88. data/examples/cookbookfiles/provisionAndInviteNewUser.rb +13 -0
  89. data/examples/cookbookfiles/purgeRecords.rb +15 -0
  90. data/examples/cookbookfiles/quickbase_adapter.rb.htm +397 -0
  91. data/examples/cookbookfiles/quickbase_record_finder.zip +0 -0
  92. data/examples/cookbookfiles/recordAndFieldIterator.rb +24 -0
  93. data/examples/cookbookfiles/runImport.rb +9 -0
  94. data/examples/cookbookfiles/runQuickBaseTwitterConnector.rb +41 -0
  95. data/examples/cookbookfiles/sendToQuickBase.rb +33 -0
  96. data/examples/cookbookfiles/setDBvar.rb +6 -0
  97. data/examples/cookbookfiles/showRequestAndResponseXML.rb +8 -0
  98. data/examples/cookbookfiles/sqlQuery.rb +11 -0
  99. data/examples/cookbookfiles/stopOnError.rb +10 -0
  100. data/examples/cookbookfiles/sum.rb +26 -0
  101. data/examples/cookbookfiles/twitterFromQuickBase.rb +42 -0
  102. data/examples/cookbookfiles/twitterWithQuickBase.rb +36 -0
  103. data/examples/cookbookfiles/uploadCSVData.rb +20 -0
  104. data/examples/cookbookfiles/uploadExcelData.rb +22 -0
  105. data/examples/cookbookfiles/uploadFileEveryHour.rb +18 -0
  106. data/examples/cookbookfiles/uploadFileIntoNewRecord.rb +8 -0
  107. data/examples/cookbookfiles/uploadFilesFromFolder.exe +0 -0
  108. data/examples/cookbookfiles/uploadFilesFromFolder.rb +69 -0
  109. data/examples/cookbookfiles/useCompanyURL.rb +12 -0
  110. data/examples/cookbookfiles/userRoles.rb +49 -0
  111. data/examples/cookbookfiles/watchCommunityForum.rb +5 -0
  112. data/examples/cookbookfiles/wikifyTable.rb +29 -0
  113. data/examples/cookbookfiles/xmlShortcuts.rb +33 -0
  114. data/examples/pmp/app/controllers/application.rb +7 -0
  115. data/examples/pmp/app/controllers/contacts_controller.rb +8 -0
  116. data/examples/pmp/app/controllers/document_library_controller.rb +2 -0
  117. data/examples/pmp/app/controllers/issues_controller.rb +5 -0
  118. data/examples/pmp/app/controllers/projects_controller.rb +22 -0
  119. data/examples/pmp/app/controllers/resources_controller.rb +2 -0
  120. data/examples/pmp/app/controllers/tasks_controller.rb +13 -0
  121. data/examples/pmp/app/controllers/time_cards_controller.rb +5 -0
  122. data/examples/pmp/app/helpers/application_helper.rb +3 -0
  123. data/examples/pmp/app/helpers/contacts_helper.rb +2 -0
  124. data/examples/pmp/app/helpers/document_library_helper.rb +2 -0
  125. data/examples/pmp/app/helpers/issues_helper.rb +2 -0
  126. data/examples/pmp/app/helpers/projects_helper.rb +2 -0
  127. data/examples/pmp/app/helpers/resources_helper.rb +2 -0
  128. data/examples/pmp/app/helpers/tasks_helper.rb +2 -0
  129. data/examples/pmp/app/helpers/time_cards_helper.rb +2 -0
  130. data/examples/pmp/app/models/contacts.rb +26 -0
  131. data/examples/pmp/app/models/document_library.rb +2 -0
  132. data/examples/pmp/app/models/issues.rb +6 -0
  133. data/examples/pmp/app/models/projects.rb +26 -0
  134. data/examples/pmp/app/models/resources.rb +2 -0
  135. data/examples/pmp/app/models/tasks.rb +12 -0
  136. data/examples/pmp/app/models/time_cards.rb +7 -0
  137. data/examples/pmp/app/schemas/contacts.xml +1 -0
  138. data/examples/pmp/app/schemas/document_library.xml +1 -0
  139. data/examples/pmp/app/schemas/issues.xml +1 -0
  140. data/examples/pmp/app/schemas/pmp.xml +1 -0
  141. data/examples/pmp/app/schemas/projects.xml +1 -0
  142. data/examples/pmp/app/schemas/readme.txt +8 -0
  143. data/examples/pmp/app/schemas/resources.xml +1 -0
  144. data/examples/pmp/app/schemas/tasks.xml +1 -0
  145. data/examples/pmp/app/schemas/time_cards.xml +1 -0
  146. data/examples/pmp/app/views/contacts/companies.rhtml +31 -0
  147. data/examples/pmp/app/views/contacts/project_contacts.rhtml +31 -0
  148. data/examples/pmp/app/views/issues/filter_issues.rhtml +26 -0
  149. data/examples/pmp/app/views/layouts/application.rhtml +56 -0
  150. data/examples/pmp/app/views/projects/all_projects.rhtml +33 -0
  151. data/examples/pmp/app/views/projects/home.rhtml +11 -0
  152. data/examples/pmp/app/views/projects/my_open_projects.rhtml +27 -0
  153. data/examples/pmp/app/views/projects/open_projects.rhtml +44 -0
  154. data/examples/pmp/app/views/projects/project_sorted_by_company.rhtml +40 -0
  155. data/examples/pmp/app/views/projects/projects_sorted_by_priority.rhtml +30 -0
  156. data/examples/pmp/app/views/projects/updated_projects.rhtml +0 -0
  157. data/examples/pmp/app/views/tasks/all_tasks.rhtml +27 -0
  158. data/examples/pmp/app/views/tasks/search.rhtml +23 -0
  159. data/examples/pmp/app/views/tasks/search2.rhtml +23 -0
  160. data/examples/pmp/app/views/tasks/search3.rhtml +23 -0
  161. data/examples/pmp/app/views/time_cards/summary.rhtml +38 -0
  162. data/examples/pmp/config/boot.rb +45 -0
  163. data/examples/pmp/config/database.yml +30 -0
  164. data/examples/pmp/config/environment.rb +60 -0
  165. data/examples/pmp/config/environments/development.rb +21 -0
  166. data/examples/pmp/config/environments/production.rb +18 -0
  167. data/examples/pmp/config/environments/test.rb +19 -0
  168. data/examples/pmp/config/routes.rb +23 -0
  169. data/examples/pmp/db/migrate/001_create_projects.rb +10 -0
  170. data/examples/pmp/db/migrate/002_create_tasks.rb +10 -0
  171. data/examples/pmp/db/migrate/003_create_issues.rb +10 -0
  172. data/examples/pmp/db/migrate/004_create_document_libraries.rb +10 -0
  173. data/examples/pmp/db/migrate/005_create_resources.rb +10 -0
  174. data/examples/pmp/db/migrate/006_create_time_cards.rb +10 -0
  175. data/examples/pmp/db/migrate/007_create_contacts.rb +10 -0
  176. data/examples/pmp/public/404.html +30 -0
  177. data/examples/pmp/public/500.html +30 -0
  178. data/examples/pmp/public/app.index.html +277 -0
  179. data/examples/pmp/public/dispatch.cgi +10 -0
  180. data/examples/pmp/public/dispatch.fcgi +24 -0
  181. data/examples/pmp/public/dispatch.rb +10 -0
  182. data/examples/pmp/public/favicon.ico +0 -0
  183. data/examples/pmp/public/images/rails.png +0 -0
  184. data/examples/pmp/public/javascripts/application.js +2 -0
  185. data/examples/pmp/public/javascripts/controls.js +833 -0
  186. data/examples/pmp/public/javascripts/dragdrop.js +942 -0
  187. data/examples/pmp/public/javascripts/effects.js +1088 -0
  188. data/examples/pmp/public/javascripts/prototype.js +2515 -0
  189. data/examples/pmp/public/robots.txt +1 -0
  190. data/examples/pmp/test/fixtures/contacts.yml +5 -0
  191. data/examples/pmp/test/fixtures/document_libraries.yml +5 -0
  192. data/examples/pmp/test/fixtures/issues.yml +5 -0
  193. data/examples/pmp/test/fixtures/projects.yml +5 -0
  194. data/examples/pmp/test/fixtures/resources.yml +5 -0
  195. data/examples/pmp/test/fixtures/tasks.yml +5 -0
  196. data/examples/pmp/test/fixtures/time_cards.yml +5 -0
  197. data/examples/pmp/test/functional/contacts_controller_test.rb +18 -0
  198. data/examples/pmp/test/functional/document_library_controller_test.rb +18 -0
  199. data/examples/pmp/test/functional/issues_controller_test.rb +18 -0
  200. data/examples/pmp/test/functional/projects_controller_test.rb +18 -0
  201. data/examples/pmp/test/functional/resources_controller_test.rb +18 -0
  202. data/examples/pmp/test/functional/tasks_controller_test.rb +18 -0
  203. data/examples/pmp/test/functional/time_cards_controller_test.rb +18 -0
  204. data/examples/pmp/test/test_helper.rb +28 -0
  205. data/examples/pmp/test/unit/contacts_test.rb +10 -0
  206. data/examples/pmp/test/unit/document_library_test.rb +10 -0
  207. data/examples/pmp/test/unit/issues_test.rb +10 -0
  208. data/examples/pmp/test/unit/projects_test.rb +10 -0
  209. data/examples/pmp/test/unit/resources_test.rb +10 -0
  210. data/examples/pmp/test/unit/tasks_test.rb +10 -0
  211. data/examples/pmp/test/unit/time_cards_test.rb +10 -0
  212. data/lib/QuickBaseClient.rb +5054 -0
  213. data/lib/QuickBaseCommandLineClient.rb +401 -0
  214. data/lib/QuickBaseContactsAppBuilder.rb +419 -0
  215. data/lib/QuickBaseEmailer.rb +334 -0
  216. data/lib/QuickBaseEventNotifier.rb +592 -0
  217. data/lib/QuickBaseMisc.rb +96 -0
  218. data/lib/QuickBaseObjects.rb +566 -0
  219. data/lib/QuickBaseRSSGenerator.rb +286 -0
  220. data/lib/QuickBaseTextData.rb +545 -0
  221. data/lib/QuickBaseTwitterConnector.rb +300 -0
  222. data/lib/QuickBaseWebClient.rb +126 -0
  223. data/lib/WorkPlaceClient.rb +45 -0
  224. data/lib/qbc.makeCSVFile.qbc +4 -0
  225. data/lib/qbc.makeCSVFile.rb +17 -0
  226. data/lib/quickbase_adapter.rb +320 -0
  227. data/lib/runFieldEntryDialog.rb +151 -0
  228. data/lib/runOfflineFieldEntryDialog.rb +203 -0
  229. data/rakefile +100 -0
  230. data/test/run_tests.bat +7 -0
  231. data/test/spec_all_tests.rb +13 -0
  232. data/test/spec_smoke_tests.rb +58 -0
  233. data/test/spec_workplace_addrecord_test.rb +46 -0
  234. data/test/spec_workplace_base_test.rb +57 -0
  235. data/test/spec_workplace_editrecord_test.rb +38 -0
  236. data/test/spec_workplace_json_test.rb +38 -0
  237. data/test/spec_workplace_objects_test.rb +39 -0
  238. data/test/spec_workplace_smoke_tests.rb +45 -0
  239. metadata +353 -0
@@ -0,0 +1,401 @@
1
+ #--#####################################################################
2
+ # Copyright (c) 2009 Gareth Lewis and Intuit, Inc.
3
+ #
4
+ # All rights reserved. This program and the accompanying materials
5
+ # are made available under the terms of the Eclipse Public License v1.0
6
+ # which accompanies this distribution, and is available at
7
+ # http://www.opensource.org/licenses/eclipse-1.0.php
8
+ #
9
+ # Contributors:
10
+ # Gareth Lewis - Initial contribution.
11
+ # Intuit Partner Platform.
12
+ #++#####################################################################
13
+
14
+ require 'QuickBaseClient'
15
+
16
+ module QuickBase
17
+
18
+ # This implements an extensible command line interface to QuickBase.
19
+ # Use setCommand() and setCommandAlias() to extend or modify the interface.
20
+ #
21
+ # Call run() to use the command line interactively.
22
+ #
23
+ # Call run( filename ) to run the commands in a file.
24
+ #
25
+ # Commands entered during an interactive session can be recorded to a file.
26
+ #
27
+ # In addition to the @commands loaded in initialize(), any public method
28
+ # from class Client can be used as a command, and any line of Ruby code
29
+ # can be executed.
30
+ #
31
+ # Run a command line client session interactively, or using the commands in a file. e.g.:
32
+ # * ruby QuickBaseCommandLineClient.rb run
33
+ # * ruby QuickBaseCommandLineClient.rb run dailyTasks.qbc
34
+ # * ruby -e "require 'quickbasecommandlineclient';QuickBase::CommandLineClient.new.run"
35
+ #
36
+ class CommandLineClient < Client
37
+
38
+ attr_reader :usage, :commands, :aliases, :availableCommands
39
+
40
+ # Information needed to display and run a command
41
+ class Command
42
+ attr_reader :name, :desc, :prerequisite, :args, :code, :prompt
43
+ def initialize( name, desc, prerequisite, args, code, prompt = nil )
44
+ @name, @desc, @prerequisite, @args, @code, @prompt = name, desc, prerequisite, args, code, prompt
45
+ end
46
+ end
47
+
48
+ # Display a message telling the user what to do.
49
+ def showUsage
50
+ if @usage.nil?
51
+ @usage = <<USAGE
52
+
53
+ Enter a command from the list of available commands.
54
+ The list of commands may change after each command.
55
+ Type TABs, commas, or spaces between parts of a command.
56
+ Use double-quotes if your commands contain TABs, commas or spaces.
57
+
58
+ e.g. addfield "my text field" text
59
+
60
+ USAGE
61
+ end
62
+
63
+ puts @usage
64
+ end
65
+
66
+ # Set up some basic commands and their abbreviations
67
+ def initialize
68
+ super
69
+
70
+ # the main purpose of commands and aliases loaded here is reduce the
71
+ # steps, typing and clicking needed to get simple things done in QuickBase
72
+
73
+ setCommand( "signin", "Sign into QuickBase", "@ticket.nil?", [ "username", "password" ], [ :authenticate ] )
74
+
75
+ setCommand( "create", "Create an application", "@ticket", [ "application name", "description" ], [ :createDatabase, :onChangedDbid ] )
76
+ setCommand( "copy", "Copy an application, with/out data", "@ticket and @dbid", [ "name", "desc", "keep data?" ], [ :_cloneDatabase, :onChangedDbid ] )
77
+ setCommand( "open", "Open an application", "@ticket", [ "application name" ], [ :findDBByname, :onChangedDbid ] )
78
+ setCommand( "use", "Use a table from the current application","@ticket and @dbid and @chdbids", [ "table name" ], [ :lookupChdbid, :onChangedDbid ] )
79
+
80
+ setCommand( "select", "Select records using a query name", "@ticket and @dbid", [ "query name" ], [ :_doQueryName, :resetrid ] )
81
+ setCommand( "setrecord", "Set the active record", "@ticket and @dbid", [ "record number" ], [ :_setActiveRecord ] )
82
+
83
+ setCommand( "changerecords", "Conditionally set field value", "@ticket and @dbid and @fields", [ "field", "value", "testfld", "test", "testval" ], [ :changeRecords ], "Are you sure?" )
84
+ setCommand( "deleterecords", "Conditionally delete records", "@ticket and @dbid and @fields", [ "test field", "test", "test value" ], [ :deleteRecords ], "Are you sure?" )
85
+ setCommand( "deleteallrecords", "Delete all records", "@ticket and @dbid", nil, [ :deleteRecords, :resetrid ], "Are you sure?" )
86
+
87
+ setCommand( "addrecord","Add a record to the active table", "@ticket and @dbid", nil, [ :_addRecord, :_getRecordInfo ] )
88
+ setCommand( "setfield", "Set a field value in the active record", "@ticket and @dbid and @rid", [ "field name", "value"], [ :setFieldValue ] )
89
+
90
+ setCommand( "addfield", "Add a field to the active table", "@ticket and @dbid", [ "field name" , "field type" ], [ :_addField ] )
91
+ setCommand( "addfieldchoices", "Add value choices for a field", "@ticket and @dbid", [ "field name" , "[choice1,choice2]" ], [ :_fieldNameAddChoices ] )
92
+
93
+ setCommand( "importfile","Import records from a CSV file", "@ticket and @dbid", [ "file name" ], [ :importCSVFile, :resetrid ] )
94
+ setCommand( "importexcelfile","Import records from Excel", "@ticket and @dbid", [ "Excel(.xls) file name", "last import column" ], [ :_importFromExcel, :resetrid ] )
95
+ setCommand( "exportfile","Export records to a CSV file", "@ticket and @dbid", [ "file name" ], [ :makeSVFile ] )
96
+
97
+ setCommand( "uploadfile", "Upload a file into a new record", "@ticket and @dbid", [ "file name", "file attachment field name" ], [:_uploadFile] )
98
+ setCommand( "updatefile", "Update the file attachment in a record","@ticket and @dbid and @rid", [ "file name", "file attachment field name" ], [:_updateFile] )
99
+
100
+ setCommand( "deletefield", "Delete a field from the active table", "@ticket and @dbid", [ "field name" ], [:_deleteFieldName], "Are you sure?" )
101
+ setCommand( "deletetable", "Delete the active table", "@ticket and @dbid", nil, [ :_deleteDatabase, :resetrid ], "Are you sure?" )
102
+
103
+ setCommand( "print", "Prints the results of the last command", "@ticket", nil, [ :_printChildElements ] )
104
+ setCommand( "listapps", "Lists the applications you can access", "@ticket", nil, [ :grantedDBs, :_printChildElements ] )
105
+
106
+ setCommand( "uselog", "Logs requests and responses to a file", "true", [ "log file" ], [ :logToFile ] )
107
+
108
+ setCommand( "signout", "Sign out of QuickBase", "@ticket", nil, [ :signOut ] )
109
+
110
+ @aliases = { "si" => "signin", "la" => "listapps", "o" => "open",
111
+ "p" => "print", "so" => "signout", "af" => "addfield",
112
+ "sel" => "select", "ar" => "addrecord", "sf" => "setfield",
113
+ "sr" => "setrecord", "q" => "quit", "if" => "importfile",
114
+ "ef" => "exportfile", "ulf" => "uploadfile", "udf" => "updatefile",
115
+ "r" => "run", "ul" => "uselog" }
116
+
117
+ end
118
+
119
+ # Add a command to the list of available commands
120
+ def setCommand( name, desc, prerequisite, args, code, prompt = nil )
121
+ @commands = Hash.new if @commands.nil?
122
+ cmd = Command.new( name, desc, prerequisite, args, code, prompt )
123
+ @commands[ name ] = cmd
124
+ end
125
+
126
+ # Set the alias, or abbreviation, for a command
127
+ def setCommandAlias( anAlias, cmd )
128
+ @aliases = Hash.new if @aliases.nil?
129
+ @aliases[ anAlias ] = cmd
130
+ end
131
+
132
+ # Get a list of commands that are valid now
133
+ def evalAvailableCommands
134
+ @availableCommands = Array.new
135
+ @commands.each{ |name,cmd|
136
+ @availableCommands << name if eval( cmd.prerequisite )
137
+ }
138
+ end
139
+
140
+ # Make a string to display a command to the user
141
+ def cmdString( command, include_desc = true )
142
+
143
+ ret = ""
144
+
145
+ cmd = @commands[command]
146
+ if cmd
147
+
148
+ cmdalias = ""
149
+ if @aliases and @aliases.has_value?( cmd.name )
150
+ @aliases.each{ |k,v| cmdalias << "#{k}," if v == cmd.name }
151
+ cmdalias[-1] = ""
152
+ cmdalias = "(#{cmdalias})"
153
+ end
154
+
155
+ if cmd.args
156
+ if include_desc
157
+ ret = "#{cmd.name}#{cmdalias} '#{cmd.args.join( ',' )}': #{cmd.desc}"
158
+ else
159
+ ret = "#{cmd.name}#{cmdalias} '#{cmd.args.join( ',' )}'"
160
+ end
161
+ else
162
+ if include_desc
163
+ ret = "#{cmd.name}#{cmdalias} : #{cmd.desc}"
164
+ else
165
+ ret = "#{cmd.name}#{cmdalias}"
166
+ end
167
+ end
168
+ end
169
+ ret
170
+ end
171
+
172
+ # Display the commands currently available
173
+ def showAvailableCommands
174
+ evalAvailableCommands
175
+ puts "\nCommands available:"
176
+ puts
177
+ puts " quit(q): End this command session"
178
+ puts " usage: Show how to use this program"
179
+ puts " ruby 'rubycode': run a line of ruby language code"
180
+ puts " run(r) 'filename': run the commands in a file"
181
+ puts " record 'filename': records your commands in a file"
182
+ @availableCommands.sort().each { |cmd| puts " #{cmdString( cmd )}" }
183
+ puts "\n"
184
+ end
185
+
186
+ # Prompt the user if a command requires an 'Are you sure?' type of response
187
+ def prompt( promptString )
188
+ if promptString
189
+ print "#{promptString} (Press 'y' if Yes): "
190
+ yn = gets
191
+ yn.chop!
192
+ return false if yn != "y"
193
+ end
194
+ true
195
+ end
196
+
197
+ # The main command entry and processing loop
198
+ def run( filename = nil )
199
+
200
+ begin
201
+
202
+ if filename
203
+ file = File.new( filename )
204
+ else
205
+ showUsage
206
+ end
207
+
208
+ recordedCommandsFile = nil
209
+
210
+ loop {
211
+
212
+ resetErrorInfo
213
+
214
+ if filename.nil?
215
+ showAvailableCommands
216
+
217
+ print "Enter a command: "
218
+ inputLine = gets
219
+
220
+ else
221
+ evalAvailableCommands
222
+ inputLine = file.gets
223
+ break if inputLine.nil?
224
+ end
225
+
226
+ if inputLine.index( '\t' )
227
+ separator = "\t"
228
+ elsif inputLine.index( "," )
229
+ separator = ","
230
+ else
231
+ separator = " "
232
+ end
233
+
234
+ args = inputLine.split
235
+ inputcommand = args[0]
236
+
237
+ if filename.nil? and recordedCommandsFile and inputcommand != "record"
238
+ recordedCommandsFile.write( inputLine )
239
+ end
240
+
241
+ input = splitString( inputLine, separator )
242
+
243
+ if input and input.length > 0
244
+
245
+ (0..input.length-1).each{ |i| input[i].strip!;input[i].gsub!( "\"", "") }
246
+
247
+ if @aliases and @aliases.include?( inputcommand )
248
+ command = @aliases[ inputcommand ]
249
+ else
250
+ command = inputcommand
251
+ end
252
+
253
+ break if command == "quit"
254
+
255
+ if command == "usage"
256
+ showUsage
257
+ elsif command == "record"
258
+ if input.length == 2
259
+ recordedCommandsFile.close if recordedCommandsFile
260
+ recordedCommandsFile = File.open( input[ 1 ], "w" )
261
+ puts "Unable to open file '#{input[ 1 ]}' for writing." if recordedCommandsFile.nil?
262
+ elsif input.length < 2
263
+ puts "Command file name is missing. Enter 'record filename'"
264
+ end
265
+ elsif command == "run"
266
+ if input.length == 2 and FileTest.readable?( input[ 1 ] )
267
+ run( input[ 1 ] )
268
+ elsif input.length < 2
269
+ puts "Command file name is missing. Enter 'run filename'"
270
+ else
271
+ puts "'#{input[1]}' is not a readable file"
272
+ end
273
+ elsif command == "ruby"
274
+ begin
275
+ inputLine.sub!( "ruby", "" )
276
+ puts inputLine
277
+ eval( inputLine )
278
+ rescue StandardError => e
279
+ puts "Error: #{e}"
280
+ end
281
+ elsif command == "?"
282
+ showAvailableCommands
283
+ puts "API commands:\n#{clientMethods().sort().join(', ')}\n"
284
+ elsif @commands and @commands.include?( command ) and @availableCommands.include?( command )
285
+
286
+ cmd = @commands[ command ]
287
+ input.shift
288
+
289
+ if cmd.args and cmd.args.length == 1
290
+ inputLine.sub!( inputcommand, "" )
291
+ inputLine.strip!
292
+ input = [ inputLine ]
293
+ end
294
+
295
+ if prompt( cmd.prompt )
296
+ begin
297
+ if cmd.args and input.length == cmd.args.length
298
+ case input.length
299
+ when 1
300
+ puts "#{cmd.code[0]}( #{input[0]} )"
301
+ send( cmd.code[0], input[0] )
302
+ when 2
303
+ puts "#{cmd.code[0]}( #{input[0]}, #{input[1]} )"
304
+ send( cmd.code[0], input[0], input[1] )
305
+ when 3
306
+ puts "#{cmd.code[0]}( #{input[0]}, #{input[1]}, #{input[2]} )"
307
+ send( cmd.code[0], input[0], input[1], input[2] )
308
+ when 4
309
+ puts "#{cmd.code[0]}( #{input[0]}, #{input[1]}, #{input[2]} , #{input[3]})"
310
+ send( cmd.code[0], input[0], input[1], input[2], input[3] )
311
+ when 5
312
+ puts "#{cmd.code[0]}( #{input[0]}, #{input[1]}, #{input[2]} , #{input[3]}, #{input[4]})"
313
+ send( cmd.code[0], input[0], input[1], input[2], input[3], input[4] )
314
+ end
315
+
316
+ (1..cmd.code.length-1).each{ |c|
317
+ puts "#{cmd.code[c]}"
318
+ send( cmd.code[c] )
319
+ }
320
+
321
+ elsif cmd.args.nil?
322
+ cmd.code.each{ |c|
323
+ puts "#{c}"
324
+ send( c )
325
+ }
326
+ else
327
+ puts "Information missing: #{cmdString( command, false )}"
328
+ end
329
+ rescue StandardError => e
330
+ puts "Error: #{e}"
331
+ end
332
+ end
333
+
334
+ elsif clientMethods().include?( command )
335
+ puts inputLine
336
+ begin
337
+ eval( inputLine )
338
+ rescue StandardError => e
339
+ puts "Error: #{e}"
340
+ end
341
+ else
342
+ puts "Invalid command '#{inputcommand}'"
343
+ end
344
+
345
+ if (!@requestSucceeded.nil?) and @requestSucceeded == false
346
+ puts "\n#{@lastError}"
347
+ end
348
+
349
+ if filename.nil?
350
+ print "\nPress Enter to continue..."
351
+ gets
352
+ end
353
+
354
+ end
355
+
356
+ }
357
+
358
+ rescue StandardError => e
359
+ puts "Error: #{e}"
360
+ ensure
361
+ signOut if @ticket and filename.nil?
362
+ recordedCommandsFile.close if recordedCommandsFile
363
+ end
364
+ end
365
+
366
+ end #class CommandLineClient -------------------------------------
367
+
368
+ end #module QuickBase ---------------------------------------------
369
+
370
+ def testQuickBaseCLClient( filename = nil )
371
+ include QuickBase
372
+ qbCLClient = CommandLineClient.new
373
+ qbCLClient.run( filename )
374
+ end
375
+
376
+ #-----------------------------------------------------------------------------------
377
+ # To test the QuickBase::CommandLineClient, copy the #require 'QuickBaseCommandLineClient'
378
+ # and '#testQuickBaseCLClient' lines # below into testQBCLC.rb, uncomment the
379
+ # lines and run 'ruby testQBCLC.rb' .
380
+ #-----------------------------------------------------------------------------------
381
+ #require 'QuickBaseCommandLineClient'
382
+ #testQuickBaseCLClient
383
+
384
+ # Run a command line client session interactively, or using the commands in a file.
385
+ # e.g. ruby QuickBaseCommandLineClient.rb run
386
+ # e.g. ruby QuickBaseCommandLineClient.rb run dailyTasks.qbc
387
+ if __FILE__ == $0 and ARGV.length > 0
388
+ if ARGV[0] == "run"
389
+ qbclc = QuickBase::CommandLineClient.new
390
+ if ARGV.length > 1
391
+ if FileTest.readable?( ARGV[1] )
392
+ qbclc.run( ARGV[1] )
393
+ else
394
+ puts "File '#{ARGV[1]}' is not a readable file."
395
+ end
396
+ else
397
+ ARGV.shift
398
+ qbclc.run()
399
+ end
400
+ end
401
+ end
@@ -0,0 +1,419 @@
1
+ #--#####################################################################
2
+ # Copyright (c) 2009 Gareth Lewis and Intuit, Inc.
3
+ #
4
+ # All rights reserved. This program and the accompanying materials
5
+ # are made available under the terms of the Eclipse Public License v1.0
6
+ # which accompanies this distribution, and is available at
7
+ # http://www.opensource.org/licenses/eclipse-1.0.php
8
+ #
9
+ # Contributors:
10
+ # Gareth Lewis - Initial contribution.
11
+ # Intuit Partner Platform.
12
+ #++#####################################################################
13
+
14
+ require 'WorkPlaceClient'
15
+
16
+ # usage: ruby QuickBaseContactsAppBuilder.rb username password [useWorkPlace].
17
+ # Creates a very simple Contacts database in QuickBase and a Rails app for it.
18
+ class QuickBaseContactsAppBuilder
19
+
20
+ def initialize(username,password,useWorkPlace=nil)
21
+ begin
22
+ if useWorkPlace
23
+ @qbc = QuickBase::WorkPlaceClient.new(username,password)
24
+ else
25
+ @qbc = QuickBase::Client.new(username,password)
26
+ end
27
+
28
+ raise @qbc.errtext if ! @qbc.requestSucceeded
29
+
30
+ @useWorkPlace = useWorkPlace
31
+ @username, @password = username,password
32
+
33
+ @rails_appname = @username.downcase.gsub( /\W/, "_" )
34
+ @rails_appname << "_contacts"
35
+ @rootClassName = ""
36
+ @rails_appname.split(/_/).each{|s| @rootClassName << s.capitalize }
37
+ @modelClassName = @rootClassName.dup
38
+ @modelClassName[-1] = ""
39
+ @modelFileName = @rails_appname.dup
40
+ @modelFileName[-1] = ""
41
+ @modelFileName << ".rb"
42
+
43
+ buildApp
44
+ rescue StandardError => connectionError
45
+ puts "\n\nError connectiong to #{ useWorkPlace ? 'workplace.intuit.com' : 'www.quickbase.com'}: #{connectionError}\n\n"
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def buildApp
52
+ if runRailsCommand
53
+ #@qbc.printRequestsAndResponses=true
54
+ if @qbc.findDBByName(@rails_appname) or @qbc.createDatabase(@rails_appname,"This application was generated using QuickBaseContactsAppBuilder.rb.")
55
+ begin
56
+ @contactsTableID = @qbc.lookupChdbid(@rails_appname, @qbc.dbid)
57
+ addFields
58
+ addSampleData
59
+ begin
60
+ generateRailsFiles
61
+ displayDoneMsg
62
+ rescue StandardError => localerror
63
+ puts "\n\nError generating rails files: #{localerror}\n\n"
64
+ end
65
+ rescue StandardError => qberror
66
+ if qberror.to_s.include?("Invalid Application Token")
67
+ puts "\n\nPlease go to QuickBase, open the '#{@rails_appname}' app, uncheck 'Require Application Tokens' and run this ruby script again.\n\n"
68
+ else
69
+ puts "\n\nError adding fields or data to the '#{@rails_appname}' app: #{qberror}."
70
+ puts "Please go to QuickBase, open the '#{@rails_appname}' app, uncheck 'Require Application Tokens' and run this ruby script again.\n\n"
71
+ end
72
+ end
73
+ else
74
+ puts "Error creating the #{@rails_appname} application.\nAre '#{@username}' and '#{@password}' correct?\n"
75
+ end
76
+ else
77
+ puts "Error running 'rails #{@rails_appname}'.\n"
78
+ end
79
+ end
80
+
81
+ def fields
82
+ ["name","phone","email","title","company"]
83
+ end
84
+
85
+ def addFields
86
+ @clist = ""
87
+ fields.each{|field|
88
+ id,label = @qbc.addField(@contactsTableID,field,"text")
89
+ @clist << "#{id.dup}."
90
+ }
91
+ @clist[-1] = ""
92
+ end
93
+
94
+ def addSampleData
95
+
96
+ sampleData = <<ENDSampleData
97
+ Fred Davis,434-344-1243,freddavis@internet.com,CEO,DavisCo
98
+ David Fredis,344-434-1243,davidfredis@email.com,Product Manager,Blaxo LLC
99
+ Freda Davis,434-344-1243,fredadavis@internet.com,Technical Lead,Nerds Inc.
100
+ Andy Tabo,454-344-1243,atabo@internet.co.uk,Senior Advisor,Carpet World
101
+ Larry Good,334-344-1243,lgood@yahaol.com,VP,Harbor Ventures LLC
102
+ ENDSampleData
103
+
104
+ @qbc.importFromCSV(@contactsTableID, @qbc.formatImportCSV(sampleData), @clist)
105
+
106
+ end
107
+
108
+ def runRailsCommand
109
+ ret = verifyDirectories
110
+ if runningOnWindows
111
+ ret = system('rails.bat', @rails_appname) unless ret
112
+ ret = system('rails.cmd', @rails_appname) unless ret
113
+ else
114
+ ret = system('rails', @rails_appname) unless ret
115
+ end
116
+ ret
117
+ end
118
+
119
+ def generateRailsFiles
120
+ #verifyDirectories
121
+ generateModel
122
+ generateViews
123
+ generateController
124
+ generateHelper
125
+ generateDatabaseConfig
126
+ generateRoutes
127
+ renameIndexHTML
128
+ end
129
+
130
+ def verifyDirectories
131
+ ok = File.directory?("#{@rails_appname}/app/models/")
132
+ ok = File.directory?("#{@rails_appname}/app/views/#{@rails_appname}/") if ok
133
+ ok = File.directory?("#{@rails_appname}/app/controllers/") if ok
134
+ ok = File.directory?("#{@rails_appname}/app/helpers/") if ok
135
+ ok = File.directory?("#{@rails_appname}/config/") if ok
136
+ ok
137
+ end
138
+
139
+ def generateModel
140
+
141
+ modelCode = <<ENDModelCode
142
+
143
+ class #{@modelClassName} < ActiveRecord::Base
144
+ def self.listAll
145
+ find_by_sql("#{@contactsTableID}:{'0'.CT.''}")
146
+ end
147
+ end
148
+
149
+ ENDModelCode
150
+
151
+ File.open("#{@rails_appname}/app/models/#{@modelFileName}", "w"){|f|f.write(modelCode)}
152
+
153
+ end
154
+
155
+ def generateViews
156
+ Dir.mkdir("#{@rails_appname}/app/views/#{@rails_appname}/") unless File.directory?("#{@rails_appname}/app/views/#{@rails_appname}/")
157
+ generateListAllView
158
+ generateShowView
159
+ generateNewView
160
+ generateEditView
161
+ generateNewContactForm
162
+ generateEditContactForm
163
+ end
164
+
165
+ def generateListAllView
166
+
167
+ listAllCode = <<ENDListAllCode
168
+
169
+ <h1>List All</h1>
170
+ <hr>
171
+ <% for contact in @contacts do %>
172
+ <%= contact.name %>,<%= contact.phone %>,<%= contact.email %>,<%= contact.title %>,<%= contact.company %>
173
+ <%= link_to 'Show', :action => 'show', :id => contact %>,
174
+ <%= link_to 'Edit', :action => 'edit', :id => contact %>,
175
+ <%= link_to 'Destroy', { :action => 'destroy', :id => contact }, :confirm => 'Are you sure?', :method => :post %> <hr>
176
+ <% end %>
177
+ <%= link_to 'New', :action => 'new' %>
178
+ ENDListAllCode
179
+
180
+ File.open("#{@rails_appname}/app/views/#{@rails_appname}/listAll.rhtml", "w" ){|f|f.write(listAllCode)}
181
+
182
+ end
183
+
184
+ def generateShowView
185
+
186
+ showCode = <<ENDShowCode
187
+ <h1>Show</h1>
188
+ <hr>
189
+
190
+ <p><b>Name</b> <%= @contact.name %></p>
191
+ <p><b>Phone</b> <%= @contact.phone %></p>
192
+ <p><b>Email</b> <%= @contact.email %></p>
193
+ <p><b>Title</b> <%= @contact.title %></p>
194
+ <p><b>Company</b> <%= @contact.company %></p>
195
+ <%= link_to 'Edit', :action => 'edit', :id => @contact %> |
196
+ <%= link_to 'Back', :action => 'listAll' %>
197
+ ENDShowCode
198
+
199
+ File.open("#{@rails_appname}/app/views/#{@rails_appname}/show.rhtml", "w" ){|f|f.write(showCode)}
200
+
201
+ end
202
+
203
+ def generateNewView
204
+
205
+ newCode = <<ENDNewCode
206
+ <h1>New</h1>
207
+ <hr>
208
+ <% form_tag :action => 'create', :id => @contact do %>
209
+ <%= render :partial => 'newform' %>
210
+ <%= submit_tag 'Create' %>
211
+ <% end %>
212
+ <%= link_to 'Back', :action => 'listAll' %>
213
+ ENDNewCode
214
+
215
+ File.open("#{@rails_appname}/app/views/#{@rails_appname}/new.rhtml", "w" ){|f|f.write(newCode)}
216
+
217
+ end
218
+
219
+ def generateEditView
220
+
221
+ editCode = <<EndEditCode
222
+ <h1>Edit</h1>
223
+ <hr>
224
+ <% form_tag :action => 'update', :id => @contact do %>
225
+ <%= render :partial => 'editform' %>
226
+ <%= submit_tag 'Edit' %>
227
+ <% end %>
228
+ <%= link_to 'Show', :action => 'show', :id => @contact %> |
229
+ <%= link_to 'Back', :action => 'listAll' %>
230
+ EndEditCode
231
+
232
+ File.open("#{@rails_appname}/app/views/#{@rails_appname}/edit.rhtml", "w" ){|f|f.write(editCode)}
233
+
234
+ end
235
+
236
+ def generateEditContactForm
237
+
238
+ formCode = <<ENDFormCode
239
+ <p><b>Name</b> <%= text_field 'contact[]', 'name' %></p>
240
+ <p><b>Phone</b> <%= text_field 'contact[]', 'phone' %></p>
241
+ <p><b>Email</b> <%= text_field 'contact[]', 'email' %></p>
242
+ <p><b>Title</b> <%= text_field 'contact[]', 'title' %></p>
243
+ <p><b>Company</b> <%= text_field 'contact[]', 'company' %></p>
244
+ ENDFormCode
245
+
246
+ File.open("#{@rails_appname}/app/views/#{@rails_appname}/_editform.rhtml", "w" ){|f|f.write(formCode)}
247
+
248
+ end
249
+
250
+ def generateNewContactForm
251
+ formCode = <<ENDFormCode
252
+ <p><b>Name</b> <%= text_field '#{@modelClassName}', 'name' %></p>
253
+ <p><b>Phone</b> <%= text_field '#{@modelClassName}', 'phone' %></p>
254
+ <p><b>Email</b> <%= text_field '#{@modelClassName}', 'email' %></p>
255
+ <p><b>Title</b> <%= text_field '#{@modelClassName}', 'title' %></p>
256
+ <p><b>Company</b> <%= text_field '#{@modelClassName}', 'company' %></p>
257
+ ENDFormCode
258
+
259
+ File.open("#{@rails_appname}/app/views/#{@rails_appname}/_newform.rhtml", "w" ){|f|f.write(formCode)}
260
+
261
+ end
262
+
263
+ def generateController
264
+
265
+ controllerCode = <<ENDControllerCode
266
+ class #{@rootClassName}Controller < ApplicationController
267
+ def listAll
268
+ @contacts = #{@modelClassName}.listAll
269
+ end
270
+ def listChanges
271
+ @contacts = #{@modelClassName}.listChanges
272
+ end
273
+ def show
274
+ @contact = #{@modelClassName}.find(params[:id])
275
+ end
276
+ def new
277
+ @contact = #{@modelClassName}.new
278
+ end
279
+ def edit
280
+ @contact = #{@modelClassName}.find(params[:id])
281
+ end
282
+ def destroy
283
+ #{@modelClassName}.find(params[:id]).destroy
284
+ index
285
+ end
286
+ def index
287
+ listAll
288
+ render :action => 'listAll'
289
+ end
290
+ def update
291
+ @contact = #{@modelClassName}.find(params[:id])
292
+ if @contact.update_attributes(params[:contact][params[:id]])
293
+ flash[:notice] = 'Contact was successfully updated.'
294
+ redirect_to :action => 'show', :id => @contact
295
+ else
296
+ render :action => 'edit'
297
+ end
298
+ end
299
+ def create
300
+ @contact = #{@modelClassName}.new(params[:#{@modelClassName}])
301
+ if @contact.save
302
+ flash[:notice] = 'Contact was successfully created.'
303
+ redirect_to :action => 'listAll'
304
+ else
305
+ render :action => 'new'
306
+ end
307
+ end
308
+ end
309
+
310
+ ENDControllerCode
311
+
312
+ File.open( "#{@rails_appname}/app/controllers/#{@rails_appname}_controller.rb", "w" ){|f|f.write(controllerCode)}
313
+
314
+ end
315
+
316
+ def generateHelper
317
+ helperCode = "module #{@rootClassName}Helper\nend\n"
318
+ File.open( "#{@rails_appname}/app/helpers/#{@rails_appname}_helper.rb", "w" ){|f|f.write(helperCode)}
319
+ end
320
+
321
+ def generateDatabaseConfig
322
+
323
+ databaseConfig = <<END_databaseConfig
324
+ development:
325
+ adapter: quickbase
326
+ database: #{@rails_appname}
327
+ username: #{@username}
328
+ password: #{@password}
329
+ printRequestsAndResponses: false
330
+ useWorkPlace: #{@useWorkPlace ? "true" : "false"}
331
+ cacheSchemas: true
332
+ decimalPrecision: 38
333
+ host: localhost
334
+
335
+ # Warning: The database defined as 'test' will be erased and
336
+ # re-generated from your development database when you run 'rake'.
337
+ # Do not set this db to the same as development or production.
338
+ test:
339
+ adapter: quickbase
340
+ database: #{@rails_appname}
341
+ username: #{@username}
342
+ password: #{@password}
343
+ useWorkPlace: #{@useWorkPlace ? "true" : "false"}
344
+ cacheSchemas: true
345
+ decimalPrecision: 38
346
+ host: localhost
347
+
348
+ production:
349
+ adapter: quickbase
350
+ database: #{@rails_appname}
351
+ username: #{@username}
352
+ password: #{@password}
353
+ cacheSchemas: true
354
+ useWorkPlace: #{@useWorkPlace ? "true" : "false"}
355
+ decimalPrecision: 38
356
+ host: localhost
357
+ END_databaseConfig
358
+
359
+ File.open( "#{@rails_appname}/config/database.yml", "w" ) {|f| f.write( databaseConfig ) }
360
+
361
+ end
362
+
363
+ def generateRoutes
364
+
365
+ routesCode = <<ENDRoutesCode
366
+ ActionController::Routing::Routes.draw do |map|
367
+ # The priority is based upon order of creation: first created -> highest priority.
368
+
369
+ # Sample of regular route:
370
+ # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
371
+ # Keep in mind you can assign values other than :controller and :action
372
+
373
+ # Sample of named route:
374
+ # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
375
+ # This route can be invoked with purchase_url(:id => product.id)
376
+
377
+ # You can have the root of your site routed by hooking up ''
378
+ # -- just remember to delete public/index.html.
379
+ map.connect '', :controller => "#{@rails_appname}", :action => "listAll"
380
+
381
+ # Allow downloading Web Service WSDL as a file with an extension
382
+ # instead of a file named 'wsdl'
383
+ map.connect ':controller/service.wsdl', :action => 'wsdl'
384
+
385
+ # Install the default route as the lowest priority.
386
+ map.connect ':controller/:action/:id.:format'
387
+ map.connect ':controller/:action/:id'
388
+ end
389
+ ENDRoutesCode
390
+
391
+ File.open( "#{@rails_appname}/config/routes.rb", "w" ) {|f| f.write( routesCode) }
392
+
393
+ end
394
+
395
+ def renameIndexHTML
396
+ File.rename( "#{@rails_appname}/public/index.html", "#{@rails_appname}/public/renamed.index.html" ) if File.exist?("#{@rails_appname}/public/index.html")
397
+ end
398
+
399
+ def displayDoneMsg
400
+ puts "\n\nDone creating the '#{@rails_appname}' application!\n\n"
401
+ puts "Please start 'ruby script/server' in the #{@rails_appname} directory"
402
+ puts "then go to http://localhost:3000/ in your browser.\n\n"
403
+ end
404
+
405
+ def runningOnWindows
406
+ RUBY_PLATFORM.split("-")[1].include?("mswin")
407
+ end
408
+
409
+ end
410
+
411
+ if ARGV[2]
412
+ QuickBaseContactsAppBuilder.new(ARGV[0],ARGV[1],ARGV[2])
413
+ elsif ARGV[1]
414
+ QuickBaseContactsAppBuilder.new(ARGV[0],ARGV[1])
415
+ else
416
+ puts "usage: ruby QuickBaseContactsAppBuilder.rb username password [useWorkPlace]"
417
+ puts "Creates a very simple Contacts database in QuickBase and a Rails app for it."
418
+ puts "To use workplace.intuit.com instead of www.quickbase.com, add 'useWorkPlace' at the end of the command."
419
+ end