2020
2121import os
2222import re
23- import xml .etree .ElementTree as ET
23+ import xml .etree .cElementTree as CET
2424from enum import Enum
2525
2626from qgis .PyQt .QtCore import QSortFilterProxyModel , QStringListModel , Qt , pyqtSignal
@@ -210,7 +210,7 @@ def refresh_model(self, source_model, db_connector=None, silent=False):
210210 ),
211211 Qt .Checked ,
212212 )
213- if enabled
213+ if enabled and modelname not in self . checked_models ()
214214 else Qt .Unchecked ,
215215 enabled ,
216216 )
@@ -248,7 +248,9 @@ def refresh_model(self, source_model, db_connector=None, silent=False):
248248 ),
249249 ),
250250 Qt .Checked
251- if model is models [- 1 ] and enabled
251+ if model is models [- 1 ]
252+ and enabled
253+ and model ["name" ] not in self .checked_models ()
252254 else Qt .Unchecked ,
253255 ),
254256 enabled ,
@@ -286,7 +288,9 @@ def refresh_model(self, source_model, db_connector=None, silent=False):
286288 int (SourceModel .Roles .PATH )
287289 ),
288290 ),
289- Qt .Checked if enabled else Qt .Unchecked ,
291+ Qt .Checked
292+ if enabled and model ["name" ] not in self .checked_models ()
293+ else Qt .Unchecked ,
290294 ),
291295 enabled ,
292296 )
@@ -304,21 +308,48 @@ def refresh_model(self, source_model, db_connector=None, silent=False):
304308 return self .rowCount ()
305309
306310 def _transfer_file_models (self , xtf_file_path ):
311+ """
312+ Get model names from an XTF file. Since XTF can be very large, we follow this strategy:
313+ 1. Parse line by line.
314+ 1.a. Compare parsed line with the regular expression to get the Header Section.
315+ 1.b. If found, stop parsing the XTF file and go to 2. If not found, append the new line to parsed lines and go
316+ to next line.
317+ 2. Give the Header Section to an XML parser and extract models. Note that we don't give the full XTF file to the XML
318+ parser because it will read it completely, which may be not optimal.
319+ :param xtf_path: Path to an XTF file
320+ :return: List of model names from the XTF
321+ """
307322 models = []
308- try :
309- root = ET .parse (xtf_file_path ).getroot ()
310- for model_element in root .iter ("{http://www.interlis.ch/INTERLIS2.3}MODEL" ):
311- model = {}
312- model ["name" ] = model_element .get ("NAME" )
313- models .append (model )
314- except ET .ParseError as e :
315- self .print_info .emit (
316- self .tr (
317- "Could not parse transferfile file `{file}` ({exception})" .format (
318- file = xtf_file_path , exception = str (e )
323+ pattern = re .compile (r"(<HEADERSECTION[^>]*.*</HEADERSECTION>)" )
324+
325+ text_found = "<foo/>"
326+ with open (xtf_file_path , "r" ) as f :
327+ lines = ""
328+ for line in f :
329+ lines += line
330+ res = re .search (pattern , lines )
331+ if res :
332+ text_found = str (res .groups ()[0 ])
333+ break
334+
335+ if text_found :
336+ try :
337+ root = CET .fromstring (text_found )
338+ element = root .find ("MODELS" )
339+ if element :
340+ for sub_element in element :
341+ if "NAME" in sub_element .attrib :
342+ model = {}
343+ model ["name" ] = sub_element .attrib ["NAME" ]
344+ models .append (model )
345+ except CET .ParseError as e :
346+ self .print_info .emit (
347+ self .tr (
348+ "Could not parse transferfile file `{file}` ({exception})" .format (
349+ file = xtf_file_path , exception = str (e )
350+ )
319351 )
320352 )
321- )
322353 return models
323354
324355 def _db_modelnames (self , db_connector = None ):
@@ -394,7 +425,7 @@ def import_sessions(self):
394425 model = item .data (int (SourceModel .Roles .NAME ))
395426 source = (
396427 item .data (int (SourceModel .Roles .PATH ))
397- if type != "model "
428+ if type == "ili "
398429 else "repository " + model
399430 )
400431
0 commit comments