@@ -35,87 +35,110 @@ def write_csv(
3535 log .error (f"Failed to write to file { filename } : { e } " )
3636
3737
38+ def _build_import_command (
39+ filename : str , model : str , worker : int , batch_size : int , ** kwargs : Any
40+ ) -> list [str ]:
41+ """Builds the command parts for an 'import' shell command."""
42+ model_name = (
43+ os .path .basename (filename ).replace (".csv" , "" ).replace ("_" , "." )
44+ if model == "auto"
45+ else model
46+ )
47+ command_parts = [
48+ "odoo-data-flow" ,
49+ "import" ,
50+ "--config" ,
51+ shlex .quote (kwargs .get ("conf_file" , "conf/connection.conf" )),
52+ "--file" ,
53+ shlex .quote (filename ),
54+ "--model" ,
55+ shlex .quote (model_name ),
56+ "--encoding" ,
57+ shlex .quote (kwargs .get ("encoding" , "utf-8" )),
58+ "--worker" ,
59+ str (worker ),
60+ "--size" ,
61+ str (batch_size ),
62+ "--sep" ,
63+ shlex .quote (kwargs .get ("sep" , ";" )),
64+ ]
65+ if kwargs .get ("groupby" ):
66+ command_parts .extend (["--groupby" , shlex .quote (kwargs ["groupby" ])])
67+ if kwargs .get ("ignore" ):
68+ command_parts .extend (["--ignore" , shlex .quote (kwargs ["ignore" ])])
69+ if kwargs .get ("context" ):
70+ command_parts .extend (["--context" , shlex .quote (str (kwargs ["context" ]))])
71+ return command_parts
72+
73+
74+ def _build_export_command (filename : str , model : str , ** kwargs : Any ) -> list [str ]:
75+ """Builds the command parts for an 'export' shell command."""
76+ return [
77+ "odoo-data-flow" ,
78+ "export" ,
79+ "--config" ,
80+ shlex .quote (kwargs .get ("conf_file" , "conf/connection.conf" )),
81+ "--file" ,
82+ shlex .quote (filename ),
83+ "--model" ,
84+ shlex .quote (model ),
85+ "--fields" ,
86+ shlex .quote (kwargs .get ("fields" , "" )),
87+ "--domain" ,
88+ shlex .quote (kwargs .get ("domain" , "[]" )),
89+ "--sep" ,
90+ shlex .quote (kwargs .get ("sep" , ";" )),
91+ "--encoding" ,
92+ shlex .quote (kwargs .get ("encoding" , "utf-8" )),
93+ ]
94+
95+
3896def write_file (
3997 filename : Optional [str ] = None ,
4098 header : Optional [list [str ]] = None ,
4199 data : Optional [list [list [Any ]]] = None ,
42100 fail : bool = False ,
43101 model : str = "auto" ,
44102 launchfile : str = "import_auto.sh" ,
45- worker : int = 1 ,
46- batch_size : int = 10 ,
47- init : bool = False ,
48- encoding : str = "utf-8" ,
49- groupby : str = "" ,
50- sep : str = ";" ,
51- context : Optional [dict [str , Any ]] = None ,
52- ignore : str = "" ,
53- ** kwargs : Any , # to catch other unused params
103+ command : str = "import" ,
104+ ** kwargs : Any ,
54105) -> None :
55- """Filewriter.
106+ """Writes data to a CSV and generates a corresponding shell script.
107+
108+ This function can generate scripts for both `import` and `export` commands
109+ based on the `command` parameter.
56110
57- Writes data to a CSV file and generates a corresponding shell script
58- to import that file using the odoo-data-flow CLI.
111+ Args:
112+ filename: The path to the data file to be written or referenced.
113+ header: A list of strings for the header row.
114+ data: A list of lists representing the data rows.
115+ fail: If True (and command is 'import'), includes a second command
116+ with the --fail flag.
117+ model: The technical name of the Odoo model.
118+ launchfile: The path where the shell script will be saved.
119+ command: The command to generate in the script ('import' or 'export').
120+ **kwargs: Catches other command-specific params like 'worker', 'fields', etc.
59121 """
60- # Step 1: Write the actual data file
61122 if filename and header is not None and data is not None :
62- write_csv (filename , header , data , encoding = encoding )
123+ write_csv (filename , header , data , encoding = kwargs .get ("encoding" , "utf-8" ))
124+
125+ if not launchfile or not filename :
126+ return
63127
64- # Step 2: If no launchfile is specified, we are done.
65- if not launchfile :
128+ command_parts : list [str ]
129+ if command == "import" :
130+ command_parts = _build_import_command (filename , model , ** kwargs )
131+ elif command == "export" :
132+ command_parts = _build_export_command (filename , model , ** kwargs )
133+ else :
134+ log .error (f"Invalid command type '{ command } ' provided to write_file." )
66135 return
67136
68- # Step 3: Only generate the import script if a filename was provided.
69- if filename :
70- # Determine the target model name
71- if model == "auto" :
72- model_name = (
73- os .path .basename (filename ).replace (".csv" , "" ).replace ("_" , "." )
74- )
75- else :
76- model_name = model
77-
78- # Build the base command with its arguments
79- # We use shlex.quote to ensure all arguments
80- # are safely escaped for the shell.
81- command_parts = [
82- "odoo-data-flow" ,
83- "import" ,
84- "--config" ,
85- shlex .quote (kwargs .get ("conf_file" , "conf/connection.conf" )),
86- "--file" ,
87- shlex .quote (filename ),
88- "--model" ,
89- shlex .quote (model_name ),
90- "--encoding" ,
91- shlex .quote (encoding ),
92- "--worker" ,
93- str (worker ),
94- "--size" ,
95- str (batch_size ),
96- "--sep" ,
97- shlex .quote (sep ),
98- ]
99-
100- # Add optional arguments if they have a value
101- if groupby :
102- command_parts .extend (["--groupby" , shlex .quote (groupby )])
103- if ignore :
104- command_parts .extend (["--ignore" , shlex .quote (ignore )])
105- if context :
106- command_parts .extend (["--context" , shlex .quote (str (context ))])
107-
108- # Write the command(s) to the shell script
109- mode = "w" if init else "a"
110- try :
111- with open (launchfile , mode , encoding = "utf-8" ) as f :
112- # Write the main import command
113- f .write (" " .join (command_parts ) + "\n " )
114-
115- # If fail mode is enabled,
116- # write the second command with the --fail flag
117- if fail :
118- fail_command_parts = [* command_parts , "--fail" ]
119- f .write (" " .join (fail_command_parts ) + "\n " )
120- except OSError as e :
121- log .error (f"Failed to write to launch file { launchfile } : { e } " )
137+ mode = "w" if kwargs .get ("init" ) else "a"
138+ try :
139+ with open (launchfile , mode , encoding = "utf-8" ) as f :
140+ f .write (" " .join (command_parts ) + "\n " )
141+ if fail and command == "import" :
142+ f .write (" " .join ([* command_parts , "--fail" ]) + "\n " )
143+ except OSError as e :
144+ log .error (f"Failed to write to launch file { launchfile } : { e } " )
0 commit comments