handle zip upload
This commit is contained in:
@@ -660,7 +660,7 @@ export default {
|
|||||||
acceptFileTypes: {
|
acceptFileTypes: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: 'image/*, application/pdf'
|
default: 'image/*, application/pdf, application/zip'
|
||||||
},
|
},
|
||||||
baseUrl: {
|
baseUrl: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export default {
|
|||||||
acceptFileTypes: {
|
acceptFileTypes: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: 'image/*, application/pdf'
|
default: 'image/*, application/pdf, application/zip'
|
||||||
},
|
},
|
||||||
withReplaceButton: {
|
withReplaceButton: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ export default {
|
|||||||
acceptFileTypes: {
|
acceptFileTypes: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: 'image/*, application/pdf'
|
default: 'image/*, application/pdf, application/zip'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['success', 'error', 'loading'],
|
emits: ['success', 'error', 'loading'],
|
||||||
@@ -131,7 +131,7 @@ export default {
|
|||||||
message () {
|
message () {
|
||||||
if (this.isLoading) {
|
if (this.isLoading) {
|
||||||
return this.t('uploading')
|
return this.t('uploading')
|
||||||
} else if (this.acceptFileTypes === 'image/*, application/pdf') {
|
} else if (this.acceptFileTypes === 'image/*, application/pdf, application/zip') {
|
||||||
return this.title || this.t('add_pdf_documents_or_images')
|
return this.title || this.t('add_pdf_documents_or_images')
|
||||||
} else {
|
} else {
|
||||||
return this.title || this.t('add_documents_or_images')
|
return this.title || this.t('add_documents_or_images')
|
||||||
@@ -146,7 +146,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
upload: Upload.methods.upload,
|
upload: Upload.methods.upload,
|
||||||
onDropFiles (e) {
|
onDropFiles (e) {
|
||||||
if (this.acceptFileTypes !== 'image/*, application/pdf' || [...e.dataTransfer.files].every((f) => f.type.match(/(?:image\/)|(?:application\/pdf)/))) {
|
if (this.acceptFileTypes !== 'image/*, application/pdf, application/zip' || [...e.dataTransfer.files].every((f) => f.type.match(/(?:image\/)|(?:application\/pdf)|(?:application\/zip)/))) {
|
||||||
this.$refs.input.files = e.dataTransfer.files
|
this.$refs.input.files = e.dataTransfer.files
|
||||||
|
|
||||||
this.upload()
|
this.upload()
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export default {
|
|||||||
acceptFileTypes: {
|
acceptFileTypes: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: 'image/*, application/pdf'
|
default: 'image/*, application/pdf, application/zip'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['add', 'replace', 'replace-and-clone', 'error'],
|
emits: ['add', 'replace', 'replace-and-clone', 'error'],
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ export default {
|
|||||||
acceptFileTypes: {
|
acceptFileTypes: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: 'image/*, application/pdf'
|
default: 'image/*, application/pdf, application/zip'
|
||||||
},
|
},
|
||||||
withReplaceButton: {
|
withReplaceButton: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export default {
|
|||||||
acceptFileTypes: {
|
acceptFileTypes: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: 'image/*, application/pdf'
|
default: 'image/*, application/pdf, application/zip'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['success'],
|
emits: ['success'],
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export default {
|
|||||||
acceptFileTypes: {
|
acceptFileTypes: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: 'image/*, application/pdf'
|
default: 'image/*, application/pdf, application/zip'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['success', 'error'],
|
emits: ['success', 'error'],
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<input id="file_dropzone_input" name="files[]" class="hidden" data-action="change:file-dropzone#onSelectFiles" data-target="file-dropzone.input" type="file" accept="image/*, application/pdf<%= ', .docx, .doc, .xlsx, .xls, .odt, .rtf' if Docuseal.multitenant? %>" multiple>
|
<input id="file_dropzone_input" name="files[]" class="hidden" data-action="change:file-dropzone#onSelectFiles" data-target="file-dropzone.input" type="file" accept="image/*, application/pdf, application/zip<%= ", #{Templates::CreateAttachments::DOCUMENT_EXTENSIONS.join(', ')}" if Docuseal.advanced_formats? %>" multiple>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</file-dropzone>
|
</file-dropzone>
|
||||||
|
|||||||
@@ -14,6 +14,6 @@
|
|||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<input type="hidden" name="form_id" value="<%= form_id %>">
|
<input type="hidden" name="form_id" value="<%= form_id %>">
|
||||||
<input id="upload_template" name="files[]" class="hidden" onchange="this.form.requestSubmit()" type="file" accept="image/*, application/pdf<%= ', .docx, .doc, .xlsx, .xls, .odt, .rtf' if Docuseal.advanced_formats? %>" multiple>
|
<input id="upload_template" name="files[]" class="hidden" onchange="this.form.requestSubmit()" type="file" accept="image/*, application/pdf, application/zip<%= ", #{Templates::CreateAttachments::DOCUMENT_EXTENSIONS.join(', ')}" if Docuseal.advanced_formats? %>" multiple>
|
||||||
<input hidden name="folder_name" value="<%= local_assigns[:folder_name] %>">
|
<input hidden name="folder_name" value="<%= local_assigns[:folder_name] %>">
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -3,6 +3,19 @@
|
|||||||
module Templates
|
module Templates
|
||||||
module CreateAttachments
|
module CreateAttachments
|
||||||
PDF_CONTENT_TYPE = 'application/pdf'
|
PDF_CONTENT_TYPE = 'application/pdf'
|
||||||
|
ZIP_CONTENT_TYPE = 'application/zip'
|
||||||
|
JSON_CONTENT_TYPE = 'application/json'
|
||||||
|
DOCUMENT_EXTENSIONS = %w[.docx .doc .xlsx .xls .odt .rtf].freeze
|
||||||
|
|
||||||
|
DOCUMENT_CONTENT_TYPES = %w[
|
||||||
|
application/vnd.openxmlformats-officedocument.wordprocessingml.document
|
||||||
|
application/msword
|
||||||
|
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
||||||
|
application/vnd.ms-excel
|
||||||
|
application/vnd.oasis.opendocument.text
|
||||||
|
application/rtf
|
||||||
|
].freeze
|
||||||
|
|
||||||
ANNOTATIONS_SIZE_LIMIT = 6.megabytes
|
ANNOTATIONS_SIZE_LIMIT = 6.megabytes
|
||||||
InvalidFileType = Class.new(StandardError)
|
InvalidFileType = Class.new(StandardError)
|
||||||
PdfEncrypted = Class.new(StandardError)
|
PdfEncrypted = Class.new(StandardError)
|
||||||
@@ -10,7 +23,7 @@ module Templates
|
|||||||
module_function
|
module_function
|
||||||
|
|
||||||
def call(template, params, extract_fields: false)
|
def call(template, params, extract_fields: false)
|
||||||
Array.wrap(params[:files].presence || params[:file]).map do |file|
|
extract_zip_files(params[:files].presence || params[:file]).flat_map do |file|
|
||||||
handle_file_types(template, file, params, extract_fields:)
|
handle_file_types(template, file, params, extract_fields:)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -53,6 +66,40 @@ module Templates
|
|||||||
raise PdfEncrypted
|
raise PdfEncrypted
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def extract_zip_files(files)
|
||||||
|
extracted_files = []
|
||||||
|
|
||||||
|
Array.wrap(files).each do |file|
|
||||||
|
if file.content_type == ZIP_CONTENT_TYPE
|
||||||
|
Zip::File.open(file.tempfile).each do |entry|
|
||||||
|
next if entry.directory?
|
||||||
|
|
||||||
|
tempfile = Tempfile.new(entry.name)
|
||||||
|
tempfile.binmode
|
||||||
|
entry.get_input_stream { |in_stream| IO.copy_stream(in_stream, tempfile) }
|
||||||
|
tempfile.rewind
|
||||||
|
|
||||||
|
type = Marcel::MimeType.for(tempfile, name: entry.name)
|
||||||
|
|
||||||
|
next if type.exclude?('image') &&
|
||||||
|
type != PDF_CONTENT_TYPE &&
|
||||||
|
type != JSON_CONTENT_TYPE &&
|
||||||
|
DOCUMENT_CONTENT_TYPES.exclude?(type)
|
||||||
|
|
||||||
|
extracted_files << ActionDispatch::Http::UploadedFile.new(
|
||||||
|
filename: File.basename(entry.name),
|
||||||
|
type:,
|
||||||
|
tempfile:
|
||||||
|
)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
extracted_files << file
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
extracted_files
|
||||||
|
end
|
||||||
|
|
||||||
def handle_file_types(template, file, params, extract_fields:)
|
def handle_file_types(template, file, params, extract_fields:)
|
||||||
if file.content_type.include?('image') || file.content_type == PDF_CONTENT_TYPE
|
if file.content_type.include?('image') || file.content_type == PDF_CONTENT_TYPE
|
||||||
return handle_pdf_or_image(template, file, file.read, params, extract_fields:)
|
return handle_pdf_or_image(template, file, file.read, params, extract_fields:)
|
||||||
|
|||||||
Reference in New Issue
Block a user