rhoconnect 3.0.0.beta1

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 (361) hide show
  1. data/CHANGELOG +208 -0
  2. data/CREDITS +38 -0
  3. data/Gemfile +18 -0
  4. data/Gemfile.lock +97 -0
  5. data/LICENSE +75 -0
  6. data/README.md +10 -0
  7. data/Rakefile +82 -0
  8. data/bench/bench +7 -0
  9. data/bench/bench_runner.rb +112 -0
  10. data/bench/benchapp/Gemfile +21 -0
  11. data/bench/benchapp/Gemfile.lock +76 -0
  12. data/bench/benchapp/Rakefile +22 -0
  13. data/bench/benchapp/application.rb +39 -0
  14. data/bench/benchapp/config.ru +36 -0
  15. data/bench/benchapp/settings/license.key +1 -0
  16. data/bench/benchapp/settings/settings.yml +20 -0
  17. data/bench/benchapp/sources/mock_adapter.rb +55 -0
  18. data/bench/benchapp/sources/queue_mock_adapter.rb +2 -0
  19. data/bench/benchapp/spec/sources/mock_adapter_spec.rb +25 -0
  20. data/bench/benchapp/spec/sources/queue_mock_adapter_spec.rb +25 -0
  21. data/bench/benchapp/spec/spec_helper.rb +42 -0
  22. data/bench/blobapp/Gemfile +31 -0
  23. data/bench/blobapp/Gemfile.lock +103 -0
  24. data/bench/blobapp/Rakefile +25 -0
  25. data/bench/blobapp/application.rb +44 -0
  26. data/bench/blobapp/config.ru +36 -0
  27. data/bench/blobapp/settings/license.key +1 -0
  28. data/bench/blobapp/settings/settings.yml +16 -0
  29. data/bench/blobapp/sources/blob_adapter.rb +71 -0
  30. data/bench/blobapp/spec/sources/blob_adapter_spec.rb +25 -0
  31. data/bench/blobapp/spec/spec_helper.rb +42 -0
  32. data/bench/lib/bench/cli.rb +16 -0
  33. data/bench/lib/bench/logging.rb +13 -0
  34. data/bench/lib/bench/mock_client.rb +41 -0
  35. data/bench/lib/bench/result.rb +50 -0
  36. data/bench/lib/bench/runner.rb +107 -0
  37. data/bench/lib/bench/session.rb +67 -0
  38. data/bench/lib/bench/statistics.rb +56 -0
  39. data/bench/lib/bench/test_data.rb +98 -0
  40. data/bench/lib/bench/timer.rb +10 -0
  41. data/bench/lib/bench/utils.rb +49 -0
  42. data/bench/lib/bench.rb +129 -0
  43. data/bench/lib/testdata/100-data.txt +148 -0
  44. data/bench/lib/testdata/5-data.txt +9 -0
  45. data/bench/lib/testdata/images/icon.ico +0 -0
  46. data/bench/lib/testdata/images/icon.png +0 -0
  47. data/bench/lib/testdata/images/loading-Landscape.png +0 -0
  48. data/bench/lib/testdata/images/loading-LandscapeLeft.png +0 -0
  49. data/bench/lib/testdata/images/loading-LandscapeRight.png +0 -0
  50. data/bench/lib/testdata/images/loading-Portrait.png +0 -0
  51. data/bench/lib/testdata/images/loading-PortraitUpsideDown.png +0 -0
  52. data/bench/lib/testdata/images/loading.png +0 -0
  53. data/bench/lib/testdata/images/loading@2x.png +0 -0
  54. data/bench/run_bench.sh +42 -0
  55. data/bench/run_blob_script.sh +3 -0
  56. data/bench/run_cud_script.sh +3 -0
  57. data/bench/run_query_md_script.sh +3 -0
  58. data/bench/run_query_only_script.sh +3 -0
  59. data/bench/run_query_script.sh +3 -0
  60. data/bench/scripts/blob_cud_script.rb +98 -0
  61. data/bench/scripts/cud_script.rb +92 -0
  62. data/bench/scripts/helpers.rb +101 -0
  63. data/bench/scripts/query_md_script.rb +45 -0
  64. data/bench/scripts/query_only_script.rb +51 -0
  65. data/bench/scripts/query_script.rb +45 -0
  66. data/bench/spec/bench_spec_helper.rb +33 -0
  67. data/bench/spec/logging_spec.rb +15 -0
  68. data/bench/spec/mock_adapter_spec.rb +61 -0
  69. data/bench/spec/mock_client_spec.rb +65 -0
  70. data/bench/spec/result_spec.rb +61 -0
  71. data/bench/spec/utils_spec.rb +36 -0
  72. data/bin/rhoconnect +34 -0
  73. data/bin/rhoconnect-setup +84 -0
  74. data/doc/async-jobs.txt +69 -0
  75. data/doc/authentication.txt +76 -0
  76. data/doc/benchmarks.txt +168 -0
  77. data/doc/blob-sync.txt +130 -0
  78. data/doc/bulk-sync.txt +102 -0
  79. data/doc/client.txt +432 -0
  80. data/doc/command-line.txt +210 -0
  81. data/doc/contributing.txt +60 -0
  82. data/doc/deploying.txt +82 -0
  83. data/doc/install.txt +28 -0
  84. data/doc/introduction.txt +20 -0
  85. data/doc/licensing.txt +18 -0
  86. data/doc/metadata.txt +458 -0
  87. data/doc/migration.txt +182 -0
  88. data/doc/public/css/print.css +29 -0
  89. data/doc/public/css/screen.css +257 -0
  90. data/doc/public/css/style.css +20 -0
  91. data/doc/push.txt +135 -0
  92. data/doc/release.txt +41 -0
  93. data/doc/rest-api.txt +367 -0
  94. data/doc/source-adapters.txt +325 -0
  95. data/doc/stats-middleware.txt +69 -0
  96. data/doc/testing.txt +222 -0
  97. data/doc/tutorial.txt +315 -0
  98. data/doc/web-console.txt +35 -0
  99. data/examples/simple/Rakefile +14 -0
  100. data/examples/simple/application.rb +27 -0
  101. data/examples/simple/config.ru +49 -0
  102. data/examples/simple/settings/license.key +1 -0
  103. data/examples/simple/settings/settings.yml +23 -0
  104. data/examples/simple/sources/sample_adapter.rb +5 -0
  105. data/examples/simple/sources/simple_adapter.rb +5 -0
  106. data/generators/rhoconnect.rb +119 -0
  107. data/generators/templates/application/Gemfile +21 -0
  108. data/generators/templates/application/Rakefile +22 -0
  109. data/generators/templates/application/application.rb +39 -0
  110. data/generators/templates/application/config.ru +36 -0
  111. data/generators/templates/application/settings/license.key +1 -0
  112. data/generators/templates/application/settings/settings.yml +14 -0
  113. data/generators/templates/application/spec/spec_helper.rb +42 -0
  114. data/generators/templates/source/source_adapter.rb +47 -0
  115. data/generators/templates/source/source_spec.rb +25 -0
  116. data/install.sh +408 -0
  117. data/installer/unix-like/rho_connect_install_checkers.rb +140 -0
  118. data/installer/unix-like/rho_connect_install_constants.rb +51 -0
  119. data/installer/unix-like/rho_connect_install_debian.rb +63 -0
  120. data/installer/unix-like/rho_connect_install_dnd.rb +58 -0
  121. data/installer/unix-like/rho_connect_install_get_params.rb +30 -0
  122. data/installer/unix-like/rho_connect_install_installers.rb +142 -0
  123. data/installer/unix-like/rho_connect_install_utilities.rb +85 -0
  124. data/installer/unix-like/rho_connect_install_yum.rb +63 -0
  125. data/installer/unix-like/rhoinstaller.rb +89 -0
  126. data/installer/utils/create_texts.rb +366 -0
  127. data/installer/utils/install_test.rb +140 -0
  128. data/installer/windows/EnvVarUpdate.nsh +328 -0
  129. data/installer/windows/ServiceLib.nsh +369 -0
  130. data/installer/windows/configUi.ini +44 -0
  131. data/installer/windows/icon.ico +0 -0
  132. data/installer/windows/rhosync.nsi +418 -0
  133. data/installer/windows/uninstall.bat +7 -0
  134. data/lib/rhoconnect/api/admin/get_api_token.rb +14 -0
  135. data/lib/rhoconnect/api/admin/get_license_info.rb +8 -0
  136. data/lib/rhoconnect/api/admin/login.rb +6 -0
  137. data/lib/rhoconnect/api/admin/reset.rb +10 -0
  138. data/lib/rhoconnect/api/admin/stats.rb +21 -0
  139. data/lib/rhoconnect/api/application/bulk_data.rb +7 -0
  140. data/lib/rhoconnect/api/application/clientcreate.rb +8 -0
  141. data/lib/rhoconnect/api/application/clientlogin.rb +6 -0
  142. data/lib/rhoconnect/api/application/clientregister.rb +6 -0
  143. data/lib/rhoconnect/api/application/clientreset.rb +6 -0
  144. data/lib/rhoconnect/api/application/query.rb +7 -0
  145. data/lib/rhoconnect/api/application/queue_updates.rb +6 -0
  146. data/lib/rhoconnect/api/application/search.rb +6 -0
  147. data/lib/rhoconnect/api/client/create_client.rb +3 -0
  148. data/lib/rhoconnect/api/client/delete_client.rb +5 -0
  149. data/lib/rhoconnect/api/client/get_client_params.rb +3 -0
  150. data/lib/rhoconnect/api/client/list_client_docs.rb +12 -0
  151. data/lib/rhoconnect/api/client/list_clients.rb +3 -0
  152. data/lib/rhoconnect/api/client/ping.rb +7 -0
  153. data/lib/rhoconnect/api/source/get_adapter.rb +3 -0
  154. data/lib/rhoconnect/api/source/get_db_doc.rb +7 -0
  155. data/lib/rhoconnect/api/source/get_source_params.rb +3 -0
  156. data/lib/rhoconnect/api/source/list_source_docs.rb +10 -0
  157. data/lib/rhoconnect/api/source/list_sources.rb +15 -0
  158. data/lib/rhoconnect/api/source/push_deletes.rb +8 -0
  159. data/lib/rhoconnect/api/source/push_objects.rb +8 -0
  160. data/lib/rhoconnect/api/source/save_adapter.rb +3 -0
  161. data/lib/rhoconnect/api/source/set_db_doc.rb +8 -0
  162. data/lib/rhoconnect/api/source/set_refresh_time.rb +8 -0
  163. data/lib/rhoconnect/api/source/upload_file.rb +4 -0
  164. data/lib/rhoconnect/api/user/create_user.rb +7 -0
  165. data/lib/rhoconnect/api/user/delete_user.rb +9 -0
  166. data/lib/rhoconnect/api/user/list_users.rb +3 -0
  167. data/lib/rhoconnect/api/user/update_user.rb +4 -0
  168. data/lib/rhoconnect/api_token.rb +19 -0
  169. data/lib/rhoconnect/app.rb +76 -0
  170. data/lib/rhoconnect/bulk_data/bulk_data.rb +88 -0
  171. data/lib/rhoconnect/bulk_data/syncdb.index.schema +4 -0
  172. data/lib/rhoconnect/bulk_data/syncdb.schema +41 -0
  173. data/lib/rhoconnect/bulk_data.rb +2 -0
  174. data/lib/rhoconnect/client.rb +96 -0
  175. data/lib/rhoconnect/client_sync.rb +412 -0
  176. data/lib/rhoconnect/console/app/helpers/auth_helper.rb +22 -0
  177. data/lib/rhoconnect/console/app/helpers/extensions.rb +19 -0
  178. data/lib/rhoconnect/console/app/helpers/helpers.rb +57 -0
  179. data/lib/rhoconnect/console/app/public/ThickBox.css +649 -0
  180. data/lib/rhoconnect/console/app/public/home.css +438 -0
  181. data/lib/rhoconnect/console/app/public/images/foot_logo_rhoconnect.png +0 -0
  182. data/lib/rhoconnect/console/app/public/images/header_halo.jpg +0 -0
  183. data/lib/rhoconnect/console/app/public/images/land_separator.gif +0 -0
  184. data/lib/rhoconnect/console/app/public/images/landing_header.jpg +0 -0
  185. data/lib/rhoconnect/console/app/public/images/logo_rhoconnect.png +0 -0
  186. data/lib/rhoconnect/console/app/public/images/rhomobile_rhohub_logo.png +0 -0
  187. data/lib/rhoconnect/console/app/public/images/tabs_separator.png +0 -0
  188. data/lib/rhoconnect/console/app/public/jqplot/excanvas.min.js +35 -0
  189. data/lib/rhoconnect/console/app/public/jqplot/jqplot.barRenderer.min.js +34 -0
  190. data/lib/rhoconnect/console/app/public/jqplot/jqplot.canvasAxisLabelRenderer.js +187 -0
  191. data/lib/rhoconnect/console/app/public/jqplot/jqplot.canvasAxisTickRenderer.js +226 -0
  192. data/lib/rhoconnect/console/app/public/jqplot/jqplot.canvasTextRenderer.js +408 -0
  193. data/lib/rhoconnect/console/app/public/jqplot/jqplot.categoryAxisRenderer.min.js +34 -0
  194. data/lib/rhoconnect/console/app/public/jqplot/jqplot.cursor.js +952 -0
  195. data/lib/rhoconnect/console/app/public/jqplot/jqplot.dateAxisRenderer.js +313 -0
  196. data/lib/rhoconnect/console/app/public/jqplot/jqplot.dateAxisRenderer.min.js +34 -0
  197. data/lib/rhoconnect/console/app/public/jqplot/jqplot.pointLabels.min.js +34 -0
  198. data/lib/rhoconnect/console/app/public/jqplot/jquery-1.4.2.min.js +154 -0
  199. data/lib/rhoconnect/console/app/public/jqplot/jquery.jqplot.min.css +1 -0
  200. data/lib/rhoconnect/console/app/public/jqplot/jquery.jqplot.min.js +34 -0
  201. data/lib/rhoconnect/console/app/public/main.css +7 -0
  202. data/lib/rhoconnect/console/app/public/reset.css +76 -0
  203. data/lib/rhoconnect/console/app/public/style.css +2201 -0
  204. data/lib/rhoconnect/console/app/public/text.txt +0 -0
  205. data/lib/rhoconnect/console/app/routes/adapter.rb +28 -0
  206. data/lib/rhoconnect/console/app/routes/auth.rb +29 -0
  207. data/lib/rhoconnect/console/app/routes/client.rb +31 -0
  208. data/lib/rhoconnect/console/app/routes/docs.rb +145 -0
  209. data/lib/rhoconnect/console/app/routes/heroku.rb +19 -0
  210. data/lib/rhoconnect/console/app/routes/home.rb +63 -0
  211. data/lib/rhoconnect/console/app/routes/timing.rb +242 -0
  212. data/lib/rhoconnect/console/app/routes/user.rb +117 -0
  213. data/lib/rhoconnect/console/app/views/adapter.erb +16 -0
  214. data/lib/rhoconnect/console/app/views/client.erb +30 -0
  215. data/lib/rhoconnect/console/app/views/content.erb +14 -0
  216. data/lib/rhoconnect/console/app/views/doc.erb +8 -0
  217. data/lib/rhoconnect/console/app/views/docdata.erb +28 -0
  218. data/lib/rhoconnect/console/app/views/docs.erb +30 -0
  219. data/lib/rhoconnect/console/app/views/edituser.erb +13 -0
  220. data/lib/rhoconnect/console/app/views/headermenu.erb +40 -0
  221. data/lib/rhoconnect/console/app/views/home.erb +24 -0
  222. data/lib/rhoconnect/console/app/views/index.erb +58 -0
  223. data/lib/rhoconnect/console/app/views/jqplot.erb +52 -0
  224. data/lib/rhoconnect/console/app/views/layout.erb +165 -0
  225. data/lib/rhoconnect/console/app/views/login.erb +26 -0
  226. data/lib/rhoconnect/console/app/views/newuser.erb +17 -0
  227. data/lib/rhoconnect/console/app/views/ping.erb +28 -0
  228. data/lib/rhoconnect/console/app/views/result.erb +11 -0
  229. data/lib/rhoconnect/console/app/views/rightboxlinks.erb +15 -0
  230. data/lib/rhoconnect/console/app/views/select_doc.erb +17 -0
  231. data/lib/rhoconnect/console/app/views/upload_doc.erb +23 -0
  232. data/lib/rhoconnect/console/app/views/user.erb +29 -0
  233. data/lib/rhoconnect/console/app/views/users.erb +12 -0
  234. data/lib/rhoconnect/console/rhoconnect_api.rb +245 -0
  235. data/lib/rhoconnect/console/server.rb +32 -0
  236. data/lib/rhoconnect/console.rb +3 -0
  237. data/lib/rhoconnect/cors.rb +229 -0
  238. data/lib/rhoconnect/credential.rb +9 -0
  239. data/lib/rhoconnect/db_adapter.rb +46 -0
  240. data/lib/rhoconnect/document.rb +49 -0
  241. data/lib/rhoconnect/dynamic_adapter.rb +91 -0
  242. data/lib/rhoconnect/generator.rb +1 -0
  243. data/lib/rhoconnect/jobs/bulk_data_job.rb +203 -0
  244. data/lib/rhoconnect/jobs/ping_job.rb +46 -0
  245. data/lib/rhoconnect/jobs/source_job.rb +16 -0
  246. data/lib/rhoconnect/license.rb +86 -0
  247. data/lib/rhoconnect/lock_ops.rb +11 -0
  248. data/lib/rhoconnect/model.rb +414 -0
  249. data/lib/rhoconnect/ping/android.rb +56 -0
  250. data/lib/rhoconnect/ping/apple.rb +52 -0
  251. data/lib/rhoconnect/ping/blackberry.rb +56 -0
  252. data/lib/rhoconnect/ping.rb +3 -0
  253. data/lib/rhoconnect/read_state.rb +31 -0
  254. data/lib/rhoconnect/rho_indifferent_access.rb +88 -0
  255. data/lib/rhoconnect/server/views/index.erb +13 -0
  256. data/lib/rhoconnect/server.rb +286 -0
  257. data/lib/rhoconnect/source.rb +289 -0
  258. data/lib/rhoconnect/source_adapter.rb +123 -0
  259. data/lib/rhoconnect/source_sync.rb +302 -0
  260. data/lib/rhoconnect/stats/middleware.rb +20 -0
  261. data/lib/rhoconnect/stats/record.rb +108 -0
  262. data/lib/rhoconnect/store.rb +232 -0
  263. data/lib/rhoconnect/tasks.rb +350 -0
  264. data/lib/rhoconnect/test_methods.rb +220 -0
  265. data/lib/rhoconnect/user.rb +95 -0
  266. data/lib/rhoconnect/version.rb +3 -0
  267. data/lib/rhoconnect/x_domain_session_wrapper.rb +53 -0
  268. data/lib/rhoconnect.rb +285 -0
  269. data/rhoconnect.gemspec +67 -0
  270. data/spec/api/admin/api_token_spec.rb +14 -0
  271. data/spec/api/admin/get_api_token_spec.rb +36 -0
  272. data/spec/api/admin/get_license_info_spec.rb +38 -0
  273. data/spec/api/admin/reset_spec.rb +22 -0
  274. data/spec/api/admin/stats_spec.rb +66 -0
  275. data/spec/api/api_helper.rb +21 -0
  276. data/spec/api/application/rhoconnect_api_spec.rb +548 -0
  277. data/spec/api/client/create_client_spec.rb +13 -0
  278. data/spec/api/client/delete_client_spec.rb +13 -0
  279. data/spec/api/client/get_client_params_spec.rb +18 -0
  280. data/spec/api/client/list_client_docs_spec.rb +32 -0
  281. data/spec/api/client/list_clients_spec.rb +22 -0
  282. data/spec/api/client/ping_spec.rb +23 -0
  283. data/spec/api/rhosync_api_spec.rb.orig +606 -0
  284. data/spec/api/source/adapter_spec.rb +29 -0
  285. data/spec/api/source/get_db_doc_spec.rb +21 -0
  286. data/spec/api/source/get_source_params_spec.rb +32 -0
  287. data/spec/api/source/list_source_docs_spec.rb +25 -0
  288. data/spec/api/source/list_sources_spec.rb +26 -0
  289. data/spec/api/source/push_deletes_spec.rb +18 -0
  290. data/spec/api/source/push_objects_spec.rb +27 -0
  291. data/spec/api/source/set_db_doc_spec.rb +19 -0
  292. data/spec/api/source/set_refresh_time_spec.rb +43 -0
  293. data/spec/api/source/upload_file_spec.rb +26 -0
  294. data/spec/api/user/create_user_spec.rb +16 -0
  295. data/spec/api/user/delete_user_spec.rb +36 -0
  296. data/spec/api/user/list_users_spec.rb +30 -0
  297. data/spec/api/user/update_user_spec.rb +31 -0
  298. data/spec/api_token_spec.rb +14 -0
  299. data/spec/app_spec.rb +18 -0
  300. data/spec/apps/emptyapp/application.rb +27 -0
  301. data/spec/apps/emptyapp/settings/license.key +1 -0
  302. data/spec/apps/emptyapp/settings/settings.yml +14 -0
  303. data/spec/apps/rhotestapp/Rakefile +1 -0
  304. data/spec/apps/rhotestapp/application.rb +19 -0
  305. data/spec/apps/rhotestapp/config.ru +1 -0
  306. data/spec/apps/rhotestapp/settings/apple_fake_cert.pem +1 -0
  307. data/spec/apps/rhotestapp/settings/license.key +1 -0
  308. data/spec/apps/rhotestapp/settings/settings.yml +36 -0
  309. data/spec/apps/rhotestapp/sources/base_adapter.rb +9 -0
  310. data/spec/apps/rhotestapp/sources/fixed_schema_adapter.rb +28 -0
  311. data/spec/apps/rhotestapp/sources/sample_adapter.rb +71 -0
  312. data/spec/apps/rhotestapp/sources/simple_adapter.rb +41 -0
  313. data/spec/apps/rhotestapp/sources/sub_adapter.rb +7 -0
  314. data/spec/apps/rhotestapp/vendor/mygem-0.1.0/lib/mygem/mygem.rb +8 -0
  315. data/spec/apps/rhotestapp/vendor/mygem-0.1.0/lib/mygem.rb +1 -0
  316. data/spec/bulk_data/bulk_data_spec.rb +97 -0
  317. data/spec/client_spec.rb +124 -0
  318. data/spec/client_sync_spec.rb +774 -0
  319. data/spec/doc/base.html +72 -0
  320. data/spec/doc/doc_spec.rb +376 -0
  321. data/spec/doc/footer.html +4 -0
  322. data/spec/doc/header.html +30 -0
  323. data/spec/document_spec.rb +31 -0
  324. data/spec/dynamic_adapter_spec.rb +43 -0
  325. data/spec/factories/factories.rb +17 -0
  326. data/spec/generator/generator_spec.rb +58 -0
  327. data/spec/generator/generator_spec_helper.rb +9 -0
  328. data/spec/jobs/bulk_data_job_spec.rb +125 -0
  329. data/spec/jobs/ping_job_spec.rb +102 -0
  330. data/spec/jobs/source_job_spec.rb +29 -0
  331. data/spec/license_spec.rb +66 -0
  332. data/spec/model_spec.rb +273 -0
  333. data/spec/perf/bulk_data_perf_spec.rb +32 -0
  334. data/spec/perf/perf_spec_helper.rb +50 -0
  335. data/spec/perf/store_perf_spec.rb +27 -0
  336. data/spec/ping/android_spec.rb +91 -0
  337. data/spec/ping/apple_spec.rb +70 -0
  338. data/spec/ping/blackberry_spec.rb +62 -0
  339. data/spec/read_state_spec.rb +35 -0
  340. data/spec/rhosync_spec.rb +75 -0
  341. data/spec/server/cors_spec.rb +287 -0
  342. data/spec/server/server_spec.rb +470 -0
  343. data/spec/server/x_domain_session_wrapper_spec.rb +150 -0
  344. data/spec/source_adapter_spec.rb +125 -0
  345. data/spec/source_spec.rb +114 -0
  346. data/spec/source_sync_spec.rb +328 -0
  347. data/spec/spec.opts +4 -0
  348. data/spec/spec_helper.rb +231 -0
  349. data/spec/stats/middleware_spec.rb +53 -0
  350. data/spec/stats/record_spec.rb +92 -0
  351. data/spec/store_spec.rb +251 -0
  352. data/spec/support/shared_examples.rb +168 -0
  353. data/spec/sync_states_spec.rb +72 -0
  354. data/spec/test_methods_spec.rb +134 -0
  355. data/spec/testdata/1000-data.txt +1414 -0
  356. data/spec/testdata/compressed/compress-data.txt +1 -0
  357. data/spec/testdata/upload1.txt +1 -0
  358. data/spec/testdata/upload2.txt +1 -0
  359. data/spec/user_spec.rb +139 -0
  360. data/tasks/redis.rake +206 -0
  361. metadata +706 -0
@@ -0,0 +1,414 @@
1
+ module Rhoconnect
2
+ # Taken from http://github.com/voloko/redis-model
3
+ #
4
+ # Simple models for redis-rb.
5
+
6
+ class Model
7
+ attr_accessor :id
8
+
9
+ def initialize(id=nil)
10
+ self.id = id
11
+ end
12
+
13
+ def redis #:nodoc:
14
+ self.class.redis
15
+ end
16
+
17
+ # Issues delete commands for all defined fields
18
+ def delete(name = nil)
19
+ if name
20
+ redis.del field_key(name.to_s)
21
+ else
22
+ self.class.fields.each do |field|
23
+ redis.del field_key(field[:name])
24
+ end
25
+ end
26
+ end
27
+
28
+ def field_key(name) #:nodoc:
29
+ self.class._field_key(prefix,id,name)
30
+ end
31
+
32
+ # Increment the specified integer field by 1 or the
33
+ # specified amount.
34
+ def increment!(name,amount=1)
35
+ raise ArgumentError, "Only integer fields can be incremented." unless self.class.fields.include?({:name => name.to_s, :type => :integer})
36
+ redis.incr(field_key(name), amount)
37
+ end
38
+
39
+ # Decrement the specified integer field by 1 or the
40
+ # specified amount.
41
+ def decrement!(name,amount=1)
42
+ raise ArgumentError, "Only integer fields can be decremented." unless self.class.fields.include?({:name => name.to_s, :type => :integer})
43
+ redis.decr(field_key(name), amount)
44
+ end
45
+
46
+ def next_id #:nodoc:
47
+ redis.incr "sequence:#{self.prefix}:id"
48
+ end
49
+
50
+ def self.is_exist?(id)
51
+ !redis.get(self._field_key(self._prefix,id,'rho__id')).nil?
52
+ end
53
+
54
+ def to_array
55
+ res = []
56
+ self.class.fields.each do |field|
57
+ res << field.merge!(:value => send(field[:name].to_sym))
58
+ end
59
+ res
60
+ end
61
+
62
+ # TODO: not used anymore
63
+ # def update(attribs)
64
+ # self.class.fields.each do |field|
65
+ # if field[:name] != 'name' and field[:name] != 'rho__id'
66
+ # redis.del field_key(field[:name])
67
+ # end
68
+ # end
69
+ # self.class.populate_attributes(self,attribs)
70
+ # end
71
+
72
+ protected
73
+ def prefix #:nodoc:
74
+ @prefix ||= self.class.prefix || self.class.class_prefix(self.class)
75
+ end
76
+
77
+ class << self
78
+ # Defaults to model_name.dasherize
79
+ attr_accessor :prefix
80
+ attr_accessor :validates_presence
81
+
82
+ def _prefix
83
+ class_prefix(self)
84
+ end
85
+
86
+ def _field_key(p,i,n) #:nodoc:
87
+ "#{p}:#{i}:#{n}"
88
+ end
89
+
90
+ def class_prefix(classname)
91
+ classname.to_s.
92
+ sub(%r{(.*::)}, '').
93
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
94
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
95
+ downcase
96
+ end
97
+
98
+ # Creates new model instance with new uniqid
99
+ # NOTE: "sequence:model_name:id" key is used
100
+ def create(params = {}, attributes = {})
101
+ raise ArgumentError.new("Record already exists for '#{params[:id]}'") if self.is_exist?(params[:id])
102
+ if self.validates_presence
103
+ self.validates_presence.each do |field|
104
+ raise ArgumentError.new("Missing required field '#{field}'") unless params[field]
105
+ end
106
+ end
107
+ o = self.new
108
+ o.id = params[:id].nil? ? o.next_id : params[:id]
109
+ params[:rho__id] = params[:id]
110
+ populate_model(o,params)
111
+ populate_attributes(o,attributes)
112
+ end
113
+
114
+ def load(id, params={})
115
+ populate_attributes(self.with_key(id),params) if self.is_exist?(id)
116
+ end
117
+
118
+ def populate_attributes(obj,attribs)
119
+ attribs.each do |attrib,value|
120
+ obj.send "#{attrib.to_s}=".to_sym, value
121
+ end
122
+ obj
123
+ end
124
+
125
+ def validates_presence_of(*names)
126
+ self.validates_presence ||= []
127
+ names.each do |name|
128
+ self.validates_presence << name
129
+ end
130
+ end
131
+
132
+ # Creates new model instance with given id
133
+ alias_method :with_key, :new
134
+ alias_method :with_next_key, :create
135
+
136
+ # Defines marshaled rw accessor for redis string value
137
+ def field(name, type = :string)
138
+ if @fields.nil?
139
+ @fields = []
140
+ field :rho__id, :string
141
+ end
142
+ type = type.to_sym
143
+ type = :integer if type == :int
144
+
145
+ class_name = marshal_class_name(name, type)
146
+
147
+ fields << {:name => name.to_s, :type => type}
148
+ if type == :string
149
+ class_eval "def #{name}; @#{name} ||= redis[field_key('#{name}')]; end"
150
+ class_eval "def #{name}=(value); @#{name} = redis[field_key('#{name}')] = value; end"
151
+ else
152
+ class_eval "def #{name}; @#{name} ||= Marshal::#{class_name}.load(redis[field_key('#{name}')]); end"
153
+ class_eval "def #{name}=(value); @#{name} = value; redis[field_key('#{name}')] = Marshal::#{class_name}.dump(value); end"
154
+ end
155
+ end
156
+ alias_method :value, :field
157
+
158
+ # Defines accessor for redis list
159
+ def list(name, type = :string)
160
+ class_name = marshal_class_name(name, type)
161
+
162
+ fields << {:name => name.to_s, :type => :list}
163
+ class_eval "def #{name}; @#{name} ||= ListProxy.new(self.redis, field_key('#{name}'), Marshal::#{class_name}); end"
164
+ eval_writer(name)
165
+ end
166
+
167
+ # Defines accessor for redis set
168
+ def set(name, type = :string)
169
+ class_name = marshal_class_name(name, type)
170
+
171
+ fields << {:name => name.to_s, :type => :set}
172
+ class_eval "def #{name}; @#{name} ||= SetProxy.new(self.redis, field_key('#{name}'), Marshal::#{class_name}); end"
173
+ eval_writer(name)
174
+ end
175
+
176
+ def marshal_class_name(name, type)
177
+ Marshal::TYPES[type] or raise ArgumentError.new("Unknown type #{type} for field #{name}")
178
+ end
179
+
180
+ # Redefine this to change connection options
181
+ def redis
182
+ @@redis ||= Store.db
183
+ end
184
+
185
+ def fields #:nodoc:
186
+ @fields ||= []
187
+ end
188
+
189
+ protected
190
+ def eval_writer(name) #:nodoc:
191
+ class_eval <<-END
192
+ def #{name}=(value)
193
+ field = self.#{name};
194
+ if value.respond_to?(:each)
195
+ value.each {|v| field << v}
196
+ else
197
+ field << v
198
+ end
199
+ end
200
+ END
201
+ end
202
+
203
+ def populate_model(model, fields)
204
+ return model if fields.empty?
205
+ fields.each do |name,value|
206
+ model.send("#{name}=", value) if model.respond_to?(name)
207
+ end
208
+ model
209
+ end
210
+ end
211
+
212
+ module Marshal
213
+ TYPES = {
214
+ :string => 'String',
215
+ :integer => 'Integer',
216
+ :float => 'Float',
217
+ :datetime => 'DateTime',
218
+ :json => 'JSON',
219
+ }
220
+
221
+ class String
222
+ def self.dump(v)
223
+ v
224
+ end
225
+
226
+ def self.load(v)
227
+ v
228
+ end
229
+ end
230
+
231
+ class Integer
232
+ def self.dump(v)
233
+ v.to_s
234
+ end
235
+
236
+ def self.load(v)
237
+ v && v.to_i
238
+ end
239
+ end
240
+
241
+ class Float
242
+ def self.dump(v)
243
+ v.to_s
244
+ end
245
+
246
+ def self.load(v)
247
+ v && v.to_f
248
+ end
249
+ end
250
+
251
+ class DateTime
252
+ def self.dump(v)
253
+ v.strftime('%FT%T%z')
254
+ end
255
+
256
+ def self.load(v)
257
+ v && ::DateTime.strptime(v, '%FT%T%z')
258
+ end
259
+ end
260
+
261
+ class JSON
262
+ def self.dump(v)
263
+ ::JSON.dump(v)
264
+ end
265
+
266
+ def self.load(v)
267
+ v && ::JSON.load(v)
268
+ end
269
+ end
270
+ end
271
+
272
+
273
+
274
+ class FieldProxy #:nodoc
275
+ def initialize(redis, name, marshal)
276
+ @redis = redis
277
+ @name = name
278
+ @marshal = marshal
279
+ end
280
+
281
+ # def method_missing(method, *argv)
282
+ # translated_method = translate_method_name(method)
283
+ # raise NoMethodError.new("Method '#{method}' is not defined") unless translated_method
284
+ # @redis.send translated_method, @name, *argv
285
+ # end
286
+ #
287
+ # protected
288
+ # def translate_method_name(m)
289
+ # m
290
+ # end
291
+ end
292
+
293
+
294
+
295
+ class ListProxy < FieldProxy #:nodoc:
296
+ def <<(v)
297
+ @redis.rpush @name, @marshal.dump(v)
298
+ end
299
+ alias_method :push_tail, :<<
300
+
301
+ def push_head(v)
302
+ @redis.lpush @name, @marshal.dump(v)
303
+ end
304
+
305
+ def pop_tail
306
+ @marshal.load(@redis.rpop(@name))
307
+ end
308
+
309
+ def pop_head
310
+ @marshal.load(@redis.lpop(@name))
311
+ end
312
+
313
+ def [](from, to = nil)
314
+ if to.nil?
315
+ @marshal.load(@redis.lindex(@name, from))
316
+ else
317
+ @redis.lrange(@name, from, to).map! { |v| @marshal.load(v) }
318
+ end
319
+ end
320
+ alias_method :range, :[]
321
+
322
+ def []=(index, v)
323
+ @redis.lset(@name, index, @marshal.dump(v))
324
+ end
325
+ alias_method :set, :[]=
326
+
327
+ def include?(v)
328
+ @redis.exists(@name, @marshal.dump(v))
329
+ end
330
+
331
+ def remove(count, v)
332
+ @redis.lrem(@name, count, @marshal.dump(v))
333
+ end
334
+
335
+ # def length
336
+ # @redis.llen(@name)
337
+ # end
338
+ #
339
+ # def trim(from, to)
340
+ # @redis.ltrim(@name, from, to)
341
+ # end
342
+ #
343
+ # def to_s
344
+ # range(0, 100).join(', ')
345
+ # end
346
+ #
347
+ # protected
348
+ # def translate_method_name(m)
349
+ # COMMANDS[m]
350
+ # end
351
+ end
352
+
353
+
354
+
355
+ class SetProxy < FieldProxy #:nodoc:
356
+ # COMMANDS = {
357
+ # :intersect_store => "sinterstore",
358
+ # :union_store => "sunionstore",
359
+ # :diff_store => "sdiffstore",
360
+ # :move => "smove",
361
+ # }
362
+
363
+ def <<(v)
364
+ @redis.sadd @name, @marshal.dump(v)
365
+ end
366
+ alias_method :add, :<<
367
+
368
+ def delete(v)
369
+ @redis.srem @name, @marshal.dump(v)
370
+ end
371
+ alias_method :remove, :delete
372
+
373
+ def include?(v)
374
+ @redis.sismember @name, @marshal.dump(v)
375
+ end
376
+ alias_method :has_key?, :include?
377
+ alias_method :member?, :include?
378
+
379
+ def members
380
+ members = @redis.smembers(@name)
381
+ if members
382
+ members.map { |v| @marshal.load(v) }
383
+ else
384
+ []
385
+ end
386
+ end
387
+
388
+ def intersect(*keys)
389
+ @redis.sinter(@name, *keys).map { |v| @marshal.load(v) }
390
+ end
391
+
392
+ def union(*keys)
393
+ @redis.sunion(@name, *keys).map { |v| @marshal.load(v) }
394
+ end
395
+
396
+ def diff(*keys)
397
+ @redis.sdiff(@name, *keys).map { |v| @marshal.load(v) }
398
+ end
399
+
400
+ # def length
401
+ # @redis.llen(@name)
402
+ # end
403
+ #
404
+ # def to_s
405
+ # members.join(', ')
406
+ # end
407
+ #
408
+ # protected
409
+ # def translate_method_name(m)
410
+ # COMMANDS[m]
411
+ # end
412
+ end
413
+ end
414
+ end
@@ -0,0 +1,56 @@
1
+ require 'rest_client'
2
+
3
+ module Rhoconnect
4
+ class Android
5
+ class StaleAuthToken < Exception; end
6
+ class InvalidAuthToken < Exception; end
7
+ class AndroidPingError < Exception; end
8
+
9
+ def self.ping(params)
10
+ begin
11
+ settings = get_config(Rhoconnect.base_directory)[Rhoconnect.environment]
12
+ authtoken = settings[:authtoken]
13
+
14
+ RestClient.post(
15
+ 'https://android.apis.google.com/c2dm/send', c2d_message(params),
16
+ :authorization => "GoogleLogin auth=#{authtoken}"
17
+ ) do |response, request, result, &block|
18
+ # return exceptions based on response code & body
19
+ case response.code
20
+ when 200
21
+ # TODO: Automate authtoken updates
22
+ if response[:update_client_auth]
23
+ raise StaleAuthToken.new(
24
+ "Stale auth token, please update :authtoken: in settings.yml."
25
+ )
26
+ # body will contain the exception class
27
+ elsif response.body =~ /^Error=(.*)$/
28
+ raise AndroidPingError.new("Android ping error: #{$1 || ''}")
29
+ else
30
+ response.return!(request, result, &block)
31
+ end
32
+ when 401, 403
33
+ raise InvalidAuthToken.new("Invalid auth token, please update :authtoken: in settings.yml.")
34
+ end
35
+ end
36
+ rescue Exception => error
37
+ log error
38
+ log error.backtrace.join("\n")
39
+ raise error
40
+ end
41
+ end
42
+
43
+ def self.c2d_message(params)
44
+ params.reject! {|k,v| v.nil? || v.length == 0}
45
+ data = {}
46
+ data['registration_id'] = params['device_pin']
47
+ data['collapse_key'] = (rand * 100000000).to_i.to_s
48
+ data['data.do_sync'] = params['sources'] ? params['sources'].join(',') : ''
49
+ data['data.alert'] = params['message'] if params['message']
50
+ data['data.vibrate'] = params['vibrate'] if params['vibrate']
51
+ data['data.sound'] = params['sound'] if params['sound']
52
+ data['data.phone_id'] = params['phone_id'] if params['phone_id']
53
+ data
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,52 @@
1
+ require 'socket'
2
+ require 'openssl'
3
+ module Rhoconnect
4
+ class Apple
5
+ def self.ping(params)
6
+ settings = get_config(Rhoconnect.base_directory)[Rhoconnect.environment]
7
+ cert_file = File.join(Rhoconnect.base_directory,settings[:iphonecertfile])
8
+ cert = File.read(cert_file) if File.exists?(cert_file)
9
+ passphrase = settings[:iphonepassphrase]
10
+ host = settings[:iphoneserver]
11
+ port = settings[:iphoneport]
12
+ begin
13
+ ssl_ctx = OpenSSL::SSL::SSLContext.new
14
+ ssl_ctx.key = OpenSSL::PKey::RSA.new(cert, passphrase)
15
+ ssl_ctx.cert = OpenSSL::X509::Certificate.new(cert)
16
+
17
+ socket = TCPSocket.new(host, port)
18
+ ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_ctx)
19
+ ssl_socket.sync = true
20
+ ssl_socket.connect
21
+
22
+ ssl_socket.write(apn_message(params))
23
+ ssl_socket.close
24
+ socket.close
25
+ rescue SocketError => error
26
+ log "Error while sending ping: #{error}"
27
+ raise error
28
+ end
29
+ end
30
+
31
+ # Generates APNS package
32
+ def self.apn_message(params)
33
+ data = {}
34
+ data['aps'] = {}
35
+ data['aps']['alert'] = params['message'] if params['message']
36
+ data['aps']['badge'] = params['badge'].to_i if params['badge']
37
+ data['aps']['sound'] = params['sound'] if params['sound']
38
+ data['aps']['vibrate'] = params['vibrate'] if params['vibrate']
39
+ data['do_sync'] = params['sources'] if params['sources']
40
+ json = data.to_json
41
+ "\0\0 #{[params['device_pin'].delete(' ')].pack('H*')}\0#{json.length.chr}#{json}"
42
+ end
43
+ end
44
+
45
+ # Deprecated - use Apple instead
46
+ class Iphone < Apple
47
+ def self.ping(params)
48
+ log "DEPRECATION WARNING: 'iphone' is a deprecated device_type, use 'apple' instead"
49
+ super(params)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,56 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ module Rhoconnect
4
+ class Blackberry
5
+ def self.ping(params)
6
+ begin
7
+ settings = get_config(Rhoconnect.base_directory)[Rhoconnect.environment]
8
+ host = settings[:mdsserver]
9
+ port = settings[:mdsserverport]
10
+
11
+ headers = { "X-WAP-APPLICATION-ID" => "/",
12
+ "X-RIM-PUSH-DEST-PORT" => params['device_port'],
13
+ "CONTENT-TYPE" => 'multipart/related; type="application/xml"; boundary=asdlfkjiurwghasf'}
14
+
15
+ Net::HTTP.new(host,port).start do |http|
16
+ request = Net::HTTP::Post.new('/pap',headers)
17
+ request.body = pap_message(params)
18
+ http.request(request)
19
+ end
20
+
21
+ rescue Exception => error
22
+ log "Error while sending ping: #{error}"
23
+ raise error
24
+ end
25
+ end
26
+
27
+ def self.pap_message(params)
28
+ data = "do_sync=" + (params['sources'] ? params['sources'].join(',') : "") + "\r\n"
29
+ data << "alert=#{params['message']}\r\n" if params['message']
30
+ data << "vibrate=#{params['vibrate']}\r\n" if params['vibrate']
31
+ data << "sound=#{params['sound']}\r\n" if params['sound']
32
+ post_body = <<-DESC
33
+ --asdlfkjiurwghasf
34
+ Content-Type: application/xml; charset=UTF-8
35
+
36
+ <?xml version="1.0"?>
37
+ <!DOCTYPE pap PUBLIC "-//WAPFORUM//DTD PAP 2.0//EN"
38
+ "http://www.wapforum.org/DTD/pap_2.0.dtd"
39
+ [<?wap-pap-ver supported-versions="2.0"?>]>
40
+ <pap>
41
+ <push-message push-id="pushID:#{(rand * 100000000).to_i.to_s}" ppg-notify-requested-to="http://localhost:7778">
42
+
43
+ <address address-value="WAPPUSH=#{params['device_pin'].to_i.to_s(base=16).upcase}%3A100/TYPE=USER@rim.net"/>
44
+ <quality-of-service delivery-method="preferconfirmed"/>
45
+ </push-message>
46
+ </pap>
47
+ --asdlfkjiurwghasf
48
+ Content-Type: text/plain
49
+
50
+ #{data}
51
+ --asdlfkjiurwghasf--
52
+ DESC
53
+ post_body.gsub!(/\n/,"\r\n")
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,3 @@
1
+ require 'rhoconnect/ping/android'
2
+ require 'rhoconnect/ping/apple'
3
+ require 'rhoconnect/ping/blackberry'
@@ -0,0 +1,31 @@
1
+ module Rhoconnect
2
+ class ReadState < Model
3
+ field :refresh_time, :integer
4
+
5
+ def self.create(fields)
6
+ fields[:id] = get_id(fields)
7
+ fields.delete(:app_id)
8
+ fields.delete(:user_id)
9
+ fields.delete(:source_name)
10
+ fields[:refresh_time] ||= Time.now.to_i
11
+ super(fields,{})
12
+ end
13
+
14
+ def self.load(params)
15
+ super(get_id(params),{})
16
+ end
17
+
18
+ def self.delete(app_id)
19
+ Store.flash_data("#{class_prefix(self)}:#{app_id}:*")
20
+ end
21
+
22
+ def self.delete_user(params)
23
+ Store.flash_data("#{class_prefix(self)}:#{params[:app_id]}:#{params[:user_id]}:#{params[:source_name]}:*")
24
+ end
25
+
26
+ private
27
+ def self.get_id(params)
28
+ "#{params[:app_id]}:#{params[:user_id]}:#{params[:source_name]}"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,88 @@
1
+ # This class has dubious semantics and we only have it so that
2
+ # people can write params[:key] instead of params['key']
3
+ # and they get the same value for both keys.
4
+
5
+ module Rhoconnect
6
+ class RhoHashWithIndifferentAccess < Hash
7
+ def initialize(constructor = {})
8
+ if constructor.is_a?(Hash)
9
+ super()
10
+ update(constructor)
11
+ end
12
+ end
13
+
14
+ def default(key = nil)
15
+ if key.is_a?(Symbol) && include?(key = key.to_s)
16
+ self[key]
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ alias_method :regular_writer, :[]= #unless method_defined?(:regular_writer)
23
+ alias_method :regular_update, :update #unless method_defined?(:regular_update)
24
+
25
+ # Assigns a new value to the hash:
26
+ #
27
+ # hash = HashWithIndifferentAccess.new
28
+ # hash[:key] = "value"
29
+ #
30
+ def []=(key, value)
31
+ regular_writer(convert_key(key), convert_value(value))
32
+ end
33
+
34
+ # Updates the instantized hash with values from the second:
35
+ #
36
+ # hash_1 = HashWithIndifferentAccess.new
37
+ # hash_1[:key] = "value"
38
+ #
39
+ # hash_2 = HashWithIndifferentAccess.new
40
+ # hash_2[:key] = "New Value!"
41
+ #
42
+ # hash_1.update(hash_2) # => {"key"=>"New Value!"}
43
+ #
44
+ def update(other_hash)
45
+ other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
46
+ self
47
+ end
48
+
49
+ alias_method :merge!, :update
50
+
51
+ # Checks the hash for a key matching the argument passed in:
52
+ #
53
+ # hash = HashWithIndifferentAccess.new
54
+ # hash["key"] = "value"
55
+ # hash.key? :key # => true
56
+ # hash.key? "key" # => true
57
+ #
58
+ def key?(key)
59
+ super(convert_key(key))
60
+ end
61
+
62
+ alias_method :include?, :key?
63
+ alias_method :has_key?, :key?
64
+ alias_method :member?, :key?
65
+
66
+ def stringify_keys!; self end
67
+ def symbolize_keys!; self end
68
+ def to_options!; self end
69
+
70
+ protected
71
+ def convert_key(key)
72
+ key.kind_of?(Symbol) ? key.to_s : key
73
+ end
74
+
75
+ def convert_value(value)
76
+ value
77
+ end
78
+ end
79
+ end
80
+
81
+ class Hash
82
+ public
83
+ def with_indifferent_access
84
+ hash = Rhoconnect::RhoHashWithIndifferentAccess.new(self)
85
+ hash.default = self.default
86
+ hash
87
+ end
88
+ end