mirror of
https://gitlab.com/itsulu-odoo/itsulu-blog-publisher.git
synced 2026-05-30 23:41:23 +00:00
Restructure project files to follow the addon layout: - Move models to addons/itsulu_blog_publisher/models/ - Move services (LLM providers, routers) to addons/itsulu_blog_publisher/services/ - Move wizards to addons/itsulu_blog_publisher/wizards/ - Move views (XML templates) to addons/itsulu_blog_publisher/views/ - Move data (cron, mail templates) to addons/itsulu_blog_publisher/data/ - Move security (ACL) to addons/itsulu_blog_publisher/security/ - Move tests and factories to addons/itsulu_blog_publisher/tests/ - Move BDD features to addons/itsulu_blog_publisher/features/ - Create __init__.py files for all Python packages This enables proper Odoo module discovery and import structure. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
119 lines
5.1 KiB
XML
119 lines
5.1 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<odoo>
|
|
<data noupdate="0">
|
|
|
|
<record id="email_template_blog_published" model="mail.template">
|
|
<field name="name">Blog Publisher — Post Published Notification</field>
|
|
<field name="model_id" ref="model_itsulu_blog_generation_log"/>
|
|
<field name="subject">[${object.blog_post_id.blog_id.name or 'ITSulu Insights'}] Blog Post Published: ${object.blog_post_id.name or 'New Post'} - ${format_date(object.create_date, date_format='MMMM dd, yyyy')}</field>
|
|
<field name="email_from">${user.email_formatted}</field>
|
|
<field name="auto_delete">True</field>
|
|
<field name="body_html"><![CDATA[
|
|
<div dir="ltr" style="font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 700px;">
|
|
|
|
<h2 style="color: #0066cc;">Today's ${object.blog_post_id.blog_id.name or 'ITSulu Insights'} Blog Post Published</h2>
|
|
|
|
<p><strong>Date:</strong> ${format_date(object.create_date, date_format='MMMM dd, yyyy (EEEE)')}</p>
|
|
<p><strong>Title:</strong> ${object.blog_post_id.name or ''}</p>
|
|
% set post_url = object.blog_post_id.website_url and ('https://itsulu.com' + object.blog_post_id.website_url) or ''
|
|
<p><strong>URL:</strong> <a href="${post_url}" target="_blank">${post_url}</a></p>
|
|
|
|
<h3 style="margin-top: 30px; color: #0066cc;">Post Details</h3>
|
|
<ul>
|
|
<li><strong>LLM Provider:</strong> ${object.llm_provider or ''} / ${object.llm_model or ''}</li>
|
|
<li><strong>Tokens Used:</strong> ${object.tokens_used or 0}</li>
|
|
<li><strong>Generation Time:</strong> ${'{:.1f}'.format(object.duration_seconds or 0)}s</li>
|
|
<li><strong>Tags:</strong>
|
|
% for tag in object.blog_post_id.tag_ids:
|
|
${tag.name}${' | ' if not loop.last else ''}
|
|
% endfor
|
|
</li>
|
|
<li><strong>Publication Status:</strong> ${'Published' if object.blog_post_id.is_published else 'Draft'}</li>
|
|
<li><strong>Blog:</strong> ${object.blog_post_id.blog_id.name or ''}</li>
|
|
</ul>
|
|
|
|
% set social = object.blog_post_id.itsulu_social_id
|
|
% if social
|
|
|
|
<h3 style="margin-top: 30px; color: #0066cc;">Social Media Posts — Ready to Post</h3>
|
|
|
|
<hr style="margin: 20px 0; border: none; border-top: 2px solid #ddd;"/>
|
|
|
|
% if social.twitter_enabled and (social.twitter_post_a or social.twitter_post_b)
|
|
<h4>🐦 X (Twitter) Post A:</h4>
|
|
<p style="background-color: #f5f5f5; padding: 15px; border-left: 4px solid #1da1f2; font-size: 14px;">
|
|
${social.twitter_post_a or ''}
|
|
</p>
|
|
|
|
<h4>🐦 X (Twitter) Post B:</h4>
|
|
<p style="background-color: #f5f5f5; padding: 15px; border-left: 4px solid #1da1f2; font-size: 14px;">
|
|
${social.twitter_post_b or ''}
|
|
</p>
|
|
% endif
|
|
|
|
<hr style="margin: 20px 0; border: none; border-top: 2px solid #ddd;"/>
|
|
|
|
% if social.bluesky_enabled and (social.bluesky_post_a or social.bluesky_post_b)
|
|
<h4>🌐 BlueSky Posts:</h4>
|
|
<p style="background-color: #f5f5f5; padding: 15px; border-left: 4px solid #1185fe; font-size: 14px;">
|
|
<strong>BlueSky A:</strong><br/>
|
|
${social.bluesky_post_a or ''}
|
|
</p>
|
|
<p style="background-color: #f5f5f5; padding: 15px; border-left: 4px solid #1185fe; font-size: 14px;">
|
|
<strong>BlueSky B:</strong><br/>
|
|
${social.bluesky_post_b or ''}
|
|
</p>
|
|
% endif
|
|
|
|
<hr style="margin: 20px 0; border: none; border-top: 2px solid #ddd;"/>
|
|
|
|
% if social.mastodon_enabled and social.mastodon_post
|
|
<h4>🦣 Fediverse/Mastodon Post:</h4>
|
|
<p style="background-color: #f5f5f5; padding: 15px; border-left: 4px solid #563acc; font-size: 14px;">
|
|
${social.mastodon_post or ''}
|
|
</p>
|
|
% endif
|
|
|
|
<hr style="margin: 20px 0; border: none; border-top: 2px solid #ddd;"/>
|
|
|
|
% if social.linkedin_enabled and social.linkedin_post
|
|
<h4>💼 LinkedIn Post:</h4>
|
|
<p style="background-color: #f5f5f5; padding: 15px; border-left: 4px solid #0a66c2; font-size: 14px;">
|
|
${social.linkedin_post or ''}
|
|
</p>
|
|
% endif
|
|
|
|
% if social.sources_referenced
|
|
<hr style="margin: 30px 0; border: none; border-top: 2px solid #ddd;"/>
|
|
<h3 style="color: #0066cc;">News Sources Referenced:</h3>
|
|
<ul>
|
|
% for line in (social.sources_referenced or '').splitlines():
|
|
% if line.strip()
|
|
% set parts = line.split(' — ', 1)
|
|
% if parts|length == 2
|
|
<li><a href="${parts[1].strip()}" target="_blank">${parts[0].strip()}</a></li>
|
|
% else
|
|
<li>${line.strip()}</li>
|
|
% endif
|
|
% endif
|
|
% endfor
|
|
</ul>
|
|
% endif
|
|
|
|
% endif <!-- end social block -->
|
|
|
|
<hr style="margin: 30px 0; border: none; border-top: 2px solid #ddd;"/>
|
|
|
|
<p style="margin-top: 40px; font-size: 12px; color: #999;">
|
|
<strong>Generated:</strong> ${format_date(object.create_date, date_format='MMMM dd, yyyy')} |
|
|
<strong>Service:</strong> ITSulu Blog Publisher<br/>
|
|
This email contains all social media post variations ready for posting
|
|
across X, BlueSky, Fediverse, and LinkedIn.
|
|
</p>
|
|
|
|
</div>
|
|
]]></field>
|
|
</record>
|
|
|
|
</data>
|
|
</odoo>
|