dato-rails 0.7.3 → 0.7.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e08eaabd558518c83178db908c5d4c0e7829f5d28241b05a9eb3c9ea3449d84d
4
- data.tar.gz: 22173dc5421c8c1fbd2fc3b844eebdfcc1876dbfd04f9c04c573878ca1694efe
3
+ metadata.gz: 7d61ca3870d999b82aed6ff238182a3a6fd4b294f87c608b1b9c4ee9425d97ad
4
+ data.tar.gz: 3032c72e0226946239830f8c5aaeb1a5f0640328aa349a269c1f156d9b40f6b8
5
5
  SHA512:
6
- metadata.gz: e0109bd3b767231c28917403f0ca96e9a207dbc9fb593cb6a41c83dc853c33ef58018a5a8cd643382c38ed7f85c8c5a817d3f4cb6d73570f1434fd5ec49fdcaa
7
- data.tar.gz: 5c6b4b06e93b9a79379c7e70fecb578518090047aeb8afa869e08c39275842f158503ff4ed4906d06cccdf144947168d0310d28247b4f626bc4bcadc019ad315
6
+ metadata.gz: 7733a018553585d7f51a8d85920932dabe04944581772d84c6e9bea5d9c8ec6107e0269c6b0832da4028533128d95c0fa91e409b17a4a1d4acf429ae9c5e1591
7
+ data.tar.gz: c705f72bf8f0ed731ff656459b0ef0e5adc4c0a351a79b250f4db55eb0835f6e17df8adb5e9e9a01f6420704c78c92972f894fc06935169795462b142b3a2a70
data/README.md CHANGED
@@ -168,6 +168,55 @@ Dato::Client.new.items.update(attributes: { title: 'Hello world' }, item_id: '12
168
168
  Dato::Client.new.items.destroy(item_id: '123')
169
169
  ```
170
170
 
171
+ ## File upload
172
+
173
+ Dato Rails also supports file uploads.
174
+ These can be created either from a local file or from a url.
175
+ Basically all file types are supported, as long as they are valid in the CMS.
176
+ Be aware that dato jobs are not synchronous, so you may need to
177
+ implement some kind of polling to check if the upload is finished.
178
+ The create method returns a job id, which can be used to retrieve the upload result.
179
+
180
+ > In addition to the binary file, also attributes and metadata can be uploaded.
181
+ Both metadata and attributes are optional.
182
+ > Provide attributes according to the [docs](https://www.datocms.com/docs/content-management-api/resources/upload)
183
+
184
+ ### Upload from Url
185
+ ```ruby
186
+ Dato::Client.new.uploads.create_from_url('https://picsum.photos/seed/picsum/200/300')
187
+ Dato::Client.new.uploads.create_from_url('https://picsum.photos/seed/picsum/200/300', attributes:)
188
+ ```
189
+
190
+ ### Upload from Local File
191
+ ```ruby
192
+ file = File.open('image.png')
193
+
194
+ Dato::Client.new.uploads.create_from_file(file.path)
195
+ Dato::Client.new.uploads.create_from_file(file.path, attributes:)
196
+ ```
197
+
198
+ ### Optional: Attributes and metadata
199
+
200
+ ```ruby
201
+ meta = { en: { title: 'Static Random Image', alt: 'some caption text' } }
202
+ attributes = { author: 'Dato Rails', default_field_metadata: meta }
203
+ ```
204
+
205
+ ### Optional: Filename
206
+ ```ruby
207
+ Dato::Client.new.uploads.create_from_url('https://picsum.photos/seed/picsum/200/300', filename: 'test.png')
208
+ Dato::Client.new.uploads.create_from_file(file.path, filename: 'test.png')
209
+ ```
210
+
211
+
212
+ ### Getting the upload id
213
+ As the file upload is asynchronous, you may need to implement some kind of polling to check if the upload is finished.
214
+ With the retrieve_job_result method you can retrieve the upload id from the job result.
215
+ ```ruby
216
+ job_id = client.uploads.create_from_file(file.path) # get back a job id
217
+ response = client.uploads.retrieve_job_result(job_id).parse # check the status
218
+ upload_id = response.dig('data', 'attributes', 'payload', 'data', 'id') # if nil, it's not done yet
219
+ ```
171
220
  ## Configuration
172
221
 
173
222
  The following options are available:
@@ -241,7 +290,8 @@ You can now clone the dato-rails project
241
290
 
242
291
 
243
292
  You then need to set a `DATO_API_TOKEN=abcd123x` in the `.env` file on the root of your project
244
- to consume data from your project.
293
+ to consume data from your project. For testing purposes, set `TEST_MODEL_TYPE_ID=1234` in the `.env` file
294
+ with the id of the author model type in your project.
245
295
 
246
296
  Then, run `bundle exec rspec` to run the tests.
247
297
 
data/lib/dato/client.rb CHANGED
@@ -1,12 +1,13 @@
1
1
  module Dato
2
2
  class Client
3
3
  delegate :live!, :execute!, :execute, to: :@gql
4
- attr_reader :items, :gql
4
+ attr_reader :items, :uploads, :gql
5
5
 
6
6
  def initialize(api_token = Dato::Config.api_token, validate_query: false, preview: false, live: false)
7
7
  @api_token = api_token
8
8
  @gql = Dato::Gql.new(api_token, validate_query, preview, live)
9
9
  @items = Dato::Items.new(api_token)
10
+ @uploads = Dato::Uploads.new(api_token)
10
11
  end
11
12
  end
12
13
  end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dato
4
+ class Uploads
5
+ BASE_ITEM_URL = "https://site-api.datocms.com/upload-requests"
6
+
7
+ def initialize(api_token)
8
+ @auth_header = "Bearer #{api_token}"
9
+
10
+ headers = {
11
+ "Authorization" => @auth_header,
12
+ "Accept" => "application/json",
13
+ "X-Api-Version" => 3
14
+ }
15
+ @http_headers = HTTP.headers(headers)
16
+ end
17
+
18
+ def create_from_url(url, filename: nil, attributes: nil, meta: nil)
19
+ file = download_file_from_url(url)
20
+ result = create_from_file(file.path, filename:, attributes:, meta:)
21
+ file.delete
22
+
23
+ result
24
+ end
25
+
26
+ def create_from_file(path_to_file, filename: nil, attributes: nil, meta: nil)
27
+ request = request_file_upload_permission(filename || path_to_file)
28
+ upload_url = request[:url]
29
+ upload_id = request[:id]
30
+
31
+ upload_file_to_bucket(url: upload_url, path: path_to_file)
32
+
33
+ upload_file_to_dato(upload_id:, attributes:)
34
+ end
35
+
36
+ def retrieve_job_result(job_id)
37
+ headers = {
38
+ "X-Api-Version" => 3,
39
+ "Authorization" => @auth_header,
40
+ "Accept" => "application/json",
41
+ "Content-Type" => "application/vnd.api+json"
42
+ }
43
+
44
+ headers = HTTP.headers(headers)
45
+
46
+ headers.get("https://site-api.datocms.com/job-results/#{job_id}")
47
+ end
48
+
49
+ private
50
+
51
+ def download_file_from_url(url)
52
+ uri = URI.parse(url)
53
+ file_type = File.extname(uri.path)
54
+ file_contents = Net::HTTP.get(uri)
55
+ temp_file = Tempfile.new(["downloaded_file", file_type])
56
+ temp_file.binmode
57
+ temp_file.write(file_contents)
58
+ temp_file.rewind
59
+ temp_file.close
60
+
61
+ temp_file
62
+ end
63
+
64
+ def request_file_upload_permission(filename)
65
+ data = {
66
+ type: "upload_request",
67
+ attributes: {filename:}
68
+ }
69
+
70
+ response = @http_headers.post(BASE_ITEM_URL, json: {data:})
71
+ response = response.parse["data"]
72
+
73
+ {
74
+ url: response["attributes"]["url"],
75
+ id: response["id"]
76
+ }
77
+ end
78
+
79
+ def upload_file_to_bucket(url:, path:)
80
+ s3_headers = HTTP.headers({"Content-Type" => MimeMagic.by_magic(File.open(path))&.type || "application/octet-stream"})
81
+ s3_headers.put(url, body: File.read(path))
82
+ end
83
+
84
+ def upload_file_to_dato(upload_id:, attributes: nil)
85
+ attributes ||= {}
86
+
87
+ headers = {
88
+ "Content-Type" => "application/vnd.api+json",
89
+ "X-Api-Version" => 3,
90
+ "Authorization" => @auth_header,
91
+ "Accept" => "application/json"
92
+ }
93
+ headers = HTTP.headers(headers)
94
+
95
+ data = {
96
+ type: "upload",
97
+ attributes: {
98
+ path: upload_id,
99
+ **attributes
100
+ }
101
+ }
102
+
103
+ response = headers.post("https://site-api.datocms.com/uploads", json: {data:})
104
+
105
+ response.parse["data"]["id"]
106
+ end
107
+ end
108
+ end
data/lib/dato/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Dato
2
- VERSION = "0.7.3"
2
+ VERSION = "0.7.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dato-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.3
4
+ version: 0.7.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alessandro Rodi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-14 00:00:00.000000000 Z
11
+ date: 2023-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec-rails
@@ -216,6 +216,7 @@ files:
216
216
  - lib/dato/fragments/responsive_image.rb
217
217
  - lib/dato/gql.rb
218
218
  - lib/dato/items.rb
219
+ - lib/dato/uploads.rb
219
220
  - lib/dato/version.rb
220
221
  - lib/tasks/dato/rails_tasks.rake
221
222
  homepage: https://github.com/renuo/dato-rails
@@ -239,7 +240,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
239
240
  - !ruby/object:Gem::Version
240
241
  version: '0'
241
242
  requirements: []
242
- rubygems_version: 3.4.10
243
+ rubygems_version: 3.3.26
243
244
  signing_key:
244
245
  specification_version: 4
245
246
  summary: Use Dato CMS in your Rails application.