nexaas-async-collector 3.0.1 → 3.1.0
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 +4 -4
- data/README.md +22 -0
- data/app/controllers/nexaas/async/collector/async_resource_controller.rb +13 -4
- data/app/helpers/nexaas/async/collector/application_helper.rb +16 -22
- data/app/models/nexaas/async/collector/async_resource.rb +43 -0
- data/app/views/nexaas/async/collector/async_resource/_show.html.erb +1 -1
- data/app/views/nexaas/async/collector/async_resource/show.js.erb +10 -4
- data/app/workers/nexaas/async/collector/async_resource_job.rb +7 -1
- data/lib/nexaas/async/collector/persist.rb +10 -7
- data/lib/nexaas/async/collector/result.rb +23 -6
- data/lib/nexaas/async/collector/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 22260bccd9579781a6b6ca2dadc82198a30cbb01
|
4
|
+
data.tar.gz: ddfe6e2396e4229904ff1f4084a498913813cd7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9029f15e453e1c4ef0a53cbe2cfcd9a320376acb8761b7b4bedf9470abb529212b4403ba751fe5417bd7b90258a8bfbf96cdb06c6acdbb4fd11c19b03a205b4e
|
7
|
+
data.tar.gz: 1b03833b73d63e95f5988681cad00ec5035a3d5dac53ab7d2f8d60579502bae2667983d48856dfaf7211d15ef8a3cd57c37f6769d49831dcf5f163069b6f87c1
|
data/README.md
CHANGED
@@ -78,6 +78,28 @@ end
|
|
78
78
|
}) %>
|
79
79
|
```
|
80
80
|
|
81
|
+
### Download file
|
82
|
+
|
83
|
+
Instead of rendering text or HTML, you can use `nexaas-async-collect` to generate files, so the user can download it.
|
84
|
+
|
85
|
+
If you want to export something to `xls` file, for example:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
<%= nexaas_async_collect({
|
89
|
+
scope_id: scope.id, # (required)
|
90
|
+
class_name: ModelService, # (required)
|
91
|
+
class_method: :model_method, # (required)
|
92
|
+
args: [arg1, arg2], # (optional)
|
93
|
+
file: {
|
94
|
+
content_type: 'application/vnd.ms-excel', # (required) content type of the file
|
95
|
+
name: 'reports', # (required) name of the file
|
96
|
+
extension: 'xls' # (require) extension of the file
|
97
|
+
}
|
98
|
+
}) %>
|
99
|
+
```
|
100
|
+
|
101
|
+
This will generate the spinner and it will redirect the user to download the file when it is ready.
|
102
|
+
|
81
103
|
## Contributing
|
82
104
|
Bug reports and pull requests are welcome on GitHub at [https://github.com/myfreecomm/nexaas-async-collector](https://github.com/myfreecomm/nexaas-async-collector). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
|
83
105
|
|
@@ -4,20 +4,29 @@ module Nexaas
|
|
4
4
|
module Async
|
5
5
|
module Collector
|
6
6
|
class AsyncResourceController < ApplicationController
|
7
|
+
|
7
8
|
def show
|
8
9
|
@result = Result.new(collector_scope.id, params[:id])
|
9
10
|
@unique_id = params[:unique_id]
|
10
|
-
respond_to
|
11
|
+
respond_to do |format|
|
12
|
+
render_for_request(format)
|
13
|
+
end
|
11
14
|
end
|
12
15
|
|
13
16
|
private
|
14
17
|
|
15
|
-
def
|
16
|
-
|
18
|
+
def render_for_request(format)
|
19
|
+
format.js { render :show }
|
20
|
+
format.all do
|
21
|
+
send_data(@result.content, {
|
22
|
+
filename: "#{@result.filename}.#{@result.extension}", type: @result.content_type,
|
23
|
+
disposition: 'attachment'
|
24
|
+
})
|
25
|
+
end
|
17
26
|
end
|
18
27
|
|
19
28
|
def collector_scope
|
20
|
-
send(
|
29
|
+
send(Nexaas::Async::Collector.scope)
|
21
30
|
end
|
22
31
|
end
|
23
32
|
end
|
@@ -2,21 +2,32 @@ module Nexaas
|
|
2
2
|
module Async
|
3
3
|
module Collector
|
4
4
|
module ApplicationHelper
|
5
|
+
|
5
6
|
#
|
6
7
|
# Helper to enqueue AsyncResourceJob and include the JavaScript code to request the result
|
7
8
|
# - scope_id: an ID that is unique (maybe user.id, account.id, organization.id, etc)
|
8
9
|
# - klass_name: The name of the class responsible for generate the content to be stored in the memory
|
9
10
|
# - klass_method: The name of the class method to be called
|
10
11
|
# - args: The arguments to be passed in the call of the class method
|
12
|
+
# - instrumentation_context: Custom context for instrumentatio with ActiveSupport::Notifications
|
13
|
+
# - file: Argument to pass file informations. This will be used to generated file for the user
|
14
|
+
# - conten_type: Content type of the file
|
15
|
+
# - name: Basename of the file to be generated
|
11
16
|
#
|
12
17
|
# Example:
|
13
|
-
# <%= nexaas_async_collect(
|
18
|
+
# <%= nexaas_async_collect({
|
19
|
+
# scope_id: current_user.id, class_name: ReportGenerator,
|
20
|
+
# class_method: :generate, args: [],
|
21
|
+
# file: { content_type: 'application/json', name: 'data' }
|
22
|
+
# }) %>
|
14
23
|
#
|
15
24
|
def nexaas_async_collect(opts={})
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
25
|
+
async_resource = Nexaas::Async::Collector::AsyncResource.new(opts)
|
26
|
+
async_resource.save!
|
27
|
+
render(partial: 'nexaas/async/collector/async_resource/show', locals: {
|
28
|
+
unique_id: SecureRandom.hex,
|
29
|
+
collect_id: async_resource.collect_id
|
30
|
+
})
|
20
31
|
end
|
21
32
|
|
22
33
|
# Rails 4.x does not add this helper automatically as Rails 5.X and 3.X does. So we had to created it to keep
|
@@ -25,23 +36,6 @@ module Nexaas
|
|
25
36
|
@@nexaas_async_collector ||= Nexaas::Async::Collector::Engine.routes.url_helpers
|
26
37
|
end
|
27
38
|
|
28
|
-
private
|
29
|
-
|
30
|
-
def validate_options(opts={})
|
31
|
-
missing_keys = required_collect_opts - opts.keys.map(&:to_s)
|
32
|
-
if missing_keys.any?
|
33
|
-
raise "Nexaas::Async::Collector: Required parameter missing: #{missing_keys.join(', ')}"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def collect_id
|
38
|
-
@collect_id ||= SecureRandom.hex(15)
|
39
|
-
end
|
40
|
-
|
41
|
-
def required_collect_opts
|
42
|
-
['scope_id', 'class_name', 'class_method']
|
43
|
-
end
|
44
|
-
|
45
39
|
end
|
46
40
|
end
|
47
41
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
module Nexaas
|
4
|
+
module Async
|
5
|
+
module Collector
|
6
|
+
class AsyncResource
|
7
|
+
|
8
|
+
attr_accessor :scope_id, :class_name, :class_method, :args,
|
9
|
+
:file, :collect_id, :instrumentation_context
|
10
|
+
|
11
|
+
include ActiveModel::Validations
|
12
|
+
|
13
|
+
validates_presence_of :scope_id, :class_name, :class_method
|
14
|
+
|
15
|
+
def initialize(opts={})
|
16
|
+
opts.each do |key, value|
|
17
|
+
self.send("#{key}=", value)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def save!
|
22
|
+
initialize_collect_id
|
23
|
+
raise "Nexaas::Async::Collector: invalid fields #{errors.messages.keys.join(', ')}" unless valid?
|
24
|
+
AsyncResourceJob.perform_async(sliced_attributes)
|
25
|
+
end
|
26
|
+
|
27
|
+
def sliced_attributes
|
28
|
+
{
|
29
|
+
scope_id: scope_id, class_name: class_name, class_method: class_method,
|
30
|
+
args: args, file: file, collect_id: collect_id,
|
31
|
+
instrumentation_context: instrumentation_context
|
32
|
+
}.reject { |_,v| v.nil? }
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def initialize_collect_id
|
38
|
+
@collect_id ||= SecureRandom.hex(15)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<script type="text/javascript" id="js-nexaas-async-collector-<%= unique_id %>">
|
2
2
|
var requestContent = function() {
|
3
3
|
$.ajax({
|
4
|
-
url: '<%= nexaas_async_collector.async_resource_path(
|
4
|
+
url: '<%= nexaas_async_collector.async_resource_path(collect_id) %>',
|
5
5
|
dataType: 'script',
|
6
6
|
data: { unique_id: '<%= unique_id %>' }
|
7
7
|
})
|
@@ -1,7 +1,13 @@
|
|
1
1
|
<% if @result.content_is_ready? %>
|
2
2
|
clearInterval(window.nexaas_async_interval);
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
|
4
|
+
<% if @result.is_file? %>
|
5
|
+
$('#js-nexaas-async-collector-loading-<%= @unique_id %>').remove();
|
6
|
+
window.location.href = '<%= async_resource_path(params[:id], format: @result.extension) %>';
|
7
|
+
<% else %>
|
8
|
+
$('#js-nexaas-async-collector-loading-<%= @unique_id %>').remove();
|
9
|
+
$('#js-nexaas-async-collector-<%= @unique_id %>').parent().append("<%= escape_javascript(@result.content.html_safe) %>");
|
10
|
+
$('#js-nexaas-async-collector-<%= @unique_id %>').remove()
|
11
|
+
$('#js-nexaas-async-collector-style-<%= @unique_id %>').remove()
|
12
|
+
<% end %>
|
7
13
|
<% end %>
|
@@ -10,12 +10,18 @@ module Nexaas
|
|
10
10
|
initialize_options(opts)
|
11
11
|
start_time = Time.current.to_i
|
12
12
|
instrument_start(start_time)
|
13
|
-
Persist.save(
|
13
|
+
Persist.save(sliced_options(opts))
|
14
14
|
instrument_finish(start_time)
|
15
15
|
end
|
16
16
|
|
17
17
|
private
|
18
18
|
|
19
|
+
def sliced_options(opts={})
|
20
|
+
opts.with_indifferent_access
|
21
|
+
.slice('collect_id', 'scope_id', 'file')
|
22
|
+
.merge('content' => generate_content)
|
23
|
+
end
|
24
|
+
|
19
25
|
def initialize_options(opts)
|
20
26
|
opts.each do |k, v|
|
21
27
|
instance_variable_set("@#{k}", v)
|
@@ -3,19 +3,22 @@ module Nexaas
|
|
3
3
|
module Collector
|
4
4
|
class Persist
|
5
5
|
class << self
|
6
|
-
def save(
|
7
|
-
|
6
|
+
def save(opts={})
|
7
|
+
opts = opts.with_indifferent_access
|
8
|
+
content = content_in_json(opts)
|
9
|
+
storage.set(opts[:collect_id], content)
|
8
10
|
end
|
9
11
|
|
10
|
-
|
12
|
+
private
|
13
|
+
|
14
|
+
def content_in_json(opts)
|
11
15
|
{
|
12
|
-
'scope_id' => scope_id,
|
13
|
-
'content' =>
|
16
|
+
'scope_id' => opts[:scope_id],
|
17
|
+
'content' => opts[:content],
|
18
|
+
'file' => opts[:file]
|
14
19
|
}.to_json
|
15
20
|
end
|
16
21
|
|
17
|
-
private
|
18
|
-
|
19
22
|
def storage
|
20
23
|
InMemoryStorage.new
|
21
24
|
end
|
@@ -11,7 +11,7 @@ module Nexaas
|
|
11
11
|
module Collector
|
12
12
|
class Result
|
13
13
|
|
14
|
-
attr_reader :scope_id, :id, :
|
14
|
+
attr_reader :scope_id, :id, :object
|
15
15
|
|
16
16
|
def initialize(scope_id, id)
|
17
17
|
@scope_id = scope_id
|
@@ -19,11 +19,27 @@ module Nexaas
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def content
|
22
|
-
|
22
|
+
object['content'] if content_is_ready?
|
23
23
|
end
|
24
24
|
|
25
25
|
def content_is_ready?
|
26
|
-
|
26
|
+
object && object['scope_id'] == scope_id && object['content']
|
27
|
+
end
|
28
|
+
|
29
|
+
def is_file?
|
30
|
+
object && !object['file'].nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
def filename
|
34
|
+
object && object.dig('file', 'name')
|
35
|
+
end
|
36
|
+
|
37
|
+
def content_type
|
38
|
+
object && object.dig('file', 'content_type')
|
39
|
+
end
|
40
|
+
|
41
|
+
def extension
|
42
|
+
object && object.dig('file', 'extension')
|
27
43
|
end
|
28
44
|
|
29
45
|
private
|
@@ -32,9 +48,10 @@ module Nexaas
|
|
32
48
|
@storage ||= InMemoryStorage.new
|
33
49
|
end
|
34
50
|
|
35
|
-
def
|
36
|
-
@
|
37
|
-
@
|
51
|
+
def object
|
52
|
+
return @object if @object
|
53
|
+
@_object = storage.get(id)
|
54
|
+
@object = JSON.parse(@_object) if @_object
|
38
55
|
end
|
39
56
|
|
40
57
|
def url
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nexaas-async-collector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eduardo Hertz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-07-
|
11
|
+
date: 2017-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -141,6 +141,7 @@ files:
|
|
141
141
|
- app/controllers/nexaas/async/collector/application_controller.rb
|
142
142
|
- app/controllers/nexaas/async/collector/async_resource_controller.rb
|
143
143
|
- app/helpers/nexaas/async/collector/application_helper.rb
|
144
|
+
- app/models/nexaas/async/collector/async_resource.rb
|
144
145
|
- app/views/nexaas/async/collector/async_resource/_loading.html.erb
|
145
146
|
- app/views/nexaas/async/collector/async_resource/_show.html.erb
|
146
147
|
- app/views/nexaas/async/collector/async_resource/show.js.erb
|