uploadcare-ruby 2.1.1 → 3.1.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/gem-push.yml +20 -0
  3. data/.github/workflows/ruby.yml +52 -0
  4. data/.gitignore +13 -6
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +32 -0
  7. data/.yardopts +4 -0
  8. data/CHANGELOG.md +33 -34
  9. data/DEVELOPMENT.md +18 -0
  10. data/Gemfile +2 -0
  11. data/LICENSE +1 -1
  12. data/README.md +369 -546
  13. data/Rakefile +5 -5
  14. data/bin/console +15 -0
  15. data/bin/setup +8 -0
  16. data/lib/uploadcare.rb +36 -26
  17. data/lib/uploadcare/api/api.rb +25 -0
  18. data/lib/uploadcare/client/conversion/base_conversion_client.rb +54 -0
  19. data/lib/uploadcare/client/conversion/document_conversion_client.rb +38 -0
  20. data/lib/uploadcare/client/conversion/video_conversion_client.rb +42 -0
  21. data/lib/uploadcare/client/file_client.rb +44 -0
  22. data/lib/uploadcare/client/file_list_client.rb +46 -0
  23. data/lib/uploadcare/client/group_client.rb +45 -0
  24. data/lib/uploadcare/client/multipart_upload/chunks_client.rb +48 -0
  25. data/lib/uploadcare/client/multipart_upload_client.rb +67 -0
  26. data/lib/uploadcare/client/project_client.rb +18 -0
  27. data/lib/uploadcare/client/rest_client.rb +74 -0
  28. data/lib/uploadcare/client/rest_group_client.rb +23 -0
  29. data/lib/uploadcare/client/upload_client.rb +36 -0
  30. data/lib/uploadcare/client/uploader_client.rb +109 -0
  31. data/lib/uploadcare/client/webhook_client.rb +47 -0
  32. data/lib/uploadcare/concern/error_handler.rb +54 -0
  33. data/lib/uploadcare/concern/throttle_handler.rb +25 -0
  34. data/lib/uploadcare/concern/upload_error_handler.rb +32 -0
  35. data/lib/uploadcare/entity/decorator/paginator.rb +79 -0
  36. data/lib/uploadcare/entity/document_converter.rb +26 -0
  37. data/lib/uploadcare/entity/entity.rb +18 -0
  38. data/lib/uploadcare/entity/file.rb +81 -0
  39. data/lib/uploadcare/entity/file_list.rb +31 -0
  40. data/lib/uploadcare/entity/group.rb +40 -0
  41. data/lib/uploadcare/entity/group_list.rb +24 -0
  42. data/lib/uploadcare/entity/project.rb +13 -0
  43. data/lib/uploadcare/entity/uploader.rb +75 -0
  44. data/lib/uploadcare/entity/video_converter.rb +26 -0
  45. data/lib/uploadcare/entity/webhook.rb +14 -0
  46. data/lib/uploadcare/exception/conversion_error.rb +8 -0
  47. data/lib/uploadcare/exception/request_error.rb +9 -0
  48. data/lib/uploadcare/exception/throttle_error.rb +16 -0
  49. data/lib/uploadcare/param/authentication_header.rb +25 -0
  50. data/lib/uploadcare/param/conversion/document/processing_job_url_builder.rb +39 -0
  51. data/lib/uploadcare/param/conversion/video/processing_job_url_builder.rb +64 -0
  52. data/lib/uploadcare/param/param.rb +10 -0
  53. data/lib/uploadcare/param/secure_auth_header.rb +37 -0
  54. data/lib/uploadcare/param/simple_auth_header.rb +14 -0
  55. data/lib/uploadcare/param/upload/signature_generator.rb +24 -0
  56. data/lib/uploadcare/param/upload/upload_params_generator.rb +23 -0
  57. data/lib/uploadcare/param/user_agent.rb +21 -0
  58. data/lib/uploadcare/ruby/version.rb +5 -0
  59. data/uploadcare-ruby.gemspec +50 -37
  60. metadata +109 -115
  61. data/.travis.yml +0 -26
  62. data/UPGRADE_NOTES.md +0 -36
  63. data/lib/uploadcare/api.rb +0 -26
  64. data/lib/uploadcare/api/file_api.rb +0 -7
  65. data/lib/uploadcare/api/file_list_api.rb +0 -19
  66. data/lib/uploadcare/api/file_storage_api.rb +0 -34
  67. data/lib/uploadcare/api/group_api.rb +0 -38
  68. data/lib/uploadcare/api/group_list_api.rb +0 -17
  69. data/lib/uploadcare/api/project_api.rb +0 -9
  70. data/lib/uploadcare/api/raw_api.rb +0 -38
  71. data/lib/uploadcare/api/uploading_api.rb +0 -71
  72. data/lib/uploadcare/api/uploading_api/upload_params.rb +0 -72
  73. data/lib/uploadcare/api/validators/file_list_options_validator.rb +0 -73
  74. data/lib/uploadcare/api/validators/group_list_options_validator.rb +0 -49
  75. data/lib/uploadcare/errors/errors.rb +0 -64
  76. data/lib/uploadcare/resources/file.rb +0 -164
  77. data/lib/uploadcare/resources/file_list.rb +0 -14
  78. data/lib/uploadcare/resources/group.rb +0 -115
  79. data/lib/uploadcare/resources/group_list.rb +0 -14
  80. data/lib/uploadcare/resources/project.rb +0 -13
  81. data/lib/uploadcare/resources/resource_list.rb +0 -83
  82. data/lib/uploadcare/rest/auth/auth.rb +0 -31
  83. data/lib/uploadcare/rest/auth/secure.rb +0 -43
  84. data/lib/uploadcare/rest/auth/simple.rb +0 -16
  85. data/lib/uploadcare/rest/connections/api_connection.rb +0 -53
  86. data/lib/uploadcare/rest/connections/upload_connection.rb +0 -22
  87. data/lib/uploadcare/rest/middlewares/auth_middleware.rb +0 -24
  88. data/lib/uploadcare/rest/middlewares/parse_json_middleware.rb +0 -33
  89. data/lib/uploadcare/rest/middlewares/raise_error_middleware.rb +0 -21
  90. data/lib/uploadcare/utils/parser.rb +0 -71
  91. data/lib/uploadcare/utils/user_agent.rb +0 -44
  92. data/lib/uploadcare/version.rb +0 -3
  93. data/spec/api/file_list_api_spec.rb +0 -95
  94. data/spec/api/file_storage_api_spec.rb +0 -88
  95. data/spec/api/group_list_api_spec.rb +0 -59
  96. data/spec/api/raw_api_spec.rb +0 -25
  97. data/spec/api/uploading_api/upload_params_spec.rb +0 -99
  98. data/spec/api/uploading_api_spec.rb +0 -59
  99. data/spec/resources/file_list_spec.rb +0 -25
  100. data/spec/resources/file_spec.rb +0 -223
  101. data/spec/resources/group_list_spec.rb +0 -25
  102. data/spec/resources/group_spec.rb +0 -101
  103. data/spec/resources/operations_spec.rb +0 -59
  104. data/spec/resources/project_spec.rb +0 -21
  105. data/spec/rest/api_connection_spec.rb +0 -68
  106. data/spec/rest/auth/secure_spec.rb +0 -66
  107. data/spec/rest/auth/simple_spec.rb +0 -31
  108. data/spec/rest/errors_spec.rb +0 -75
  109. data/spec/rest/upload_connection_spec.rb +0 -19
  110. data/spec/shared/resource_list.rb +0 -188
  111. data/spec/spec_helper.rb +0 -54
  112. data/spec/uploadcare_spec.rb +0 -16
  113. data/spec/utils/parser_spec.rb +0 -85
  114. data/spec/utils/user_agent_spec.rb +0 -46
  115. data/spec/view.png +0 -0
  116. data/spec/view2.jpg +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a91d6bc58cb4485cc93ff080fa5f66040b6ab0f0
4
- data.tar.gz: ae95eb7e6d60828a91883c1c481e7a469d49702a
2
+ SHA256:
3
+ metadata.gz: b37d6357bdceca37eb0175201e52847b253c701771e3bed959e7e945e4b384b7
4
+ data.tar.gz: c70b33bed6660c649df6e93a5bb7e8b3cb5a4c79884a7c146086f0658da690a3
5
5
  SHA512:
6
- metadata.gz: e3b503ac19459939ec38af251f322c3804dec77546deeeba3d192757927a2cf4eef04d4f2b2ac2265efc42e42233f54d0f2fe66d2dcd29ced6ab18c65f6432c8
7
- data.tar.gz: c08f3fb47d507b520c0859ee268ce8926b014fa7895b3a288f881586e857724a825f075899827f07a02c33228c790a26848728294cd5b8add0e323c14c49502f
6
+ metadata.gz: 47b8ead48824c45759a89a62e170374afe3cc0e8a39690ba4851c04785ee52096769a4415fea2e7ecffb62a864a5fae5f6fb1e95bf450442141973b0412990e7
7
+ data.tar.gz: a7aa262e0982825592487187f99018f5276582dffbfa3ef412abc06a3c9d723906d64d2443c79c20eb0dce137ae1cec4384c40b54e692170915289c8191032b0
@@ -0,0 +1,20 @@
1
+ name: Publish Gem
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - v*
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+
11
+ steps:
12
+ - uses: actions/checkout@v1
13
+
14
+ - name: Release Gem
15
+ if: contains(github.ref, 'refs/tags/v')
16
+ uses: cadwallion/publish-rubygems-action@v1.0.0
17
+ env:
18
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
19
+ RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
20
+ RELEASE_COMMAND: rake release
@@ -0,0 +1,52 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on: [push, pull_request]
11
+
12
+ jobs:
13
+ test:
14
+
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ matrix:
18
+ ruby-version: [
19
+ '2.4', '2.5', # eol
20
+ '2.6', '2.7', # maintained
21
+ ]
22
+
23
+ steps:
24
+ - uses: actions/checkout@v2
25
+ - name: Set up Ruby
26
+ uses: ruby/setup-ruby@v1
27
+ with:
28
+ ruby-version: ${{ matrix.ruby-version }}
29
+ bundler-cache: true
30
+ - name: Run tests
31
+ run: bundle exec rake
32
+ env:
33
+ UPLOADCARE_PUBLIC_KEY: demopublickey
34
+ UPLOADCARE_SECRET_KEY: demoprivatekey
35
+
36
+ style-check:
37
+ runs-on: ubuntu-latest
38
+ continue-on-error: true
39
+ strategy:
40
+ matrix:
41
+ ruby-version: ['2.7',]
42
+ steps:
43
+ - uses: actions/checkout@v2
44
+ - name: Set up Ruby
45
+ uses: ruby/setup-ruby@v1
46
+ with:
47
+ ruby-version: ${{ matrix.ruby-version }}
48
+ bundler-cache: true
49
+ - name: Install Rubocop
50
+ run: gem install rubocop
51
+ - name: Check codestyle
52
+ run: rubocop
data/.gitignore CHANGED
@@ -1,7 +1,14 @@
1
- Gemfile.lock
2
- .ruby-gemset
3
- .ruby-version
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /spec/fixtures/big.jpeg
4
10
 
5
- *.DS_Store
6
- *.gem
7
- coverage
11
+ # rspec failure tracking
12
+ .rspec_status
13
+ .byebug_history
14
+ Gemfile.lock
data/.rspec CHANGED
@@ -1 +1,3 @@
1
+ --format documentation
1
2
  --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,32 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7
3
+
4
+ Metrics/LineLength:
5
+ Max: 120
6
+
7
+ IneffectiveAccessModifier:
8
+ Enabled: false
9
+
10
+ Style/HashTransformKeys:
11
+ Exclude:
12
+ - 'lib/uploadcare/entity/decorator/paginator.rb'
13
+ - 'lib/uploadcare/client/conversion/video_conversion_client.rb'
14
+
15
+ Gemspec/RequiredRubyVersion:
16
+ Exclude:
17
+ - 'uploadcare-ruby.gemspec'
18
+
19
+ Metrics/BlockLength:
20
+ Exclude:
21
+ - 'bin/'
22
+ - 'spec/**/*'
23
+ - 'uploadcare-ruby.gemspec'
24
+
25
+ Metrics/MethodLength:
26
+ Max: 20
27
+
28
+ Style/Documentation:
29
+ Enabled: false
30
+
31
+ Style/OptionalBooleanParameter:
32
+ AllowedMethods: ['create']
data/.yardopts ADDED
@@ -0,0 +1,4 @@
1
+ -
2
+ DEVELOPMENT.md
3
+ CHANGELOG.md
4
+ LICENSE
data/CHANGELOG.md CHANGED
@@ -1,54 +1,53 @@
1
1
  # Changelog
2
- All notable changes to this project will be documented in this file.
3
2
 
4
- The format is based now on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
- and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
3
+ ## 3.1.0-rc1 2021-08-11
6
4
 
7
- ## [Unreleased] - FIXME
5
+ ### Added
6
+ - Add video conversion
7
+ - Add document conversion
8
+ - Add new attributes to Uploadcare::File (variations, video_info, source, rekognition_info)
8
9
 
10
+ ### Fixed
9
11
 
10
- ## [2.1.1] - 2018-05-24
12
+ - Fix the `uninitialized constant Uploadcare::Client::ApiStruct (NameError)` error
11
13
 
12
- ### Changed
13
- - Allow user to override User-Agent header
14
- - User-Agent format reports gem name, version and environment
14
+ ## 3.0.5 2021-04-15
15
15
 
16
- ## 2.1.0 - 2018-04-23 [YANKED]
16
+ - Replace Travis-CI with Github Actions
17
+ - Automate gem pushing
17
18
 
18
- ## 2.0.0 - 2017-09-26
19
+ ## 3.0.4-dev 2020-03-19
19
20
 
20
- There are **breaking** changes in this release, please read [upgrade notes](UPGRADE_NOTES.md#v1---v2)
21
+ - Added better pagination methods for GroupList & FileList
22
+ - Improved documentation and install instructions
23
+ - Added CI
21
24
 
22
- ### Added
23
- - Support for `store` flag in [Upload API](https://uploadcare.com/documentation/upload/) methods
24
- - Methods to store/delete multiple files at once: `Uploadcare::Api#store_files` & `Uploadcare::Api#delete_files`
25
+ ## 3.0.3-dev 2020-03-13
25
26
 
26
- ### Changed
27
- - Upgraded to REST API v0.5
28
- - All POST/PUT/DELETE params are now being sent as JSON instead of being form-encoded
29
- - Pagination implementation for files and groups
27
+ - Added better pagination and iterators for GroupList & FileList
30
28
 
31
- ## 1.1.0 - 2017-03-21
29
+ ## 3.0.2-dev 2020-03-11
32
30
 
33
- ### Added
34
- - Added to new methods to `Uploadcare::Api::File`, `#internal_copy` and `#external_copy`.
35
- - Added support of [secure authorization](https://uploadcare.com/documentation/rest/#request) for REST API. It is now used by default (can be overriden in config)
31
+ - Expanded File and Group entities
32
+ - Changed user agent syntax
36
33
 
37
- ### Fixed
38
- - Fixed middleware names that could break other gems ([#13](https://github.com/uploadcare/uploadcare-ruby/issues/13)).
34
+ ## 3.0.1-dev 2020-03-11
39
35
 
40
- ### Deprecated
41
- - `Uploadcare::Api::File#copy` in favor of `#internal_copy` and `#external_copy`.
36
+ - Added Upload/group functionality
37
+ - Added user API
38
+ - Added user agent
39
+ - Isolated clients, entities and concerns
40
+ - Expanded documentation
42
41
 
42
+ ## 3.0.0-dev 2020-02-18
43
43
 
44
- ## 1.0.6, 2017-01-30
44
+ ### Changed
45
+ - Rewrote gem from scratch
45
46
 
46
47
  ### Added
47
- - Ruby version and public API key sent via User-Agent header (can be overriden in config)
48
-
49
- ### Fixed
50
- - Incorrect dependencies
51
-
52
48
 
53
- [Unreleased]: https://github.com/uploadcare/uploadcare-ruby/compare/v2.1.1...HEAD
54
- [2.1.1]: https://github.com/uploadcare/uploadcare-ruby/compare/v2.0.0...v2.1.1
49
+ - Client wrappers for REST API
50
+ - Serializers for REST API
51
+ - Client wrappers for Upload API
52
+ - Serializers for Upload API
53
+ - rdoc documentation
data/DEVELOPMENT.md ADDED
@@ -0,0 +1,18 @@
1
+ ## How to contribute
2
+
3
+ https://github.com/uploadcare/.github/blob/master/CONTRIBUTING.md
4
+
5
+ ## Useful docs
6
+
7
+ ### Uploadcare:
8
+
9
+ * https://uploadcare.com/docs/api_reference/
10
+ * https://uploadcare.com/api-refs/rest-api/
11
+
12
+ ### ApiStruct:
13
+
14
+ * https://github.com/rubygarage/api_struct/
15
+
16
+ ## Uploadcare-ruby gem architecture
17
+
18
+ ![http://www.plantuml.com/plantuml/uml/bPHDRzj838Rl-XM4zn1WiHRsOoyR88iuXOFcKWHDqcimaLxBquvcL9AowtxyzqepqYGrYY050cH69X-IByav5pMiVUkAed96X5QTfIy54T7jrWgDVrx16rE1De6fGKkzW2NQB9VB-7_zoRIT0zLmQ8oYfXQw3RMS9ZFgEnTCFLqsrk7UMT7YsnnsxTNguIZoNNIg38DMrrU4P2DWQvpz32wZzPtqnha3MStXXH9rIe8qq2jduPMSEO3_Y7x6rzJ0WwD3fjOK7jwZKg4DXvOOqWKlIB6klAZn5JBPS3v7UOQJ83j9-RnAASsNQHNlPsTdFv3iKJu9yJjT1gPBwp0ZHGCZdMDqHPP-LkPH-YGIjSQR1aACZpr4HnMFElApudwryMyXeUSAzDl5nSMGn0XIUB71HqLJrosacAj_4vHwGKtMqp_bd-LVongxH-0DU6ShJFMyCsn3BxI5wy1JQnDudS77LMJTfdfNjUaKFDnrb4Uc23KgMsDWXprfI7lICPHEKj4d4PBqe0SpfXmyTHnsjivZTZBDQlca8S5NO2zJ2Mlcm5GPhRPWYMEB-6ax71tusG8MY-Xu7praiI0sLY13dpceEYHuDBQRk6KCxTbBdc7QMzrI5MhGlt__bx4f-BqcZlNDm5Rp0K9cAZbcgcmH9uTxJrR9DCRw56-_XSSEF7vke4SvFSfnRTYqUJmXo5qqd5VDFhZfVKeRFIH4kwdthszlhwaRAL6gED2MCVJay8A1pfDyOnjlj6VCCGBBcEMgiuFFr__dD-mqx_VJ1sZ-DTPKf4joc_RlzBdNosC_sHLvOSe9ESFAUVIBYLWcwOeyJ-NCE8Ul-zPz1m00](http://www.plantuml.com/plantuml/svg/bPHDRzj838Rl-XM4zn1WiHRsOoyR88iuXOFcKWHDqcimaLxBquvcL9AowtxyzqepqYGrYY050cH69X-IByav5pMiVUkAed96X5QTfIy54T7jrWgDVrx16rE1De6fGKkzW2NQB9VB-7_zoRIT0zLmQ8oYfXQw3RMS9ZFgEnTCFLqsrk7UMT7YsnnsxTNguIZoNNIg38DMrrU4P2DWQvpz32wZzPtqnha3MStXXH9rIe8qq2jduPMSEO3_Y7x6rzJ0WwD3fjOK7jwZKg4DXvOOqWKlIB6klAZn5JBPS3v7UOQJ83j9-RnAASsNQHNlPsTdFv3iKJu9yJjT1gPBwp0ZHGCZdMDqHPP-LkPH-YGIjSQR1aACZpr4HnMFElApudwryMyXeUSAzDl5nSMGn0XIUB71HqLJrosacAj_4vHwGKtMqp_bd-LVongxH-0DU6ShJFMyCsn3BxI5wy1JQnDudS77LMJTfdfNjUaKFDnrb4Uc23KgMsDWXprfI7lICPHEKj4d4PBqe0SpfXmyTHnsjivZTZBDQlca8S5NO2zJ2Mlcm5GPhRPWYMEB-6ax71tusG8MY-Xu7praiI0sLY13dpceEYHuDBQRk6KCxTbBdc7QMzrI5MhGlt__bx4f-BqcZlNDm5Rp0K9cAZbcgcmH9uTxJrR9DCRw56-_XSSEF7vke4SvFSfnRTYqUJmXo5qqd5VDFhZfVKeRFIH4kwdthszlhwaRAL6gED2MCVJay8A1pfDyOnjlj6VCCGBBcEMgiuFFr__dD-mqx_VJ1sZ-DTPKf4joc_RlzBdNosC_sHLvOSe9ESFAUVIBYLWcwOeyJ-NCE8Ul-zPz1m00)
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in uploadcare-ruby.gemspec
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018 Uploadcare, LLC
3
+ Copyright (c) 2021 Uploadcare Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,117 +1,92 @@
1
- [![Build Status][travis-img]][travis]
2
- [![Coverage Status][coverals-img]][coverals]
1
+ # Ruby integration for Uploadcare
2
+
3
+ ![license](https://img.shields.io/badge/license-MIT-brightgreen.svg)
4
+ [![Build Status][actions-img]][actions-badge]
3
5
  [![Uploadcare stack on StackShare][stack-img]][stack]
6
+ <!--[![Coverage Status][coverals-img]][coverals]-->
4
7
 
5
- [travis-img]: https://secure.travis-ci.org/uploadcare/uploadcare-ruby.png?branch=master
6
- [travis]: http://travis-ci.org/uploadcare/uploadcare-ruby
7
- [coverals-img]: https://coveralls.io/repos/github/uploadcare/uploadcare-ruby/badge.svg?branch=master
8
- [coverals]: https://coveralls.io/github/uploadcare/uploadcare-ruby?branch=master
8
+ [actions-badge]: https://github.com/uploadcare/uploadcare-ruby/actions/workflows/ruby.yml
9
+ [actions-img]: https://github.com/uploadcare/uploadcare-ruby/actions/workflows/ruby.yml/badge.svg
10
+ [coverals-img]: https://coveralls.io/repos/github/uploadcare/uploadcare-ruby/badge.svg?branch=main
11
+ [coverals]: https://coveralls.io/github/uploadcare/uploadcare-ruby?branch=main
9
12
  [stack-img]: https://img.shields.io/badge/tech-stack-0690fa.svg?style=flat
10
13
  [stack]: https://stackshare.io/uploadcare/stacks/
11
14
 
12
- A [Ruby](https://www.ruby-lang.org/en/) wrapper for [Uploadcare](https://uploadcare.com).
15
+ Uploadcare Ruby integration handles uploads and further operations with files by
16
+ wrapping Upload and REST APIs.
17
+
18
+ * [Installation](#installation)
19
+ * [Usage](#usage)
20
+ * [Uploading files](#uploading-files)
21
+ * [Uploading and storing a single file](#uploading-and-storing-a-single-file)
22
+ * [Multiple ways to upload files](#multiple-ways-to-upload-files)
23
+ * [Uploading options](#uploading-options)
24
+ * [File management](#file-management)
25
+ * [File](#file)
26
+ * [FileList](#filelist)
27
+ * [Pagination](#pagination)
28
+ * [Group](#group)
29
+ * [GroupList](#grouplist)
30
+ * [Webhook](#webhook)
31
+ * [Project](#project)
32
+ * [Conversion](#conversion)
33
+ * [Useful links](#useful-links)
34
+
35
+ ## Requirements
36
+ * ruby 2.4+
37
+
38
+ ## Compatibility
39
+
40
+ Note that `uploadcare-ruby` **3.x** is not backward compatible with
41
+ **[2.x](https://github.com/uploadcare/uploadcare-ruby/tree/v2.x)**.
13
42
 
14
43
  ## Installation
15
44
 
16
- Installing `uploadcare-ruby` is quite simple and takes a couple of steps.
17
- First of, add the following line to your app's Gemfile:
45
+ Add this line to your application's Gemfile:
18
46
 
19
47
  ```ruby
20
48
  gem 'uploadcare-ruby'
21
49
  ```
22
50
 
23
- Once you've added the line, execute this:
51
+ And then execute:
24
52
 
25
- ```shell
26
- $ bundle install
27
- ```
53
+ $ bundle
28
54
 
29
- Or that (for manual install):
55
+ If already not, create your project in [Uploadcare dashboard](https://uploadcare.com/dashboard/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby) and copy
56
+ its API keys from there.
30
57
 
31
- ```shell
32
- $ gem install uploadcare-ruby
58
+ Set your Uploadcare keys in config file or through environment variables:
59
+ ```bash
60
+ export UPLOADCARE_PUBLIC_KEY=demopublickey
61
+ export UPLOADCARE_SECRET_KEY=demoprivatekey
33
62
  ```
34
63
 
35
- ## Initialization
36
-
37
- Init is simply done through creating an API object.
64
+ Or configure your app yourself if you are using different way of storing keys.
65
+ Gem configuration is available in `Uploadcare.configuration`. Full list of
66
+ settings can be seen in [`lib/uploadcare.rb`](lib/uploadcare.rb)
38
67
 
39
68
  ```ruby
40
- require 'uploadcare'
41
-
42
- @api = Uploadcare::Api.new # default settings are used
43
-
44
- @api = Uploadcare::Api.new(settings) # using user-defined settings
69
+ # your_config_initializer_file.rb
70
+ Uploadcare.config.public_key = 'demopublickey'
71
+ Uploadcare.config.secret_key = 'demoprivatekey'
45
72
  ```
46
73
 
47
- Here's how the default settings look like:
48
-
49
- ``` ruby
50
- {
51
- public_key: 'demopublickey', # you need to override this
52
- private_key: 'demoprivatekey', # you need to override this
53
- upload_url_base: 'https://upload.uploadcare.com',
54
- api_url_base: 'https://api.uploadcare.com',
55
- static_url_base: 'https://ucarecdn.com',
56
- api_version: '0.5',
57
- cache_files: true,
58
- autostore: :auto,
59
- auth_scheme: :secure
60
- }
61
- ```
62
-
63
- You're free to use both `demopublickey` and `demoprivatekey`
64
- for initial testing purposes. We wipe out files loaded to our
65
- demo account periodically. For a better experience,
66
- consider creating an Uploadcare account. Check out
67
- [this](http://kb.uploadcare.com/article/234-uc-project-and-account)
68
- article to get up an running in minutes.
69
-
70
- Please note, in order to use [Upload API](https://uploadcare.com/documentation/upload/)
71
- you will only need the public key alone. However, using
72
- [REST API](https://uploadcare.com/documentation/rest/) requires you to
73
- use both public and private keys for authentication.
74
- While “private key” is a common way to name a key from an
75
- authentication key pair, the actual thing for our `auth-param` is `secret_key`.
76
-
77
- `:autostore` option allows you to set the default storage
78
- behaviour upon uploads. For more info see [`store` flag][uploads from url] for
79
- uploads via URL and [`UPLOADCARE_STORE` flag][in-body file uploads] for file uploads
80
-
81
- [in-body file uploads]: https://uploadcare.com/documentation/upload/#upload-body
82
- [uploads from url]: https://uploadcare.com/documentation/upload/#from-url
83
-
84
74
  ## Usage
85
75
 
86
- This section contains practical usage examples. Please note,
87
- everything that follows gets way more clear once you've looked
88
- through our docs [intro](https://uploadcare.com/documentation/).
76
+ This section contains practical usage examples. Please note, everything that
77
+ follows gets way more clear once you've looked through our
78
+ [docs](https://uploadcare.com/docs/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby).
89
79
 
90
- ### Basic usage: uploading a single file, manipulations
80
+ ### Uploading files
81
+ #### Uploading and storing a single file
91
82
 
92
83
  Using Uploadcare is simple, and here are the basics of handling files.
93
84
 
94
- First of, create the API object:
95
-
96
- ```ruby
97
- @api = Uploadcare::Api.new(CONFIG)
98
-
99
- ```
100
-
101
- And yeah, now you can upload a file:
102
-
103
85
  ```ruby
104
86
  @file_to_upload = File.open("your-file.png")
105
87
 
106
- @uc_file = @api.upload(@file_to_upload)
107
- # => #<Uploadcare::Api::File ...
108
- ```
109
-
110
- Then, let's check out UUID and URL of the
111
- file you've just uploaded:
88
+ @uc_file = Uploadcare::Uploader.upload(@file_to_upload)
112
89
 
113
- ```ruby
114
- # file uuid (you'd probably want to store those somewhere)
115
90
  @uc_file.uuid
116
91
  # => "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40"
117
92
 
@@ -120,10 +95,9 @@ file you've just uploaded:
120
95
  # => "https://ucarecdn.com/dc99200d-9bd6-4b43-bfa9-aa7bfaefca40/"
121
96
  ```
122
97
 
123
- Your might then want to store or delete the uploaded file.
124
- Storing files could be crucial if you aren't using the
125
- “Automatic file storing” option for your Uploadcare project.
126
- If not stored manually or automatically, files get deleted
98
+ Your might then want to store or delete the uploaded file. Storing files could
99
+ be crucial if you aren't using the “Automatic file storing” option for your
100
+ Uploadcare project. If not stored manually or automatically, files get deleted
127
101
  within a 24-hour period.
128
102
 
129
103
  ```ruby
@@ -136,51 +110,28 @@ within a 24-hour period.
136
110
  # => #<Uploadcare::Api::File ...
137
111
  ```
138
112
 
139
- ### Uploading a file from URL
113
+ #### Multiple ways to upload files
140
114
 
141
- Now, this one is also quick. Just pass your URL into our API
142
- and you're good to go.
115
+ Uploadcare supports multiple ways to upload files:
143
116
 
144
117
  ```ruby
145
- # the smart upload
146
- @file = @api.upload "http://your.awesome/avatar.jpg"
147
- # => #<Uploadcare::Api::File ...
148
-
149
- # use this one if you want to explicitly upload from URL
150
- @file = @api.upload_from_url "http://your.awesome/avatar.jpg"
151
- # => #<Uploadcare::Api::File ...
118
+ # Smart upload - detects type of passed object and picks appropriate upload method
119
+ Uploadcare::Uploader.upload('https://placekitten.com/96/139')
152
120
  ```
153
- Keep in mind that providing invalid URL
154
- will raise `ArgumentError`.
155
-
156
- ### Uploading multiple files
157
121
 
158
- Uploading multiple files is as simple as passing an array
159
- of `File` instances into our API.
122
+ There are explicit ways to select upload type:
160
123
 
161
124
  ```ruby
162
- file1 = File.open("path/to/your/file.png")
163
- file2 = File.open("path/to/your/another-file.png")
164
- files = [file1, file2]
125
+ files = [File.open('1.jpg'), File.open('1.jpg']
126
+ Uploadcare::Uploader.upload_files(files)
165
127
 
166
- @uc_files = @api.upload files
167
- # => [#<Uploadcare::Api::File uuid="dc99200d-9bd6-4b43-bfa9-aa7bfaefca40">,
168
- # #<Uploadcare::Api::File uuid="96cdc400-adc3-435b-9c94-04cd87633fbb">]
169
- ```
170
-
171
- In case of multiple input, the respective output would also be an array.
172
- You can iterate through the array to address to single files.
173
- You might also want to request more info about a file using `load_data`.
128
+ Uploadcare::Uploader.upload_from_url('https://placekitten.com/96/139')
174
129
 
175
- ```ruby
176
- @uc_files[0]
177
- # => #<Uploadcare::Api::File uuid="dc99200d-9bd6-4b43-bfa9-aa7bfaefca40">
178
-
179
- @uc_files[1].load_data
180
- # => #<Uploadcare::Api::File uuid="96cdc400-adc3-435b-9c94-04cd87633fbb", original_file_url="https://ucarecdn.com/96cdc400-adc3-435b-9c94-04cd87633fbb/samuelzeller118195.jpg", image_info={"width"=>4896, "geo_location"=>nil, "datetime_original"=>nil, "height"=>3264}, ....>
130
+ # multipart upload - can be useful for files bigger than 10 mb
131
+ Uploadcare::Uploader.multipart_upload(File.open('big_file.bin'))
181
132
  ```
182
133
 
183
- ### Upload options
134
+ #### Uploading options
184
135
 
185
136
  You can override global [`:autostore`](#initialization) option for each upload request:
186
137
 
@@ -189,246 +140,89 @@ You can override global [`:autostore`](#initialization) option for each upload r
189
140
  @api.upload_from_url(url, store: :auto)
190
141
  ```
191
142
 
192
- ### `File` object
193
-
194
- Now that we've already outlined using arrays of `File` instances
195
- to upload multiple files, let's fix on the `File` itself.
196
- It's the the primary object for Uploadcare API.
197
- Basically, it's an avatar for a file you uploaded.
198
- And all the further operations are performed using this avatar,
199
- the `File` object.
200
-
143
+ ### File management
144
+ Most methods are also available through `Uploadcare::Api` object:
201
145
  ```ruby
202
- @file_to_upload = File.open("your-file.png")
203
-
204
- @uc_file = @api.upload(@file_to_upload)
205
- # => #<Uploadcare::Api::File ...
206
-
207
- @uc_file.uuid
208
- # => "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40"
209
-
210
- @uc_file.cdn_url
211
- # => "https://ucarecdn.com/dc99200d-9bd6-4b43-bfa9-aa7bfaefca40/"
146
+ # Same as Uploadcare::Uploader.upload
147
+ Uploadcare::Api.upload('https://placekitten.com/96/139')
212
148
  ```
213
149
 
214
- Please note, all the data associated with files is only accessible
215
- through separate HTTP requests only. So if you don't specifically
216
- need file data (filenames, image dimensions, etc.), you'll be just
217
- fine with using `:uuid` and `:cdn_url` methods for file output:
150
+ Entities are representations of objects in Uploadcare cloud.
218
151
 
219
- ```erb
220
- <img src="#{@file.cdn_url}"/>
221
- ```
222
-
223
- Great, we've just lowered a precious loading time.
224
- However, if you do need the data, you can always request
225
- it manually:
226
-
227
- ```ruby
228
- @uc_file.load_data
229
- ```
230
-
231
- That way your file object will respond to any method described
232
- in [API docs](https://uploadcare.com/documentation/rest/#file).
233
- Basically, that's an an OpenStruct, so you know what to do:
234
-
235
- ```ruby
236
- @uc_file.original_filename
237
- # => "logo.png"
238
-
239
- @uc_file.image_info
240
- # => {"width"=>397, "geo_location"=>nil, "datetime_original"=>nil, "height"=>81}
241
- ```
152
+ #### File
242
153
 
243
- ### `File` object from UUID or CDN URL
244
-
245
- `File` objects are needed to manipulate files on our CDN.
246
- The usual case would be you as a client storing file UUIDs
247
- or CDN URLs somewhere on your side, e.g. in a database.
248
- This is how you can use those to create `File` objects:
249
-
250
- ```ruby
251
- # file object from UUID
252
- @file = @api.file "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40"
253
- # => #<Uploadcare::Api::File uuid="dc99200d-9bd6-4b43-bfa9-aa7bfaefca40"
254
-
255
- # file object from CDN URL
256
- @file = @api.file "https://ucarecdn.com/dc99200d-9bd6-4b43-bfa9-aa7bfaefca40/"
257
- # => #<Uploadcare::Api::File uuid="dc99200d-9bd6-4b43-bfa9-aa7bfaefca40"
258
-
259
- # note, files you generate won't be loaded on init,
260
- # you'll need to load those manually
261
- @file.is_loaded?
262
- # => false
263
- ```
264
-
265
- ### Operations
266
-
267
- Another way to manipulate files on CDN is through operations.
268
- This is particularly useful for images.
269
- We've got on-the-fly crop, resize, rotation, format conversions, and
270
- [more](https://uploadcare.com/documentation/cdn/).
271
- Image operations are there to help you build responsive designs,
272
- generate thumbnails and galleries, change formats, etc.
273
- Currently, this gem has no specific methods for image operations,
274
- we're planning to implement those in further versions.
275
- However, we do support applying image operations through
276
- adding them to CDN URLs. That's an Uploadcare CDN-native
277
- way described in our [docs](https://uploadcare.com/documentation/cdn/).
154
+ File entity contains its metadata.
278
155
 
279
156
  ```ruby
280
- @file = @api.file "https://ucarecdn.com/dc99200d-9bd6-4b43-bfa9-aa7bfaefca40/-/crop/150x150/center/-/format/png/"
281
- # => #<Uploadcare::Api::File uuid="dc99200d-9bd6-4b43-bfa9-aa7bfaefca40"
282
-
283
- @file.operations
284
- # => ["crop/150x150/center", "format/png"]
285
-
286
- # note that by default :cdn_url method returns URLs with no operations:
287
- @file.cdn_url
288
- # => "https://ucarecdn.com/dc99200d-9bd6-4b43-bfa9-aa7bfaefca40/""
289
-
290
- # you can pass "true" into the :cdn_url method to get URL including operations:
291
- @file.cdn_url(true)
292
- # => "https://ucarecdn.com/a8775cf7-0c2c-44fa-b071-4dd48637ecac/-/crop/150x150/center/-/format/png/"
293
-
294
- # there also are specific methods to either dump or include image operations
295
- # in the output URL:
296
- @file.cdn_url_with_operations
297
- @file.cdn_url_without_operations
298
- ```
299
-
300
- While there's no operation wrapper, the best way of handling operations
301
- is through adding them to URLs as strings:
302
-
303
- ```ruby
304
- <img src="#{file.cdn_url}-/crop/#{width}x#{height}/center/"/>
305
- # or something like that
306
- ```
307
-
308
- ### Copying files
309
-
310
- You can also create file copies using our API.
311
- There are multiple ways of creating those.
312
- Also, copying is important for image files because
313
- it allows you to “apply” all the CDN operations
314
- specified in the source URL to a separate static image.
315
-
316
- First of all, a copy of your file can be put in the Uploadcare storage.
317
- This is called “internal copy”, and here's how it works:
318
-
319
- ```ruby
320
- @uc_file.internal_copy
321
-
322
- # =>
323
- {
324
- "type"=>"file",
325
- "result"=> {
326
- "uuid"=>"a191a3df-2c43-4939-9590-784aa371ad6d",
327
- "original_file_url"=>"https://ucarecdn.com/a191a3df-2c43-4939-9590-784aa371ad6d/19xldj.jpg",
328
- "image_info"=>nil,
329
- "datetime_stored"=>nil,
330
- "mime_type"=>"application/octet-stream",
331
- "is_ready"=>true,
332
- "url"=>"https://api.uploadcare.com/files/a191a3df-2c43-4939-9590-784aa371ad6d/",
333
- "original_filename"=>"19xldj.jpg",
334
- "datetime_uploaded"=>"2017-02-10T14:14:18.690581Z",
335
- "size"=>0,
336
- "is_image"=>nil,
337
- "datetime_removed"=>nil,
338
- "source"=>"/4ea293d5-153f-422f-a24e-350237109606/"
339
- }
340
- }
341
- ```
342
-
343
- Once the procedure is complete, a copy would be a separate file
344
- with its own UUID and attributes.
345
-
346
- `#internal_copy` can optionally be used with the options hash argument.
347
- The available options are:
348
-
349
- - *store*
350
-
351
- By default a copy is created without “storing”.
352
- Which means it will be deleted within a 24-hour period.
353
- You can make your output copy permanent by passing the
354
- `store: true` option to the `#internal_copy` method.
355
-
356
- Example:
357
-
358
- ```ruby
359
- @uc_file.internal_copy(store: true)
360
- ```
361
-
362
- - *strip_operations*
157
+ @file = Uploadcare::File.file('FILE_ID_IN_YOUR_PROJECT')
158
+ {"datetime_removed"=>nil,
159
+ "datetime_stored"=>"2020-01-16T15:03:15.315064Z",
160
+ "datetime_uploaded"=>"2020-01-16T15:03:14.676902Z",
161
+ "image_info"=>
162
+ {"color_mode"=>"RGB",
163
+ "orientation"=>nil,
164
+ "format"=>"JPEG",
165
+ "sequence"=>false,
166
+ "height"=>183,
167
+ "width"=>190,
168
+ "geo_location"=>nil,
169
+ "datetime_original"=>nil,
170
+ "dpi"=>nil},
171
+ "is_image"=>true,
172
+ "is_ready"=>true,
173
+ "mime_type"=>"image/jpeg",
174
+ "original_file_url"=>
175
+ "https://ucarecdn.com/FILE_ID_IN_YOUR_PROJECT/imagepng.jpeg",
176
+ "original_filename"=>"image.png.jpeg",
177
+ "size"=>5345,
178
+ "url"=>
179
+ "https://api.uploadcare.com/files/FILE_ID_IN_YOUR_PROJECT/",
180
+ "uuid"=>"8f64f313-e6b1-4731-96c0-6751f1e7a50a"}
363
181
 
364
- If your file is an image and you applied some operations to it,
365
- then by default the same set of operations is also applied to a copy.
366
- You can override this by passing `strip_operations: true` to the
367
- `#internal_copy` method.
182
+ @file.store # copies file, returns a new (copied) file metadata
368
183
 
369
- Example:
184
+ @file.store # stores file, returns updated metadata
370
185
 
371
- ```ruby
372
- file = @api.file "https://ucarecdn.com/24626d2f-3f23-4464-b190-37115ce7742a/-/resize/50x50/"
373
- file.internal_copy
374
- # => This will trigger POST /files/ with {"source": "https://ucarecdn.com/24626d2f-3f23-4464-b190-37115ce7742a/-/resize/50x50/"} in the body
375
- file.internal_copy(strip_operations: true)
376
- # => This will trigger POST /files/ with {"source": "https://ucarecdn.com/24626d2f-3f23-4464-b190-37115ce7742a/"} in the body
377
- ```
378
-
379
- Another option is copying your file to a custom storage.
380
- We call it “external copy” and here's the usage example:
381
-
382
- ```ruby
383
- @uc_file.external_copy('my_custom_storage_name')
384
-
385
- # =>
386
- {
387
- "type"=>"url",
388
- "result"=>"s3://my_bucket_name/c969be02-9925-4a7e-aa6d-b0730368791c/view.png"
389
- }
186
+ @file.delete #deletes file. Returns updated metadata
390
187
  ```
391
188
 
392
- First argument of the `#external_copy` method is a name of
393
- a custom destination storage for your file.
394
-
395
- There's also an optional second argument — options hash. The available options are:
396
-
397
- - *make_public*
398
-
399
- Make a copy available via public links. Can be either `true` or `false`.
400
-
401
- - *pattern*
189
+ Metadata of deleted files is stored permanently.
402
190
 
403
- Name pattern for a copy. If the parameter is omitted, custom storage pattern is used.
191
+ #### FileList
404
192
 
405
- - *strip_operations*
406
-
407
- Same as for `#internal_copy`
408
-
409
- You might want to learn more about
410
- [storage options](https://uploadcare.com/documentation/storages/) or
411
- [copying files](https://uploadcare.com/documentation/rest/#files-post)
412
- with Uploadcare.
413
-
414
-
415
- ### File lists
416
-
417
- `Uploadcare::Api::FileList` represents the whole collection of files (or it's subset) and privides a way to iterate through it, making pagination transparent. FileList objects can be created using `Uploadcare::Api#file_list` method.
193
+ `Uploadcare::Entity::FileList` represents the whole collection of files (or it's
194
+ subset) and provides a way to iterate through it, making pagination transparent.
195
+ FileList objects can be created using `Uploadcare::Entity.file_list` method.
418
196
 
419
197
  ```ruby
420
- @list = @api.file_list # => instance of Uploadcare::Api::FileList
198
+ @list = Uploadcare::Entity.file_list
199
+ # Returns instance of Uploadcare::Api::FileList
200
+ <Hashie::Mash
201
+ next=nil
202
+ per_page=100
203
+ previous=nil
204
+ results=[
205
+ # Array of Entity::File
206
+ ]
207
+ total=8>
208
+ # load last page of files
209
+ @files = @list.files
210
+ # load all files
211
+ @all_files = @list.load
421
212
  ```
422
213
 
423
- This method accepts some options to controll which files should be fetched and how they should be fetched:
214
+ This method accepts some options to controll which files should be fetched and
215
+ how they should be fetched:
424
216
 
425
- - **:limit** - Controls page size. Accepts values from 1 to 1000, defaults to 100.
426
- - **:stored** - Can be either `true` or `false`. When true, file list will contain only stored files. When false - only not stored.
427
- - **:removed** - Can be either `true` or `false`. When true, file list will contain only removed files. When false - all except removed. Defaults to false.
428
- - **:ordering** - Controls the order of returned files. Available values: `datetime_updated`, `-datetime_updated`, `size`, `-size`. Defaults to `datetime_uploaded`. More info can be found [here](https://uploadcare.com/documentation/rest/#file-files)
429
- - **:from** - Specifies the starting point for a collection. Resulting collection will contain files from the given value and to the end in a direction set by an **ordering** option. When files are ordered by datetime_updated in any direction, accepts either a `DateTime` object or an ISO 8601 string. When files are ordered by size, acepts non-negative integers (size in bytes). More info can be found [here](https://uploadcare.com/documentation/rest/#file-files)
217
+ - **:limit** Controls page size. Accepts values from 1 to 1000, defaults to 100.
218
+ - **:stored** Can be either `true` or `false`. When true, file list will contain only stored files. When false only not stored.
219
+ - **:removed** Can be either `true` or `false`. When true, file list will contain only removed files. When false all except removed. Defaults to false.
220
+ - **:ordering** Controls the order of returned files. Available values: `datetime_updated`, `-datetime_updated`, `size`, `-size`. Defaults to `datetime_uploaded`. More info can be found [here](https://uploadcare.com/documentation/rest/#file-files/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby).
221
+ - **:from** Specifies the starting point for a collection. Resulting collection will contain files from the given value and to the end in a direction set by an **ordering** option. When files are ordered by `datetime_updated` in any direction, accepts either a `DateTime` object or an ISO 8601 string. When files are ordered by size, accepts non-negative integers (size in bytes). More info can be found [here](https://uploadcare.com/documentation/rest/#file-files/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby).
430
222
 
431
- Options used to create a file list can be accessed through `#options` method. Note that, once set, they don't affect file fetching process anymore and are stored just for your convenience. That is why they are frozen.
223
+ Options used to create a file list can be accessed through `#options` method.
224
+ Note that, once set, they don't affect file fetching process anymore and are
225
+ stored just for your convenience. That is why they are frozen.
432
226
 
433
227
  ```ruby
434
228
  options = {
@@ -438,286 +232,315 @@ options = {
438
232
  from: "2017-01-01T00:00:00",
439
233
  }
440
234
  @list = @api.file_list(options)
441
- @list.options # => same as options hash above, but frozen
442
- ```
443
-
444
- `Uploadcare::Api::FileList` implements Enumerable interface and holds a collection of `Uploadcare::Api::File` objects, as well as some meta information.
445
-
446
- ```ruby
447
- @list = @api.file_list
448
- @list.total # => 1977
449
- @list.meta # => {
450
- # "next"=> "https://api.uploadcare.com/files/?from=2017-03-09T10%3A30%3A01.877590%2B00%3A00&offset=0",
451
- # "previous"=>nil,
452
- # "total"=>1977,
453
- # "per_page"=>100
454
- # }
455
-
456
- # Enumerable interface
457
- @list.first(5) # => array of 5 x Uploadcare::Api::File
458
- @list.each{|file| puts file.original_filename}
459
- @list.map{|file| file.uuid}
460
- @list.reduce(0){|overall_size, file| overall_size += file.size}
461
- # ...
462
235
  ```
463
236
 
464
- On the inside, `FileList` loada files page by page. First page is loaded when you call `Uploadcare::Api#file_list` and subsequent pages are being loaded when needed. The size of pages is controlled by a `:limit` option.
465
-
466
- Currently loaded files are available through `FileList#objects`. `FileList#loaded` method returns the number of currently loaded files.
467
-
237
+ To simply get all associated objects:
468
238
  ```ruby
469
- @list = @api.file_list(limit: 5) # will load first 5 files
470
- @list.loaded # => 5
471
- @list.fully_loaded? # => false
472
-
473
- @list.objects # => array of 5 x Uploadcare::Api::File
474
- @list.objects[4] # => #<Uploadcare::Api::File ...>
475
- @list.objects[5] # => nil (since 6th file is not yet loaded)
476
-
477
- @list[4] # won't load anything, because 5 files are already loaded
478
- @list[5] # will load the next page
479
- @list.loaded # => 10
480
-
481
- # Note that the example below will load all the files left, page by page,
482
- # and return the count only when they all will be loaded
483
- @list.count # => 132
484
- @list.fully_loaded? # => true
239
+ @list.all # => returns Array of Files
485
240
  ```
486
241
 
487
- Loaded files are preserved when `break` statement or an exception occures inside a block provided to #each, #map, etc.
242
+ #### Pagination
488
243
 
244
+ Initially, `FileList` is a paginated collection. It can be navigated using following methods:
489
245
  ```ruby
490
- @list = @api.file_list(limit: 10)
491
- @list.loaded # => 10
492
-
493
- i = 0
494
- @list.map do |file|
495
- raise if i >= 19
496
- i += 1
497
- file.uuid
498
- end # => RuntimeError
499
-
500
- @list.loaded # => 20
246
+ @file_list = Uploadcare::Entity::FileList.file_list
247
+ # Let's assume there are 250 files in cloud. By default, UC loads 100 files. To get next 100 files, do:
248
+ @next_page = @file_list.next_page
249
+ # To get previous page:
250
+ @previous_page = @next_page.previous_page
501
251
  ```
502
252
 
503
-
504
- ### Store / delete multiple files at once
505
-
506
- There are two methods to do so: `Uploadcare::Api#store_files` and
507
- `Uploadcare::Api#delete_files`. Both of them accept a list of either
508
- UUIDs or `Uploadcare::Api::File`s:
509
-
253
+ Alternatively, it's possible to iterate through full list of groups or files with `each`:
510
254
  ```ruby
511
- uuids_to_store = ['f5c477e0-22af-469d-859a-712e14e14361', 'ec72c6eb-5ea8-4057-a009-52ffffb27c94']
512
- @api.store_files(uuids_to_store)
513
- # => {'status' => 'ok', 'problems' => {}, 'result' => [{...}, {...}]}
514
-
515
- old_files = @api.file_list(stored: true, ordering: '-datetime_uploaded', from: "2015-01-01T00:00:00")
516
- old_files.each_slice(100) do |batch|
517
- response = @api.delete_files(batch)
518
- # Do something with response if you need to
255
+ @list.each do |file|
256
+ p file.url
519
257
  end
520
258
  ```
521
259
 
522
- Our API supports up to 100 files per request. Calling `#store_files` or
523
- `#delete_files` with more than 100 files at once will cause an ArgumentError.
260
+ #### Group
524
261
 
525
- For more details see our [documentation on batch file storage/deletion](https://uploadcare.com/documentation/rest/#files-storage)
526
-
527
- ### `Group` object
528
-
529
- Groups are structures intended to organize sets of separate files.
530
- Each group is assigned UUID.
531
- Note, group UUIDs include a `~#{files_count}` part at the end.
262
+ Groups are structures intended to organize sets of separate files. Each group is
263
+ assigned UUID. Note, group UUIDs include a `~#{files_count}` part at the end.
532
264
  That's a requirement of our API.
533
265
 
534
266
  ```ruby
535
- # group can be created from an array of Uploadcare files
267
+ # group can be created from an array of Uploadcare files (UUIDs)
268
+ @file = '134dc30c-093e-4f48-a5b9-966fe9cb1d01'
269
+ @file2 = '134dc30c-093e-4f48-a5b9-966fe9cb1d02'
536
270
  @files_ary = [@file, @file2]
537
- @files = @api.upload @files_ary
538
- @group = @api.create_group @files
539
- # => #<Uploadcare::Api::Group uuid="0d192d66-c7a6-4465-b2cd-46716c5e3df3~2", files_count=2 ...
540
-
541
- # another way to from a group is via an array of strings holding UUIDs
542
- @uuids_ary = ["c969be02-9925-4a7e-aa6d-b0730368791c", "c969be02-9925-4a7e-aa6d-b0730368791c"]
543
- @group = @api.create_group @uuids_ary
544
- # => #<Uploadcare::Api::Group uuid="0d192d66-c7a6-4465-b2cd-46716c5e3df3~2", files_count=2 ...
271
+ @files = Uploadcare::Uploader.upload @files_ary
272
+ @group = Uploadcare::Group.create @files
545
273
 
546
- # also, you can create a group object via group UUID
547
- @group_uloaded = @api.group "#{uuid}"
274
+ # group can be stored by group ID. It means that all files of a group will be stored on Uploadcare servers permanently
275
+ Uploadcare::Group.store(group.id)
548
276
  ```
549
277
 
550
- As with files, groups created via UUIDs are not loaded by default.
551
- You need to load the data manually, as it requires a separate
552
- HTTP GET request. New groups created with the `:create_group` method
553
- are loaded by default.
278
+ #### GroupList
279
+ `GroupList` is a list of `Group`
554
280
 
555
281
  ```ruby
556
- @group = @api.group "#{uuid}"
557
-
558
- @group.is_loaded?
559
- # => false
560
-
561
- @group.load_data
562
- # => #<Uploadcare::Api::Group uuid="0d192d66-c7a6-4465-b2cd-46716c5e3df3~2", files_count=2 ...
563
-
564
- # once a group is loaded, you can use any methods described in our API docs
565
- # the files within a loaded group are loaded by default
566
- @group.files
567
- # => [#<Uploadcare::Api::File uuid="24626d2f-3f23-4464-b190-37115ce7742a" ...>,
568
- # ... #{files_count} of them ...
569
- # #<Uploadcare::Api::File uuid="7bb9efa4-05c0-4f36-b0ef-11a4221867f6" ...>]
282
+ @group_list = Uploadcare::GroupList.list
283
+ # To get an array of groups:
284
+ @groups = @group_list.all
570
285
  ```
571
286
 
572
- Check out our docs to learn more about
573
- [groups](https://uploadcare.com/documentation/rest/#group).
574
-
287
+ This is a paginated list, so [pagination](#Pagination) methods apply
575
288
 
576
- ### Group lists
289
+ #### Webhook
290
+ https://uploadcare.com/docs/api_reference/rest/webhooks/
577
291
 
578
- `Uploadcare::Api::GroupList` represents a group collection. It works in a same way as `Uploadcare::Api::FileList` does, but with groups.
292
+ You can use webhooks to provide notifications about your uploads to target urls.
293
+ This gem lets you create and manage webhooks.
579
294
 
580
295
  ```ruby
581
- @list = @api.group_list(limit: 10) # => instance of Uploadcare::Api::GroupList
582
- @list[0] # => instance of Uploadcare::Api::Group
296
+ Uploadcare::Webhook.create(target_url: 'https://example.com/listen', event: 'file.uploaded', is_active: true)
297
+ Uploadcare::Webhook.update(<webhook_id>, target_url: 'https://newexample.com/listen/new', event: 'file.uploaded', is_active: true)
298
+ Uploadcare::Webhook.delete('https://example.com/listen')
299
+ Uploadcare::Webhook.list
583
300
  ```
584
301
 
585
- The only thing that differs is an available options list:
586
-
587
- - **:limit** - Controls page size. Accepts values from 1 to 1000, defaults to 100.
588
- - **:ordering** - Controls the order of returned files. Available values: `datetime_created`, `-datetime_created`. Defaults to `datetime_created`. More info can be found [here](https://uploadcare.com/documentation/rest/#group-groups)
589
- - **:from** - Specifies the starting point for a collection. Resulting collection will contain files from the given value and to the end in a direction set by an **ordering** option. Accepts either a `DateTime` object or an ISO 8601 string. More info can be found [here](https://uploadcare.com/documentation/rest/#group-groups)
590
-
591
-
592
- ### `Project` object
302
+ #### Project
593
303
 
594
- `Project` provides basic info about the connected Uploadcare project.
595
- That object is also an OpenStruct, so every methods out of
596
- [these](https://uploadcare.com/documentation/rest/#project) will work.
304
+ `Project` provides basic info about the connected Uploadcare project. That
305
+ object is also an Hashie::Mash, so every methods out of
306
+ [these](https://uploadcare.com/documentation/rest/#project/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby) will work.
597
307
 
598
308
  ```ruby
599
- project = @api.project
309
+ @project = Uploadcare::Project.project
600
310
  # => #<Uploadcare::Api::Project collaborators=[], name="demo", pub_key="demopublickey", autostore_enabled=true>
601
311
 
602
- project.name
312
+ @project.name
603
313
  # => "demo"
604
314
 
605
- p.collaborators
315
+ @project.collaborators
606
316
  # => []
607
317
  # while that one was empty, it usually goes like this:
608
318
  # [{"email": collaborator@gmail.com, "name": "Collaborator"}, {"email": collaborator@gmail.com, "name": "Collaborator"}]
609
319
  ```
610
320
 
611
- ### Raw API
321
+ #### Conversion
612
322
 
613
- Raw API is a simple interface allowing you to make
614
- custom requests to Uploadcare REST API.
615
- It's mainly used when you want a low-level control
616
- over your app.
323
+ ##### Video
617
324
 
618
- ```ruby
619
- # here's how you make any requests
620
- @api.request :get, "/files/", {page: 2}
325
+ Uploadcare can encode video files from all popular formats, adjust their quality, format and dimensions, cut out a video fragment, and generate thumbnails via [REST API](https://uploadcare.com/api-refs/rest-api/v0.6.0/).
621
326
 
622
- # and there also are shortcuts for methods
623
- @api.get '/files', {page: 2}
327
+ After each video file upload you obtain a file identifier in UUID format.
328
+ Then you can use this file identifier to convert your video in multiple ways:
624
329
 
625
- @api.post ...
330
+ ```ruby
331
+ Uploadcare::VideoConverter.convert(
332
+ [
333
+ {
334
+ uuid: "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40",
335
+ size: { resize_mode: 'change_ratio', width: '600', height: '400' },
336
+ quality: 'best',
337
+ format: 'ogg',
338
+ cut: { start_time: '0:0:0.0', length: '0:0:1.0' },
339
+ thumbs: { N: 2, number: 1 }
340
+ }
341
+ ], store: false
342
+ )
343
+ ```
344
+ This method accepts options to set properties of an output file:
626
345
 
627
- @api.put ...
346
+ - **uuid** — the file UUID-identifier.
347
+ - **size**:
348
+ - **resize_mode** - size operation to apply to a video file. Can be `preserve_ratio (default)`, `change_ratio`, `scale_crop` or `add_padding`.
349
+ - **width** - width for a converted video.
350
+ - **height** - height for a converted video.
351
+
352
+ ```
353
+ NOTE: you can choose to provide a single dimension (width OR height).
354
+ The value you specify for any of the dimensions should be a non-zero integer divisible by 4
355
+ ```
628
356
 
629
- @api.delete ...
357
+ - **quality** - sets the level of video quality that affects file sizes and hence loading times and volumes of generated traffic. Can be `normal (default)`, `better`, `best`, `lighter`, `lightest`.
358
+ - **format** - format for a converted video. Can be `mp4 (default)`, `webm`, `ogg`.
359
+ - **cut**:
360
+ - **start_time** - defines the starting point of a fragment to cut based on your input file timeline.
361
+ - **length** - defines the duration of that fragment.
362
+ - **thumbs**:
363
+ - **N** - quantity of thumbnails for your video - non-zero integer ranging from 1 to 50; defaults to 1.
364
+ - **number** - zero-based index of a particular thumbnail in a created set, ranging from 1 to (N - 1).
365
+ - **store** - a flag indicating if Uploadcare should store your transformed outputs.
630
366
 
367
+ ```ruby
368
+ # Response
369
+ {
370
+ :result => [
371
+ {
372
+ :original_source=>"dc99200d-9bd6-4b43-bfa9-aa7bfaefca40/video/-/size/600x400/change_ratio/-/quality/best/-/format/ogg/-/cut/0:0:0.0/0:0:1.0/-/thumbs~2/1/",
373
+ :token=>911933811,
374
+ :uuid=>"6f9b88bd-625c-4d60-bfde-145fa3813d95",
375
+ :thumbnails_group_uuid=>"cf34c5a1-8fcc-4db2-9ec5-62c389e84468~2"
376
+ }
377
+ ],
378
+ :problems=>{}
379
+ }
631
380
  ```
381
+ Params in the response:
382
+ - **result** - info related to your transformed output(-s):
383
+ - **original_source** - built path for a particular video with all the conversion operations and parameters.
384
+ - **token** - a processing job token that can be used to get a [job status](https://uploadcare.com/docs/transformations/video-encoding/#status) (see below).
385
+ - **uuid** - UUID of your processed video file.
386
+ - **thumbnails_group_uuid** - holds :uuid-thumb-group, a UUID of a [file group](https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/groupsList) with thumbnails for an output video, based on the thumbs [operation](https://uploadcare.com/docs/transformations/video-encoding/#operation-thumbs) parameters.
387
+ - **problems** - problems related to your processing job, if any.
632
388
 
633
- All of the raw API methods return a parsed JSON response
634
- or raise an error (handling those is done on your side in the case).
389
+ To convert multiple videos just add params as a hash for each video to the first argument of the `Uploadcare::VideoConverter#convert` method:
635
390
 
636
- ### Error handling
391
+ ```ruby
392
+ Uploadcare::VideoConverter.convert(
393
+ [
394
+ { video_one_params }, { video_two_params }, ...
395
+ ], store: false
396
+ )
397
+ ```
637
398
 
638
- Starting from the version 1.0.2, we've got have custom exceptions
639
- that will be raised in case the Uploadcare service returns
640
- something with 4xx or 5xx HTTP status.
641
399
 
642
- Check out the list of custom errors:
400
+ To check a status of a video processing job you can simply use appropriate method of `Uploadcare::VideoConverter`:
643
401
 
644
402
  ```ruby
645
- 400 => Uploadcare::Error::RequestError::BadRequest,
646
- 401 => Uploadcare::Error::RequestError::Unauthorized,
647
- 403 => Uploadcare::Error::RequestError::Forbidden,
648
- 404 => Uploadcare::Error::RequestError::NotFound,
649
- 406 => Uploadcare::Error::RequestError::NotAcceptable,
650
- 408 => Uploadcare::Error::RequestError::RequestTimeout,
651
- 422 => Uploadcare::Error::RequestError::UnprocessableEntity,
652
- 429 => Uploadcare::Error::RequestError::TooManyRequests,
653
- 500 => Uploadcare::Error::ServerError::InternalServerError,
654
- 502 => Uploadcare::Error::ServerError::BadGateway,
655
- 503 => Uploadcare::Error::ServerError::ServiceUnavailable,
656
- 504 => Uploadcare::Error::ServerError::GatewayTimeout
657
- ```
658
-
659
- That's how you handle a particular error
660
- (in this case, a “404: Not Found” error):
403
+ token = 911933811
404
+ Uploadcare::VideoConverter.status(token)
405
+ ```
406
+ `token` here is a processing job token, obtained in a response of a convert video request.
661
407
 
662
408
  ```ruby
663
- begin
664
- @connection.send :get, '/random_url/', {}
665
- rescue Uploadcare::Error::RequestError::NotFound => e
666
- nil
667
- end
409
+ # Response
410
+ {
411
+ :status => "finished",
412
+ :error => nil,
413
+ :result => {
414
+ :uuid => "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40",
415
+ :thumbnails_group_uuid => "0f181f24-7551-42e5-bebc-14b15d9d3838~2"
416
+ }
417
+ }
668
418
  ```
669
419
 
670
- Handling any request error (covers all 4xx status codes):
420
+ Params in the response:
421
+ - **status** - processing job status, can have one of the following values:
422
+ - *pending* — video file is being prepared for conversion.
423
+ - *processing* — video file processing is in progress.
424
+ - *finished* — the processing is finished.
425
+ - *failed* — we failed to process the video, see error for details.
426
+ - *canceled* — video processing was canceled.
427
+ - **error** - holds a processing error if we failed to handle your video.
428
+ - **result** - repeats the contents of your processing output.
429
+ - **thumbnails_group_uuid** - holds :uuid-thumb-group, a UUID of a file group with thumbnails for an output video, based on the thumbs operation parameters.
430
+ - **uuid** - a UUID of your processed video file.
671
431
 
672
- ```ruby
673
- begin
674
- @connection.send :get, '/random_url/', {}
675
- rescue Uploadcare::Error::RequestError => e
676
- nil
677
- end
678
- ```
432
+ More examples and options can be found [here](https://uploadcare.com/docs/transformations/video-encoding/#video-encoding)
433
+
434
+ ##### Document
679
435
 
680
- Handling any Uploadcare service error:
436
+ Uploadcare allows converting documents to the following target formats: DOC, DOCX, XLS, XLSX, ODT, ODS, RTF, TXT, PDF, JPG, ENHANCED JPG, PNG. Document Conversion works via our [REST API](https://uploadcare.com/api-refs/rest-api/v0.6.0/).
437
+
438
+ After each document file upload you obtain a file identifier in UUID format.
439
+ Then you can use this file identifier to convert your document to a new format:
681
440
 
682
441
  ```ruby
683
- begin
684
- @connection.send :get, '/random_url/', {}
685
- rescue Uploadcare::Error => e
686
- nil
687
- end
442
+ Uploadcare::DocumentConverter.convert(
443
+ [
444
+ {
445
+ uuid: "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40",
446
+ format: 'pdf'
447
+ }
448
+ ], store: false
449
+ )
450
+ ```
451
+ or create an image of a particular page (if using image format):
452
+ ```ruby
453
+ Uploadcare::DocumentConverter.convert(
454
+ [
455
+ {
456
+ uuid: "a4b9db2f-1591-4f4c-8f68-94018924525d",
457
+ format: 'png',
458
+ page: 1
459
+ }
460
+ ], store: false
461
+ )
688
462
  ```
689
463
 
690
- Since many of the above listed things depend on Uploadcare servers,
691
- errors might occasionally occur. Be prepared to handle those.
692
-
693
- ## Testing
464
+ This method accepts options to set properties of an output file:
694
465
 
695
- For testing purposes, run `bundle exec rspec`.
466
+ - **uuid** the file UUID-identifier.
467
+ - **format** - defines the target format you want a source file converted to. The supported values are: `pdf (default)`, `doc`, `docx`, `xls`, `xlsx`, `odt`, `ods`, `rtf`, `txt`, `jpg`, `enhanced.jpg`, `png`. In case the format operation was not found, your input document will be converted to `pdf`.
468
+ - **page** - a page number of a multi-paged document to either `jpg` or `png`. The method will not work for any other target formats.
696
469
 
697
- Please note, if you're willing to run tests using your own keys,
698
- make a `spec/config.yml` file containing the following:
470
+ ```
471
+ NOTE: Use an enhanced.jpg output format for PDF documents with inline fonts.
472
+ When converting multi-page documents to an image format (jpg or png), the output will be a zip archive with one image per page.
473
+ ```
699
474
 
700
- ```yaml
701
- public_key: 'PUBLIC KEY'
702
- private_key: 'PRIVATE KEY'
475
+ ```ruby
476
+ # Response
477
+ {
478
+ :result => [
479
+ {
480
+ :original_source=>"a4b9db2f-1591-4f4c-8f68-94018924525d/document/-/format/png/-/page/1/",
481
+ :token=>21120220
482
+ :uuid=>"88fe5ada-90f1-422a-a233-3a0f3a7cf23c"
483
+ }
484
+ ],
485
+ :problems=>{}
486
+ }
703
487
  ```
488
+ Params in the response:
489
+ - **result** - info related to your transformed output(-s):
490
+ - **original_source** - source file identifier including a target format, if present.
491
+ - **token** - a processing job token that can be used to get a [job status](https://uploadcare.com/docs/transformations/document-conversion/#status) (see below).
492
+ - **uuid** - UUID of your processed document file.
493
+ - **problems** - problems related to your processing job, if any.
704
494
 
705
- ## Contributors
495
+ To convert multiple documents just add params as a hash for each document to the first argument of the `Uploadcare::DocumentConverter#convert` method:
706
496
 
707
- This is open source so fork, hack, request a pull — get a discount.
497
+ ```ruby
498
+ Uploadcare::DocumentConverter.convert(
499
+ [
500
+ { doc_one_params }, { doc_two_params }, ...
501
+ ], store: false
502
+ )
503
+ ```
708
504
 
709
- - [@romanonthego](https://github.com/romanonthego)
710
- - [@vizvamitra](https://github.com/vizvamitra)
711
- - [@dmitry-mukhin](https://github.com/dmitry-mukhin)
712
- - [@zenati](https://github.com/zenati)
713
- - [@renius](https://github.com/renius)
505
+ To check a status of a document processing job you can simply use appropriate method of `Uploadcare::DocumentConverter`:
714
506
 
715
- ## Security issues
507
+ ```ruby
508
+ token = 21120220
509
+ Uploadcare::DocumentConverter.status(token)
510
+ ```
511
+ `token` here is a processing job token, obtained in a response of a convert document request.
716
512
 
717
- If you think you ran into something in Uploadcare libraries
718
- which might have security implications, please hit us up at
719
- [bugbounty@uploadcare.com](mailto:bugbounty@uploadcare.com)
720
- or Hackerone.
513
+ ```ruby
514
+ # Response
515
+ {
516
+ :status => "finished",
517
+ :error => nil,
518
+ :result => {
519
+ :uuid => "a4b9db2f-1591-4f4c-8f68-94018924525d"
520
+ }
521
+ }
522
+ ```
721
523
 
722
- We'll contact you personally in a short time to fix an issue
723
- through co-op and prior to any public disclosure.
524
+ Params in the response:
525
+ - **status** - processing job status, can have one of the following values:
526
+ - *pending* — document file is being prepared for conversion.
527
+ - *processing* — document file processing is in progress.
528
+ - *finished* — the processing is finished.
529
+ - *failed* — we failed to process the document, see error for details.
530
+ - *canceled* — document processing was canceled.
531
+ - **error** - holds a processing error if we failed to handle your document.
532
+ - **result** - repeats the contents of your processing output.
533
+ - **uuid** - a UUID of your processed document file.
534
+
535
+ More examples and options can be found [here](https://uploadcare.com/docs/transformations/document-conversion/#document-conversion)
536
+
537
+ ## Useful links
538
+
539
+ * [Development](https://github.com/uploadcare/uploadcare-ruby/blob/main/DEVELOPMENT.md)
540
+ * [Uploadcare documentation](https://uploadcare.com/docs/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby)
541
+ * [Upload API reference](https://uploadcare.com/api-refs/upload-api/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby)
542
+ * [REST API reference](https://uploadcare.com/api-refs/rest-api/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby)
543
+ * [Changelog](./CHANGELOG.md)
544
+ * [Contributing guide](https://github.com/uploadcare/.github/blob/master/CONTRIBUTING.md)
545
+ * [Security policy](https://github.com/uploadcare/uploadcare-ruby/security/policy)
546
+ * [Support](https://github.com/uploadcare/.github/blob/master/SUPPORT.md)