[IMP] automation_script: improve website, theme and transform knowledge article#6
Conversation
…ge article - Added onboarding guide link in notification email body for quick access to the Knowledge article. - Transform welcome article body into reusable QWeb template with safe HTML parsing. - Rename homepage view record to standard homepage and update related references. - Move theme apply functions into website_theme_apply.xml. - Add theme selection function and update theme_id search attribute. - Automatically uninstall AI module before installing web_studio to avoid conflicts. - Extract SCSS customization data from database attachments and update website_theme_apply.xml. - Improve SCSS validation and normalization handling.
chga-odoo
left a comment
There was a problem hiding this comment.
good work @dhgoy-odoo ,
I gave few suggestions and one more suggestions to remove unnecessary empty line
Thanks!
| # Search AI module | ||
| search_payload = { | ||
| "jsonrpc": "2.0", | ||
| "method": "call", | ||
| "params": { | ||
| "service": "object", | ||
| "method": "execute_kw", | ||
| "args": [ | ||
| db_name, | ||
| uid, | ||
| PASSWORD, | ||
| "ir.module.module", | ||
| "search_read", | ||
| [[("name", "=", "ai")]], | ||
| { | ||
| "fields": ["id", "state"], | ||
| "limit": 1 | ||
| } | ||
| ] | ||
| }, | ||
| "id": 1 | ||
| } | ||
|
|
||
| response = requests.post( | ||
| f"{BASE_URL}{port}/jsonrpc", | ||
| json=search_payload | ||
| ).json() | ||
|
|
||
| if "error" in response: | ||
| raise Exception( | ||
| f"Failed to search ai module: {response['error']}" | ||
| ) | ||
|
|
||
| ai_module = response.get("result", []) | ||
|
|
||
| # Uninstall AI module if installed | ||
| if ai_module and ai_module[0]["state"] == "installed": | ||
|
|
||
| ai_module_id = ai_module[0]["id"] | ||
|
|
||
| uninstall_payload = { | ||
| "jsonrpc": "2.0", | ||
| "method": "call", | ||
| "params": { | ||
| "service": "object", | ||
| "method": "execute_kw", | ||
| "args": [ | ||
| db_name, | ||
| uid, | ||
| PASSWORD, | ||
| "ir.module.module", | ||
| "button_immediate_uninstall", | ||
| [[ai_module_id]] | ||
| ] | ||
| }, | ||
| "id": 2 | ||
| } | ||
|
|
||
| uninstall_response = requests.post( | ||
| f"{BASE_URL}{port}/jsonrpc", | ||
| json=uninstall_payload | ||
| ).json() | ||
|
|
||
| if "error" in uninstall_response: | ||
| raise Exception( | ||
| f"Failed to uninstall ai module: {uninstall_response['error']}" | ||
| ) | ||
|
|
||
| _logger.info("AI module uninstalled successfully.") | ||
|
|
There was a problem hiding this comment.
better to create a separate function like ai_module_uninstall for clean code
no need to uninstall every time, uninstall only when we need to install web_studio
try to handle all possibility of error into response (ex. check for result in uninstall_response).
|
|
||
|
|
||
| if state == "uninstalled": | ||
| self.install_web_studio(port, db_name, uid, model_id) |
There was a problem hiding this comment.
yo can add function call to uninstall ai module just before calling of install_web_studio, (ref below comments)
| conn = psycopg2.connect( | ||
| dbname=self.db_name, | ||
| ) | ||
|
|
||
| cr = conn.cursor() | ||
|
|
||
| query = """ | ||
| SELECT url, index_content | ||
| FROM ir_attachment | ||
| WHERE name IN ( | ||
| 'user_color_palette.scss', | ||
| 'user_values.scss', | ||
| 'user_theme_color_palette.scss' | ||
| ) | ||
| """ | ||
|
|
||
| cr.execute(query) | ||
|
|
||
| records = cr.fetchall() |
There was a problem hiding this comment.
we have define session method already, you can use that for retrieve data from db.
|
|
||
| # Remove 'category' field if exists | ||
| if category_fields := record.xpath('.//field[@name="category"]'): | ||
| record.remove(category_fields[0]) |
There was a problem hiding this comment.
should add this code in sequence like remove field and add field grouped(consecutive line)
| for el in wrapper.xpath('//*[@data-heading-link-id]'): | ||
| del el.attrib['data-heading-link-id'] |
There was a problem hiding this comment.
we are already remove this type of attributes (ex. data-oe-version, ata-last-history-steps), you can add this attributes there so that attributes can be removed from all files not only in knowledge .
| depends_list = sorted(set(depends_list + new_depends)) | ||
| return depends_list | ||
|
|
||
| def clean_homepage_view(self, destination_module_path): |
There was a problem hiding this comment.
function name doesn't match with its work, give appropriate name.
| field_node.attrib.pop('ref', None) | ||
| field_node.set( | ||
| 'search', | ||
| f"[('id', '=', ref('{old_ref}', raise_if_not_found=False))]" | ||
| ) |
There was a problem hiding this comment.
search for any function which doing work on website field if exist then you can move this part there otherwise its fine.
| # find email field inside record | ||
| email_field = record.xpath("./field[@name='email']") | ||
|
|
||
| if email_field: | ||
| email = email_field[0].text | ||
|
|
||
| if email and '@' in email: | ||
|
|
||
| # split before and after @ | ||
| local_part, domain = email.split('@', 1) | ||
|
|
||
| # make only before @ lowercase | ||
| local_part = local_part.lower() | ||
|
|
||
| # update email | ||
| email_field[0].text = f"{local_part}@{domain}" | ||
|
|
There was a problem hiding this comment.
| # find email field inside record | |
| email_field = record.xpath("./field[@name='email']") | |
| if email_field: | |
| email = email_field[0].text | |
| if email and '@' in email: | |
| # split before and after @ | |
| local_part, domain = email.split('@', 1) | |
| # make only before @ lowercase | |
| local_part = local_part.lower() | |
| # update email | |
| email_field[0].text = f"{local_part}@{domain}" |
no need this here because we are already doing work on email , you can update code there.
Knowledge article.
parsing.
references.
conflicts.
website_theme_apply.xml.