Class: GeneratedPdfsController
- Inherits:
-
CrmController
- Object
- ActionController::Base
- ApplicationController
- CrmController
- GeneratedPdfsController
- Defined in:
- app/controllers/generated_pdfs_controller.rb
Overview
PDF Studio — generate and iterate PDFs, then import them into the publication
library. The PDF analogue of GeneratedImagesController (the Image Variation
pattern). Access is limited to marketing reps and managers (admins inherit).
Constant Summary
Constants included from Controllers::ReferenceFindable
Controllers::ReferenceFindable::ID_EMBEDDED_PATTERNS
Constants included from Controllers::AnalyticsEvents
Controllers::AnalyticsEvents::MAX_QUEUED_EVENTS, Controllers::AnalyticsEvents::SESSION_KEY
Constants included from Controllers::ErrorRendering
Controllers::ErrorRendering::NON_CONTENT_PATH_PREFIXES
Instance Method Summary collapse
-
#destroy ⇒ Object
DELETE /pdf_studio/:id — discard.
-
#index ⇒ Object
GET /pdf_studio.
-
#new_session ⇒ Object
POST /pdf_studio/new_session — start a conversational PDF session with Sunny (the studio's primary entry point: describe the PDF in plain language and Sunny generates/edits it, staging the result back here for review/import).
-
#raw ⇒ Object
GET /pdf_studio/:id/raw — stream the staged PDF inline for the embedded viewer.
-
#show ⇒ Object
GET /pdf_studio/:id.
-
#source_raw ⇒ Object
GET /pdf_studio/:id/source_raw — stream the SOURCE publication's current PDF inline: the left pane of the side-by-side review for translated staged PDFs.
-
#typst_preview ⇒ Object
POST /pdf_studio/:id/typst_preview — compile edited Typst source WITHOUT persisting anything (the side-by-side editor's live preview).
-
#typst_update ⇒ Object
POST /pdf_studio/:id/typst_update — compile edited Typst source AND make it the new staged PDF: replace the staged bytes, update the master source in the layout, and refresh the page count.
-
#update ⇒ Object
PATCH /pdf_studio/:id — import into the publication library.
Methods inherited from CrmController
#access_denied, #context_id, #context_object, #crm_home_path, #current_ability, #default_url_options, #download_temp, #get_tempfile_path_for_download, #init_status_job_collector, #initialize_crm_lazy_chunks, #persist_enqueued_status_jobs, #record_not_found, #redirect_to_job_or_fallback, #render_edit_action, #set_context, #set_download_path, #stash_file_for_temp_download, #sync_admin_presence_cookie, #touch_employee_last_seen
Methods inherited from ApplicationController
#account_impersonated?, #add_to_flash, #after_sign_in_path_for, #bypass_forgery_protection?, #chat_enabled?, #cloudflare_cleared?, #default_catalog, #default_url_options, #enable_turbo_frames, #find_publication, #fix_invalid_accept_header, #init_js_utils, #is_globals_call?, #layout_by_resource, #locale_store, #redirect_to, #require_employee_for_crm, #set_base_host, #set_real_ip, #set_report_errors_for, #should_render_layout?, #skip_layout_for_turbo_frame?, #stamp_impersonation_context, #tab_frame_breakout_request?, #warmlyyours_canada_ip?, #warmlyyours_ip?, #y
Methods included from Controllers::ReturnPathHandling
#check_for_return_path, #redirect_to_return_path_or_default
Methods included from Controllers::AnalyticsEvents
#consume_queued_analytics_events, #registration_lead_type, #track_event
Methods included from Controllers::DeviceDetection
Methods included from Controllers::SubdomainDetection
#is_crm_request?, #is_www_request?, #json_request?
Methods included from Controllers::TurboSafeRedirect
Methods included from Controllers::TrackingDetection
#bot_request?, #gdpr_country?, #gdpr_country_data, #prevent_bots, #set_tracking_cookie, #track_visitor?
Methods included from Controllers::AcceleratedFileSending
#send_file_accelerated, #send_upload_accelerated
Methods included from Controllers::ErrorRendering
#excp_string, #mail_to_for_error_reporting, #render_400, #render_404, #render_406, #render_410, #render_500, #render_invalid_authenticity_token, #render_ip_spoof_error, #render_unpermitted_parameters, #safe_referer_or_fallback
Methods included from Controllers::TurnstileVerification
#load_turnstile_script_tag, #turnstile_lazy_widget, #turnstile_script_tag, #turnstile_widget, #validate_turnstile!
Methods included from Controllers::CloudflareCaching
edge_cached, #edge_cached_action?, #reset_cloudflare_cache, #set_cloudflare_cache, #skip_edge_cache!, #skip_session
Methods included from Controllers::Webpackable
#preload_webpack_fonts, #webpack_css_include, #webpack_css_url, #webpack_js_include, #wpd_is_running?
Methods included from Controllers::Localizable
#cloudflare_country_locale, #determine_request_locale, #geocoder_locale, #guest_user_locale_check, #locale_optional_www_auth_path?, #param_locale, #set_locale, #set_request_locale, #skip_localization?, #warmlyyours_ip_locale
Methods included from Controllers::Authenticable
#access_denied, #authenticate_account, #authenticate_account!, #authenticate_account_from_login_token!, #check_is_a_manager, #check_is_a_sales_manager, #check_is_an_admin, #check_is_an_employee, #check_party, #clear_mismatched_guest_user, #create_guest_user, #credentials?, #current_or_guest_user, #current_or_guest_user_id_read_only, #current_user, #devise_mapping, #fully_logged_in?, #generate_bot_id, #guest_user, #identifiable?, #init_current_user, #initialize_guest, #load_context_user, #logging_in, #resource, #resource_name, #restrict_access_for_non_employees, #scrubbed_request_path, #user_object, #warn_on_session_guest_id_leak
Methods included from UrlsHelper
#catalog_breadcrumb_links, #catalog_link, #catalog_link_for_product_line, #catalog_link_for_sku, #cms_link, #delocalized_path, #path_to_sales_product_sku, #path_to_sales_product_sku_for_product_line, #path_to_sales_product_sku_for_product_line_slug, #product_line_from_catalog_link, #protocol_neutral_url, #sanitize_external_url, #valid_external_url?
Instance Method Details
#destroy ⇒ Object
DELETE /pdf_studio/:id — discard.
114 115 116 117 118 119 120 |
# File 'app/controllers/generated_pdfs_controller.rb', line 114 def destroy return unless guard_pending @generated_pdf.update!(status: 'rejected') flash[:info] = 'PDF discarded.' redirect_to generated_pdfs_path end |
#index ⇒ Object
GET /pdf_studio
11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'app/controllers/generated_pdfs_controller.rb', line 11 def index @status = params[:status].presence_in(GeneratedPdf::STATUSES) || 'pending' # rubocop:disable Rails/StrongParametersExpect @pagy, @generated_pdfs = pagy( GeneratedPdf.includes({ created_by: :party }, :source_publication).where(status: @status).order(created_at: :desc), limit: params[:per_page] ) @stats = { total: GeneratedPdf.count, pending: GeneratedPdf.pending.count, imported: GeneratedPdf.imported.count, rejected: GeneratedPdf.rejected.count } end |
#new_session ⇒ Object
POST /pdf_studio/new_session — start a conversational PDF session with Sunny
(the studio's primary entry point: describe the PDF in plain language and
Sunny generates/edits it, staging the result back here for review/import).
34 35 36 37 38 39 40 41 42 |
# File 'app/controllers/generated_pdfs_controller.rb', line 34 def new_session result = Pdf::StudioSession.start(user: current_user) if result.success? redirect_to assistant_path(result.conversation) else flash[:error] = "Could not start a PDF session: #{result.error}" redirect_to generated_pdfs_path end end |
#raw ⇒ Object
GET /pdf_studio/:id/raw — stream the staged PDF inline for the embedded viewer.
45 46 47 48 49 50 51 |
# File 'app/controllers/generated_pdfs_controller.rb', line 45 def raw bytes = @generated_pdf.pdf_bytes head(:not_found) and return if bytes.blank? send_data bytes, type: 'application/pdf', disposition: 'inline', filename: @generated_pdf.file_name.presence || 'document.pdf' end |
#show ⇒ Object
GET /pdf_studio/:id
26 27 28 29 |
# File 'app/controllers/generated_pdfs_controller.rb', line 26 def show @source_publication = @generated_pdf.source_publication @source_conversation = @generated_pdf.source_record if @generated_pdf.source_record.is_a?(AssistantConversation) end |
#source_raw ⇒ Object
GET /pdf_studio/:id/source_raw — stream the SOURCE publication's current PDF
inline: the left pane of the side-by-side review for translated staged PDFs.
55 56 57 58 59 60 61 |
# File 'app/controllers/generated_pdfs_controller.rb', line 55 def source_raw literature = @generated_pdf.source_publication&.literature head(:not_found) and return unless literature&. send_data literature..data, type: 'application/pdf', disposition: 'inline', filename: literature..presence || 'source.pdf' end |
#typst_preview ⇒ Object
POST /pdf_studio/:id/typst_preview — compile edited Typst source WITHOUT
persisting anything (the side-by-side editor's live preview). Returns the
PDF bytes, or 422 + typst diagnostics for the editor's error pane.
66 67 68 69 70 71 72 |
# File 'app/controllers/generated_pdfs_controller.rb', line 66 def typst_preview source = params.require(:source) result = Pdf::Typst.compile(source) send_data result.bytes, type: 'application/pdf', disposition: 'inline', filename: 'preview.pdf' rescue Pdf::Typst::Error => e render json: { error: e. }, status: :unprocessable_content end |
#typst_update ⇒ Object
POST /pdf_studio/:id/typst_update — compile edited Typst source AND make it
the new staged PDF: replace the staged bytes, update the master source in
the layout, and refresh the page count. This is what the reviewer imports.
77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'app/controllers/generated_pdfs_controller.rb', line 77 def typst_update return unless guard_pending source = params.require(:source) result = Pdf::Typst.compile(source) @generated_pdf.assign_pdf(result.bytes, filename: @generated_pdf.file_name.presence || 'document.pdf') @generated_pdf.layout = @generated_pdf.layout.to_h.merge('typst_source' => source) @generated_pdf.page_count = result.[:pages] @generated_pdf.save! render json: { success: true, pages: @generated_pdf.page_count } rescue Pdf::Typst::Error => e render json: { error: e. }, status: :unprocessable_content end |
#update ⇒ Object
PATCH /pdf_studio/:id — import into the publication library.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'app/controllers/generated_pdfs_controller.rb', line 92 def update return unless guard_pending result = GeneratedPdfImporter.call( @generated_pdf, mode: params[:mode].presence, base_name: params[:base_name].presence || @generated_pdf.title, sku: params[:sku].presence, locales: Array(params[:locales]).compact_blank.presence, notes: params[:notes].presence ) if result.success? flash[:success] = result.notice redirect_to generated_pdfs_path(status: 'imported') else flash[:error] = result.error redirect_to generated_pdf_path(@generated_pdf) end end |