gooddata-edge 0.6.27.edge

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 (364) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.gitignore +36 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +89 -0
  6. data/.yardopts +22 -0
  7. data/CHANGELOG.md +196 -0
  8. data/CLI.md +439 -0
  9. data/DEPENDENCIES.md +817 -0
  10. data/Gemfile +4 -0
  11. data/Guardfile +5 -0
  12. data/LICENSE +22 -0
  13. data/LICENSE.rb +5 -0
  14. data/README.md +75 -0
  15. data/Rakefile +179 -0
  16. data/TODO.md +32 -0
  17. data/authors.sh +4 -0
  18. data/bin/gooddata +7 -0
  19. data/dependency_decisions.yml +104 -0
  20. data/gooddata +9 -0
  21. data/gooddata.gemspec +63 -0
  22. data/lib/gooddata.rb +31 -0
  23. data/lib/gooddata/app/app.rb +16 -0
  24. data/lib/gooddata/bricks/base_downloader.rb +86 -0
  25. data/lib/gooddata/bricks/brick.rb +38 -0
  26. data/lib/gooddata/bricks/bricks.rb +15 -0
  27. data/lib/gooddata/bricks/middleware/aws_middleware.rb +29 -0
  28. data/lib/gooddata/bricks/middleware/base_middleware.rb +56 -0
  29. data/lib/gooddata/bricks/middleware/bench_middleware.rb +24 -0
  30. data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +37 -0
  31. data/lib/gooddata/bricks/middleware/decode_params_middleware.rb +20 -0
  32. data/lib/gooddata/bricks/middleware/fs_download_middleware.rb +48 -0
  33. data/lib/gooddata/bricks/middleware/fs_upload_middleware.rb +36 -0
  34. data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +39 -0
  35. data/lib/gooddata/bricks/middleware/logger_middleware.rb +29 -0
  36. data/lib/gooddata/bricks/middleware/middleware.rb +12 -0
  37. data/lib/gooddata/bricks/middleware/restforce_middleware.rb +61 -0
  38. data/lib/gooddata/bricks/middleware/stdout_middleware.rb +23 -0
  39. data/lib/gooddata/bricks/middleware/twitter_middleware.rb +29 -0
  40. data/lib/gooddata/bricks/middleware/undot_params_middleware.rb +37 -0
  41. data/lib/gooddata/bricks/pipeline.rb +32 -0
  42. data/lib/gooddata/bricks/utils.rb +18 -0
  43. data/lib/gooddata/cli/cli.rb +27 -0
  44. data/lib/gooddata/cli/commands/auth_cmd.rb +29 -0
  45. data/lib/gooddata/cli/commands/domain_cmd.rb +28 -0
  46. data/lib/gooddata/cli/commands/project_cmd.rb +45 -0
  47. data/lib/gooddata/cli/hooks.rb +57 -0
  48. data/lib/gooddata/cli/shared.rb +61 -0
  49. data/lib/gooddata/cli/terminal.rb +20 -0
  50. data/lib/gooddata/client.rb +67 -0
  51. data/lib/gooddata/commands/api.rb +64 -0
  52. data/lib/gooddata/commands/auth.rb +107 -0
  53. data/lib/gooddata/commands/base.rb +12 -0
  54. data/lib/gooddata/commands/commands.rb +12 -0
  55. data/lib/gooddata/commands/datasets.rb +148 -0
  56. data/lib/gooddata/commands/datawarehouse.rb +20 -0
  57. data/lib/gooddata/commands/domain.rb +40 -0
  58. data/lib/gooddata/commands/process.rb +67 -0
  59. data/lib/gooddata/commands/project.rb +175 -0
  60. data/lib/gooddata/commands/projects.rb +20 -0
  61. data/lib/gooddata/commands/role.rb +36 -0
  62. data/lib/gooddata/commands/runners.rb +47 -0
  63. data/lib/gooddata/commands/scaffold.rb +69 -0
  64. data/lib/gooddata/commands/user.rb +39 -0
  65. data/lib/gooddata/connection.rb +127 -0
  66. data/lib/gooddata/core/core.rb +12 -0
  67. data/lib/gooddata/core/logging.rb +105 -0
  68. data/lib/gooddata/core/nil_logger.rb +23 -0
  69. data/lib/gooddata/core/project.rb +74 -0
  70. data/lib/gooddata/core/rest.rb +149 -0
  71. data/lib/gooddata/core/user.rb +20 -0
  72. data/lib/gooddata/data/data.rb +12 -0
  73. data/lib/gooddata/data/guesser.rb +122 -0
  74. data/lib/gooddata/exceptions/attr_element_not_found.rb +16 -0
  75. data/lib/gooddata/exceptions/command_failed.rb +11 -0
  76. data/lib/gooddata/exceptions/exceptions.rb +12 -0
  77. data/lib/gooddata/exceptions/execution_limit_exceeded.rb +13 -0
  78. data/lib/gooddata/exceptions/filter_maqlization.rb +16 -0
  79. data/lib/gooddata/exceptions/malformed_user.rb +15 -0
  80. data/lib/gooddata/exceptions/no_project_error.rb +15 -0
  81. data/lib/gooddata/exceptions/object_migration.rb +32 -0
  82. data/lib/gooddata/exceptions/project_not_found.rb +13 -0
  83. data/lib/gooddata/exceptions/segment_not_empty.rb +18 -0
  84. data/lib/gooddata/exceptions/uncomputable_report.rb +13 -0
  85. data/lib/gooddata/exceptions/user_in_different_domain.rb +15 -0
  86. data/lib/gooddata/exceptions/validation_error.rb +16 -0
  87. data/lib/gooddata/extensions/big_decimal.rb +17 -0
  88. data/lib/gooddata/extensions/enumerable.rb +39 -0
  89. data/lib/gooddata/extensions/extensions.rb +10 -0
  90. data/lib/gooddata/extensions/false.rb +15 -0
  91. data/lib/gooddata/extensions/hash.rb +38 -0
  92. data/lib/gooddata/extensions/nil.rb +15 -0
  93. data/lib/gooddata/extensions/numeric.rb +15 -0
  94. data/lib/gooddata/extensions/object.rb +27 -0
  95. data/lib/gooddata/extensions/symbol.rb +15 -0
  96. data/lib/gooddata/extensions/true.rb +15 -0
  97. data/lib/gooddata/extract.rb +21 -0
  98. data/lib/gooddata/goodzilla/goodzilla.rb +159 -0
  99. data/lib/gooddata/helpers/auth_helpers.rb +75 -0
  100. data/lib/gooddata/helpers/csv_helper.rb +61 -0
  101. data/lib/gooddata/helpers/data_helper.rb +116 -0
  102. data/lib/gooddata/helpers/global_helpers.rb +331 -0
  103. data/lib/gooddata/helpers/global_helpers_params.rb +172 -0
  104. data/lib/gooddata/helpers/helpers.rb +10 -0
  105. data/lib/gooddata/mixins/author.rb +26 -0
  106. data/lib/gooddata/mixins/content_getter.rb +15 -0
  107. data/lib/gooddata/mixins/content_property_reader.rb +17 -0
  108. data/lib/gooddata/mixins/content_property_writer.rb +17 -0
  109. data/lib/gooddata/mixins/contributor.rb +20 -0
  110. data/lib/gooddata/mixins/data_getter.rb +15 -0
  111. data/lib/gooddata/mixins/data_property_reader.rb +19 -0
  112. data/lib/gooddata/mixins/data_property_writer.rb +19 -0
  113. data/lib/gooddata/mixins/inspector.rb +53 -0
  114. data/lib/gooddata/mixins/is_attribute.rb +17 -0
  115. data/lib/gooddata/mixins/is_dimension.rb +17 -0
  116. data/lib/gooddata/mixins/is_fact.rb +17 -0
  117. data/lib/gooddata/mixins/is_label.rb +19 -0
  118. data/lib/gooddata/mixins/links.rb +15 -0
  119. data/lib/gooddata/mixins/md_finders.rb +77 -0
  120. data/lib/gooddata/mixins/md_grantees.rb +42 -0
  121. data/lib/gooddata/mixins/md_id_to_uri.rb +34 -0
  122. data/lib/gooddata/mixins/md_json.rb +15 -0
  123. data/lib/gooddata/mixins/md_lock.rb +87 -0
  124. data/lib/gooddata/mixins/md_object_id.rb +15 -0
  125. data/lib/gooddata/mixins/md_object_indexer.rb +64 -0
  126. data/lib/gooddata/mixins/md_object_query.rb +128 -0
  127. data/lib/gooddata/mixins/md_relations.rb +43 -0
  128. data/lib/gooddata/mixins/meta_getter.rb +17 -0
  129. data/lib/gooddata/mixins/meta_property_reader.rb +19 -0
  130. data/lib/gooddata/mixins/meta_property_writer.rb +19 -0
  131. data/lib/gooddata/mixins/mixins.rb +19 -0
  132. data/lib/gooddata/mixins/not_attribute.rb +17 -0
  133. data/lib/gooddata/mixins/not_exportable.rb +15 -0
  134. data/lib/gooddata/mixins/not_fact.rb +17 -0
  135. data/lib/gooddata/mixins/not_group.rb +17 -0
  136. data/lib/gooddata/mixins/not_label.rb +19 -0
  137. data/lib/gooddata/mixins/not_metric.rb +19 -0
  138. data/lib/gooddata/mixins/obj_id.rb +15 -0
  139. data/lib/gooddata/mixins/rest_getters.rb +17 -0
  140. data/lib/gooddata/mixins/rest_resource.rb +47 -0
  141. data/lib/gooddata/mixins/root_key_getter.rb +15 -0
  142. data/lib/gooddata/mixins/root_key_setter.rb +15 -0
  143. data/lib/gooddata/mixins/timestamps.rb +19 -0
  144. data/lib/gooddata/mixins/to_json.rb +11 -0
  145. data/lib/gooddata/mixins/uri_getter.rb +9 -0
  146. data/lib/gooddata/models/blueprint/anchor_field.rb +64 -0
  147. data/lib/gooddata/models/blueprint/attribute_field.rb +29 -0
  148. data/lib/gooddata/models/blueprint/blueprint.rb +11 -0
  149. data/lib/gooddata/models/blueprint/blueprint_field.rb +70 -0
  150. data/lib/gooddata/models/blueprint/dashboard_builder.rb +30 -0
  151. data/lib/gooddata/models/blueprint/dataset_blueprint.rb +449 -0
  152. data/lib/gooddata/models/blueprint/date_dimension.rb +14 -0
  153. data/lib/gooddata/models/blueprint/fact_field.rb +20 -0
  154. data/lib/gooddata/models/blueprint/label_field.rb +43 -0
  155. data/lib/gooddata/models/blueprint/project_blueprint.rb +746 -0
  156. data/lib/gooddata/models/blueprint/project_builder.rb +83 -0
  157. data/lib/gooddata/models/blueprint/reference_field.rb +43 -0
  158. data/lib/gooddata/models/blueprint/schema_blueprint.rb +160 -0
  159. data/lib/gooddata/models/blueprint/schema_builder.rb +89 -0
  160. data/lib/gooddata/models/blueprint/to_manifest.rb +181 -0
  161. data/lib/gooddata/models/blueprint/to_wire.rb +154 -0
  162. data/lib/gooddata/models/client.rb +182 -0
  163. data/lib/gooddata/models/client_synchronization_result.rb +31 -0
  164. data/lib/gooddata/models/client_synchronization_result_details.rb +41 -0
  165. data/lib/gooddata/models/datawarehouse.rb +92 -0
  166. data/lib/gooddata/models/domain.rb +479 -0
  167. data/lib/gooddata/models/execution.rb +115 -0
  168. data/lib/gooddata/models/execution_detail.rb +81 -0
  169. data/lib/gooddata/models/from_wire.rb +160 -0
  170. data/lib/gooddata/models/invitation.rb +75 -0
  171. data/lib/gooddata/models/links.rb +50 -0
  172. data/lib/gooddata/models/membership.rb +441 -0
  173. data/lib/gooddata/models/metadata.rb +272 -0
  174. data/lib/gooddata/models/metadata/attribute.rb +134 -0
  175. data/lib/gooddata/models/metadata/dashboard.rb +108 -0
  176. data/lib/gooddata/models/metadata/dashboard/dashboard_item.rb +76 -0
  177. data/lib/gooddata/models/metadata/dashboard/filter_apply_item.rb +37 -0
  178. data/lib/gooddata/models/metadata/dashboard/filter_item.rb +64 -0
  179. data/lib/gooddata/models/metadata/dashboard/geo_chart_item.rb +56 -0
  180. data/lib/gooddata/models/metadata/dashboard/headline_item.rb +56 -0
  181. data/lib/gooddata/models/metadata/dashboard/iframe_item.rb +46 -0
  182. data/lib/gooddata/models/metadata/dashboard/report_item.rb +92 -0
  183. data/lib/gooddata/models/metadata/dashboard/text_item.rb +55 -0
  184. data/lib/gooddata/models/metadata/dashboard_tab.rb +141 -0
  185. data/lib/gooddata/models/metadata/dataset.rb +64 -0
  186. data/lib/gooddata/models/metadata/dimension.rb +54 -0
  187. data/lib/gooddata/models/metadata/fact.rb +44 -0
  188. data/lib/gooddata/models/metadata/label.rb +128 -0
  189. data/lib/gooddata/models/metadata/metadata.rb +12 -0
  190. data/lib/gooddata/models/metadata/metric.rb +198 -0
  191. data/lib/gooddata/models/metadata/report.rb +247 -0
  192. data/lib/gooddata/models/metadata/report_definition.rb +264 -0
  193. data/lib/gooddata/models/metadata/scheduled_mail.rb +274 -0
  194. data/lib/gooddata/models/metadata/scheduled_mail/dashboard_attachment.rb +62 -0
  195. data/lib/gooddata/models/metadata/scheduled_mail/report_attachment.rb +64 -0
  196. data/lib/gooddata/models/metadata/variable.rb +91 -0
  197. data/lib/gooddata/models/model.rb +282 -0
  198. data/lib/gooddata/models/models.rb +12 -0
  199. data/lib/gooddata/models/module_constants.rb +31 -0
  200. data/lib/gooddata/models/process.rb +316 -0
  201. data/lib/gooddata/models/profile.rb +426 -0
  202. data/lib/gooddata/models/project.rb +1514 -0
  203. data/lib/gooddata/models/project_creator.rb +126 -0
  204. data/lib/gooddata/models/project_metadata.rb +67 -0
  205. data/lib/gooddata/models/project_role.rb +79 -0
  206. data/lib/gooddata/models/report_data_result.rb +266 -0
  207. data/lib/gooddata/models/schedule.rb +518 -0
  208. data/lib/gooddata/models/segment.rb +201 -0
  209. data/lib/gooddata/models/tab_builder.rb +27 -0
  210. data/lib/gooddata/models/user_filters/mandatory_user_filter.rb +76 -0
  211. data/lib/gooddata/models/user_filters/user_filter.rb +100 -0
  212. data/lib/gooddata/models/user_filters/user_filter_builder.rb +512 -0
  213. data/lib/gooddata/models/user_filters/user_filters.rb +13 -0
  214. data/lib/gooddata/models/user_filters/variable_user_filter.rb +31 -0
  215. data/lib/gooddata/models/user_group.rb +241 -0
  216. data/lib/gooddata/rest/README.md +37 -0
  217. data/lib/gooddata/rest/client.rb +389 -0
  218. data/lib/gooddata/rest/connection.rb +765 -0
  219. data/lib/gooddata/rest/object.rb +69 -0
  220. data/lib/gooddata/rest/object_factory.rb +76 -0
  221. data/lib/gooddata/rest/resource.rb +27 -0
  222. data/lib/gooddata/rest/rest.rb +24 -0
  223. data/lib/gooddata/version.rb +23 -0
  224. data/lib/templates/bricks/brick.rb.erb +7 -0
  225. data/lib/templates/bricks/main.rb.erb +5 -0
  226. data/lib/templates/project/Goodfile.erb +4 -0
  227. data/lib/templates/project/data/commits.csv +4 -0
  228. data/lib/templates/project/data/devs.csv +4 -0
  229. data/lib/templates/project/data/repos.csv +3 -0
  230. data/lib/templates/project/model/model.rb.erb +20 -0
  231. data/spec/bricks/bricks_spec.rb +112 -0
  232. data/spec/bricks/default-config.json +8 -0
  233. data/spec/data/.gooddata +4 -0
  234. data/spec/data/blueprints/additional_dataset_module.json +32 -0
  235. data/spec/data/blueprints/big_blueprint_not_pruned.json +2079 -0
  236. data/spec/data/blueprints/invalid_blueprint.json +103 -0
  237. data/spec/data/blueprints/m_n_model.json +104 -0
  238. data/spec/data/blueprints/model_module.json +25 -0
  239. data/spec/data/blueprints/test_blueprint.json +38 -0
  240. data/spec/data/blueprints/test_project_model_spec.json +106 -0
  241. data/spec/data/cc/data/source/commits.csv +4 -0
  242. data/spec/data/cc/data/source/devs.csv +4 -0
  243. data/spec/data/cc/data/source/repos.csv +3 -0
  244. data/spec/data/cc/devel.prm +0 -0
  245. data/spec/data/cc/graph/graph.grf +11 -0
  246. data/spec/data/cc/workspace.prm +19 -0
  247. data/spec/data/column_based_permissions.csv +7 -0
  248. data/spec/data/column_based_permissions2.csv +6 -0
  249. data/spec/data/gd_gse_data_blueprint.json +1371 -0
  250. data/spec/data/gd_gse_data_manifest.json +1424 -0
  251. data/spec/data/gd_gse_data_model.json +1772 -0
  252. data/spec/data/gooddata_version_process/gooddata_version.rb +9 -0
  253. data/spec/data/gooddata_version_process/gooddata_version.zip +0 -0
  254. data/spec/data/hello_world_process/hello_world.rb +9 -0
  255. data/spec/data/hello_world_process/hello_world.zip +0 -0
  256. data/spec/data/line_based_permissions.csv +3 -0
  257. data/spec/data/manifests/test_blueprint.json +32 -0
  258. data/spec/data/manifests/test_project.json +107 -0
  259. data/spec/data/reports/left_attr_report.json +108 -0
  260. data/spec/data/reports/metric_only_one_line.json +83 -0
  261. data/spec/data/reports/report_1.json +197 -0
  262. data/spec/data/reports/top_attr_report.json +108 -0
  263. data/spec/data/ruby_params_process/ruby_params.rb +9 -0
  264. data/spec/data/ruby_process/deep_files/deep_stuff.txt +1 -0
  265. data/spec/data/ruby_process/process.rb +8 -0
  266. data/spec/data/ruby_process/stuff.txt +1 -0
  267. data/spec/data/superfluous_titles_view.json +81 -0
  268. data/spec/data/test-ci-data.csv +2 -0
  269. data/spec/data/users.csv +12 -0
  270. data/spec/data/wire_models/model_view.json +1775 -0
  271. data/spec/data/wire_models/nu_model.json +3046 -0
  272. data/spec/data/wire_models/test_blueprint.json +63 -0
  273. data/spec/data/wire_test_project.json +150 -0
  274. data/spec/environment/default.rb +41 -0
  275. data/spec/environment/develop.rb +31 -0
  276. data/spec/environment/environment.rb +18 -0
  277. data/spec/environment/hotfix.rb +21 -0
  278. data/spec/environment/production.rb +35 -0
  279. data/spec/environment/release.rb +21 -0
  280. data/spec/environment/staging.rb +30 -0
  281. data/spec/environment/staging_3.rb +36 -0
  282. data/spec/helpers/blueprint_helper.rb +26 -0
  283. data/spec/helpers/cli_helper.rb +36 -0
  284. data/spec/helpers/connection_helper.rb +41 -0
  285. data/spec/helpers/crypto_helper.rb +17 -0
  286. data/spec/helpers/csv_helper.rb +18 -0
  287. data/spec/helpers/process_helper.rb +33 -0
  288. data/spec/helpers/project_helper.rb +59 -0
  289. data/spec/helpers/schedule_helper.rb +31 -0
  290. data/spec/helpers/spec_helper.rb +15 -0
  291. data/spec/integration/blueprint_updates_spec.rb +101 -0
  292. data/spec/integration/blueprint_with_grain_spec.rb +72 -0
  293. data/spec/integration/clients_spec.rb +134 -0
  294. data/spec/integration/command_datawarehouse_spec.rb +39 -0
  295. data/spec/integration/command_projects_spec.rb +32 -0
  296. data/spec/integration/create_from_template_spec.rb +22 -0
  297. data/spec/integration/create_project_spec.rb +24 -0
  298. data/spec/integration/date_dim_switch_spec.rb +142 -0
  299. data/spec/integration/deprecated_load_spec.rb +58 -0
  300. data/spec/integration/full_process_schedule_spec.rb +298 -0
  301. data/spec/integration/full_project_spec.rb +569 -0
  302. data/spec/integration/over_to_user_filters_spec.rb +94 -0
  303. data/spec/integration/partial_md_export_import_spec.rb +42 -0
  304. data/spec/integration/project_spec.rb +264 -0
  305. data/spec/integration/rest_spec.rb +213 -0
  306. data/spec/integration/schedule_spec.rb +626 -0
  307. data/spec/integration/segments_spec.rb +141 -0
  308. data/spec/integration/user_filters_spec.rb +290 -0
  309. data/spec/integration/user_group_spec.rb +127 -0
  310. data/spec/integration/variables_spec.rb +188 -0
  311. data/spec/logging_in_logging_out_spec.rb +93 -0
  312. data/spec/spec_helper.rb +95 -0
  313. data/spec/unit/bricks/bricks_spec.rb +35 -0
  314. data/spec/unit/bricks/middleware/aws_middelware_spec.rb +51 -0
  315. data/spec/unit/bricks/middleware/bench_middleware_spec.rb +15 -0
  316. data/spec/unit/bricks/middleware/bulk_salesforce_middleware_spec.rb +15 -0
  317. data/spec/unit/bricks/middleware/gooddata_middleware_spec.rb +15 -0
  318. data/spec/unit/bricks/middleware/logger_middleware_spec.rb +15 -0
  319. data/spec/unit/bricks/middleware/restforce_middleware_spec.rb +15 -0
  320. data/spec/unit/bricks/middleware/stdout_middleware_spec.rb +15 -0
  321. data/spec/unit/bricks/middleware/twitter_middleware_spec.rb +15 -0
  322. data/spec/unit/cli/cli_spec.rb +17 -0
  323. data/spec/unit/cli/commands/cmd_auth_spec.rb +17 -0
  324. data/spec/unit/commands/command_projects_spec.rb +22 -0
  325. data/spec/unit/core/connection_spec.rb +57 -0
  326. data/spec/unit/core/logging_spec.rb +133 -0
  327. data/spec/unit/core/nil_logger_spec.rb +13 -0
  328. data/spec/unit/core/project_spec.rb +54 -0
  329. data/spec/unit/extensions/hash_spec.rb +23 -0
  330. data/spec/unit/godzilla/goodzilla_spec.rb +78 -0
  331. data/spec/unit/helpers/csv_helper_spec.rb +22 -0
  332. data/spec/unit/helpers/data_helper_spec.rb +61 -0
  333. data/spec/unit/helpers/global_helpers_spec.rb +111 -0
  334. data/spec/unit/helpers_spec.rb +86 -0
  335. data/spec/unit/models/blueprint/attributes_spec.rb +29 -0
  336. data/spec/unit/models/blueprint/dataset_spec.rb +121 -0
  337. data/spec/unit/models/blueprint/labels_spec.rb +44 -0
  338. data/spec/unit/models/blueprint/project_blueprint_spec.rb +648 -0
  339. data/spec/unit/models/blueprint/reference_spec.rb +29 -0
  340. data/spec/unit/models/blueprint/schema_builder_spec.rb +38 -0
  341. data/spec/unit/models/blueprint/to_wire_spec.rb +174 -0
  342. data/spec/unit/models/domain_spec.rb +144 -0
  343. data/spec/unit/models/execution_spec.rb +108 -0
  344. data/spec/unit/models/from_wire_spec.rb +296 -0
  345. data/spec/unit/models/invitation_spec.rb +17 -0
  346. data/spec/unit/models/membership_spec.rb +132 -0
  347. data/spec/unit/models/metadata_spec.rb +104 -0
  348. data/spec/unit/models/metric_spec.rb +117 -0
  349. data/spec/unit/models/model_spec.rb +82 -0
  350. data/spec/unit/models/params_spec.rb +118 -0
  351. data/spec/unit/models/profile_spec.rb +215 -0
  352. data/spec/unit/models/project_creator_spec.rb +127 -0
  353. data/spec/unit/models/project_role_spec.rb +94 -0
  354. data/spec/unit/models/project_spec.rb +162 -0
  355. data/spec/unit/models/report_result_data_spec.rb +199 -0
  356. data/spec/unit/models/schedule_spec.rb +418 -0
  357. data/spec/unit/models/to_manifest_spec.rb +63 -0
  358. data/spec/unit/models/unit_project_spec.rb +125 -0
  359. data/spec/unit/models/user_filters_spec.rb +95 -0
  360. data/spec/unit/models/variable_spec.rb +265 -0
  361. data/spec/unit/rest/polling_spec.rb +89 -0
  362. data/spec/unit/rest/resource_spec.rb +10 -0
  363. data/yard-server.sh +3 -0
  364. metadata +1125 -0
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2015 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require 'pathname'
8
+
9
+ base = Pathname(__FILE__).dirname.expand_path
10
+
11
+ Dir.glob(base + '*.rb').each do |file|
12
+ require_relative file
13
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2015 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require_relative 'user_filter'
8
+
9
+ module GoodData
10
+ class VariableUserFilter < UserFilter
11
+ # Creates or updates the variable user filter on the server
12
+ #
13
+ # @return [String]
14
+ def save
15
+ res = client.post(uri, :variable => @json)
16
+ @json[:uri] = res['uri']
17
+ self
18
+ end
19
+
20
+ # Method used for replacing values in their state according to mapping. Can be used to replace any values but it is typically used to replace the URIs. Returns a new object of the same type.
21
+ #
22
+ # @param [Array<Array>]Mapping specifying what should be exchanged for what. As mapping should be used output of GoodData::Helpers.prepare_mapping.
23
+ # @return [GoodData::VariableUserFilter]
24
+ def replace(mapping)
25
+ x = GoodData::MdObject.replace_quoted(self, mapping)
26
+ x = GoodData::MdObject.replace_bracketed(x, mapping)
27
+ vals = GoodData::MdObject.find_replaceable_values(x, mapping)
28
+ GoodData::MdObject.replace_bracketed(x, vals)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,241 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2015 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require_relative '../rest/rest'
8
+ require_relative '../rest/resource'
9
+ require_relative '../mixins/author'
10
+ require_relative '../mixins/contributor'
11
+ require_relative '../mixins/links'
12
+ require_relative '../mixins/rest_resource'
13
+ require_relative '../mixins/uri_getter'
14
+
15
+ module GoodData
16
+ # Representation of User Group
17
+ #
18
+ # Use user groups to manage user access to dashboards on the GoodData Portal.
19
+ # Create groups to more quickly manage permissions for users with
20
+ # the the same role or who need similar access to dashboards.
21
+ # Groups can be part of groups.
22
+ class UserGroup < Rest::Resource
23
+ include Mixin::Author
24
+ include Mixin::Contributor
25
+ include Mixin::Links
26
+ include Mixin::UriGetter
27
+
28
+ EMPTY_OBJECT = {
29
+ 'userGroup' => {
30
+ 'content' => {
31
+ 'name' => nil,
32
+ 'description' => nil,
33
+ 'project' => nil
34
+ }
35
+ }
36
+ }
37
+
38
+ class << self
39
+ # Returns list of all segments or a particular segment
40
+ #
41
+ # @param id [String|Symbol] Uri of the segment required or :all for all segments.
42
+ # @return [Array<GoodData::Segment>] List of segments for a particular domain
43
+ def [](id, opts = {})
44
+ # TODO: Replace with GoodData.get_client_and_project(opts)
45
+ project = opts[:project]
46
+ fail 'Project has to be passed in options' unless project
47
+ fail 'Project has to be of type GoodData::Project' unless project.is_a?(GoodData::Project)
48
+ client = project.client
49
+
50
+ results = client.get('/gdc/userGroups', params: { :project => project.pid, :user => opts[:user] }.compact)
51
+ groups = GoodData::Helpers.get_path(results, %w(userGroups items)).map { |i| client.create(GoodData::UserGroup, i, :project => project) }
52
+ id == :all ? groups : groups.find { |g| g.obj_id == id || g.name == id }
53
+ end
54
+
55
+ # Create new user group
56
+ #
57
+ # @param data [Hash] Initial data
58
+ # @return [UserGroup] Newly created user group
59
+ def create(data)
60
+ new_data = GoodData::Helpers.deep_dup(EMPTY_OBJECT).tap do |d|
61
+ d['userGroup']['content']['name'] = data[:name]
62
+ d['userGroup']['content']['description'] = data[:description]
63
+ d['userGroup']['content']['project'] = data[:project].respond_to?(:uri) ? data[:project].uri : data[:project]
64
+ end
65
+
66
+ client.create(GoodData::UserGroup, GoodData::Helpers.deep_stringify_keys(new_data))
67
+ end
68
+
69
+ # Constructs payload for user management/manipulation
70
+ #
71
+ # @return [Hash] Created payload
72
+ def construct_payload(users, operation)
73
+ users = users.is_a?(Array) ? users : [users]
74
+
75
+ {
76
+ modifyMembers: {
77
+ operation: operation,
78
+ items: users.map do |user|
79
+ uri = user.respond_to?(:uri) ? user.uri : user
80
+ fail 'You cannot add group as member of another group as of now.' if uri =~ %r{^\/gdc\/userGroups\/}
81
+ uri
82
+ end
83
+ }
84
+ }
85
+ end
86
+
87
+ # URI used for membership manipulation/managementv
88
+ #
89
+ # @param client [Client] Client used for communication with platform
90
+ # @param users [User | String | Array<User> | Array<String>] User(s) to be modified
91
+ # @param operation [String] Operation to be performed - ADD, SET, REMOVE
92
+ # @param uri [String] URI to be used for operation
93
+ # @return [String] URI used for membership manipulation/management
94
+ def modify_users(client, users, operation, uri)
95
+ payload = construct_payload(users, operation)
96
+ client.post(uri, payload)
97
+ end
98
+ end
99
+
100
+ # Initialize object with json
101
+ #
102
+ # @return [UserGroup] User Group object initialized with json
103
+ def initialize(json)
104
+ @json = json
105
+ self
106
+ end
107
+
108
+ # Add member(s) to user group
109
+ #
110
+ # @param [String | User | Array<User>] Users to add to user group
111
+ # @return [nil] Nothing is returned
112
+ def add_members(user)
113
+ UserGroup.modify_users(client, user, 'ADD', uri_modify_members)
114
+ end
115
+
116
+ alias_method :add_member, :add_members
117
+
118
+ # Gets user group name
119
+ #
120
+ # @return [String] User group name
121
+ def name
122
+ content['name']
123
+ end
124
+
125
+ # Sets user group name
126
+ #
127
+ # @param name [String] New user group name
128
+ # @return [String] New user group name
129
+ def name=(name)
130
+ content['name'] = name
131
+ name
132
+ end
133
+
134
+ # Gets user group description
135
+ #
136
+ # @return [String] User group description
137
+ def description
138
+ content['description']
139
+ end
140
+
141
+ # Sets user group description
142
+ #
143
+ # @param name [String] New user group description
144
+ # @return [String] New user group description
145
+ def description=(name)
146
+ content['description'] = name
147
+ end
148
+
149
+ # Gets Users with this Role
150
+ #
151
+ # @return [Array<GoodData::Profile>] List of users
152
+ def members
153
+ url = GoodData::Helpers.get_path(data, %w(links members))
154
+ return [] unless url
155
+ Enumerator.new do |y|
156
+ loop do
157
+ res = client.get url
158
+ res['userGroupMembers']['paging']['next']
159
+ res['userGroupMembers']['items'].each do |member|
160
+ case member.keys.first
161
+ when 'user'
162
+ y << client.create(GoodData::Profile, client.get(GoodData::Helpers.get_path(member, %w(user links self))), :project => project)
163
+ when 'userGroup'
164
+ y << client.create(UserGroup, client.get(GoodData::Helpers.get_path(member, %w(userGroup links self))), :project => project)
165
+ end
166
+ end
167
+ url = res['userGroupMembers']['paging']['next']
168
+ break unless url
169
+ end
170
+ end
171
+ end
172
+
173
+ # Verifies if user is in a group or any nested group and returns true if it does
174
+ #
175
+ # @return [Boolean] Retruns true if member is member of the group or any of its members
176
+ def member?(a_member)
177
+ # could be better on API directly?
178
+ uri = a_member.respond_to?(:uri) ? a_member.uri : a_member
179
+ members.map(&:uri).include?(uri)
180
+ end
181
+
182
+ # Save user group
183
+ # New group is created if needed else existing one is updated
184
+ #
185
+ # @return [UserGroup] Created or updated user group
186
+ def save
187
+ res = if uri
188
+ # get rid of unsupprted keys
189
+ data = json['userGroup']
190
+ client.put(uri, 'userGroup' => data.except('meta', 'links'))
191
+ else
192
+ client.post('/gdc/userGroups', @json)
193
+ end
194
+ @json = client.get(res['uri'])
195
+ self
196
+ end
197
+
198
+ # Remove member(s) from user group
199
+ #
200
+ # @param [String | User | Array<User>] Users to remove from user group
201
+ # @return [nil] Nothing is returned
202
+ def remove_members(user)
203
+ UserGroup.modify_users(client, user, 'REMOVE', uri_modify_members)
204
+ end
205
+
206
+ alias_method :remove_member, :remove_members
207
+
208
+ # Set member(s) to user group.
209
+ # Only users passed to this call will be new members of user group.
210
+ # Old members not passed to this method will be removed!
211
+ #
212
+ # @param [String | User | Array<User>] Users to set as members of user group
213
+ # @return [nil] Nothing is returned
214
+ def set_members(user) # rubocop:disable Style/AccessorMethodName
215
+ UserGroup.modify_users(client, user, 'SET', uri_modify_members)
216
+ end
217
+
218
+ alias_method :set_member, :set_members
219
+
220
+ # URI used for membership manipulation/management
221
+ #
222
+ # @return [String] URI used for membership manipulation/management
223
+ def uri_modify_members
224
+ links['modifyMembers']
225
+ end
226
+
227
+ # Is it a user group?
228
+ #
229
+ # @return [Boolean] Return true if it is a user group
230
+ def user_group?
231
+ true
232
+ end
233
+
234
+ # Checks if two user groups are same
235
+ #
236
+ # @return [Boolean] Return true if the two groups are same
237
+ def ==(other)
238
+ uri == other.uri
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,37 @@
1
+ # Rest
2
+
3
+ Proof of Concept of GoodWay of dealing with non-perfect REST Endpoints
4
+
5
+ ## Terminology
6
+
7
+ Terms like 'MUST', 'MUST NOT', 'SHALL', 'SHALL NOT' are used as defined in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt)
8
+
9
+ ## Architecture
10
+
11
+ There are few basic classes.
12
+
13
+ - Connection
14
+ - Client
15
+ - Factory
16
+ - Object
17
+ - Resource
18
+
19
+ ## Connection
20
+
21
+ Low-level network connection
22
+
23
+ ## Client
24
+
25
+ User's interface to GoodData Platform.
26
+
27
+ ## Factory
28
+
29
+ Authority responsible for creating Object bounded to some Connection.
30
+
31
+ ## Object
32
+
33
+ Remote REST-like accessible content.
34
+
35
+ ## Resource
36
+
37
+ Objects which are (at least mimicking to be) first class citizen REST Resource with full CRUD
@@ -0,0 +1,389 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2015 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require 'rest-client'
8
+
9
+ require_relative '../helpers/auth_helpers'
10
+
11
+ require_relative 'connection'
12
+ require_relative 'object_factory'
13
+
14
+ require_relative '../mixins/inspector'
15
+
16
+ module GoodData
17
+ module Rest
18
+ # User's interface to GoodData Platform.
19
+ #
20
+ # MUST provide way to use - DELETE, GET, POST, PUT
21
+ # SHOULD provide way to use - HEAD, Bulk GET ...
22
+ class Client
23
+ #################################
24
+ # Constants
25
+ #################################
26
+ DEFAULT_CONNECTION_IMPLEMENTATION = GoodData::Rest::Connection
27
+ DEFAULT_SLEEP_INTERVAL = 10
28
+ DEFAULT_POLL_TIME_LIMIT = 5 * 60 * 60 # 5 hours
29
+
30
+ #################################
31
+ # Class variables
32
+ #################################
33
+ @@instance = nil # rubocop:disable ClassVars
34
+
35
+ #################################
36
+ # Getters/Setters
37
+ #################################
38
+
39
+ # Decide if we need provide direct access to connection
40
+ attr_reader :connection
41
+
42
+ # TODO: Decide if we need provide direct access to factory
43
+ attr_reader :factory
44
+ attr_reader :opts
45
+
46
+ include Mixin::Inspector
47
+ inspector :object_id
48
+
49
+ #################################
50
+ # Class methods
51
+ #################################
52
+ class << self
53
+ # Globally available way to connect (and create client and set global instance)
54
+ #
55
+ # ## HACK
56
+ # To make transition from old implementation to new one following HACK IS TEMPORARILY ENGAGED!
57
+ #
58
+ # 1. First call of #connect sets the GoodData::Rest::Client.instance (static, singleton instance)
59
+ # 2. There are METHOD functions with same signature as their CLASS counterparts using singleton instance
60
+ #
61
+ # ## Example
62
+ #
63
+ # client = GoodData.connect('jon.smith@goodddata.com', 's3cr3tp4sw0rd')
64
+ #
65
+ # @param username [String] Username to be used for authentication
66
+ # @param password [String] Password to be used for authentication
67
+ # @return [GoodData::Rest::Client] Client
68
+ def connect(username, password = 'aaaa', opts = {})
69
+ if username.nil? && password.nil?
70
+ username = ENV['GD_GEM_USER']
71
+ password = ENV['GD_GEM_PASSWORD']
72
+ end
73
+
74
+ username = GoodData::Helpers.symbolize_keys(username) if username.is_a?(Hash)
75
+
76
+ new_opts = opts.dup
77
+ if username.is_a?(Hash) && username.key?(:sst_token)
78
+ new_opts = new_opts.merge(username)
79
+ elsif username.is_a? Hash
80
+ new_opts = new_opts.merge(username)
81
+ new_opts[:username] = username[:login] || username[:user] || username[:username]
82
+ new_opts[:password] = username[:password]
83
+ elsif username.nil? && password.nil? && opts.blank?
84
+ new_opts = Helpers::AuthHelper.read_credentials
85
+ else
86
+ new_opts[:username] = username
87
+ new_opts[:password] = password
88
+ end
89
+
90
+ new_opts = { verify_ssl: true }.merge(new_opts)
91
+ if username.is_a?(Hash) && username[:cookies]
92
+ new_opts[:sst_token] = username[:cookies]['GDCAuthSST']
93
+ new_opts[:cookies] = username[:cookies]
94
+ end
95
+
96
+ unless new_opts[:sst_token]
97
+ fail ArgumentError, 'No username specified' if new_opts[:username].nil?
98
+ fail ArgumentError, 'No password specified' if new_opts[:password].nil?
99
+ end
100
+
101
+ if username.is_a?(Hash) && username.key?(:server)
102
+ new_opts[:server] = username[:server]
103
+ end
104
+
105
+ client = Client.new(new_opts)
106
+ GoodData.logger.info("Connected to server with webdav path #{client.user_webdav_path}")
107
+
108
+ if client
109
+ at_exit do
110
+ puts client.connection.stats_table if client && client.connection && (GoodData.stats_on? || client.stats_on?)
111
+ end
112
+ end
113
+
114
+ # HACK: This line assigns class instance # if not done yet
115
+ @@instance = client # rubocop:disable ClassVars
116
+ end
117
+
118
+ def connect_sso(sso)
119
+ client = Client.new(sso)
120
+ client
121
+ end
122
+
123
+ def disconnect
124
+ if @@instance # rubocop:disable Style/GuardClause
125
+ @@instance.disconnect
126
+ @@instance = nil # rubocop:disable ClassVars
127
+ end
128
+ end
129
+
130
+ def connection
131
+ @@instance
132
+ end
133
+
134
+ # Retry block if exception thrown
135
+ def retryable(options = {}, &block)
136
+ GoodData::Rest::Connection.retryable(options, &block)
137
+ end
138
+
139
+ alias_method :client, :connection
140
+ end
141
+
142
+ # Constructor of client
143
+ # @param opts [Hash] Client options
144
+ # @option opts [String] :username Username used for authentication
145
+ # @option opts [String] :password Password used for authentication
146
+ # @option opts :connection_factory Object able to create new instances of GoodData::Rest::Connection
147
+ # @option opts [GoodData::Rest::Connection] :connection Existing GoodData::Rest::Connection
148
+ def initialize(opts)
149
+ # TODO: Decide if we want to pass the options directly or not
150
+ @opts = opts
151
+
152
+ @connection_factory = @opts[:connection_factory] || DEFAULT_CONNECTION_IMPLEMENTATION
153
+
154
+ # TODO: See previous TODO
155
+ # Create connection
156
+ @connection = opts[:connection] || @connection_factory.new(opts)
157
+
158
+ # Connect
159
+ connect
160
+
161
+ # Create factory bound to previously created connection
162
+ @factory = ObjectFactory.new(self)
163
+ end
164
+
165
+ def create_project(options = { title: 'Project' })
166
+ GoodData::Project.create({ client: self }.merge(options))
167
+ end
168
+
169
+ def create_project_from_blueprint(blueprint, options = {})
170
+ GoodData::Model::ProjectCreator.migrate(options.merge(spec: blueprint, client: self))
171
+ end
172
+
173
+ def domain(domain_name)
174
+ GoodData::Domain[domain_name, :client => self]
175
+ end
176
+
177
+ def project_is_accessible?(id)
178
+ projects(id) && true
179
+ rescue
180
+ true
181
+ end
182
+
183
+ def projects(id = :all)
184
+ GoodData::Project[id, client: self]
185
+ end
186
+
187
+ def processes(id = :all)
188
+ GoodData::Process[id, client: self]
189
+ end
190
+
191
+ def connect
192
+ username = @opts[:username]
193
+ password = @opts[:password]
194
+
195
+ @connection.connect(username, password, @opts)
196
+ end
197
+
198
+ def disconnect
199
+ @connection.disconnect
200
+ end
201
+
202
+ #######################
203
+ # Factory stuff
204
+ ######################
205
+ def create(klass, data = {}, opts = {})
206
+ @factory.create(klass, data, opts)
207
+ end
208
+
209
+ def find(klass, opts = {})
210
+ @factory.find(klass, opts)
211
+ end
212
+
213
+ # Gets resource by name
214
+ def resource(res_name)
215
+ puts "Getting resource '#{res_name}'"
216
+ nil
217
+ end
218
+
219
+ def user(id = nil)
220
+ if id
221
+ create(GoodData::Profile, get(id))
222
+ else
223
+ create(GoodData::Profile, @connection.user)
224
+ end
225
+ end
226
+
227
+ def stats_off
228
+ @stats = false
229
+ end
230
+
231
+ def stats_on
232
+ @stats = true
233
+ end
234
+
235
+ def stats_on?
236
+ @stats
237
+ end
238
+
239
+ def generate_request_id
240
+ @connection.generate_request_id
241
+ end
242
+
243
+ #######################
244
+ # Rest
245
+ #######################
246
+ # HTTP DELETE
247
+ #
248
+ # @param uri [String] Target URI
249
+ def delete(uri, opts = {})
250
+ @connection.delete uri, opts
251
+ end
252
+
253
+ # HTTP GET
254
+ #
255
+ # @param uri [String] Target URI
256
+ def get(uri, opts = {}, & block)
257
+ @connection.get uri, opts, & block
258
+ end
259
+
260
+ def project_webdav_path(opts = { project: GoodData.project })
261
+ p = opts[:project]
262
+ fail ArgumentError, 'No :project specified' if p.nil?
263
+
264
+ project = GoodData::Project[p, opts]
265
+ fail ArgumentError, 'Wrong :project specified' if project.nil?
266
+
267
+ url = project.links['uploads']
268
+ fail 'Project WebDAV not supported in this Data Center' unless url
269
+
270
+ GoodData.logger.warn 'Beware! Project webdav is deprecated and should not be used.'
271
+ url
272
+ end
273
+
274
+ def user_webdav_path
275
+ uri = if opts[:webdav_server]
276
+ opts[:webdav_server]
277
+ else
278
+ links.find { |i| i['category'] == 'uploads' }['link']
279
+ end
280
+ res = uri.chomp('/') + '/'
281
+ res[0] == '/' ? "#{connection.server}#{res}" : res
282
+ end
283
+
284
+ # Generalizaton of poller. Since we have quite a variation of how async proceses are handled
285
+ # this is a helper that should help you with resources where the information about "Are we done"
286
+ # is the http code of response. By default we repeat as long as the code == 202. You can
287
+ # change the code if necessary. It expects the URI as an input where it can poll. It returns the
288
+ # value of last poll. In majority of cases these are the data that you need.
289
+ #
290
+ # @param link [String] Link for polling
291
+ # @param options [Hash] Options
292
+ # @return [Hash] Result of polling
293
+ def poll_on_code(link, options = {})
294
+ code = options[:code] || 202
295
+ process = options[:process]
296
+
297
+ response = poll_on_response(link, options.merge(:process => false)) do |resp|
298
+ resp.code == code
299
+ end
300
+
301
+ if process == false
302
+ response
303
+ else
304
+ get(link)
305
+ end
306
+ end
307
+
308
+ # Generalizaton of poller. Since we have quite a variation of how async proceses are handled
309
+ # this is a helper that should help you with resources where the information about "Are we done"
310
+ # is inside the response. It expects the URI as an input where it can poll and a block that should
311
+ # return either true -> 'meaning we are done' or false -> meaning sleep and repeat. It returns the
312
+ # value of last poll. In majority of cases these are the data that you need
313
+ #
314
+ # @param link [String] Link for polling
315
+ # @param options [Hash] Options
316
+ # @return [Hash] Result of polling
317
+ def poll_on_response(link, options = {}, &bl)
318
+ sleep_interval = options[:sleep_interval] || DEFAULT_SLEEP_INTERVAL
319
+ time_limit = options[:time_limit] || DEFAULT_POLL_TIME_LIMIT
320
+ process = options[:process] == false ? false : true
321
+
322
+ # get the first status and start the timer
323
+ response = get(link, process: process)
324
+ poll_start = Time.now
325
+
326
+ while bl.call(response)
327
+ limit_breached = time_limit && (Time.now - poll_start > time_limit)
328
+ if limit_breached
329
+ fail ExecutionLimitExceeded, "The time limit #{time_limit} secs for polling on #{link} is over"
330
+ end
331
+ sleep sleep_interval
332
+ GoodData::Rest::Client.retryable(:tries => 3, :refresh_token => proc { connection.refresh_token }) do
333
+ response = get(link, process: process)
334
+ end
335
+ end
336
+ response
337
+ end
338
+
339
+ # HTTP PUT
340
+ #
341
+ # @param uri [String] Target URI
342
+ def put(uri, data, opts = {})
343
+ @connection.put uri, data, opts
344
+ end
345
+
346
+ # HTTP POST
347
+ #
348
+ # @param uri [String] Target URI
349
+ def post(uri, data, opts = {})
350
+ @connection.post uri, data, opts
351
+ end
352
+
353
+ # Uploads file to staging
354
+ #
355
+ # @param file [String] file to be uploaded
356
+ # @param options [Hash] must contain :staging_url key (file will be uploaded to :staging_url + File.basename(file))
357
+ def upload(file, options = {})
358
+ @connection.upload file, options
359
+ end
360
+
361
+ # Downloads file from staging
362
+ #
363
+ # @param source_relative_path [String] path relative to @param options[:staging_url]
364
+ # @param target_file_path [String] path to be downloaded to
365
+ # @param options [Hash] must contain :staging_url key (file will be downloaded from :staging_url + source_relative_path)
366
+ def download(source_relative_path, target_file_path, options = {})
367
+ @connection.download source_relative_path, target_file_path, options
368
+ end
369
+
370
+ def download_from_user_webdav(source_relative_path, target_file_path, options = { client: GoodData.client, project: project })
371
+ download(source_relative_path, target_file_path, options.merge(:directory => options[:directory],
372
+ :staging_url => user_webdav_path))
373
+ end
374
+
375
+ def upload_to_user_webdav(file, options = {})
376
+ upload(file, options.merge(:directory => options[:directory],
377
+ :staging_url => user_webdav_path))
378
+ end
379
+
380
+ def with_project(pid, &block)
381
+ GoodData.with_project(pid, client: self, &block)
382
+ end
383
+
384
+ def links
385
+ GoodData::Helpers.get_path(get('/gdc'), %w(about links))
386
+ end
387
+ end
388
+ end
389
+ end