feat: implement specialty content module with expanded Page entity fields, database migrations, and data import utilities
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
import urllib.parse
|
||||
import xml.etree.ElementTree as ET
|
||||
import oracledb
|
||||
from datetime import datetime
|
||||
import sys
|
||||
import json
|
||||
|
||||
def wrap_in_editorjs(html_content):
|
||||
editor_json = {
|
||||
"time": int(datetime.now().timestamp() * 1000),
|
||||
"blocks": [
|
||||
{
|
||||
"type": "raw",
|
||||
"data": {
|
||||
"html": html_content
|
||||
}
|
||||
}
|
||||
],
|
||||
"version": "2.22.2"
|
||||
}
|
||||
return json.dumps(editor_json)
|
||||
|
||||
def main(xml_file_path):
|
||||
print(f"Reading {xml_file_path} ...")
|
||||
tree = ET.parse(xml_file_path)
|
||||
root = tree.getroot()
|
||||
|
||||
ns = {
|
||||
'wp': 'http://wordpress.org/export/1.2/',
|
||||
'content': 'http://purl.org/rss/1.0/modules/content/',
|
||||
'dc': 'http://purl.org/dc/elements/1.1/'
|
||||
}
|
||||
|
||||
dsn = "localhost:1521/sisvietnam"
|
||||
conn = oracledb.connect(user="sisvietnam", password="sisvietnam", dsn=dsn)
|
||||
cursor = conn.cursor()
|
||||
|
||||
dt = datetime.now()
|
||||
layout = "SPECIALTY_DETAIL"
|
||||
page_type = "CUSTOM"
|
||||
status = "PUBLISHED"
|
||||
|
||||
count = 0
|
||||
warnings = []
|
||||
|
||||
for channel in root.findall('channel'):
|
||||
for item in channel.findall('item'):
|
||||
title_tag = item.find('title')
|
||||
title = title_tag.text if title_tag is not None else "Untitled"
|
||||
|
||||
post_name_tag = item.find('wp:post_name', ns)
|
||||
if post_name_tag is not None and post_name_tag.text:
|
||||
slug = post_name_tag.text
|
||||
else:
|
||||
link_tag = item.find('link')
|
||||
slug = link_tag.text.strip('/').split('/')[-1] if link_tag is not None else "unknown"
|
||||
|
||||
slug = urllib.parse.unquote(slug)
|
||||
|
||||
if slug == "khoa-than-kinh-dot-quy-2":
|
||||
slug = "khoa-than-kinh-dot-quy"
|
||||
|
||||
# No longer skipping khoa-cap-cuu
|
||||
|
||||
content_tag = item.find('content:encoded', ns)
|
||||
content_text = content_tag.text if content_tag is not None and content_tag.text else ""
|
||||
|
||||
# Check if missing container
|
||||
if '<div class="wp-content-container' not in content_text and content_text.strip():
|
||||
warnings.append(f"CẢNH BÁO: Bài viết '{title}' ({slug}) thiếu thẻ container. Hệ thống đã tự động bổ sung.")
|
||||
content_text = f'<div class="wp-content-container prose max-w-none">\n{content_text}\n</div>'
|
||||
|
||||
# Wrap into Editor.js JSON
|
||||
final_content = wrap_in_editorjs(content_text)
|
||||
|
||||
cursor.execute("SELECT id FROM sis_page WHERE slug = :1", [slug])
|
||||
row = cursor.fetchone()
|
||||
|
||||
if row:
|
||||
sql = "UPDATE sis_page SET title = :1, content = :2, layout = :3, page_type = :4 WHERE slug = :5"
|
||||
cursor.execute(sql, [title, final_content, layout, page_type, slug])
|
||||
else:
|
||||
sql = """
|
||||
INSERT INTO sis_page (
|
||||
id, title, slug, content, status, page_type, display_order, layout,
|
||||
created_date, last_modified_date, created_by, last_modified_by
|
||||
) VALUES (
|
||||
sequence_generator.nextval, :title, :slug, :content, :status, :page_type, 0, :layout,
|
||||
:created_date, :last_modified_date, 'system', 'system'
|
||||
)
|
||||
"""
|
||||
cursor.execute(sql, {
|
||||
'title': title,
|
||||
'slug': slug,
|
||||
'content': final_content,
|
||||
'status': status,
|
||||
'page_type': page_type,
|
||||
'layout': layout,
|
||||
'created_date': dt,
|
||||
'last_modified_date': dt
|
||||
})
|
||||
count += 1
|
||||
|
||||
conn.commit()
|
||||
print(f"\n--- TỔNG KẾT ---")
|
||||
print(f"Successfully processed {count} specialty pages.")
|
||||
for w in warnings:
|
||||
print(w)
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) > 1:
|
||||
main(sys.argv[1])
|
||||
else:
|
||||
print("Usage: python3 import_specialties.py <path_to_xml>")
|
||||
Reference in New Issue
Block a user