Skip to content
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ jobs:
env:
UPLOADCARE_PUBLIC_KEY: demopublickey
UPLOADCARE_SECRET_KEY: demoprivatekey
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
if: matrix.ruby-version == '3.3'
with:
file: ./coverage/lcov.info
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
Comment on lines +37 to +44
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Update to a newer version of codecov/codecov-action

The static analysis tool indicates that codecov/codecov-action@v3 is too old to run on GitHub Actions. Consider updating to @v4 which is the current stable version.

-    - name: Upload coverage reports to Codecov
-      uses: codecov/codecov-action@v3
-      if: matrix.ruby-version == '3.3'
-      with:
-        file: ./coverage/lcov.info
-        flags: unittests
-        name: codecov-umbrella
-        fail_ci_if_error: false
+    - name: Upload coverage reports to Codecov
+      uses: codecov/codecov-action@v4
+      if: matrix.ruby-version == '3.3'
+      with:
+        file: ./coverage/lcov.info
+        flags: unittests
+        name: codecov-umbrella
+        fail_ci_if_error: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
if: matrix.ruby-version == '3.3'
with:
file: ./coverage/lcov.info
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
if: matrix.ruby-version == '3.3'
with:
file: ./coverage/lcov.info
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
🧰 Tools
🪛 actionlint (1.7.7)

38-38: the runner of "codecov/codecov-action@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
In .github/workflows/ruby.yml around lines 37 to 44, the codecov GitHub Action
is using an outdated version v3. Update the version from
codecov/codecov-action@v3 to codecov/codecov-action@v4 to use the current stable
release compatible with GitHub Actions.


style-check:
runs-on: ubuntu-latest
Expand Down
6 changes: 0 additions & 6 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@ Layout/LineLength:
Lint/IneffectiveAccessModifier:
Enabled: false

Style/HashTransformKeys:
Exclude:
- 'lib/uploadcare/entity/decorator/paginator.rb'
- 'lib/uploadcare/client/conversion/video_conversion_client.rb'
- 'lib/uploadcare/entity/file.rb'

Metrics/BlockLength:
Exclude:
- 'bin/'
Expand Down
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ gem 'byebug'
gem 'rake'
gem 'rspec'
gem 'rubocop'
gem 'simplecov', require: false
gem 'simplecov-lcov', require: false
gem 'vcr'
gem 'webmock'

Expand Down
170 changes: 114 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@ And then execute:

$ bundle

If you use `api_struct` gem in your project, replace it with `uploadcare-api_struct`:
```ruby
gem 'uploadcare-api_struct'
```
and run `bundle install`

If already not, create your project in [Uploadcare dashboard](https://app.uploadcare.com/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby) and copy
its [API keys](https://app.uploadcare.com/projects/-/api-keys/) from there.

Expand Down Expand Up @@ -115,11 +109,11 @@ Your might then want to store or delete the uploaded file.
```ruby
# that's how you store a file, if you have uploaded the file using store: false and changed your mind later
@uc_file.store
# => #<Uploadcare::Api::File ...
# => #<Uploadcare::File ...

# and that works for deleting it
@uc_file.delete
# => #<Uploadcare::Api::File ...
# => #<Uploadcare::File ...
```

#### Multiple ways to upload files
Expand Down Expand Up @@ -207,14 +201,14 @@ You can upload file with custom metadata, for example `subsystem` and `pet`:

### File management

Entities are representations of objects in Uploadcare cloud.
The File resource allows you to manage uploaded files, including storing, deleting, copying, and fetching file information.

#### File

File entity contains its metadata. It also supports `include` param to include additional fields to the file object, such as: "appdata".
#### Fetching File Information

```ruby
@file = Uploadcare::File.file("FILE_UUID", include: "appdata")
# Fetch file information with optional inclusion of additional fields (e.g., appdata)
@file = Uploadcare::File.new(uuid: "FILE_UUID")
file_info = @file.info(include: "metadata")
{
"datetime_removed"=>nil,
"datetime_stored"=>"2018-11-26T12:49:10.477888Z",
Expand Down Expand Up @@ -313,19 +307,86 @@ File entity contains its metadata. It also supports `include` param to include a
}
}

@file.local_copy # copy file to local storage
```
#### Storing Files

@file.remote_copy # copy file to remote storage
# Store a single file
``` ruby
file = Uploadcare::File.new(uuid: "FILE_UUID")
stored_file = file.store

@file.store # stores file, returns updated metadata
puts stored_file.datetime_stored
# => "2024-11-05T09:13:40.543471Z"
```

# Batch store files using their UUIDs
``` ruby
uuids = ['uuid1', 'uuid2', 'uuid3']
batch_result = Uploadcare::File.batch_store(uuids)
```

@file.delete #deletes file. Returns updated metadata
# Check the status of the operation
``` ruby
puts batch_result.status # => "success"
```

The File object is also can be converted if it is a document or a video file. Imagine, you have a document file:
# Access successfully stored files
``` ruby
batch_result.result.each do |file|
puts file.uuid
end
```

# Handle files that encountered issues
``` ruby
unless batch_result.problems.empty?
batch_result.problems.each do |uuid, error|
puts "Failed to store file #{uuid}: #{error}"
end
end
Comment on lines +366 to +399
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix unintended H1 headings in the “Storing Files” section

The narrative lines starting with # (e.g., # Store a single file) render as top-level headings, which breaks the document structure and triggers MD001 (“heading increment”) in markdownlint. These should be plain text (or end with a colon) instead of headings.

Please update these lines accordingly, and apply the same pattern to the adjacent “Check the status…”, “Access successfully stored files…”, and “Handle files…” lines.

Apply this diff:

-# Store a single file
+Store a single file:
 ``` ruby
 file = Uploadcare::File.new(uuid: "FILE_UUID")
 stored_file = file.store
 puts stored_file.datetime_stored
 # => "2024-11-05T09:13:40.543471Z"

-# Batch store files using their UUIDs
+Batch store files using their UUIDs:

uuids = ['uuid1', 'uuid2', 'uuid3']
batch_result = Uploadcare::File.batch_store(uuids)

-# Check the status of the operation
+Check the status of the operation:

puts batch_result.status # => "success"

-# Access successfully stored files
+Access successfully stored files:

batch_result.result.each do |file|
  puts file.uuid
end

-# Handle files that encountered issues
+Handle files that encountered issues:

unless batch_result.problems.empty?
  batch_result.problems.each do |uuid, error|
    puts "Failed to store file #{uuid}: #{error}"
  end
end

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
Store a single file:
🤖 Prompt for AI Agents
In README.md around lines 366 to 399, several narrative lines beginning with `#`
are being parsed as top-level Markdown headings (triggering MD001); change those
lines to plain text (remove the leading `#`) and add a trailing colon for
clarity so they read like section labels: "Batch store files using their
UUIDs:", "Check the status of the operation:", "Access successfully stored
files:", and "Handle files that encountered issues:". Ensure the surrounding
fenced code blocks remain unchanged and that only the four narrative lines are
edited to remove the `#` and append a colon.

```

#### Deleting Files

# Delete a single file
```ruby
file = Uploadcare::File.new(uuid: "FILE_UUID")
deleted_file = file.delete
puts deleted_file.datetime_removed
# => "2024-11-05T09:13:40.543471Z"
```

# Batch delete multiple files
```ruby
@file = Uploadcare::File.file("FILE_UUID")
uuids = ['FILE_UUID_1', 'FILE_UUID_2']
result = Uploadcare::File.batch_delete(uuids)
puts result.result
```

#### Copying Files

# Copy a file to local storage
```ruby
source = '1bac376c-aa7e-4356-861b-dd2657b5bfd2'
file = Uploadcare::File.local_copy(source, store: true)

puts file.uuid
# => "new-uuid-of-the-copied-file"
```

# Copy a file to remote storage
```ruby
source_object = '1bac376c-aa7e-4356-861b-dd2657b5bfd2'
target = 'custom_storage_connected_to_the_project'
file = Uploadcare::File.remote_copy(source_object, target, make_public: true)

puts file
# => "https://my-storage.example.com/path/to/copied-file"
```
Comment on lines +404 to +438
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove stray H1 headings in “Deleting”/“Copying” subsections

Same issue here: the descriptive lines prefixed with # (e.g., # Delete a single file) become H1 headings, causing markdownlint MD001 errors and malformed structure. Please convert them to plain text with trailing colons (or similar) so the hierarchy remains intact.

Apply this diff:

-# Delete a single file
+Delete a single file:
 ```ruby
 file = Uploadcare::File.new(uuid: "FILE_UUID")
 deleted_file = file.delete
 puts deleted_file.datetime_removed
 # => "2024-11-05T09:13:40.543471Z"

-# Batch delete multiple files
+Batch delete multiple files:

uuids = ['FILE_UUID_1', 'FILE_UUID_2']
result = Uploadcare::File.batch_delete(uuids)
puts result.result

-# Copy a file to local storage
+Copy a file to local storage:

source = '1bac376c-aa7e-4356-861b-dd2657b5bfd2'
file = Uploadcare::File.local_copy(source, store: true)

puts file.uuid
# => "new-uuid-of-the-copied-file"

-# Copy a file to remote storage
+Copy a file to remote storage:

source_object = '1bac376c-aa7e-4356-861b-dd2657b5bfd2'
target = 'custom_storage_connected_to_the_project'
file = Uploadcare::File.remote_copy(source_object, target, make_public: true)

puts file
# => "https://my-storage.example.com/path/to/copied-file"
As per static analysis hints (markdownlint MD001).

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.18.1)</summary>

419-419: Heading levels should only increment by one level at a time
Expected: h2; Actual: h4

(MD001, heading-increment)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

In README.md around lines 404 to 438, several examples use leading '#' which
creates H1 headings (triggering markdownlint MD001) — change those heading lines
to plain descriptive text with a trailing colon (e.g., "Batch delete multiple
files:") and keep the fenced code blocks unchanged so the section hierarchy
remains correct and lint errors are resolved.


</details>

<!-- fingerprinting:phantom:triton:sabertoothed -->

<!-- This is an auto-generated comment by CodeRabbit -->

The File object also can be converted if it is a document or a video file. Imagine, you have a document file:

```ruby
@file = Uploadcare::File.new(uuid: "FILE_UUID")
```

To convert it to an another file, just do:
Expand Down Expand Up @@ -366,25 +427,20 @@ Metadata of deleted files is stored permanently.

#### FileList

`Uploadcare::FileList` represents the whole collection of files (or it's
subset) and provides a way to iterate through it, making pagination transparent.
FileList objects can be created using `Uploadcare::FileList.file_list` method.
`Uploadcare::File.list` retrieves a collection of files from Uploadcare, supporting optional filtering and pagination. It provides methods to iterate through the collection and access associated file objects seamlessly.

```ruby
@list = Uploadcare::FileList.file_list
# Returns instance of Uploadcare::Entity::FileList
<Hashie::Mash
next=nil
per_page=100
previous=nil
results=[
# Array of Entity::File
]
total=8>
# load last page of files
@files = @list.files
# load all files
@all_files = @list.load
# Retrieve a list of files
options = {
limit: 10, # Controls the number of files returned (default: 100)
stored: true, # Only include stored files (optional)
removed: false, # Exclude removed files (optional)
ordering: '-datetime_uploaded', # Order by latest uploaded files first
from: '2022-01-01T00:00:00' # Start from this point in the collection
}

@file_list = Uploadcare::File.list(options)
# => Returns an instance of PaginatedCollection containing Uploadcare::File objects
```

This method accepts some options to control which files should be fetched and
Expand All @@ -407,7 +463,7 @@ options = {
ordering: "-datetime_uploaded",
from: "2017-01-01T00:00:00",
}
@list = @api.file_list(options)
@list = Uploadcare::File.list(options)
```

To simply get all associated objects:
Expand All @@ -417,9 +473,9 @@ To simply get all associated objects:

#### Pagination

Initially, `FileList` is a paginated collection. It can be navigated using following methods:
Initially, `File.list` returns a paginated collection. It can be navigated using following methods:
```ruby
@file_list = Uploadcare::FileList.file_list
@file_list = Uploadcare::File.list
# Let's assume there are 250 files in cloud. By default, UC loads 100 files. To get next 100 files, do:
@next_page = @file_list.next_page
# To get previous page:
Expand Down Expand Up @@ -469,18 +525,20 @@ That's a requirement of our API.
Uploadcare::Group.store(group.id)

# get a file group by its ID.
Uploadcare::Group.rest_info(group.id)
@group = Uploadcare::Group.new(uuid: "Group UUID")
@group.info("Group UUID")

# group can be deleted by group ID.
Uploadcare::Group.delete(group.id)
@group = Uploadcare::Group.new(uuid: "Group UUID")
@group.delete("Group UUID")
# Note: This operation only removes the group object itself. All the files that were part of the group are left as is.
```

#### GroupList
`GroupList` is a list of `Group`
`Group.list` returns a list of `Group`

```ruby
@group_list = Uploadcare::GroupList.list
@group_list = Uploadcare::Group.list
# To get an array of groups:
@groups = @group_list.all
```
Expand Down Expand Up @@ -558,10 +616,10 @@ An `Add-On` is an application implemented by Uploadcare that accepts uploaded fi
```ruby
# Execute AWS Rekognition Add-On for a given target to detect labels in an image.
# Note: Detected labels are stored in the file's appdata.
Uploadcare::Addons.ws_rekognition_detect_labels('FILE_UUID')
Uploadcare::AddOns.aws_rekognition_detect_labels('FILE_UUID')

# Check the status of AWS Rekognition.
Uploadcare::Addons.ws_rekognition_detect_labels_status('RETURNED_ID_FROM_WS_REKOGNITION_DETECT_LABELS')
Uploadcare::AddOns.aws_rekognition_detect_labels_status('RETURNED_ID_FROM_WS_REKOGNITION_DETECT_LABELS')
```

##### AWS Rekognition Moderation
Expand All @@ -570,48 +628,48 @@ Uploadcare::Addons.ws_rekognition_detect_labels_status('RETURNED_ID_FROM_WS_REKO
# Execute AWS Rekognition Moderation Add-On for a given target to detect moderation labels in an image.
# Note: Detected moderation labels are stored in the file's appdata.

Uploadcare::Addons.ws_rekognition_detect_moderation_labels('FILE_UUID')
Uploadcare::AddOns.aws_rekognition_detect_moderation_labels('FILE_UUID')

# Check the status of an Add-On execution request that had been started using the Execute Add-On operation.
Uploadcare::Addons.ws_rekognition_detect_moderation_labels_status('RETURNED_ID_FROM_WS_REKOGNITION_DETECT_MODERATION_LABELS')
Uploadcare::AddOns.aws_rekognition_detect_moderation_labels_status('RETURNED_ID_FROM_WS_REKOGNITION_DETECT_MODERATION_LABELS')
```

##### ClamAV

```ruby
# ClamAV virus checking Add-On for a given target.
Uploadcare::Addons.uc_clamav_virus_scan('FILE_UUID')
Uploadcare::AddOns.uc_clamav_virus_scan('FILE_UUID')

# Check and purge infected file.
Uploadcare::Addons.uc_clamav_virus_scan('FILE_UUID', purge_infected: true )
Uploadcare::AddOns.uc_clamav_virus_scan('FILE_UUID', purge_infected: true )

# Check the status of an Add-On execution request that had been started using the Execute Add-On operation.
Uploadcare::Addons.uc_clamav_virus_scan_status('RETURNED_ID_FROM_UC_CLAMAV_VIRUS_SCAN')
Uploadcare::AddOns.uc_clamav_virus_scan_status('RETURNED_ID_FROM_UC_CLAMAV_VIRUS_SCAN')
```

##### Remove.bg

```ruby
# Execute remove.bg background image removal Add-On for a given target.
Uploadcare::Addons.remove_bg('FILE_UUID')
Uploadcare::AddOns.remove_bg('FILE_UUID')

# You can pass optional parameters.
# See the full list of parameters here: https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/removeBgExecute
Uploadcare::Addons.remove_bg('FILE_UUID', crop: true, type_level: '2')
Uploadcare::AddOns.remove_bg('FILE_UUID', crop: true, type_level: '2')

# Check the status of an Add-On execution request that had been started using the Execute Add-On operation.
Uploadcare::Addons.remove_bg_status('RETURNED_ID_FROM_REMOVE_BG')
Uploadcare::AddOns.remove_bg_status('RETURNED_ID_FROM_REMOVE_BG')
```

#### Project

`Project` provides basic info about the connected Uploadcare project. That
`show` provides basic info about the connected Uploadcare project. That
object is also an Hashie::Mash, so every methods out of
[these](https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/projectInfo) will work.

```ruby
@project = Uploadcare::Project.project
# => #<Uploadcare::Api::Project collaborators=[], name="demo", pub_key="your_public_key", autostore_enabled=true>
@project = Uploadcare::Project.show
# => #<Uploadcare::Project collaborators=[], name="demo", pub_key="your_public_key", autostore_enabled=true>

@project.name
# => "demo"
Expand Down
6 changes: 5 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)

task default: :spec
require 'rubocop/rake_task'

RuboCop::RakeTask.new

task default: %i[spec rubocop]
2 changes: 1 addition & 1 deletion bin/console
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# frozen_string_literal: true

require 'bundler/setup'
require 'uploadcare/ruby'
require 'uploadcare'

# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.
Expand Down
Loading
Loading