Class: Assistant::BlogMediaToolBuilder
- Inherits:
-
Object
- Object
- Assistant::BlogMediaToolBuilder
- Defined in:
- app/services/assistant/blog_media_tool_builder.rb
Overview
Service object: blog media tool builder.
Defined Under Namespace
Classes: EmbedOpGuardError
Constant Summary collapse
- CRM_POST_URL =
URL for crm post.
BlogToolBuilder::CRM_POST_URL
Class Method Summary collapse
-
.find_embed_figure(html, uuid) ⇒ Object
Locate the embed wrapper by its data-embedded-asset-uuid in the post solution.
- .save_post_with_embed_op!(post, new_html, change_note:, audit_context:) ⇒ Object
- .serialize_fragment(fragment) ⇒ Object
- .tools(audit_context: {}) ⇒ Object
Class Method Details
.find_embed_figure(html, uuid) ⇒ Object
do NOT interpolate uuid into a CSS selector string. embed UUIDs
come straight from tool input, so quotes/CSS metacharacters (e.g. a
value like "]/script>) can turn a stale or malicious value into a
selector parse error — or worse, match the wrong node before we
mutate the fragment. Iterate the candidate nodes and compare the
attribute by string equality instead.
Locate the embed wrapper by its data-embedded-asset-uuid in the post
solution. Most embeds are , but video embeds are sometimes
rendered as (see
BlogContentValidator#detect_dropped_embeds for the full list). Match
any element carrying the attribute to stay aligned with the validator.
Returns [node, fragment] or [nil, nil].
552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
# File 'app/services/assistant/blog_media_tool_builder.rb', line 552 def (html, uuid) return [nil, nil] if html.nil? || html.to_s.empty? || uuid.to_s.empty? fragment = if defined?(Nokogiri::HTML5) Nokogiri::HTML5.fragment(html.to_s) else Nokogiri::HTML.fragment(html.to_s) end uuid_str = uuid.to_s node = fragment.css('[data-embedded-asset-uuid]').find do |el| el['data-embedded-asset-uuid'] == uuid_str end [node, fragment] end |
.save_post_with_embed_op!(post, new_html, change_note:, audit_context:) ⇒ Object
572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 |
# File 'app/services/assistant/blog_media_tool_builder.rb', line 572 def (post, new_html, change_note:, audit_context:) # These atomic embed ops (remove_embed / replace_embed / move_embed) # write post.solution directly, so without this guard a hallucinated # <figure data-embedded-asset-uuid="..."> from replace_embed could # land in the database without going through the same body / link / # asset-reference checks update_blog_post and edit_blog_post rely on. # We pass skip_embed_check: true because the user's intent to drop or # rearrange the targeted UUID is explicit (that's the whole point of # these tools), but every other content rule must still pass. guard_err = Assistant::BlogToolBuilder.guard_content( body_args: { old_html: post.solution.to_s, new_html: new_html.to_s, post_id: post.id, skip_embed_check: true } ) raise EmbedOpGuardError, guard_err if guard_err = Employee.find_by(id: audit_context[:user_id]) post.solution = new_html post.auto_update_revised_at = true if post.respond_to?(:auto_update_revised_at=) post.updater_id = &.id post.revision_change_notes = change_note post.save! post.reload Assistant::BlogToolBuilder.stabilize_post_solution_after_save!(post) Assistant::BlogContentValidator.upsert_link_graph(post) # remove/replace/move all rewrite published body HTML, so the edge copy # is stale the moment this commits — same gap update_blog_post had. Assistant::BlogToolBuilder.purge_edge_cache_after_edit!(post) post end |
.serialize_fragment(fragment) ⇒ Object
568 569 570 |
# File 'app/services/assistant/blog_media_tool_builder.rb', line 568 def serialize_fragment(fragment) fragment.to_html end |
.tools(audit_context: {}) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'app/services/assistant/blog_media_tool_builder.rb', line 24 def tools(audit_context: {}) [ build_insert_image_tool, build_insert_video_tool, build_insert_faqs_tool, build_insert_product_tool, (audit_context), (audit_context), (audit_context), (audit_context) ] end |