From 126f5d58a26410a14d54838ec4b15f1f3f1ad4c5 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Fri, 16 Oct 2026 20:02:54 +0300 Subject: [PATCH] convert docx --- Dockerfile | 4 ++-- Gemfile | 1 + Gemfile.lock | 11 +++++++++++ app/views/shared/_native_navbar.html.erb | 4 ++-- app/views/templates/_dropzone.html.erb | 2 +- app/views/templates/_upload_button.html.erb | 2 +- app/views/templates/edit.html.erb | 2 +- config/initializers/autoload.rb | 1 + lib/templates/create_attachments.rb | 21 +++++++++++++++++++++ 9 files changed, 41 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index e6f2d6cc6..798389b17 100644 --- a/Dockerfile +++ b/Dockerfile @@ -52,7 +52,7 @@ ENV OPENSSL_CONF=/etc/openssl_legacy.cnf WORKDIR /app -RUN apk add --no-cache libpq vips redis onnxruntime leptonica jemalloc && \ +RUN apk add --no-cache libpq vips redis onnxruntime leptonica jemalloc font-liberation font-carlito && \ rm -f /usr/bin/onnx_test_runner /usr/bin/onnxruntime_test RUN addgroup -g 2000 docuseal && adduser -u 2000 -G docuseal -s /bin/sh -D -h /home/docuseal docuseal @@ -91,7 +91,7 @@ COPY --chown=docuseal:docuseal --from=download /model.onnx /app/tmp/model.onnx COPY --chown=docuseal:docuseal --from=webpack /app/public/packs ./public/packs RUN mkdir -p /app/public/fonts && ln -s /fonts/DancingScript-Regular.otf /app/public/fonts/ && \ - mkdir -p /usr/share/fonts/noto && ln -s /fonts/GoNotoKurrent-Regular.ttf /usr/share/fonts/noto/ && ln -s /fonts/GoNotoKurrent-Bold.ttf /usr/share/fonts/noto/ && fc-cache -f && \ + mkdir -p /usr/share/fonts/noto/bold && ln -s /fonts/GoNotoKurrent-Regular.ttf /usr/share/fonts/noto/ && ln -s /fonts/GoNotoKurrent-Bold.ttf /usr/share/fonts/noto/bold/ && fc-cache -f && \ bundle exec bootsnap precompile -j 1 --gemfile app/ lib/ && \ chown -R docuseal:docuseal /app/tmp/cache diff --git a/Gemfile b/Gemfile index 99e771b98..fc482901b 100644 --- a/Gemfile +++ b/Gemfile @@ -45,6 +45,7 @@ gem 'trilogy', require: false gem 'turbo-rails' gem 'twitter_cldr', require: false gem 'tzinfo-data' +gem 'wordcraft', require: false, group: :ce gem 'xlsxtream', require: false group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index e62707472..487c8624c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -572,6 +572,16 @@ GEM base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) + wordcraft (0.7.0-aarch64-linux-gnu) + ffi (>= 1.15) + wordcraft (0.7.0-aarch64-linux-musl) + ffi (>= 1.15) + wordcraft (0.7.0-arm64-darwin) + ffi (>= 1.15) + wordcraft (0.7.0-x86_64-linux-gnu) + ffi (>= 1.15) + wordcraft (0.7.0-x86_64-linux-musl) + ffi (>= 1.15) xlsxtream (3.1.0) zip_kit (>= 6.2, < 7) xpath (3.2.0) @@ -650,6 +660,7 @@ DEPENDENCIES tzinfo-data web-console webmock + wordcraft xlsxtream RUBY VERSION diff --git a/app/views/shared/_native_navbar.html.erb b/app/views/shared/_native_navbar.html.erb index 997f6492f..4eb16702b 100644 --- a/app/views/shared/_native_navbar.html.erb +++ b/app/views/shared/_native_navbar.html.erb @@ -22,13 +22,13 @@ <% end %> <% if can?(:create, ::Template) && controller_name.in?(%w[templates_dashboard submissions_dashboard template_folders templates_archived submissions_archived]) %> <% folder_name = @template_folder&.full_name %> - "> + <%= link_to t('create'), new_template_path(folder_name: folder_name), data: { turbo_frame: :modal, native_modal: :medium } %> <% unless controller_name.in?(%w[templates_archived submissions_archived]) %> - "> + <%= link_to t('create'), new_template_path(folder_name: folder_name), data: { turbo_frame: :modal, native_modal: :medium } %> diff --git a/app/views/templates/_dropzone.html.erb b/app/views/templates/_dropzone.html.erb index 855823781..cdc4bf4fc 100644 --- a/app/views/templates/_dropzone.html.erb +++ b/app/views/templates/_dropzone.html.erb @@ -31,7 +31,7 @@ - " multiple> + diff --git a/app/views/templates/_upload_button.html.erb b/app/views/templates/_upload_button.html.erb index dbf104cb3..095464db3 100644 --- a/app/views/templates/_upload_button.html.erb +++ b/app/views/templates/_upload_button.html.erb @@ -16,7 +16,7 @@ - " multiple> + <% end %> diff --git a/app/views/templates/edit.html.erb b/app/views/templates/edit.html.erb index 6c527eb21..65e5739e0 100644 --- a/app/views/templates/edit.html.erb +++ b/app/views/templates/edit.html.erb @@ -10,4 +10,4 @@ <% account_configs = current_account.account_configs.where(key: [AccountConfig::TEMPLATE_CUSTOM_FIELDS_KEY, AccountConfig::TEMPLATE_DATE_FORMATS_KEY]).to_a %> <% custom_fields = account_configs.find { |e| e.key == AccountConfig::TEMPLATE_CUSTOM_FIELDS_KEY }&.value || [] %> <% date_formats = account_configs.find { |e| e.key == AccountConfig::TEMPLATE_DATE_FORMATS_KEY }&.value || [] %> - + diff --git a/config/initializers/autoload.rb b/config/initializers/autoload.rb index fd307b35d..cf66fc063 100644 --- a/config/initializers/autoload.rb +++ b/config/initializers/autoload.rb @@ -9,3 +9,4 @@ autoload :OnnxRuntime, 'onnxruntime' autoload :RQRCode, 'rqrcode' autoload :ArabicLetterConnector, 'arabic-letter-connector/logic' autoload :JWT, 'jwt' +autoload :WordCraft, 'wordcraft' diff --git a/lib/templates/create_attachments.rb b/lib/templates/create_attachments.rb index 6f8f695d6..b7c11a9af 100644 --- a/lib/templates/create_attachments.rb +++ b/lib/templates/create_attachments.rb @@ -6,6 +6,7 @@ module Templates ZIP_CONTENT_TYPE = 'application/zip' X_ZIP_CONTENT_TYPE = 'application/x-zip-compressed' JSON_CONTENT_TYPE = 'application/json' + WORD_EXTENSIONS = %w[.docx .doc .rtf].freeze DOCUMENT_EXTENSIONS = %w[.docx .doc .xlsx .xls .odt .rtf].freeze DOCUMENT_CONTENT_TYPES = %w[ @@ -134,7 +135,27 @@ module Templates return [handle_pdf_or_image(template, file, file.read, params, extract_fields:), []] end + if File.extname(file.original_filename.to_s).downcase.in?(WORD_EXTENSIONS) + return [handle_word_document(template, file, params), []] + end + raise InvalidFileType, "#{file.content_type}/#{dynamic}" end + + def handle_word_document(template, file, params) + pdf = WordCraft.convert(file.read) + + pdf_file = ActionDispatch::Http::UploadedFile.new( + tempfile: StringIO.new(pdf), + filename: "#{File.basename(file.original_filename, '.*')}.pdf", + type: PDF_CONTENT_TYPE + ) + + handle_pdf_or_image(template, pdf_file, pdf, params) + end + + def document_extensions + Docuseal.advanced_formats? ? DOCUMENT_EXTENSIONS : WORD_EXTENSIONS + end end end