#!/usr/bin/env python3
# cf-init v1.2 — Create empty 1C configuration scaffold
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
"""Generates minimal XML source files for a 1C configuration."""
import sys, os, argparse, uuid
def esc_xml(s):
return s.replace('&','&').replace('<','<').replace('>','>').replace('"','"')
def new_uuid():
return str(uuid.uuid4())
def write_utf8_bom(path, content):
with open(path, 'w', encoding='utf-8-sig', newline='') as f:
f.write(content)
def main():
sys.stdout.reconfigure(encoding="utf-8")
sys.stderr.reconfigure(encoding="utf-8")
parser = argparse.ArgumentParser(description='Create empty 1C configuration scaffold', allow_abbrev=False)
parser.add_argument('-Name', dest='Name', required=True)
parser.add_argument('-Synonym', dest='Synonym', default=None)
parser.add_argument('-OutputDir', dest='OutputDir', default='src')
parser.add_argument('-Version', dest='Version', default='')
parser.add_argument('-Vendor', dest='Vendor', default='')
parser.add_argument('-CompatibilityMode', dest='CompatibilityMode', default='Version8_3_24')
args = parser.parse_args()
name = args.Name
synonym = args.Synonym if args.Synonym else name
output_dir = args.OutputDir
version = args.Version
vendor = args.Vendor
compat = args.CompatibilityMode
# --- Resolve output dir ---
if not os.path.isabs(output_dir):
output_dir = os.path.join(os.getcwd(), output_dir)
# --- Check existing ---
cfg_file = os.path.join(output_dir, "Configuration.xml")
if os.path.exists(cfg_file):
print(f"Configuration.xml already exists: {cfg_file}", file=sys.stderr)
sys.exit(1)
# --- Generate UUIDs ---
uuid_cfg = new_uuid()
uuid_lang = new_uuid()
co = [new_uuid() for _ in range(7)]
# --- Mobile functionalities ---
mobile_funcs = [
("Biometrics","true"), ("Location","false"), ("BackgroundLocation","false"),
("BluetoothPrinters","false"), ("WiFiPrinters","false"), ("Contacts","false"),
("Calendars","false"), ("PushNotifications","false"), ("LocalNotifications","false"),
("InAppPurchases","false"), ("PersonalComputerFileExchange","false"), ("Ads","false"),
("NumberDialing","false"), ("CallProcessing","false"), ("CallLog","false"),
("AutoSendSMS","false"), ("ReceiveSMS","false"), ("SMSLog","false"),
("Camera","false"), ("Microphone","false"), ("MusicLibrary","false"),
("PictureAndVideoLibraries","false"), ("AudioPlaybackAndVibration","false"),
("BackgroundAudioPlaybackAndVibration","false"), ("InstallPackages","false"),
("OSBackup","true"), ("ApplicationUsageStatistics","false"),
("BarcodeScanning","false"), ("BackgroundAudioRecording","false"),
("AllFilesAccess","false"), ("Videoconferences","false"), ("NFC","false"),
("DocumentScanning","false"), ("SpeechToText","false"), ("Geofences","false"),
("IncomingShareRequests","false"), ("AllIncomingShareRequestsTypesProcessing","false"),
]
mobile_xml = ""
for func_name, func_use in mobile_funcs:
mobile_xml += f"\r\n\t\t\t\t\r\n\t\t\t\t\t{func_name}\r\n\t\t\t\t\t{func_use}\r\n\t\t\t\t"
# --- Synonym XML ---
synonym_xml = ""
if synonym:
synonym_xml = f"\r\n\t\t\t\t\r\n\t\t\t\t\tru\r\n\t\t\t\t\t{esc_xml(synonym)}\r\n\t\t\t\t\r\n\t\t\t"
vendor_xml = esc_xml(vendor) if vendor else ""
version_xml = esc_xml(version) if version else ""
class_ids = [
"9cd510cd-abfc-11d4-9434-004095e12fc7",
"9fcd25a0-4822-11d4-9414-008048da11f9",
"e3687481-0a87-462c-a166-9f34594f9bba",
"9de14907-ec23-4a07-96f0-85521cb6b53b",
"51f2d5d8-ea4d-4064-8892-82951750031e",
"e68182ea-4237-4383-967f-90c1e3370bc7",
"fb282519-d103-4dd3-bc12-cb271d631dfc",
]
contained_objects = ""
for i in range(7):
contained_objects += f"""\t\t\t
\t\t\t\t{class_ids[i]}
\t\t\t\t{co[i]}
\t\t\t\n"""
cfg_xml = f'''
\t
\t\t
{contained_objects}\t\t
\t\t
\t\t\t{esc_xml(name)}
\t\t\t{synonym_xml}
\t\t\t
\t\t\t
\t\t\t{compat}
\t\t\tManagedApplication
\t\t\t
\t\t\t\tPlatformApplication
\t\t\t
\t\t\tRussian
\t\t\t
\t\t\t{vendor_xml}
\t\t\t{version_xml}
\t\t\t
\t\t\tfalse
\t\t\tfalse
\t\t\tfalse
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t{mobile_xml}
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\tNormal
\t\t\t
\t\t\t
\t\t\tLanguage.Русский
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\t
\t\t\tManaged
\t\t\tNotAutoFree
\t\t\tDontUse
\t\t\tDontUse
\t\t\tTaxiEnableVersion8_2
\t\t\tDontUse
\t\t\t{compat}
\t\t\t
\t\t
\t\t
\t\t\tРусский
\t\t
\t
'''
# --- Languages/Русский.xml ---
lang_xml = f'''
\t
\t\t
\t\t\tРусский
\t\t\t
\t\t\t\t
\t\t\t\t\tru
\t\t\t\t\tРусский
\t\t\t\t
\t\t\t
\t\t\t
\t\t\tru
\t\t
\t
'''
# --- Ext/ClientApplicationInterface.xml (default ERP-style panel layout) ---
# Open panel on top, Sections panel on left; Functions/Favorites/History declared
# via panelDef but not placed by default. Without this file the web client renders
# section icons without labels (icon-only mode).
open_panel_inst = new_uuid()
sections_panel_inst = new_uuid()
cai_xml = f'''
\t
\t\t
\t\t\tcbab57f2-a0f3-4f0a-89ea-4cb19570ab75
\t\t
\t
\t
\t\t
\t\t\tb553047f-c9aa-4157-978d-448ecad24248
\t\t
\t
\t
\t
\t
\t
\t
'''
# --- Create directories ---
os.makedirs(output_dir, exist_ok=True)
lang_dir = os.path.join(output_dir, "Languages")
os.makedirs(lang_dir, exist_ok=True)
ext_dir = os.path.join(output_dir, "Ext")
os.makedirs(ext_dir, exist_ok=True)
# --- Write files ---
write_utf8_bom(cfg_file, cfg_xml)
lang_file = os.path.join(lang_dir, "Русский.xml")
write_utf8_bom(lang_file, lang_xml)
cai_file = os.path.join(ext_dir, "ClientApplicationInterface.xml")
write_utf8_bom(cai_file, cai_xml)
print(f"[OK] Создана конфигурация: {name}")
print(f" Каталог: {output_dir}")
print(f" Configuration.xml: {cfg_file}")
print(f" Languages: {lang_file}")
print(f" Ext/CAI: {cai_file}")
if __name__ == '__main__':
main()