#!/usr/bin/env python3 # add-form v1.0 — Add managed form to 1C external data processor # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import os import sys import uuid from lxml import etree NSMAP = {"md": "http://v8.1c.ru/8.3/MDClasses"} def save_xml_with_bom(tree, path): """Save XML tree to file with UTF-8 BOM.""" xml_bytes = etree.tostring(tree, xml_declaration=True, encoding="UTF-8") xml_bytes = xml_bytes.replace(b"encoding='UTF-8'", b'encoding="UTF-8"') with open(path, "wb") as f: f.write(b"\xef\xbb\xbf") f.write(xml_bytes) def write_text_with_bom(path, text): """Write text to file with UTF-8 BOM.""" with open(path, "w", encoding="utf-8-sig") as f: f.write(text) def main(): sys.stdout.reconfigure(encoding="utf-8") sys.stderr.reconfigure(encoding="utf-8") parser = argparse.ArgumentParser(description="Add managed form to 1C processor", allow_abbrev=False) parser.add_argument("-ProcessorName", required=True) parser.add_argument("-FormName", required=True) parser.add_argument("-Synonym", default=None) parser.add_argument("-Main", action="store_true") parser.add_argument("-SrcDir", default="src") args = parser.parse_args() processor_name = args.ProcessorName form_name = args.FormName synonym = args.Synonym if args.Synonym is not None else form_name is_main = args.Main src_dir = args.SrcDir # --- Checks --- root_xml_path = os.path.join(src_dir, f"{processor_name}.xml") if not os.path.exists(root_xml_path): print(f"Корневой файл обработки не найден: {root_xml_path}. Сначала выполните epf-init.", file=sys.stderr) sys.exit(1) processor_dir = os.path.join(src_dir, processor_name) forms_dir = os.path.join(processor_dir, "Forms") form_meta_path = os.path.join(forms_dir, f"{form_name}.xml") if os.path.exists(form_meta_path): print(f"Форма уже существует: {form_meta_path}", file=sys.stderr) sys.exit(1) # --- Create directories --- form_dir = os.path.join(forms_dir, form_name) form_ext_dir = os.path.join(form_dir, "Ext") form_module_dir = os.path.join(form_ext_dir, "Form") os.makedirs(form_module_dir, exist_ok=True) # --- 1. Form metadata (Forms/.xml) --- form_uuid = str(uuid.uuid4()) form_meta_xml = ( '\n' '\n' f'\t
\n' '\t\t\n' f'\t\t\t{form_name}\n' '\t\t\t\n' '\t\t\t\t\n' '\t\t\t\t\tru\n' f'\t\t\t\t\t{synonym}\n' '\t\t\t\t\n' '\t\t\t\n' '\t\t\t\n' '\t\t\tManaged\n' '\t\t\tfalse\n' '\t\t\t\n' '\t\t\t\tPlatformApplication\n' '\t\t\t\tMobilePlatformApplication\n' '\t\t\t\n' '\t\t\t\n' '\t\t\n' '\t
\n' '
' ) write_text_with_bom(form_meta_path, form_meta_xml) # --- 2. Form description (Forms//Ext/Form.xml) --- form_xml_path = os.path.join(form_ext_dir, "Form.xml") form_xml = ( '\n' '
\n' '\t\n' '\t\ttrue\n' '\t\n' '\t\n' '\t\n' f'\t\t\n' '\t\t\t\n' f'\t\t\t\tcfg:ExternalDataProcessorObject.{processor_name}\n' '\t\t\t\n' '\t\t\ttrue\n' '\t\t\n' '\t\n' '' ) write_text_with_bom(form_xml_path, form_xml) # --- 3. BSL module (Forms//Ext/Form/Module.bsl) --- module_path = os.path.join(form_module_dir, "Module.bsl") module_bsl = ( '#\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438\u0421\u043e\u0431\u044b\u0442\u0438\u0439\u0424\u043e\u0440\u043c\u044b\n' '\n' '#\u041a\u043e\u043d\u0435\u0446\u041e\u0431\u043b\u0430\u0441\u0442\u0438\n' '\n' '#\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438\u0421\u043e\u0431\u044b\u0442\u0438\u0439\u042d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432\u0424\u043e\u0440\u043c\u044b\n' '\n' '#\u041a\u043e\u043d\u0435\u0446\u041e\u0431\u043b\u0430\u0441\u0442\u0438\n' '\n' '#\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438\u041a\u043e\u043c\u0430\u043d\u0434\u0424\u043e\u0440\u043c\u044b\n' '\n' '#\u041a\u043e\u043d\u0435\u0446\u041e\u0431\u043b\u0430\u0441\u0442\u0438\n' '\n' '#\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438\u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u0439\n' '\n' '#\u041a\u043e\u043d\u0435\u0446\u041e\u0431\u043b\u0430\u0441\u0442\u0438\n' '\n' '#\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u0421\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0435\u041f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u044b\u0418\u0424\u0443\u043d\u043a\u0446\u0438\u0438\n' '\n' '#\u041a\u043e\u043d\u0435\u0446\u041e\u0431\u043b\u0430\u0441\u0442\u0438' ) write_text_with_bom(module_path, module_bsl) # --- 4. Modify root XML --- root_xml_full = os.path.abspath(root_xml_path) parser_xml = etree.XMLParser(remove_blank_text=False) tree = etree.parse(root_xml_full, parser_xml) root = tree.getroot() ns = "http://v8.1c.ru/8.3/MDClasses" child_objects = root.find(".//md:ChildObjects", NSMAP) if child_objects is None: print(f"Не найден элемент ChildObjects в {root_xml_path}", file=sys.stderr) sys.exit(1) # Add
before first