active_list 7.2.0 → 7.3.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/lib/active_list/exporters/abstract_exporter.rb +34 -1
- data/lib/active_list/exporters/csv_exporter.rb +6 -2
- data/lib/active_list/exporters/excel_csv_exporter.rb +2 -2
- data/lib/active_list/exporters/open_document_spreadsheet_exporter.rb +34 -52
- data/lib/active_list/generator.rb +3 -2
- data/lib/active_list/generator/finder.rb +58 -0
- data/lib/active_list/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 493c967944f09543ead6e2782c62bbf1379d7db9ce73aaf99a31a30ae7f7ef26
|
4
|
+
data.tar.gz: 5b06ebaf0f046687c035febfd6399d86c700ab15540aa8629faf30793889dc29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abac2cf9a73fbb3ebcc26466e481178f4fb3645b30dbfb00dd01a807e84f6132d59b0bb3d4cd016ad9998cbc0c709c75012132f69fd9b4c434f4cb13adb7da9e
|
7
|
+
data.tar.gz: 8cf5cb483304b2da19a74b86ee1289a9d14612c640c6394f1bebed329498ddb4d2f7b9714d614db2df2813e45de7e5cebafd251cf38b988bcb0ff94ed709978f
|
@@ -12,12 +12,39 @@ module ActiveList
|
|
12
12
|
'txt'
|
13
13
|
end
|
14
14
|
|
15
|
+
def file_name_code
|
16
|
+
"file_name = #{table.model.name}.model_name.human\n".c
|
17
|
+
end
|
18
|
+
|
15
19
|
def mime_type
|
16
20
|
Mime::TEXT
|
17
21
|
end
|
18
22
|
|
23
|
+
def generate_file_code(format)
|
24
|
+
code = file_name_code
|
25
|
+
if generator.export_class
|
26
|
+
code << generator.exportable_query_code
|
27
|
+
code << "#{generator.export_class}.perform_later(user: current_user,\n"
|
28
|
+
code << " query: query,\n"
|
29
|
+
code << " content: #{columns_to_hash},\n"
|
30
|
+
code << " file_name: file_name,\n"
|
31
|
+
code << " format: '#{format}',\n"
|
32
|
+
code << " file_extension: '#{file_extension}')\n"
|
33
|
+
code << "notify_success(:document_in_preparation)\n"
|
34
|
+
code << "redirect_to(:back)\n"
|
35
|
+
else
|
36
|
+
code << generate_data_code
|
37
|
+
code << send_data_code
|
38
|
+
end
|
39
|
+
code.c
|
40
|
+
end
|
41
|
+
|
19
42
|
def send_data_code
|
20
|
-
raise NotImplementedError
|
43
|
+
raise NotImplementedError.new("#{self.class.name}#send_data_code must be implemented in sub-classes.")
|
44
|
+
end
|
45
|
+
|
46
|
+
def generate_data_code
|
47
|
+
raise NotImplementedError.new("#{self.class.name}#generate_data_code must be implemented in sub-classes.")
|
21
48
|
end
|
22
49
|
|
23
50
|
def columns_headers(options = {})
|
@@ -46,6 +73,12 @@ module ActiveList
|
|
46
73
|
end
|
47
74
|
array
|
48
75
|
end
|
76
|
+
|
77
|
+
def columns_to_hash
|
78
|
+
table.exportable_columns.map do |column|
|
79
|
+
[column.header_code, column.exporting_datum_code('record').to_s]
|
80
|
+
end.to_h
|
81
|
+
end
|
49
82
|
end
|
50
83
|
end
|
51
84
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module ActiveList
|
2
2
|
module Exporters
|
3
3
|
class CsvExporter < AbstractExporter
|
4
|
+
|
4
5
|
def file_extension
|
5
6
|
'csv'
|
6
7
|
end
|
@@ -9,7 +10,7 @@ module ActiveList
|
|
9
10
|
Mime[:csv]
|
10
11
|
end
|
11
12
|
|
12
|
-
def
|
13
|
+
def generate_data_code
|
13
14
|
record = 'r'
|
14
15
|
code = generator.select_data_code(paginate: false)
|
15
16
|
code << "data = ::CSV.generate do |csv|\n"
|
@@ -18,9 +19,12 @@ module ActiveList
|
|
18
19
|
code << " csv << [#{columns_to_array(:body, record: record).join(', ')}]\n"
|
19
20
|
code << " end\n"
|
20
21
|
code << "end\n"
|
21
|
-
code << "send_data(data, type: #{mime_type.to_s.inspect}, disposition: 'inline', filename: #{table.model.name}.model_name.human.gsub(/[^a-z0-9]/i, '_') + '.#{file_extension}')\n"
|
22
22
|
code.c
|
23
23
|
end
|
24
|
+
|
25
|
+
def send_data_code
|
26
|
+
"send_data(data, type: #{mime_type.to_s.inspect}, disposition: 'inline', filename: file_name.parameterize + '.#{file_extension}')\n".c
|
27
|
+
end
|
24
28
|
end
|
25
29
|
end
|
26
30
|
end
|
@@ -4,6 +4,7 @@ Mime::Type.register('text/csv', :xcsv) unless defined? Mime::XCSV
|
|
4
4
|
module ActiveList
|
5
5
|
module Exporters
|
6
6
|
class ExcelCsvExporter < CsvExporter
|
7
|
+
|
7
8
|
def file_extension
|
8
9
|
'csv'
|
9
10
|
end
|
@@ -12,7 +13,7 @@ module ActiveList
|
|
12
13
|
Mime[:xcsv]
|
13
14
|
end
|
14
15
|
|
15
|
-
def
|
16
|
+
def generate_data_code
|
16
17
|
record = 'r'
|
17
18
|
code = generator.select_data_code(paginate: false)
|
18
19
|
encoding = 'CP1252'
|
@@ -22,7 +23,6 @@ module ActiveList
|
|
22
23
|
code << " csv << [#{columns_to_array(:body, record: record, encoding: encoding).join(', ')}]\n"
|
23
24
|
code << " end\n"
|
24
25
|
code << "end\n"
|
25
|
-
code << "send_data(data, type: #{mime_type.to_s.inspect}, disposition: 'inline', filename: #{table.model.name}.model_name.human.gsub(/[^a-z0-9]/i,'_')+'.#{file_extension}')\n"
|
26
26
|
code.c
|
27
27
|
end
|
28
28
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'rodf'
|
4
4
|
|
5
5
|
# Register ODS format unless is already set
|
6
6
|
Mime::Type.register('application/vnd.oasis.opendocument.spreadsheet', :ods) unless defined? Mime::ODS
|
@@ -8,11 +8,6 @@ Mime::Type.register('application/vnd.oasis.opendocument.spreadsheet', :ods) unle
|
|
8
8
|
module ActiveList
|
9
9
|
module Exporters
|
10
10
|
class OpenDocumentSpreadsheetExporter < AbstractExporter
|
11
|
-
DATE_ELEMENTS = {
|
12
|
-
'm' => '<number:month number:style="long"/>',
|
13
|
-
'd' => '<number:day number:style="long"/>',
|
14
|
-
'Y' => '<number:year/>'
|
15
|
-
}.freeze
|
16
11
|
|
17
12
|
def file_extension
|
18
13
|
'ods'
|
@@ -22,55 +17,42 @@ module ActiveList
|
|
22
17
|
Mime[:ods]
|
23
18
|
end
|
24
19
|
|
25
|
-
def
|
26
|
-
xml_escape = "to_s.gsub('&', '&').gsub('\\'', ''').gsub('<', '<').gsub('>', '>')"
|
27
|
-
xml_escape << ".force_encoding('US-ASCII')" if xml_escape.respond_to?(:force_encoding)
|
20
|
+
def generate_data_code
|
28
21
|
record = 'r'
|
29
|
-
code = generator.select_data_code(paginate: false)
|
30
|
-
code << "name = #{table.model.name}.model_name.human.gsub(/[^a-z0-9]/i, '_')\n"
|
31
|
-
code << "file = ActiveList.temporary_directory.join(name + rand(999_999_999).to_s(36) + '.#{file_extension}')\n"
|
32
|
-
code << "FileUtils.mkdir_p(file.dirname)\n"
|
33
|
-
code << "Zip::OutputStream.open(file) do |zile|\n"
|
34
|
-
# MimeType in first place
|
35
|
-
code << " zile.put_next_entry('mimetype', nil, nil, Zip::Entry::STORED)\n"
|
36
|
-
code << " zile << '#{mime_type}'\n"
|
37
|
-
|
38
|
-
# Manifest
|
39
|
-
code << " zile.put_next_entry('META-INF/manifest.xml')\n"
|
40
|
-
code << " zile << ('<?xml version=\"1.0\" encoding=\"UTF-8\"?><manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\"><manifest:file-entry manifest:media-type=\"#{mime_type}\" manifest:full-path=\"/\"/><manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"content.xml\"/></manifest:manifest>')\n"
|
41
|
-
code << " zile.put_next_entry('content.xml')\n"
|
42
22
|
|
43
|
-
code
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
23
|
+
code = generator.select_data_code(paginate: false)
|
24
|
+
code << <<~RUBY
|
25
|
+
records = #{generator.records_variable_name}
|
26
|
+
data = RODF::Spreadsheet.new
|
27
|
+
|
28
|
+
data.instance_eval do
|
29
|
+
office_style :head, family: :cell do
|
30
|
+
property :text, 'font-weight': :bold
|
31
|
+
property :paragraph, 'text-align': :center
|
32
|
+
end
|
33
|
+
|
34
|
+
table #{table.model.name}.model_name.human do
|
35
|
+
row do
|
36
|
+
#{columns_to_array(:header)}.each do |header|
|
37
|
+
cell header, style: :head
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
for #{record} in records
|
42
|
+
row do
|
43
|
+
#{columns_to_array(:body, record: record)}.each do |value|
|
44
|
+
cell value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
RUBY
|
51
|
+
code.c
|
52
|
+
end
|
50
53
|
|
51
|
-
|
52
|
-
|
53
|
-
code << " zile << ('<table:table-column table:number-columns-repeated=\"#{table.exportable_columns.size}\"/>')\n"
|
54
|
-
code << " zile << ('<table:table-header-rows><table:table-row>" + columns_headers.collect { |h| "<table:table-cell table:style-name=\"header\" office:value-type=\"string\"><text:p>'+(#{h}).#{xml_escape}+'</text:p></table:table-cell>" }.join + "</table:table-row></table:table-header-rows>')\n"
|
55
|
-
code << " for #{record} in #{generator.records_variable_name}\n"
|
56
|
-
code << " zile << ('<table:table-row>" + table.exportable_columns.collect do |column|
|
57
|
-
'<table:table-cell' + (if column.numeric? || column.datatype == :decimal
|
58
|
-
" office:value-type=\"float\" office:value=\"'+(#{column.datum_code(record)}).#{xml_escape}+'\""
|
59
|
-
elsif column.datatype == :boolean
|
60
|
-
" office:value-type=\"boolean\" office:boolean-value=\"'+(#{column.datum_code(record)}).#{xml_escape}+'\""
|
61
|
-
elsif column.datatype == :date
|
62
|
-
" office:value-type=\"date\" table:style-name=\"ce1\" office:date-value=\"'+(#{column.datum_code(record)}).#{xml_escape}+'\""
|
63
|
-
else
|
64
|
-
' office:value-type="string"'
|
65
|
-
end) + "><text:p>'+(" + column.exporting_datum_code(record, true) + ").#{xml_escape}+'</text:p></table:table-cell>"
|
66
|
-
end.join + "</table:table-row>')\n"
|
67
|
-
code << " end\n"
|
68
|
-
code << " zile << ('</table:table></office:spreadsheet></office:body></office:document-content>')\n"
|
69
|
-
code << "end\n"
|
70
|
-
code << "send_file(file, stream: false, type: #{mime_type.to_s.inspect}, disposition: 'inline', filename: name+'.#{file_extension}')\n"
|
71
|
-
# code << "File.delete(file)\n" # Removes tmp files before they explode the disk
|
72
|
-
# raise code
|
73
|
-
code
|
54
|
+
def send_data_code
|
55
|
+
"send_data(data.bytes, type: #{mime_type.to_s.inspect}, disposition: 'inline', filename: file_name.parameterize + '.#{file_extension}')\n".c
|
74
56
|
end
|
75
57
|
end
|
76
58
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ActiveList
|
2
2
|
class Generator
|
3
|
-
attr_accessor :table, :controller, :controller_method_name, :view_method_name, :records_variable_name
|
3
|
+
attr_accessor :table, :controller, :controller_method_name, :view_method_name, :records_variable_name, :export_class
|
4
4
|
|
5
5
|
def initialize(*args, &_block)
|
6
6
|
options = args.extract_options!
|
@@ -12,6 +12,7 @@ module ActiveList
|
|
12
12
|
@view_method_name = "_#{@controller.controller_name}_list_#{name}_tag"
|
13
13
|
@records_variable_name = "@#{name}"
|
14
14
|
@table = ActiveList::Definition::Table.new(name, model, options)
|
15
|
+
@export_class = options[:export_class]
|
15
16
|
if block_given?
|
16
17
|
yield @table
|
17
18
|
else
|
@@ -47,7 +48,7 @@ module ActiveList
|
|
47
48
|
code << " end\n"
|
48
49
|
for format, exporter in ActiveList::Exporters.hash
|
49
50
|
code << " format.#{format} do\n"
|
50
|
-
code << exporter.new(self).
|
51
|
+
code << exporter.new(self).generate_file_code(format).dig(3)
|
51
52
|
code << " end\n"
|
52
53
|
end
|
53
54
|
code << " end\n"
|
@@ -64,6 +64,64 @@ module ActiveList
|
|
64
64
|
code
|
65
65
|
end
|
66
66
|
|
67
|
+
def exportable_query_code(options = {})
|
68
|
+
unless @table.options.keys.include?(:order)
|
69
|
+
columns = @table.table_columns
|
70
|
+
@table.options[:order] = (columns.any? ? columns.first.name.to_sym : { id: :desc })
|
71
|
+
end
|
72
|
+
|
73
|
+
class_name = "options[\"constant_name\"]&.constantize || #{@table.model.name}"
|
74
|
+
class_name = "(controller_name != '#{class_name.tableize}' && !options[\"constant_name\"] ? controller_name.to_s.classify.constantize : #{class_name})" if collection?
|
75
|
+
|
76
|
+
code = ''
|
77
|
+
|
78
|
+
code << "query = #{class_name}.to_s\n"
|
79
|
+
code << "query << #{scope_code.inspect}\n" if scope_code
|
80
|
+
|
81
|
+
if select_code
|
82
|
+
code << "select = #{select_code}\n"
|
83
|
+
code << "query << \".select(\"\n"
|
84
|
+
code << "query << select.inspect\n"
|
85
|
+
code << "query << \")\"\n"
|
86
|
+
end
|
87
|
+
|
88
|
+
if from_code
|
89
|
+
code << "from = #{from_code}\n"
|
90
|
+
code << "query << \".from(\"\n"
|
91
|
+
code << "query << from.inspect\n"
|
92
|
+
code << "query << \")\"\n"
|
93
|
+
end
|
94
|
+
|
95
|
+
unless @table.options[:conditions].blank?
|
96
|
+
code << "condition = #{conditions_code}\n"
|
97
|
+
code << "query << \".where(\"\n"
|
98
|
+
code << "query << condition.inspect\n"
|
99
|
+
code << "query << \")\"\n"
|
100
|
+
end
|
101
|
+
|
102
|
+
code << "query << \".joins(#{@table.options[:joins].inspect})\"\n" unless @table.options[:joins].blank?
|
103
|
+
|
104
|
+
unless includes_reflections.empty?
|
105
|
+
expr = includes_reflections.inspect[1..-2]
|
106
|
+
code << "query << \".includes(#{expr})\"\n"
|
107
|
+
code << "query << \".references(#{expr})\"\n"
|
108
|
+
end
|
109
|
+
|
110
|
+
unless @table.options[:group].blank?
|
111
|
+
code << "group = #{@table.options[:group].inspect}\n"
|
112
|
+
code << "query << \".group(\"\n"
|
113
|
+
code << "query << group.inspect\n"
|
114
|
+
code << "query << \")\"\n"
|
115
|
+
end
|
116
|
+
|
117
|
+
code << "order = #{var_name(:order)}\n"
|
118
|
+
code << "query << \".reorder(\"\n"
|
119
|
+
code << "query << order.inspect\n"
|
120
|
+
code << "query << \")\"\n"
|
121
|
+
|
122
|
+
code.c
|
123
|
+
end
|
124
|
+
|
67
125
|
protected
|
68
126
|
|
69
127
|
# Compute includes Hash
|
data/lib/active_list/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_list
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brice Texier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-09-
|
11
|
+
date: 2020-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -86,6 +86,20 @@ dependencies:
|
|
86
86
|
- - ">="
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rodf
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :runtime
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
89
103
|
- !ruby/object:Gem::Dependency
|
90
104
|
name: sqlite3
|
91
105
|
requirement: !ruby/object:Gem::Requirement
|