Mercurial > pyarq-presupuestos
comparison Generic/fiebdc.py @ 1:2ac1551ad2ab version 0.0.0
add code
| author | Miguel Ángel Bárcena Rodríguez <miguelangel@obraencurso.es> |
|---|---|
| date | Sun, 31 Oct 2010 20:07:33 +0100 |
| parents | |
| children | 6502bfdaa84d |
comparison
equal
deleted
inserted
replaced
| 0:a1703c4f2990 | 1:2ac1551ad2ab |
|---|---|
| 1 #!/usr/bin/python | |
| 2 # -*- coding: utf-8 -*- | |
| 3 ## File fiebdc.py | |
| 4 ## This file is part of pyArq-Presupuestos. | |
| 5 ## | |
| 6 ## Copyright (C) 2010 Miguel Ángel Bárcena Rodríguez | |
| 7 ## <miguelangel@obraencurso.es> | |
| 8 ## | |
| 9 ## pyArq-Presupuestos is free software: you can redistribute it and/or modify | |
| 10 ## it under the terms of the GNU General Public License as published by | |
| 11 ## the Free Software Foundation, either version 3 of the License, or | |
| 12 ## (at your option) any later version. | |
| 13 ## | |
| 14 ## pyArq-Presupuestos is distributed in the hope that it will be useful, | |
| 15 ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 16 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 17 ## GNU General Public License for more details. | |
| 18 ## | |
| 19 ## You should have received a copy of the GNU General Public License | |
| 20 ## along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 21 | |
| 22 # specifications in http://www.fiebdc.org | |
| 23 | |
| 24 # Modules | |
| 25 import time | |
| 26 import re | |
| 27 import calendar | |
| 28 import os.path | |
| 29 | |
| 30 # pyArq-Presupuestos modules | |
| 31 import base | |
| 32 from Generic import utils | |
| 33 from Generic import globals | |
| 34 | |
| 35 class Read(object): | |
| 36 """fiebdc.Read: | |
| 37 | |
| 38 Description: | |
| 39 Reads and parses a fiebdc file | |
| 40 Constructor: | |
| 41 fiebdc.Read(filename=None, budget=None) | |
| 42 Ancestry: | |
| 43 +-- object | |
| 44 +-- Read | |
| 45 Atributes: | |
| 46 "__budget": budget ("base.Budget" object) | |
| 47 "__file_format": File format of the fiebdc file | |
| 48 "__format_list": List of file format that can be readed | |
| 49 "__character_sets_dict": Dictionary with the character sets supported | |
| 50 "__character_set": character_set of the file | |
| 51 "__generator": program which the file is created | |
| 52 "__cancel": Boolean value, True mean that the read process must stop | |
| 53 "__filename": The filename of the fiebdc file that is readed | |
| 54 "__pattern": re compiled pattern dict | |
| 55 Methods: | |
| 56 __init__(self, filename=None, budget=None) | |
| 57 cancel(self) | |
| 58 eraseControlCharacters(self, string) | |
| 59 validateCode(self, code) | |
| 60 parseDate(self, date) | |
| 61 parseRecord(self,record) | |
| 62 _parseV(self, field_list) | |
| 63 _parseC(self, field_list) | |
| 64 _parseDY(self, field_list) | |
| 65 _parseMN(self, field_list) | |
| 66 _parseT(self, field_list) | |
| 67 _parseK(self, field_list) | |
| 68 _parseW(self, field_list) | |
| 69 _parseL(self, field_list) | |
| 70 _parseQ(self, field_list) | |
| 71 _parseJ(self, field_list) | |
| 72 _parseG(self, field_list) | |
| 73 _parseE(self, field_list) | |
| 74 _parseX(self, field_list) | |
| 75 _parseF(self, field_list) | |
| 76 readFile(self, budget=None, filename=None) | |
| 77 """ | |
| 78 def __init__(self, filename=None, budget=None): | |
| 79 """def __init__(self, filename=None, budget=None) | |
| 80 | |
| 81 Sets the instance attributes | |
| 82 """ | |
| 83 self.__budget = budget | |
| 84 self.__filename = filename | |
| 85 if not self.__budget is None: | |
| 86 self.__budget.filename = self.__filename | |
| 87 self.__cancel = False | |
| 88 self.__format_list = ["FIEBDC-3/95", "FIEBDC-3/98", "FIEBDC-3/2002", | |
| 89 "FIEBDC-3/2004", "FIEBDC-3/2007"] | |
| 90 # ANSI->¿"ISO-8859-15" or "latin1 ISO-8859-1" or "cp1252 windows-1252"? | |
| 91 # 850 -> IBM850 -> cp850 | |
| 92 # 437 -> IBM437 -> cp437 | |
| 93 self.__character_sets_dict = {"ANSI" : "cp1252", | |
| 94 "850" : "850", | |
| 95 "437" : "cp437"} | |
| 96 self.__file_format = "FIEBDC-3/2007" | |
| 97 self.__generator = globals.version | |
| 98 self.__character_set = "850" | |
| 99 self.__pattern = { | |
| 100 "control_tilde" : re.compile("((\r\n)| |\t)+~"), | |
| 101 "control_vbar" : re.compile("((\r\n)| |\t)+\|"), | |
| 102 "control_backslash" : re.compile(r"((\r\n)| |\t)+\\"), | |
| 103 "valid_code" : re.compile("[^A-Za-z0-9ñÑ.$#%&_]"), | |
| 104 "special_char": re.compile("[#%&]"), | |
| 105 "no_float": re.compile("[^0-9.]"), | |
| 106 "formula" : re.compile(".*[^0123456789\.()\+\-\*/\^abcdp ].*"), | |
| 107 "comment": re.compile("#.*\r\n"), | |
| 108 "empty_line": re.compile(r"(\r\n) *\r\n"), | |
| 109 "space_before_backslash" : re.compile(r"( )+\\"), | |
| 110 "space_after_backslash" : re.compile(r"\\( )+"), | |
| 111 "start_noend_backslash" : re.compile("(\r\n\\\.*[^\\\])\r\n"), | |
| 112 "end_oper": re.compile("(\+|-|\*|/|/^|@|&|<|>|<=|>=|=|!) *\r\n"), | |
| 113 "matricial_var" : re.compile("(\r\n *[%|\$][A-ZÑ].*=.*,) *\r\n"), | |
| 114 "descomposition" : re.compile("^([^:]+):(.*)$"), | |
| 115 "var" : re.compile("^([$%][A-ZÑ][()0-9, ]*)=(.*)$"), | |
| 116 "after_first_tilde" : re.compile("^[^~]*~"), | |
| 117 "end_control" : re.compile("((\r\n)| |\t)+$"), | |
| 118 } | |
| 119 | |
| 120 def cancel(self): | |
| 121 """def cancel(self) | |
| 122 | |
| 123 Sets the "__cancel" attribute to True, It stops the read process. | |
| 124 """ | |
| 125 self.__cancel = True | |
| 126 | |
| 127 def eraseControlCharacters(self, string): | |
| 128 """eraseControlCharacters(self,string) | |
| 129 | |
| 130 Return a copy of the string with the blank characters (32), | |
| 131 tabs (9) and end of line (13 and 10) before of the separators | |
| 132 '~', '|' erased. | |
| 133 Before separator \ not deleted because it affects the reading of the | |
| 134 record ~P | |
| 135 """ | |
| 136 # "control_tilde" : "((\r\n)| |\t)+~" | |
| 137 string = self.__pattern["control_tilde"].sub("~",string) | |
| 138 # "control_vbar" : "((\r\n)| |\t)+\|" | |
| 139 string = self.__pattern["control_vbar"].sub("|",string) | |
| 140 # "control_backslash" : r"((\r\n)| |\t)+\\" | |
| 141 #string = self.__pattern["control_backslash"].sub(r"\\",string) | |
| 142 return string | |
| 143 | |
| 144 def validateCode(self, code): | |
| 145 """validateCode(self, code) | |
| 146 | |
| 147 Test if the code have invalid characters and try to erase it, | |
| 148 if it is posible return a valid code else return a empty string. | |
| 149 """ | |
| 150 if not isinstance(code, str): | |
| 151 print _("Invalid code, it must be a string") | |
| 152 return "" | |
| 153 # Valid chararcter: A-Z a-z 0-9 ñ Ñ . $ # % & _ | |
| 154 # "valid_code" : "[^A-Za-z0-9ñÑ.$#%&_]" | |
| 155 _code = self.__pattern["valid_code"].sub("", code) | |
| 156 if _code != code: | |
| 157 print utils.mapping(_("The code '$1' have invalid characters."), | |
| 158 (code,)) | |
| 159 code = _code | |
| 160 # the lasts characters can not be <#> or <##> | |
| 161 # <##> -> root record in FIEFDC-3 | |
| 162 # <#> -> chapter record in FIEFDC-3 | |
| 163 if len(code) > 0: | |
| 164 while code[-1] == "#": | |
| 165 code = code[:-1] | |
| 166 if len(code) > 20: | |
| 167 code = code[:20] | |
| 168 # only one charecter # % or & | |
| 169 if sum([code.count(c) for c in '#%&']) > 1: | |
| 170 print utils.mapping(_("The code '$1' contains special "\ | |
| 171 "characters repeated."),(code,)) | |
| 172 _i = min([code.find(c) for c in '#%&']) | |
| 173 code = code[:_i+1] + \ | |
| 174 self.__pattern["special_char"].sub("", code[_i+1:]) | |
| 175 return code | |
| 176 | |
| 177 def parseDate(self, date): | |
| 178 """parseDate(self, date) | |
| 179 | |
| 180 date: in the format: | |
| 181 uneven len: add a Leading 0 | |
| 182 len = 8 DDMMYYYY | |
| 183 len <= 6 DDMMYY “80/20”. >80 -> >1980 <80 -> <2080 | |
| 184 len < 5 MMYY | |
| 185 len < 3 YY | |
| 186 Test date string and return a tuple (YYYY, MM, DD) | |
| 187 or None if the date format is invalid | |
| 188 """ | |
| 189 # All characters must be numbers, len <= 8 and not empty string | |
| 190 if not date.isdigit() or len(date) > 8 or date == "": | |
| 191 return None | |
| 192 else: | |
| 193 if len(date)%2 == 1: # uneven len: add a leading 0 | |
| 194 date = "0" + date | |
| 195 if len(date) == 8: | |
| 196 _d = int(date[:2]) | |
| 197 _m = int(date[2:4]) | |
| 198 _y = int(date[4:8]) | |
| 199 elif len(date) <= 6: | |
| 200 _y = int(date[-2:]) | |
| 201 if _y < 80: _y = 2000 + _y | |
| 202 else: _y = 1900 + _y | |
| 203 if len(date) == 6: | |
| 204 _d = int(date[:2]) | |
| 205 _m = int(date[2:4]) | |
| 206 elif len(date) == 4: | |
| 207 _d = 0 | |
| 208 _m = int(date[:2]) | |
| 209 elif len(date) == 2: | |
| 210 _d = 0 | |
| 211 _m = 0 | |
| 212 if not _d in range(1,31): _d = 0 | |
| 213 if not _m in range(1,12): _m = 0 | |
| 214 if _m == 0: _d = 0 | |
| 215 if _m != 0 and _d != 0: | |
| 216 if calendar.monthrange(_y, _m)[1] < _d: | |
| 217 _d = 0 | |
| 218 return (_y, _m, _d) | |
| 219 | |
| 220 def parseRecord(self,record): | |
| 221 """parseRecord(self,record) | |
| 222 | |
| 223 record: the record line readed from the file whith the format: | |
| 224 type|field|field|subfield\subfield|... | |
| 225 [a] nothing or "a" | |
| 226 {a} zero or more #-#twice#-# "a" | |
| 227 <a> one or more #-#twice#-# "a" | |
| 228 Types: V C D Y M N T K L Q J G E X B F A | |
| 229 V: Property and Version | |
| 230 1- [File_Owner] | |
| 231 2- Format_Version[\DDMMYYYY] | |
| 232 3- [Program_Generator] | |
| 233 4- [Header]\{Title\} | |
| 234 5- [Chaters_set] | |
| 235 6- [Comment] | |
| 236 C: Record: | |
| 237 1- Code{\Code} | |
| 238 2- [Unit] | |
| 239 3- [Summary] | |
| 240 4- {Price\} | |
| 241 5- {Date\} | |
| 242 6- [Type] | |
| 243 D or Y: DECOMPOSITION or ADD DECOMPOSITION | |
| 244 1- Parent Code | |
| 245 2- <Child Code\ [Factor]\ [Yield]> | |
| 246 M or N: MEASURE or ADD MEASURE | |
| 247 1- [Parent Code\]Child Code | |
| 248 2- {Path\} | |
| 249 3- TOTAL MEASURE | |
| 250 4- {Type\Comment\Unit\Length\Width\Height\} | |
| 251 5- [Label] | |
| 252 T: Text | |
| 253 1- Code | |
| 254 2- Description text | |
| 255 K: Coefficients | |
| 256 1- { DN \ DD \ DS \ DR \ DI \ DP \ DC \ DM \ DIVISA \ } | |
| 257 2- CI \ GG \ BI \ BAJA \ IVA | |
| 258 3- { DRC \ DC \ DRO \ DFS \ DRS \ DFO \ DUO \ DI \ DES \ DN \ | |
| 259 DD \ DS \ DIVISA \ } | |
| 260 4- [ n ] | |
| 261 L: Sheet of Conditions 1 | |
| 262 A) | |
| 263 1- Empty | |
| 264 2- {Section Code\Section Title} | |
| 265 B) | |
| 266 1- Record Code | |
| 267 2- {Section Code\Section Text} | |
| 268 3- {Section Code\RTF file} | |
| 269 4- {Section Code\HTM file} | |
| 270 Q: Sheet of Conditions 2 | |
| 271 1- Record Code | |
| 272 2- {Section Code\Paragraph key\{Field key;}\}| | |
| 273 J: Sheet of Conditions 3 | |
| 274 1- Paragraph code | |
| 275 2- [Paragraph text] | |
| 276 3- [RTF file] | |
| 277 4- [HTML file] | |
| 278 G: Grafic info | |
| 279 1- <grafic_file.ext\> | |
| 280 E: Company | |
| 281 1- company Code | |
| 282 2 [ summary ] | |
| 283 3- [ name ] | |
| 284 4- { [ type ] \ [ subname ] \ [ address ] \ [ postal_code ] | |
| 285 \ [ town ] \ [ province ] \ [ country ] \ { phone; } | |
| 286 \ { fax; } \ {contact_person; } \ } | |
| 287 5- [ cif ] \ [ web ] \ [ email ] \ | |
| 288 X: Tecnical information | |
| 289 A) | |
| 290 1- Empty | |
| 291 2- < TI_Code \ TI_Descitption \ TI_Unit > | |
| 292 B) | |
| 293 1- Record_code | |
| 294 2- < TI_Code \ TI_value > | |
| 295 F: #-#Adjunto#-# File | |
| 296 1- Record code | |
| 297 2- { Type \ { Filenames; } \ [Description] } | |
| 298 B: Change code | |
| 299 1- Record Code | |
| 300 2- New code | |
| 301 A: Labels | |
| 302 1- Record Code | |
| 303 2- <Label\> | |
| 304 """ | |
| 305 # TODO: ~L ~J RTF and HTML files | |
| 306 # TODO: test ~Q ~J ~G | |
| 307 # TODO: ~P. Registro tipo Descripción Paramétrica. | |
| 308 # TODO: ~O. Registro tipo Relación Comercial. | |
| 309 # TODO: test records | |
| 310 _field_list = record.split("|") | |
| 311 self._record_number = self._record_number +1 | |
| 312 _budget = self.__budget | |
| 313 if _field_list[0] == "V": | |
| 314 self._record_V_number += 1 | |
| 315 self._parseV(_field_list) | |
| 316 elif _field_list[0] == "C": | |
| 317 self._record_C_number += 1 | |
| 318 self._parseC(_field_list) | |
| 319 elif _field_list[0] == "D": | |
| 320 self._record_D_number += 1 | |
| 321 self._parseDY(_field_list) | |
| 322 elif _field_list[0] == "Y": | |
| 323 self._record_Y_number += 1 | |
| 324 self._parseDY(_field_list) | |
| 325 elif _field_list[0] == "M": | |
| 326 self._record_M_number += 1 | |
| 327 self._parseMN(_field_list) | |
| 328 elif _field_list[0] == "N": | |
| 329 self._record_N_number += 1 | |
| 330 self._parseMN(_field_list) | |
| 331 elif _field_list[0] == "T": | |
| 332 self._record_T_number += 1 | |
| 333 self._parseT(_field_list) | |
| 334 elif _field_list[0] == "K": | |
| 335 self._record_K_number += 1 | |
| 336 self._parseK(_field_list) | |
| 337 elif _field_list[0] == "W": | |
| 338 self._record_W_number += 1 | |
| 339 self._parseW(_field_list) | |
| 340 elif _field_list[0] == "L": | |
| 341 self._record_L_number += 1 | |
| 342 self._parseL(_field_list) | |
| 343 elif _field_list[0] == "Q": | |
| 344 self._record_Q_number += 1 | |
| 345 self._parseQ(_field_list) | |
| 346 elif _field_list[0] == "J": | |
| 347 self._record_J_number += 1 | |
| 348 self._parseJ(_field_list) | |
| 349 elif _field_list[0] == "G": | |
| 350 self._record_G_number += 1 | |
| 351 self._parseG(_field_list) | |
| 352 elif _field_list[0] == "E": | |
| 353 self._record_E_number += 1 | |
| 354 self._parseE(_field_list) | |
| 355 elif _field_list[0] == "O": | |
| 356 self._record_O_number += 1 | |
| 357 elif _field_list[0] == "P": | |
| 358 self._record_P_number += 1 | |
| 359 self._parseP(_field_list) | |
| 360 elif _field_list[0] == "X": | |
| 361 self._record_X_number += 1 | |
| 362 self._parseX(_field_list) | |
| 363 elif _field_list[0] == "B": | |
| 364 self._record_B_number += 1 | |
| 365 self._parseB(_field_list) | |
| 366 elif _field_list[0] == "F": | |
| 367 self._record_F_number += 1 | |
| 368 self._parseF(_field_list) | |
| 369 elif _field_list[0] == "A": | |
| 370 self._record_A_number += 1 | |
| 371 self._parseA(_field_list) | |
| 372 else: | |
| 373 self._record_Unknow_number += 1 | |
| 374 | |
| 375 def _parseV(self, field_list): | |
| 376 """_parseV(self, field_list) | |
| 377 | |
| 378 field_list: field list of the record | |
| 379 0- V :Property and Version | |
| 380 1- [File_Owner] | |
| 381 2- Format_Version[\DDMMYYYY] | |
| 382 3- [Program_Generator] | |
| 383 4- [Header]\{Title\} | |
| 384 5- [Chaters_set] | |
| 385 6- [Comment] | |
| 386 7- [Data type] | |
| 387 8- [Number budget certificate] | |
| 388 9- [Date budget certificate] | |
| 389 """ | |
| 390 if self._record_number != 1: | |
| 391 print utils.mapping(_("The 'V' record (Property and Version) "\ | |
| 392 "must be the first record in the file but it is the "\ | |
| 393 "number: $1"), (self._record_number,)) | |
| 394 print _("The default values were taken and this V record is "\ | |
| 395 "ignored") | |
| 396 return | |
| 397 # _____number of fields_____ | |
| 398 # Any INFORMATION after last field separator is ignored | |
| 399 if len(field_list) > 10: | |
| 400 field_list = field_list[:10] | |
| 401 # If there are no sufficient fields, the fields are added | |
| 402 # with empty value:"" | |
| 403 else: | |
| 404 field_list = field_list + [""]*(10-len(field_list)) | |
| 405 # control character are erased: end of line, tab, space | |
| 406 # only leading and trailing whitespace in owner, generator, comment | |
| 407 # _____Fields_____ | |
| 408 _record_type = self.delete_control_space(field_list[0]) | |
| 409 _owner = field_list[1].strip() | |
| 410 _owner = self.delete_control(_owner) | |
| 411 _version_date = self.delete_control_space(field_list[2]) | |
| 412 _generator = field_list[3].strip() | |
| 413 _generator = self.delete_control(_generator) | |
| 414 _header_title = field_list[4].strip() | |
| 415 _header_title = self.delete_control(_header_title) | |
| 416 _character_set = self.delete_control_space(field_list[5]) | |
| 417 _comment = field_list[6].strip("\t \n\r") | |
| 418 _data_type = self.delete_control_space(field_list[7]) | |
| 419 _number_certificate = self.delete_control_space(field_list[8]) | |
| 420 __date_certificate = self.delete_control_space(field_list[9]) | |
| 421 # _____Owner_____ | |
| 422 self.__budget.setOwner(_owner) | |
| 423 # _____Version-Date_____ | |
| 424 _version_date = _version_date.split("\\") | |
| 425 _file_format = _version_date[0] | |
| 426 if _file_format in self.__format_list: | |
| 427 self.__file_format = _file_format | |
| 428 print _("FIEBDC format: %s" % _file_format) | |
| 429 if len(_version_date) > 1: | |
| 430 _date = _version_date[1] | |
| 431 if _date != "": | |
| 432 _parsed_date = self.parseDate(_date) | |
| 433 if _parsed_date is not None: | |
| 434 self.__budget.setDate(_parsed_date) | |
| 435 # _____Generator_____ | |
| 436 # ignored field | |
| 437 print _("FIEBDC file generated by %s" % _generator) | |
| 438 # _____Header_Title_____ | |
| 439 _header_title = _header_title.split("\\") | |
| 440 _header_title = [_title.strip() for _title in _header_title] | |
| 441 _header = _header_title.pop(0) | |
| 442 _title = [ ] | |
| 443 for _title_index in _header_title: | |
| 444 if _title_index != "": | |
| 445 _title.append(_title_index) | |
| 446 if _header != "": | |
| 447 self.__budget.setTitleList([ _header, _title ]) | |
| 448 # _____Characters_set_____ | |
| 449 # field parsed in readFile method | |
| 450 # _____Comment_____ | |
| 451 if _comment != "": | |
| 452 self.__budget.setComment(_comment) | |
| 453 # _____Data type_____ | |
| 454 # 1 -> Base data. | |
| 455 # 2 -> Budget. | |
| 456 # 3 -> Budget certificate. | |
| 457 # 4 -> Base date update. | |
| 458 try: | |
| 459 _data_type = int(_data_type) | |
| 460 except ValueError: | |
| 461 _data_type = "" | |
| 462 if _data_type == 3: | |
| 463 # _____Number budget certificate_____ | |
| 464 try: | |
| 465 _number_certificate = int(_number_certificate) | |
| 466 except ValueError: | |
| 467 _number_certificate = "" | |
| 468 # _____Date budget certificate_____ | |
| 469 if _date_certificate != "": | |
| 470 _parsed_date_certificate = self.parseDate(_date_certificate) | |
| 471 if _parsed_date_certificate is None: | |
| 472 _date_certificate = "" | |
| 473 else: | |
| 474 _date_certificate = _parsed_date_certificate | |
| 475 self.__budget.setBudgetype(_data_type) | |
| 476 self.__budget.setCertificateOrder(_number_certificate) | |
| 477 self.__budget.setCertificateDate(_parsed_date_cerfificate) | |
| 478 elif _data_type != "": | |
| 479 self.__budget.setBudgeType(_data_type) | |
| 480 self.num_valid_record = self.num_valid_record + 1 | |
| 481 | |
| 482 def _parseK(self, field_list): | |
| 483 """_parseK(self, field_list) | |
| 484 | |
| 485 field_list: field list of the record | |
| 486 0- K: Coefficients | |
| 487 1- { DN \ DD \ DS \ DR \ DI \ DP \ DC \ DM \ DIVISA \ } | |
| 488 2- CI \ GG \ BI \ BAJA \ IVA | |
| 489 3- | |
| 490 A){ DRC \ DC \ DRO \ DFS \ DRS \ DFO \ DUO \ DI \ DES \ DN \ | |
| 491 DD \ DS \ DIVISA \ } | |
| 492 B){ DRC \ DC \ \ DFS \ DRS \ \ DUO \ DI \ DES \ DN \ | |
| 493 DD \ DS \ DSP\ DEC\ DIVISA \ } | |
| 494 4- [ n ] | |
| 495 """ | |
| 496 # _____Number of fields_____ | |
| 497 # Any INFORMATION after last field separator is ignored | |
| 498 # The record must have 3 fields | |
| 499 # The last field is ignored, pyArq hate dll's | |
| 500 if len(field_list) > 4: | |
| 501 field_list = field_list[1:4] | |
| 502 # The record must have 3 fields | |
| 503 else: | |
| 504 field_list = field_list[1:] + [""]*(4-len(field_list)) | |
| 505 # control character are erased: end of line, tab, space | |
| 506 # _____Fields_____ | |
| 507 _field0 = self.delete_control_space(field_list[0]) | |
| 508 _field1 = self.delete_control_space(field_list[1]) | |
| 509 _field2 = self.delete_control_space(field_list[2]) | |
| 510 # _____Field 1_____ | |
| 511 if len(_field1) > 0 and _field1[-1] == "\\": | |
| 512 _field1 = _field1[:-1] | |
| 513 # if there are a \ character at the end it must be erased | |
| 514 _percentages = _field1.split("\\") | |
| 515 if len(_percentages) > 5: | |
| 516 _percentages = _percentages[:5] | |
| 517 # If there are no sufficient subfields, the subfields are added | |
| 518 # with empty value:"" | |
| 519 else: | |
| 520 _percentages = _percentages + [""]*(5-len(_percentages)) | |
| 521 _percentage_titles = [ "CI", "GG", "BI", "BAJA", "IVA" ] | |
| 522 _percentage_dict = {} | |
| 523 for _percentage_index in range(len(_percentages)): | |
| 524 try: | |
| 525 _percentage = int(_percentages[_percentage_index]) | |
| 526 except ValueError: | |
| 527 _percentage = "" | |
| 528 _percentage_dict[_percentage_titles[_percentage_index]] = \ | |
| 529 _percentage | |
| 530 self.__budget.setPercentages(_percentage_dict) | |
| 531 # _____Field 0 and 1_____ | |
| 532 # Default number of decimal places | |
| 533 # Number of titles in ~V record | |
| 534 _title_num = len(self.__budget.getTitleList()[1]) | |
| 535 if _title_num == 0: _title_num = 1 | |
| 536 # If the field 2 is empty, the field 0 is readed | |
| 537 if _field2 == "": | |
| 538 # _____Field 0_____ | |
| 539 if _field0[-1] == "\\": | |
| 540 _field0 = _field0[:-1] | |
| 541 # if there are a \ character at the end it must be erased | |
| 542 _decimal_list = _field0.split("\\") | |
| 543 _decimal_index = 0 | |
| 544 if len(_decimal_list)%9 != 0: | |
| 545 # if it is not multiple of 9, empty subfield are added | |
| 546 _decimal_list = _decimal_list + [""]*(9 - \ | |
| 547 len(_decimal_list)%9) | |
| 548 # The number of decimal values is the same as the numbers of | |
| 549 # titles in the V record | |
| 550 if len(_decimal_list)//9 > _title_num: | |
| 551 _decimal_list = _decimal_list[:_title_num*9] | |
| 552 elif len(_decimal_list)//9 < _title_num: | |
| 553 _decimal_list = _decimal_list + _decimal_list[-9:] * \ | |
| 554 (_title_num-(len(_decimal_list)//9)) | |
| 555 while _decimal_index <= len(_decimal_list)-9: | |
| 556 _decimals = _decimal_list[_decimal_index:(_decimal_index + 9)] | |
| 557 _forlist = range(len(_decimals)-1) | |
| 558 for _index in range(len(_decimals)): | |
| 559 try: | |
| 560 #TODO: test this | |
| 561 _decimals[_index] = int(_decimals[_index]) | |
| 562 except ValueError: | |
| 563 _decimals[_index] = "" | |
| 564 _DN = _decimals[0] | |
| 565 _DD = _decimals[1] | |
| 566 _DS = _decimals[2] | |
| 567 _DR = _decimals[3] | |
| 568 _DI = _decimals[4] | |
| 569 _DP = _decimals[5] | |
| 570 _DC = _decimals[6] | |
| 571 _DM = _decimals[7] | |
| 572 _DIVISA = _decimals[8] | |
| 573 _percentage_dict = {"DN" : _DN, | |
| 574 "DD" : _DD, | |
| 575 "DSP" : _DS, | |
| 576 "DS" : _DS, | |
| 577 "DFC" : _DR, | |
| 578 "DFPU" : _DR, | |
| 579 "DFUO" : _DR, | |
| 580 "DFA" : _DR, | |
| 581 "DRC" : _DR, | |
| 582 "DRPU" : _DR, | |
| 583 "DRUO" : _DR, | |
| 584 "DRA" : _DR, | |
| 585 "DP" : _DC, | |
| 586 "DC" : _DC, | |
| 587 "DPU" : _DC, | |
| 588 "DUO" : _DC, | |
| 589 "DEA" : _DC, | |
| 590 "DES" : _DC, | |
| 591 "DIR" : _DI, | |
| 592 "DIRC" : _DI, | |
| 593 "DCD" : _DP, | |
| 594 "DIVISA": _DIVISA } | |
| 595 _decimal_index = _decimal_index + 9 | |
| 596 self.__budget.setDecimals(_percentage_dict, | |
| 597 (_decimal_index//9)) | |
| 598 else: | |
| 599 # _____Field 3_____ | |
| 600 if _field2[-1] == "\\": | |
| 601 _field2 = _field2[:-1] | |
| 602 # if there are a \ character at the end it must be erased | |
| 603 _decimal_list = _field2.split("\\") | |
| 604 # test if the Divisa subfield is 12 or 14 position | |
| 605 # Divisa is the only Alphanumeric subfield | |
| 606 # "no_float": "[^0-9.]" | |
| 607 if len(_decimal_list) >= 13 and \ | |
| 608 self.__pattern["no_float"].search(_decimal_list[12]): | |
| 609 _multiple = 13 | |
| 610 elif len(_decimal_list) >= 15 and \ | |
| 611 self.__pattern["no_float"].search(_decimal_list[14]): | |
| 612 _multiple = 15 | |
| 613 else: | |
| 614 if self.__file_format == "FIEBDC-3/2002": | |
| 615 _multiple = 13 | |
| 616 elif self.__file_format == "FIEBDC-3/2004": | |
| 617 _multiple = 13 | |
| 618 elif self.__file_format == "FIEBDC-3/2007": | |
| 619 _multiple = 15 | |
| 620 else: | |
| 621 _multiple = 15 | |
| 622 _decimal_index = 0 | |
| 623 if len(_decimal_list)%_multiple != 0 : | |
| 624 # if it is not multiple of _multiple, empty subfield are added | |
| 625 _decimal_list = _decimal_list + \ | |
| 626 [""]*(_multiple-len(_decimal_list)%_multiple) | |
| 627 # The number of decimal values is the same as the numbers of | |
| 628 # titles in the V record | |
| 629 if len(_decimal_list)//_multiple > _title_num: | |
| 630 _decimal_list = _decimal_list[:_title_num*_multiple] | |
| 631 elif len(_decimal_list)//_multiple < _title_num: | |
| 632 _decimal_list = _decimal_list + [_decimal_list[-_multiple:]]*\ | |
| 633 (_title_num-(len(_decimal_list)//_multiple)) | |
| 634 while _decimal_index <= len(_decimal_list)-_multiple: | |
| 635 _decimals = _decimal_list[_decimal_index:(_decimal_index +\ | |
| 636 _multiple)] | |
| 637 for _index in range(len(_decimals)-1): | |
| 638 try: | |
| 639 _decimals[_index] = int(_decimals[_index]) | |
| 640 except: | |
| 641 _decimals[_index] = "" | |
| 642 if _multiple == 13: | |
| 643 _DRC = _decimals[0] | |
| 644 _DC = _decimals[1] | |
| 645 _DRO = _decimals[2] | |
| 646 _DFS = _decimals[3] | |
| 647 _DRS = _decimals[4] | |
| 648 _DFO = _decimals[5] | |
| 649 _DUO = _decimals[6] | |
| 650 _DI = _decimals[7] | |
| 651 _DES = _decimals[8] | |
| 652 _DN = _decimals[9] | |
| 653 _DD = _decimals[10] | |
| 654 _DS = _decimals[11] | |
| 655 _DIVISA = _decimals[12] | |
| 656 _percentage_dict = { | |
| 657 "DN" : _DN, | |
| 658 "DD" : _DD, | |
| 659 "DSP" : _DS, | |
| 660 "DS" : _DS, | |
| 661 "DFC" : _DFS, | |
| 662 "DFPU" : _DRC, | |
| 663 "DFUO" : _DFS, | |
| 664 "DFA" : _DFS, | |
| 665 "DRC" : _DRS, | |
| 666 "DRPU" : _DRC, | |
| 667 "DRUO" : _DRS, | |
| 668 "DRA" : _DRS, | |
| 669 "DP" : _DC, | |
| 670 "DC" : _DC, | |
| 671 "DPU" : _DC, | |
| 672 "DUO" : _DUO, | |
| 673 "DEA" : _DES, | |
| 674 "DES" : _DES, | |
| 675 "DIR" : _DI, | |
| 676 "DIRC" : _DC, | |
| 677 "DCD" : _DI, | |
| 678 "DIVISA": _DIVISA, | |
| 679 } | |
| 680 else: # _multiple == 15: | |
| 681 _DRC = _decimals[0] | |
| 682 _DC = _decimals[1] | |
| 683 _DRO = _decimals[2] | |
| 684 _DFS = _decimals[3] | |
| 685 _DRS = _decimals[4] | |
| 686 _DFO = _decimals[5] | |
| 687 _DUO = _decimals[6] | |
| 688 _DI = _decimals[7] | |
| 689 _DES = _decimals[8] | |
| 690 _DN = _decimals[9] | |
| 691 _DD = _decimals[10] | |
| 692 _DS = _decimals[11] | |
| 693 _DSP = _decimals[12] | |
| 694 _DEC = _decimals[13] | |
| 695 _DIVISA = _decimals[14] | |
| 696 _percentage_dict = { | |
| 697 "DN" : _DN, | |
| 698 "DD" : _DD, | |
| 699 "DSP" : _DSP, | |
| 700 "DS" : _DS, | |
| 701 "DFC" : _DFS, | |
| 702 "DFPU" : _DRC, | |
| 703 "DFUO" : _DFS, | |
| 704 "DFA" : _DFS, | |
| 705 "DRC" : _DRS, | |
| 706 "DRPU" : _DRC, | |
| 707 "DRUO" : _DRS, | |
| 708 "DRA" : _DRS, | |
| 709 "DP" : _DC, | |
| 710 "DC" : _DC, | |
| 711 "DPU" : _DC, | |
| 712 "DUO" : _DUO, | |
| 713 "DEA" : _DEC, | |
| 714 "DES" : _DES, | |
| 715 "DIR" : _DI, | |
| 716 "DIRC" : _DC, | |
| 717 "DCD" : _DI, | |
| 718 "DIVISA": _DIVISA} | |
| 719 _decimal_index = _decimal_index + 13 | |
| 720 self.__budget.setDecimals(_percentage_dict, | |
| 721 (_decimal_index//13)) | |
| 722 self.num_valid_record = self.num_valid_record +1 | |
| 723 | |
| 724 def _parseC(self, field_list): | |
| 725 """_parseC(self, field_list) | |
| 726 | |
| 727 field_list: field list of the record | |
| 728 0- C: Record | |
| 729 1- Code{\Code} | |
| 730 2- [Unit] | |
| 731 3- [Summary] | |
| 732 4- {Price\} | |
| 733 5- {Date\} | |
| 734 6- [Type] | |
| 735 """ | |
| 736 # _____number of fields_____ | |
| 737 # Any INFORMATION after last field separator is ignored | |
| 738 if len(field_list) > 7: | |
| 739 field_list = field_list[:7] | |
| 740 # If there are no sufficient fields, the fields are added | |
| 741 # with empty value:"" | |
| 742 else: | |
| 743 field_list = field_list + [""]*(7-len(field_list)) | |
| 744 # control character are erased: en of line, tab, space | |
| 745 # _____Fields_____ | |
| 746 _record_type = field_list[0] | |
| 747 _codes = self.delete_control_space(field_list[1]) | |
| 748 _unit = self.delete_control_space(field_list[2]) | |
| 749 _summary = self.delete_control(field_list[3]) | |
| 750 _prices = self.delete_control_space(field_list[4]) | |
| 751 _dates = self.delete_control_space(field_list[5]) | |
| 752 _type = self.delete_control_space(field_list[6]) | |
| 753 # _____Code_____ | |
| 754 _codes = _codes.split("\\") | |
| 755 if len(_codes) > 0: | |
| 756 # parse the hierarchy of the first code | |
| 757 # hierarchy: 0->root, 1->Chapter/subchapter, 2->other | |
| 758 if len(_codes[0]) > 2 and _codes[0][-2:] == "##": | |
| 759 _hierarchy = 0 | |
| 760 elif len(_codes[0]) > 1 and _codes[0][-1:] == "#": | |
| 761 _hierarchy = 1 | |
| 762 else: | |
| 763 _hierarchy = 2 | |
| 764 # "#" and "##" characters at the end of the code are erased | |
| 765 # invalid characters are also erased | |
| 766 # maximun len 20 characters | |
| 767 _codes = [self.validateCode(_code) for _code in _codes] | |
| 768 # empty codes are ignored | |
| 769 while "" in _codes: | |
| 770 _codes.remove("") | |
| 771 if len(_codes) > 0: | |
| 772 #TODO: test this | |
| 773 _code = _codes[0] | |
| 774 _synonyms = _codes | |
| 775 else: | |
| 776 print _("Record C without a valid code") | |
| 777 return | |
| 778 # _____Unit_____ | |
| 779 # nothing to do | |
| 780 # _____Summary_____ | |
| 781 # nothing to do | |
| 782 # _____Price_____ and _____Dates_____ | |
| 783 # last \ is erased | |
| 784 if len(_dates) > 0 and _dates[-1] == "\\": | |
| 785 _dates = _dates[:-1] | |
| 786 if len(_prices) > 0 and _prices[-1] == "\\": | |
| 787 _prices = _prices[:-1] | |
| 788 _dates = _dates.split("\\") | |
| 789 _prices = _prices.split("\\") | |
| 790 # number of prices = number of titles in "V" line | |
| 791 # if there are no sufficient prices it takes the last price defined | |
| 792 _title_num = len(self.__budget.getTitleList()[1]) | |
| 793 if _title_num == 0: _title_num = 1 | |
| 794 if len(_prices) > _title_num: _prices = _prices[:_title_num] | |
| 795 elif len(_prices) < _title_num: | |
| 796 _prices = _prices + [_prices[-1]]*(_title_num-len(_prices)) | |
| 797 # number of dates = number of prices | |
| 798 # if there are no sufficient dates it takes the last date defined | |
| 799 if len(_dates) > len(_prices): _dates = _dates[:len(_prices)] | |
| 800 elif len(_dates) < len(_prices): | |
| 801 _dates = _dates + [_dates[-1]]*(len(_prices)-len(_dates)) | |
| 802 for _index in range(len(_prices)): | |
| 803 # TODO: lack to specify the number of decimals of the price | |
| 804 try: | |
| 805 _prices[_index] = float(_prices[_index]) | |
| 806 except: | |
| 807 _prices[_index] = 0.0 | |
| 808 _parsed_date = self.parseDate(_dates[_index]) | |
| 809 if _parsed_date is None: | |
| 810 _dates[_index] = "" | |
| 811 else: | |
| 812 _dates[_index] = _parsed_date | |
| 813 # _____Type_____ | |
| 814 # 0 Without classifying | |
| 815 # EA Auxiliary element | |
| 816 # EU Unitary element | |
| 817 # EC Complex element | |
| 818 # EF Functional element | |
| 819 # OB Construction site | |
| 820 # PA Cost overrun | |
| 821 # PU Unitary budget | |
| 822 # 1 Labourforce | |
| 823 # H Labourforce | |
| 824 # 2 Machinery and auxiliary equipment | |
| 825 # Q Machinery | |
| 826 # % Auxiliary equipment | |
| 827 # 3 Building materials | |
| 828 # MC Cement | |
| 829 # MCr Ceramic | |
| 830 # MM Wood | |
| 831 # MS Iron and steel | |
| 832 # ME Energy | |
| 833 # MCu Copper | |
| 834 # MAl Aluminium | |
| 835 # ML Bonding agents | |
| 836 # M Others materials | |
| 837 # Hierarchy type subtype | |
| 838 # 0->root -> 0 -> None,OB | |
| 839 # 1->[sub]chapter -> 0 -> None,PU | |
| 840 # 2->Other -> 0 -> None,EA,EU,EC,EF,PA | |
| 841 # 1 -> None,H | |
| 842 # 2 -> None,Q,% | |
| 843 # 3 -> None,MC,MCr,MM,MS,ME,MCu,Mal,ML,M | |
| 844 if _hierarchy == 0: | |
| 845 if _type == "OB": | |
| 846 _subtype = _type | |
| 847 _type = 0 | |
| 848 elif _type == "0" or _type == "": | |
| 849 _subtype = "" | |
| 850 _type = 0 | |
| 851 else: | |
| 852 print utils.mapping(_("Incorrect type ($1) in the code $2"), | |
| 853 (str(_type), _code)) | |
| 854 _type = 0 | |
| 855 _subtype = "" | |
| 856 elif _hierarchy == 1: | |
| 857 if _type == "PU": | |
| 858 _subtype = _type | |
| 859 _type = 0 | |
| 860 elif _type == "0" or _type == "": | |
| 861 _subtype = "" | |
| 862 _type = 0 | |
| 863 else: | |
| 864 print utils.mapping(_("Incorrect type ($1) in the code $2"), | |
| 865 (str(_type), _code)) | |
| 866 _type = 0 | |
| 867 _subtype = "" | |
| 868 else: | |
| 869 if _type == "EA" or _type == "EU" or _type == "EC" or \ | |
| 870 _type == "EF" or _type == "PA": | |
| 871 _subtype = _type | |
| 872 _type = 0 | |
| 873 elif _type == "H": | |
| 874 _subtype = _type | |
| 875 _type = 1 | |
| 876 elif _type == "Q" or _type == "%": | |
| 877 _subtype = _type | |
| 878 _type = 2 | |
| 879 elif _type == "MC" or _type == "MCr" or _type == "MM" or \ | |
| 880 _type == "MS" or _type == "ME" or _type == "MCu" or \ | |
| 881 _type == "Mal" or _type == "ML" or _type == "M": | |
| 882 _subtype = _type | |
| 883 _type = 3 | |
| 884 elif _type == "0" or _type == "1" or _type == "2" or \ | |
| 885 _type == "3": | |
| 886 _subtype = "" | |
| 887 _type = int(_type) | |
| 888 elif _type == "": | |
| 889 _subtype = "" | |
| 890 _type = 0 | |
| 891 else: | |
| 892 print utils.mapping(_("Incorrect type ($1) in the code $2"), | |
| 893 (str(_type), _code)) | |
| 894 _type = 0 | |
| 895 _subtype = "" | |
| 896 self.__budget.setRecord(_code, _synonyms, _hierarchy, | |
| 897 _unit, _summary, _prices, _dates, _type, _subtype) | |
| 898 self.num_valid_record = self.num_valid_record + 1 | |
| 899 | |
| 900 def _parseDY(self, field_list): | |
| 901 """_parseDY(self, field_list) | |
| 902 | |
| 903 field_list: field list of the record | |
| 904 0- D or Y: DECOMPOSITION or ADD DECOMPOSITION | |
| 905 1- Parent Code | |
| 906 2- <Child Code\ [Factor]\ [Yield]> | |
| 907 """ | |
| 908 # _____number of fields_____ | |
| 909 # Any INFORMATION after last field separator is ignored | |
| 910 # The record must have 3 fields | |
| 911 if len(field_list) > 3: | |
| 912 field_list = field_list[:3] | |
| 913 # If there are no sufficient fields, the fields are added | |
| 914 # with empty value:"" | |
| 915 else: | |
| 916 field_list = field_list + [""]*(3-len(field_list)) | |
| 917 # control character are erased: end of line, tab, space | |
| 918 # _____Fields_____ | |
| 919 _record_type = field_list[0] | |
| 920 _code = self.delete_control_space(field_list[1]) | |
| 921 _children = self.delete_control_space(field_list[2]) | |
| 922 # _____Code_____ | |
| 923 # "#" and "##" characters at the end of the code are erased | |
| 924 # invalid characters are also erased | |
| 925 _code = self.validateCode(_code) | |
| 926 # _____children_____ | |
| 927 # TODO: test the number of decimals in factor an yield values | |
| 928 _children = _children.split( "\\" ) | |
| 929 _children_list = [ ] | |
| 930 _child_index = 0 | |
| 931 while _child_index < len(_children)-3: | |
| 932 # _____subfields_____ | |
| 933 _child_code = _children[_child_index] | |
| 934 _factor = _children[_child_index+1] | |
| 935 _yield = _children[_child_index+2] | |
| 936 # _____child_code_____ | |
| 937 _child_code = self.validateCode(_child_code) | |
| 938 # _____factor_____ | |
| 939 if _factor != "": | |
| 940 try: | |
| 941 _factor = float(_factor) | |
| 942 except ValueError: | |
| 943 print utils.mapping(_("ValueError loadig the "\ | |
| 944 "descomposition of the record $1, the factor "\ | |
| 945 "of the child $2 must be a float number and "\ | |
| 946 "can not be $3, seted default value 1.0"), | |
| 947 (_code, _child_code, _factor)) | |
| 948 _factor = 1.0 | |
| 949 #____yield___ | |
| 950 if _yield != "": | |
| 951 try: | |
| 952 _yield = float(_yield) | |
| 953 except ValueError: | |
| 954 print utils.mapping(_("ValueError loading the "\ | |
| 955 "descomposition of the record $1, the yield of "\ | |
| 956 "the child $2, must be a float number and can"\ | |
| 957 "not be $3, seted default value 1.0"), | |
| 958 (_code, _child_code, _factor)) | |
| 959 _yield = 1.0 | |
| 960 if _child_code != "" and _code != "": | |
| 961 _children_list.append([_child_code, _factor, _yield ]) | |
| 962 if _record_type == "D": | |
| 963 _position = _child_index / 3 | |
| 964 else: #_record_type == "Y" | |
| 965 _position = -1 | |
| 966 self.__budget.setTree(_code, _child_code, _position, _factor, | |
| 967 _yield, "", "", "", "") | |
| 968 _child_index = _child_index + 3 | |
| 969 self.num_valid_record = self.num_valid_record +1 | |
| 970 | |
| 971 def _parseT(self, field_list): | |
| 972 """_parseT(self, field_list) | |
| 973 | |
| 974 field_list: field list of the record | |
| 975 0- T: Text | |
| 976 1- Record code | |
| 977 2- Description text | |
| 978 """ | |
| 979 # _____Number of fields_____ | |
| 980 # Any INFORMATION after last field separator is ignored | |
| 981 # The record must have 3 fields | |
| 982 if len(field_list) > 3: | |
| 983 field_list = field_list[0:3] | |
| 984 field_list = field_list[1:] | |
| 985 if len(field_list) != 2: | |
| 986 return | |
| 987 # control character are erased: end of line, tab, space | |
| 988 # _____Fields_____ | |
| 989 _code = self.delete_control_space(field_list[0]) | |
| 990 _text = field_list[1] | |
| 991 # _____Code_____ | |
| 992 # "#" and "##" characters at the end of the code are erased | |
| 993 # invalid characters are also erased | |
| 994 _code = self.validateCode(_code) | |
| 995 # _____Text_____ | |
| 996 self.__budget.setText(_code, _text) | |
| 997 self.num_valid_record = self.num_valid_record + 1 | |
| 998 | |
| 999 def _parseMN(self, field_list): | |
| 1000 """_parseMN(self, field_list) | |
| 1001 | |
| 1002 field_list: field list of the record | |
| 1003 0- M or N: MEASURE or ADD MEASURE | |
| 1004 1- [Parent Code\]Child Code | |
| 1005 2- {Path\} | |
| 1006 3- TOTAL MEASURE | |
| 1007 4- {Type\Comment\Unit\Length\Width\Height\} | |
| 1008 5- [Label] | |
| 1009 """ | |
| 1010 | |
| 1011 # _____Number of fields_____ | |
| 1012 # Any INFORMATION after last field separator is ignored | |
| 1013 # The record must have 6 fields | |
| 1014 if len(field_list) > 6: | |
| 1015 field_list = field_list[:6] | |
| 1016 # If there are no sufficient fields, the fields are added | |
| 1017 # with empty value:"" | |
| 1018 else: | |
| 1019 field_list = field_list + [""]*(6-len(field_list)) | |
| 1020 # control character are erased: end of line, tab, space | |
| 1021 # _____Fields_____ | |
| 1022 _record_type = field_list[0] | |
| 1023 _codes = self.delete_control_space(field_list[1]) | |
| 1024 _path = self.delete_control_space(field_list[2]) | |
| 1025 _total = self.delete_control_space(field_list[3]) | |
| 1026 _lines = self.delete_control(field_list[4]) | |
| 1027 _label = self.delete_control_space(field_list[5]) | |
| 1028 # _____Codes_____ | |
| 1029 _code_list = _codes.split( "\\" ) | |
| 1030 # "#" and "##" characters at the end of the code are erased | |
| 1031 # invalid characters are also erased | |
| 1032 if len(_code_list) == 2: | |
| 1033 _parent_code = self.validateCode(_code_list[0]) | |
| 1034 if _parent_code == "": | |
| 1035 _parent_code = None | |
| 1036 _child_code = self.validateCode(_code_list[1]) | |
| 1037 elif len(_code_list) == 1: | |
| 1038 _child_code = self.validateCode(_code_list[0]) | |
| 1039 _parent_code = None | |
| 1040 else: | |
| 1041 print utils.mapping(_("Invalid codes in $1 record, codes $2"), | |
| 1042 (_record_type, _codes)) | |
| 1043 return | |
| 1044 if _child_code == "": | |
| 1045 print utils.mapping(_("Empty child code in $1 record, codes: "\ | |
| 1046 "$2"), (_record_type, _codes)) | |
| 1047 return | |
| 1048 # _____Path_____ | |
| 1049 # TODO: path=0, no-estructured measures | |
| 1050 _path_list = _path.split( "\\" ) | |
| 1051 if len(_path_list) > 0: | |
| 1052 while _path_list[-1] == "": | |
| 1053 _path_list = _path_list[:-1] | |
| 1054 _path = _path_list[-1] | |
| 1055 try: | |
| 1056 _path = int(_path) | |
| 1057 except ValueError: | |
| 1058 print utils.mapping(_("Invalid path in $1 record, "\ | |
| 1059 "codes $2"), (_record_type, _codes)) | |
| 1060 return | |
| 1061 if _path > 0: | |
| 1062 _path -= 1 | |
| 1063 else: | |
| 1064 _path = 0 | |
| 1065 # _____Total_____ | |
| 1066 try: | |
| 1067 _total = float(_total) | |
| 1068 except ValueError: | |
| 1069 print utils.mapping(_("Invalid Total Measure value in $1 "\ | |
| 1070 "record, codes $2"), (_record_type, _codes)) | |
| 1071 return | |
| 1072 # _____Measure lines_____ | |
| 1073 _lines = _lines.split( "\\" ) | |
| 1074 _line_index = 0 | |
| 1075 _line_list = [ ] | |
| 1076 while _line_index < len(_lines)-6: | |
| 1077 _linetype = _lines[_line_index] | |
| 1078 if _linetype == "": | |
| 1079 _linetype = 0 | |
| 1080 elif _linetype == "1" or _linetype == "2" or \ | |
| 1081 _linetype == "3": | |
| 1082 _linetype = int(_linetype) | |
| 1083 else: | |
| 1084 _linetype = 0 | |
| 1085 _comment= _lines[_line_index + 1] | |
| 1086 if _linetype == 3: | |
| 1087 # "formula": ".*[^0123456789\.()\+\-\*/\^abcdp ].*" | |
| 1088 if self.__pattern["formula"].match(_comment): | |
| 1089 print utils.mapping(_("The comment is not a formula or "\ | |
| 1090 "its have invalid characters, in the $1 record, "\ | |
| 1091 "codes $2"), (_record_type, _codes)) | |
| 1092 return | |
| 1093 else: | |
| 1094 _formula = _comment | |
| 1095 _comment = "" | |
| 1096 else: | |
| 1097 _formula = "" | |
| 1098 _units = _lines[_line_index + 2] | |
| 1099 _length = _lines[_line_index + 3] | |
| 1100 _width = _lines[_line_index + 4] | |
| 1101 _height = _lines[_line_index + 5] | |
| 1102 try: | |
| 1103 if _units != "": _units = float(_units) | |
| 1104 if _length != "": _length = float(_length) | |
| 1105 if _width != "": _width = float(_width) | |
| 1106 if _height != "": _height = float(_height) | |
| 1107 except ValueError: | |
| 1108 print utils.mapping("The measure values are not float "\ | |
| 1109 "numbers, code $1", (_codes,)) | |
| 1110 return | |
| 1111 _line_list.append([_linetype, _comment, _units, | |
| 1112 _length, _width, _height, _formula]) | |
| 1113 _line_index = _line_index + 6 | |
| 1114 self.__budget.setTree(_parent_code, _child_code, _path, "", "", | |
| 1115 _total, _line_list, _label, _record_type) | |
| 1116 self.num_valid_record = self.num_valid_record + 1 | |
| 1117 | |
| 1118 def _parseW(self, field_list): | |
| 1119 """_parseW(self, field_list) | |
| 1120 | |
| 1121 field_list: field list of the record | |
| 1122 0- W: Geografical field | |
| 1123 1- Field Code | |
| 1124 2- Field | |
| 1125 """ | |
| 1126 # _____Number of fields_____ | |
| 1127 # Any INFORMATION after last field separator is ignored | |
| 1128 # The record must have 2 fields | |
| 1129 if len(field_list) >= 2: | |
| 1130 field_list = field_list[1:2] | |
| 1131 else: | |
| 1132 return | |
| 1133 # control character are erased: end of line, tab, space | |
| 1134 # _____Fields_____ | |
| 1135 _code_fields = field_list[0] | |
| 1136 # last \ is erased | |
| 1137 if len(_code_fields) and _code_fields[-1] == "\\": | |
| 1138 _code_fields = _code_fields[:-1] | |
| 1139 _code_fields = _code_fields.split("\\") | |
| 1140 _field_dict = {} | |
| 1141 _field_index = 0 | |
| 1142 while _field_index < len(_code_fields)-1: | |
| 1143 # _____subfields_____ | |
| 1144 _field_code = _code_fields[_field_index] | |
| 1145 _field_title = _code_fields[_field_index+1] | |
| 1146 # control character are erased: end of line, tab, space | |
| 1147 # _____section_code_____ | |
| 1148 #"control": "[\t \n\r]" | |
| 1149 _field_code = self.delete_control_space(_field_code) | |
| 1150 # _____section_title_____ | |
| 1151 if _field_code != "": | |
| 1152 _field_dict[_field_code] = _field_title | |
| 1153 _field_index = _field_index + 2 | |
| 1154 self.__budget.setSheetFields(_field_dict) | |
| 1155 self.num_valid_record = self.num_valid_record +1 | |
| 1156 | |
| 1157 def _parseL(self, field_list): | |
| 1158 """_parseL(self, field_list) | |
| 1159 | |
| 1160 field_list: field list of the record | |
| 1161 0- L: Sheet of Conditions 1 | |
| 1162 A: | |
| 1163 1- Empty | |
| 1164 2- {Section Code\Section Title} | |
| 1165 B: | |
| 1166 1- Record Code | |
| 1167 2- {Section Code\Section Text} | |
| 1168 3- {Section Code\RTF file} | |
| 1169 4- {Section Code\HTM file} | |
| 1170 """ | |
| 1171 # _____Number of fields_____ | |
| 1172 # The record must have at least 3 fields | |
| 1173 if len(field_list) < 3: | |
| 1174 return | |
| 1175 _code = field_list[1] | |
| 1176 if _code == "": | |
| 1177 # A: Section Titles | |
| 1178 # Any INFORMATION after last field separator is ignored | |
| 1179 # The record must have 3 fields | |
| 1180 if len(field_list) > 3: | |
| 1181 field_list = field_list[0:3] | |
| 1182 field_list = field_list[1:3] | |
| 1183 # _____Fields_____ | |
| 1184 _section_codes = field_list[1] | |
| 1185 # last \ is erased | |
| 1186 if len(_section_codes) and _section_codes[-1] == "\\": | |
| 1187 _section_codes = _section_codes[:-1] | |
| 1188 _section_codes = _section_codes.split("\\") | |
| 1189 _section_dict = {} | |
| 1190 _section_index = 0 | |
| 1191 while _section_index < len(_section_codes)-1: | |
| 1192 # _____subfields_____ | |
| 1193 _section_code = _section_codes[_section_index] | |
| 1194 | |
| 1195 _section_title = _section_codes[_section_index+1] | |
| 1196 # control character are erased: end of line, tab, space | |
| 1197 # _____section_code_____ | |
| 1198 _section_code = self.delete_control_space(_section_code) | |
| 1199 # _____section_title_____ | |
| 1200 _section_title = self.delete_control_space(_section_title) | |
| 1201 if _section_code != "": | |
| 1202 _section_dict[_section_code] = _section_title | |
| 1203 _section_index = _section_index + 2 | |
| 1204 self.__budget.setSheetSections(_section_dict) | |
| 1205 self.num_valid_record = self.num_valid_record +1 | |
| 1206 | |
| 1207 else: | |
| 1208 # Any INFORMATION after last field separator is ignored | |
| 1209 # The record must have 5 fields | |
| 1210 if len(field_list) > 5: | |
| 1211 field_list = field_list[0:5] | |
| 1212 field_list = field_list[1:] | |
| 1213 # _____Fields_____ | |
| 1214 # _____Record Code_____ | |
| 1215 _record_code = self.delete_control_space(field_list[0]) | |
| 1216 # "#" and "##" characters at the end of the code are erased | |
| 1217 # invalid characters are also erased | |
| 1218 _record_code = self.validateCode(_record_code) | |
| 1219 _scodes_text = field_list[1] | |
| 1220 if _scodes_text == "": | |
| 1221 # TODO: rtf and html files | |
| 1222 print "Html and rtf files not implemented in ~L record" | |
| 1223 else: | |
| 1224 # _____Section-code_Section-text_____ | |
| 1225 # last \ is erased | |
| 1226 if len(_scodes_text) and _scodes_text[-1] == "\\": | |
| 1227 _scodes_text = _scodes_text[:-1] | |
| 1228 _scodes_text = _scodes_text.split("\\") | |
| 1229 _paragraph_dict = {} | |
| 1230 _section_dict = {} | |
| 1231 _section_index = 0 | |
| 1232 while _section_index < len(_scodes_text)-1: | |
| 1233 # _____subfields_____ | |
| 1234 _section_code = _scodes_text[_section_index] | |
| 1235 _section_text = _scodes_text[_section_index+1] | |
| 1236 # control character are erased: end of line, tab, space | |
| 1237 # _____section_code_____ | |
| 1238 _section_code = self.delete_control_space(_section_code) | |
| 1239 # _____section_text_____ | |
| 1240 if _section_code != "" and _section_text != "": | |
| 1241 #-# paragraph #-# | |
| 1242 _paragraph_code = _record_code + _section_code + "*" | |
| 1243 _paragraph_dict[ _paragraph_code ] = _section_text | |
| 1244 _section_dict[_section_code] = _paragraph_code | |
| 1245 _section_index = _section_index + 2 | |
| 1246 self.__budget.setSheetParagraphs(_paragraph_dict) | |
| 1247 self.__budget.setSheetRecord(_record_code, "*", _section_dict) | |
| 1248 self.num_valid_record = self.num_valid_record +1 | |
| 1249 | |
| 1250 def _parseQ(self, field_list): | |
| 1251 """_parseQ(self, field_list) | |
| 1252 | |
| 1253 field_list: field list of the record | |
| 1254 0- Q: Sheet of Conditions 2 | |
| 1255 1- Record Code | |
| 1256 2- {Section Code\Paragraph key\{Field key;}\}| | |
| 1257 """ | |
| 1258 # _____Number of fields_____ | |
| 1259 # The record must have at least 3 fields | |
| 1260 if len(field_list) < 3: | |
| 1261 return | |
| 1262 _code = field_list[1] | |
| 1263 # Any INFORMATION after last field separator is ignored | |
| 1264 # The record must have 3 fields | |
| 1265 if len(field_list) > 3: | |
| 1266 field_list = field_list[0:3] | |
| 1267 field_list = field_list[1:] | |
| 1268 # _____Fields_____ | |
| 1269 # _____Record Code_____ | |
| 1270 _record_code = self.delete_control_space(field_list[0]) | |
| 1271 # "#" and "##" characters at the end of the code are erased | |
| 1272 # invalid characters are also erased | |
| 1273 _record_code = self.validateCode(_record_code) | |
| 1274 _scodes_pkey = field_list[1] | |
| 1275 # last \ is erased | |
| 1276 if len(_scodes_pkey) and _scodes_pkey[-1] == "\\": | |
| 1277 _scodes_pkey = _scodes_pkey[:-1] | |
| 1278 _scodes_pkey = _scodes_pkey.split("\\") | |
| 1279 _field_dict = {} | |
| 1280 _section_index = 0 | |
| 1281 while _section_index < len(_scodes_pkey) -1: | |
| 1282 # _____subfields_____ | |
| 1283 _section_code = _scodes_pkey[_section_index] | |
| 1284 _paragraph_key = _scodes_text[_section_index+1] | |
| 1285 _field_keys = _scodes_text[_section_index+2] | |
| 1286 # control character are erased: end of line, tab, space | |
| 1287 # _____section_code_____ | |
| 1288 _section_code = self.delete_control_space(_section_code) | |
| 1289 # _____section_text_____ | |
| 1290 _paragraph_key = self.delete_control_space(_paragraph_key) | |
| 1291 # _____Fields keys_____ | |
| 1292 _field_keys = self.delete_control_space(_field_keys) | |
| 1293 # last ; is erased | |
| 1294 if len(_field_keys) and _field_keys[-1] == ";": | |
| 1295 _field_keys = _field_keys[:-1] | |
| 1296 _field_keys_list = _scodes_pkey.split(";") | |
| 1297 for _field_key in _field_keys_list: | |
| 1298 if _field_key != "" and _section_code != "" and \ | |
| 1299 _paragraph_key != "": | |
| 1300 if _field_key in _field_dict: | |
| 1301 _section_dict = _field_dict[_field_key] | |
| 1302 else: | |
| 1303 _section_dict = {} | |
| 1304 _field_dict[_field_key] = _section_dict | |
| 1305 _section_dict[_section_code] = _paragraph_code | |
| 1306 _section_index = _section_index + 3 | |
| 1307 for _field, _section_dict in _field_dict.iteritems(): | |
| 1308 self.__budget.setSheetRecord(_record_code, _field, _section_dict) | |
| 1309 self.num_valid_record = self.num_valid_record +1 | |
| 1310 | |
| 1311 def _parseJ(self, field_list): | |
| 1312 """_parseJ(self, field_list) | |
| 1313 | |
| 1314 field_list: field list of the record | |
| 1315 0- J: Sheet of Conditions 3 | |
| 1316 1- Paragraph code | |
| 1317 2- [Paragraph text] | |
| 1318 3- [RTF file] | |
| 1319 4- [HTML file] | |
| 1320 """ | |
| 1321 # _____Number of fields_____ | |
| 1322 # The record must have at least 3 fields | |
| 1323 if len(field_list) < 3: | |
| 1324 return | |
| 1325 # Any INFORMATION after last field separator is ignored | |
| 1326 # The record must have 5 fields | |
| 1327 if len(field_list) > 5: | |
| 1328 field_list = field_list[0:5] | |
| 1329 field_list = field_list[1:] | |
| 1330 # _____Fields_____ | |
| 1331 # _____Paragraph code_____ | |
| 1332 _paragraph_code = self.delete_control_space(field_list[0]) | |
| 1333 # _____Paragraph text_____ | |
| 1334 _paragraph_text = field_list[1] | |
| 1335 if _paragraph_text == "": | |
| 1336 # TODO: rtf and html files | |
| 1337 print "Html and rtf files not implemented in ~J record" | |
| 1338 else: | |
| 1339 self.__budget.setSheetParagraph(paragraph_code, paragraph_text) | |
| 1340 self.num_valid_record = self.num_valid_record +1 | |
| 1341 | |
| 1342 def _parseG(self, field_list): | |
| 1343 """_parseG(self, field_list) | |
| 1344 | |
| 1345 field_list: field list of the record | |
| 1346 0- G: Grafic info | |
| 1347 1- record code | |
| 1348 2- <grafic_file.ext\> | |
| 1349 """ | |
| 1350 # _____Number of fields_____ | |
| 1351 # The record must have at least 3 fields | |
| 1352 if len(field_list) < 3: | |
| 1353 return | |
| 1354 # Any INFORMATION after last field separator is ignored | |
| 1355 # The record must have 3 fields | |
| 1356 if len(field_list) > 3: | |
| 1357 field_list = field_list[0:3] | |
| 1358 field_list = field_list[1:] | |
| 1359 # _____Fields_____ | |
| 1360 # _____Record Code_____ | |
| 1361 _record_code = self.delete_control_space(field_list[0]) | |
| 1362 # "#" and "##" characters at the end of the code are erased | |
| 1363 # invalid characters are also erased | |
| 1364 _record_code = self.validateCode(_record_code) | |
| 1365 # _____Grafic files_____ | |
| 1366 _grafic_files = self.delete_control(field_list[1]) | |
| 1367 # _____subfields_____ | |
| 1368 # last \ is erased | |
| 1369 if len(_grafic_files) and _grafic_files[-1] == "\\": | |
| 1370 _grafic_files = _grafic_files[:-1] | |
| 1371 _grafic_file_list = _grafic_files.split("\\") | |
| 1372 _tested_grafic_file_list = [] | |
| 1373 for _grafic_file in _grafic_file_list: | |
| 1374 _path = os.path.dirname(self.__filename) | |
| 1375 _grafic_file_path = os.path.join(_path, _grafic_file) | |
| 1376 if os.path.exists(_grafic_file_path): | |
| 1377 _tested_grafic_file_list.append(_grafic_file_path) | |
| 1378 else: | |
| 1379 _name_ext = os.path.splitext(_grafic_file) | |
| 1380 _grafic_file_name = _name_ext[0] | |
| 1381 _grafic_file_ext = _name_ext[1] | |
| 1382 _grafic_file_name_u = _grafic_file_name.upper() | |
| 1383 _grafic_file_name_l = _grafic_file_name.lower() | |
| 1384 _grafic_file_ext_u = _grafic_file_ext.upper() | |
| 1385 _grafic_file_ext_l = _grafic_file_ext.lower() | |
| 1386 _uu = _grafic_file_name_u + _grafic_file_ext_u | |
| 1387 _ul = _grafic_file_name_u + _grafic_file_ext_l | |
| 1388 _lu = _grafic_file_name_l + _grafic_file_ext_u | |
| 1389 _ll = _grafic_file_name_l + _grafic_file_ext_l | |
| 1390 _grafic_file_path_uu = os.path.join(_path, _uu) | |
| 1391 _grafic_file_path_ul = os.path.join(_path, _ul) | |
| 1392 _grafic_file_path_lu = os.path.join(_path, _lu) | |
| 1393 _grafic_file_path_ll = os.path.join(_path, _ll) | |
| 1394 if os.path.exists(_grafic_file_path_uu): | |
| 1395 _tested_grafic_file_list.append(_grafic_file_path_uu) | |
| 1396 elif os.path.exists(_grafic_file_path_ul): | |
| 1397 _tested_grafic_file_list.append(_grafic_file_path_ul) | |
| 1398 elif os.path.exists(_grafic_file_path_lu): | |
| 1399 _tested_grafic_file_list.append(_grafic_file_path_lu) | |
| 1400 elif os.path.exists(_grafic_file_path_ll): | |
| 1401 _tested_grafic_file_list.append(_grafic_file_path_ll) | |
| 1402 else: | |
| 1403 print utils.mapping(_("The file $1 do not exist"), | |
| 1404 (_grafic_file_path,)) | |
| 1405 if len(_grafic_file_list) > 0: | |
| 1406 for _grafic_file in _tested_grafic_file_list: | |
| 1407 self.__budget.addFile(_record_code, _grafic_file, "img", "") | |
| 1408 self.num_valid_record = self.num_valid_record +1 | |
| 1409 | |
| 1410 def _parseE(self, field_list): | |
| 1411 """_parseE(self, field_list) | |
| 1412 | |
| 1413 field_list: field list of the record | |
| 1414 0- E: Company | |
| 1415 1- company Code | |
| 1416 2 [ summary ] | |
| 1417 3- [ name ] | |
| 1418 4- { [ type ] \ [ subname ] \ [ address ] \ [ postal_code ] | |
| 1419 \ [ town ] \ [ province ] \ [ country ] \ { phone; } | |
| 1420 \ { fax; } \ {contact_person; } \ } | |
| 1421 5- [ cif ] \ [ web ] \ [ email ] \ | |
| 1422 """ | |
| 1423 | |
| 1424 # _____Number of fields_____ | |
| 1425 # Any INFORMATION after last field separator is ignored | |
| 1426 # The record must have 6 fields | |
| 1427 if len(field_list) > 6: | |
| 1428 field_list = field_list[1:6] | |
| 1429 # If there are no sufficient fields, the fields are added | |
| 1430 # with empty value:"" | |
| 1431 else: | |
| 1432 field_list = field_list[1:] + [""]*(6-len(field_list)) | |
| 1433 # _____Fields_____ | |
| 1434 # _____company Code_____ | |
| 1435 _company_code = self.delete_control_space(field_list[0]) | |
| 1436 if _company_code == "": | |
| 1437 return | |
| 1438 # _____Summary_____ | |
| 1439 | |
| 1440 _sumamary = self.delete_control(field_list[1]) | |
| 1441 # _____Name_____ | |
| 1442 _name = self.delete_control(field_list[2]) | |
| 1443 # _____local_offices_____ | |
| 1444 _local_offices = self.delete_control(field_list[3]) | |
| 1445 # _____subfields of local_offices_____ | |
| 1446 # last \ is erased | |
| 1447 if len(_local_offices) and _local_offices[-1] == "\\": | |
| 1448 _local_offices = _local_offices[:-1] | |
| 1449 _local_offices_list = _local_offices.split("\\") | |
| 1450 # If there are no sufficent subfields, the subfields are added | |
| 1451 # whith empty value | |
| 1452 _nsub = len(_local_offices_list) % 10 | |
| 1453 if _nsub != 0: | |
| 1454 _local_offices_list = _local_offices_list + \ | |
| 1455 [""]*(10-len(field_list)) | |
| 1456 _local_offices = [] | |
| 1457 _local_offices_index = 0 | |
| 1458 while _local_offices_index < len(_local_offices_list)-9: | |
| 1459 # _____subfields_____ | |
| 1460 _type = _local_offices_list[_local_offices_index] | |
| 1461 _subname = _local_offices_list[_local_offices_index+1] | |
| 1462 _address = _local_offices_list[_local_offices_index+2] | |
| 1463 _postal_code = _local_offices_list[_local_offices_index+3] | |
| 1464 _town = _local_offices_list[_local_offices_index+4] | |
| 1465 _province = _local_offices_list[_local_offices_index+5] | |
| 1466 _country = _local_offices_list[_local_offices_index+6] | |
| 1467 _phone = _local_offices_list[_local_offices_index+7] | |
| 1468 # last ; is erased | |
| 1469 if len(_phone) and _phone[-1] == ";": | |
| 1470 _phone = _phone[:-1] | |
| 1471 _phone_list = _phone.split(";") | |
| 1472 _fax = _local_offices_list[_local_offices_index+8] | |
| 1473 # last ; is erased | |
| 1474 if len(_fax) and _fax[-1] == ";": | |
| 1475 _fax = _fax[:-1] | |
| 1476 _fax_list = _fax.split(";") | |
| 1477 _contact_person = _local_offices_list[_local_offices_index+9] | |
| 1478 if _type != "" or _subname != "" or _address != "" or \ | |
| 1479 _postal_code != "" or _town != "" or _province != "" or \ | |
| 1480 _country != "" or _phone != "" or _fax != "" or \ | |
| 1481 _contact_person != "": | |
| 1482 _local_offices.append([_type, _subname, _address, | |
| 1483 _postal_code, _town, _province, | |
| 1484 _country, _phone_list, _fax_list, | |
| 1485 _contact_person]) | |
| 1486 _local_offices_index = _local_offices_index + 10 | |
| 1487 # _____cif web email_____ | |
| 1488 _c_w_e = self.delete_control_space(field_list[4]) | |
| 1489 # last \ is erased | |
| 1490 if len(_c_w_e) and _c_w_e[-1] == "\\": | |
| 1491 _c_w_e = _c_w_e[:-1] | |
| 1492 _c_w_e_list = _c_w_e.split("\\") | |
| 1493 # _____subfields_____ | |
| 1494 # If there are no sufficient fields, the fields are added | |
| 1495 # with empty value:"" | |
| 1496 _c_w_e_list = _c_w_e_list + [""]*(3-len(_c_w_e_list)) | |
| 1497 _cif = _c_w_e_list[0] | |
| 1498 _web = _c_w_e_list[1] | |
| 1499 _email = _c_w_e_list[2] | |
| 1500 self.__budget.setCompany(_company_code, _sumamary, _name, | |
| 1501 _local_offices, _cif, _web, _email) | |
| 1502 self.num_valid_record = self.num_valid_record +1 | |
| 1503 | |
| 1504 def _parseX(self, field_list): | |
| 1505 """_parseX(self, field_list) | |
| 1506 | |
| 1507 field_list: field list of the record | |
| 1508 A) | |
| 1509 0- X: Tecnical information | |
| 1510 1- Empty | |
| 1511 2- < TI_Code \ TI_Descitption \ TI_Unit > | |
| 1512 B) | |
| 1513 0- X: Tecnical information | |
| 1514 1- Record_code | |
| 1515 2- < TI_Code \ TI_value > | |
| 1516 """ | |
| 1517 # Tecnical information | |
| 1518 # The record must have at least 3 fields | |
| 1519 if len(field_list) < 3: | |
| 1520 return | |
| 1521 # Any INFORMATION after last field separator is ignored | |
| 1522 # The record must have 3 fields | |
| 1523 if len(field_list) > 3: | |
| 1524 field_list = field_list[0:3] | |
| 1525 field_list = field_list[1:] | |
| 1526 # _____Fields_____ | |
| 1527 # "control": "[\t \n\r]" | |
| 1528 _field_1 = self.delete_control_space(field_list[0]) | |
| 1529 _field_2 = self.delete_control_space(field_list[1]) | |
| 1530 if _field_1 == "": | |
| 1531 # A) | |
| 1532 _field_2_list = _field_2.split("\\") | |
| 1533 _ti_index = 0 | |
| 1534 while _ti_index < len(_field_2_list)-3: | |
| 1535 _ti_code = _field_2_list[_ti_index] | |
| 1536 _ti_description = _field_2_list[_ti_index+1] | |
| 1537 _ti_unit = _field_2_list[_ti_index+2] | |
| 1538 if _ti_code != "": | |
| 1539 self.__budget.addTecInfo(_ti_code, _ti_description, | |
| 1540 _ti_unit) | |
| 1541 _ti_index = _ti_index + 3 | |
| 1542 else: | |
| 1543 # B) | |
| 1544 # "#" and "##" characters at the end of the code are erased | |
| 1545 # invalid characters are also erased | |
| 1546 _record_code = self.validateCode(_field_1) | |
| 1547 _field_2_list = _field_2.split("\\") | |
| 1548 _ti_index = 0 | |
| 1549 _ti_dict = {} | |
| 1550 while _ti_index < len(_field_2_list)-2: | |
| 1551 _ti_code = _field_2_list[_ti_index] | |
| 1552 _ti_value = _field_2_list[_ti_index+1] | |
| 1553 if _ti_code != "" and _ty_value != "": | |
| 1554 _ti_dict[_ti_code] = _ty_value | |
| 1555 _ti_index = _ti_index + 2 | |
| 1556 self.__budget.setTecnicalInformation(_record_code, _ti_dict) | |
| 1557 self.num_valid_record = self.num_valid_record +1 | |
| 1558 | |
| 1559 def _parseF(self, field_list): | |
| 1560 """_parseF(self, field_list) | |
| 1561 | |
| 1562 field_list: field list of the record | |
| 1563 0- F: Files | |
| 1564 1- Record code | |
| 1565 2- { Type \ { Filenames; } \ [Description] } | |
| 1566 """ | |
| 1567 | |
| 1568 # _____Number of fields_____ | |
| 1569 # The record must have at least 3 fields | |
| 1570 if len(field_list) < 3: | |
| 1571 return | |
| 1572 # Any INFORMATION after last field separator is ignored | |
| 1573 # The record must have 3 fields | |
| 1574 if len(field_list) > 3: | |
| 1575 field_list = field_list[0:3] | |
| 1576 field_list = field_list[1:] | |
| 1577 # _____Fields_____ | |
| 1578 # _____Record Code_____ | |
| 1579 _record_code = self.delete_control_space(field_list[0]) | |
| 1580 # "#" and "##" characters at the end of the code are erased | |
| 1581 # invalid characters are also erased | |
| 1582 _record_code = self.validateCode(_record_code) | |
| 1583 # _____Grafic files_____ | |
| 1584 _files = self.delete_control(field_list[1]) | |
| 1585 # _____subfields_____ | |
| 1586 # last \ is erased | |
| 1587 if len(_files) and _files[-1] == "\\": | |
| 1588 _files = _files[:-1] | |
| 1589 _files_list = _files.split("\\") | |
| 1590 # adding empty subfiels if necesary | |
| 1591 if len(_files_list)%3 > 0: | |
| 1592 _files_list.extend[""]*(3 - len(_files_list)%3) | |
| 1593 _file_index = 0 | |
| 1594 _tested_files_list = [] | |
| 1595 while _file_index < len(_files_list)-3: | |
| 1596 _type = _files_list[_file_index].replace(" ","") | |
| 1597 ## _types = { | |
| 1598 ## "0": _("others"), | |
| 1599 ## "1": _("características técnicas y de fabricación"), | |
| 1600 ## "2": _("manual de colocación, uso y mantenimiento"), | |
| 1601 ## "3": _("certificado/s de elementos y sistemas"), | |
| 1602 ## "4": _("normativa y bibliografía"), | |
| 1603 ## "5": _("tarifa de precios"), | |
| 1604 ## "6": _("condiciones de venta"), | |
| 1605 ## "7": _("carta de colores"), | |
| 1606 ## "8": _("ámbito de aplicación y criterios selección"), | |
| 1607 ## "9": _("cálculo de elementos y sistemas"), | |
| 1608 ## "10": _("presentación, datos generales, objetivos, etc. de "\ | |
| 1609 ## "empresa"), | |
| 1610 ## "11": _("certificado/s de empresa"), | |
| 1611 ## "12": _("obras realizadas")} | |
| 1612 _types = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", | |
| 1613 "11", "12"] | |
| 1614 if not _type in _types: | |
| 1615 _type = "0" | |
| 1616 _filenames = _files_list[_file_index + 1] | |
| 1617 _description = _files_list[_file_index + 2] | |
| 1618 _file_index += 3 | |
| 1619 if len(_filenames) and _filenames[-1] == ";": | |
| 1620 _files = _files[:-1] | |
| 1621 _filenames_list = _files.split(";") | |
| 1622 _path = os.path.dirname(self.__filename) | |
| 1623 for _filename in filenames_list: | |
| 1624 _file_path = os.path.join(_path, _filename) | |
| 1625 if os.path.exists(_file_path): | |
| 1626 _tested_files_list.append([_file_path, _type, | |
| 1627 _description]) | |
| 1628 else: | |
| 1629 _name_ext = os.path.splitext(_filename) | |
| 1630 _file_name = _name_ext[0] | |
| 1631 _file_ext = _name_ext[1] | |
| 1632 _file_name_u = _file_name.upper() | |
| 1633 _file_name_l = _file_name.lower() | |
| 1634 _file_ext_u = _file_ext.upper() | |
| 1635 _file_ext_l = _file_ext.lower() | |
| 1636 _uu = _file_name_u + _file_ext_u | |
| 1637 _ul = _file_name_u + _file_ext_l | |
| 1638 _lu = _file_name_l + _file_ext_u | |
| 1639 _ll = _file_name_l + _file_ext_l | |
| 1640 _file_path_uu = os.path.join(_path, _uu) | |
| 1641 _file_path_ul = os.path.join(_path, _ul) | |
| 1642 _file_path_lu = os.path.join(_path, _lu) | |
| 1643 _file_path_ll = os.path.join(_path, _ll) | |
| 1644 if os.path.exists(_file_path_uu): | |
| 1645 _tested_files_list.append([_file_path_uu, _type, | |
| 1646 _description]) | |
| 1647 elif os.path.exists(_grafic_file_path_ul): | |
| 1648 _tested_files_list.append([_file_path_ul, _type, | |
| 1649 _description]) | |
| 1650 elif os.path.exists(_grafic_file_path_lu): | |
| 1651 _tested_files_list.append([_file_path_lu, _type, | |
| 1652 _description]) | |
| 1653 elif os.path.exists(_grafic_file_path_ll): | |
| 1654 _tested_files_list.append([_file_path_ll, _type, | |
| 1655 _description]) | |
| 1656 else: | |
| 1657 print utils.mapping(_("The file $1 do not exist"), | |
| 1658 (_file_path,)) | |
| 1659 if len(_tested_files_list) > 0: | |
| 1660 for _file in _tested_file_list: | |
| 1661 self.__budget.addFile(_record_code, _file[0], file[1], file[2]) | |
| 1662 self.num_valid_record = self.num_valid_record +1 | |
| 1663 | |
| 1664 def _parseB(self, field_list): | |
| 1665 """_parseB(self, field_list) | |
| 1666 | |
| 1667 field_list: field list of the record | |
| 1668 0- B: Change code | |
| 1669 1- Record Code | |
| 1670 2- New code | |
| 1671 """ | |
| 1672 # _____Number of fields_____ | |
| 1673 # Any INFORMATION after last field separator is ignored | |
| 1674 # The record must have 3 fields | |
| 1675 if len(field_list) > 3: | |
| 1676 field_list = field_list[0:3] | |
| 1677 field_list = field_list[1:] | |
| 1678 if len(field_list) != 2: | |
| 1679 return | |
| 1680 # control character are erased: end of line, tab, space | |
| 1681 # _____Fields_____ | |
| 1682 _code = self.delete_control_space(field_list[0]) | |
| 1683 _new_code = self.delete_control_space(field_list[1]) | |
| 1684 # _____Codes_____ | |
| 1685 # "#" and "##" characters at the end of the code are erased | |
| 1686 # invalid characters are also erased | |
| 1687 _code = self.validateCode(_code) | |
| 1688 _new_code = self.validateCode(_new_code) | |
| 1689 # change code | |
| 1690 self.__budget.changeCode(_code, _new_code) | |
| 1691 self.num_valid_record = self.num_valid_record + 1 | |
| 1692 | |
| 1693 def _parseA(self, field_list): | |
| 1694 """_parseA(self, field_list) | |
| 1695 | |
| 1696 field_list: field list of the record | |
| 1697 0- A: Labels | |
| 1698 1- Record Code | |
| 1699 2- <Label\> | |
| 1700 """ | |
| 1701 # _____Number of fields_____ | |
| 1702 # Any INFORMATION after last field separator is ignored | |
| 1703 # The record must have 3 fields | |
| 1704 if len(field_list) > 3: | |
| 1705 field_list = field_list[0:3] | |
| 1706 field_list = field_list[1:] | |
| 1707 if len(field_list) != 2: | |
| 1708 return | |
| 1709 # control character are erased: end of line, tab, space | |
| 1710 # _____Fields_____ | |
| 1711 # "control": "[\t \n\r]" | |
| 1712 _code = self.delete_control_space(field_list[0]) | |
| 1713 _labels = self.delete_control_space(field_list[1]) | |
| 1714 # _____Codes_____ | |
| 1715 # "#" and "##" characters at the end of the code are erased | |
| 1716 # invalid characters are also erased | |
| 1717 _code = self.validateCode(_code) | |
| 1718 # _____Labels_____ | |
| 1719 # last \ is erased | |
| 1720 # TODO: change the others parsers to this: | |
| 1721 while len(_labels) > 0 and _labels[-1] == "\\": | |
| 1722 _labels = _labels[:-1] | |
| 1723 # replace "_" to " " | |
| 1724 _labels = _labels.replace("_"," ") | |
| 1725 _label_list = _labels.split("\\") | |
| 1726 for _label in _label_list: | |
| 1727 self.__budget.addLabel(_code, _label) | |
| 1728 self.num_valid_record = self.num_valid_record + 1 | |
| 1729 | |
| 1730 def _parseP(self, field_list): | |
| 1731 """_parseP(self, field_list) | |
| 1732 | |
| 1733 field_list: Parametric record | |
| 1734 A) Global paremetric record | |
| 1735 0- P: Parametric | |
| 1736 1- Empty | |
| 1737 2- [Parametric description] | |
| 1738 3- [library.DLL] | |
| 1739 B) Family Parametric record | |
| 1740 0- P: Parametric | |
| 1741 1- Family Code | |
| 1742 2- [Parametric description] | |
| 1743 """ | |
| 1744 # TODO: Use global parametric record | |
| 1745 if len(field_list) > 2: | |
| 1746 # delete control caracters and spaces | |
| 1747 _family_code = self.delete_control_space(field_list[1]) | |
| 1748 if _family_code == "": # A)Global paremetric record | |
| 1749 # The record must have 3 or 4 fields | |
| 1750 if len(field_list) > 4: | |
| 1751 field_list = field_list[0:4] | |
| 1752 field_list = field_list[1:] | |
| 1753 if len(field_list) == 2: | |
| 1754 field_list.append("") | |
| 1755 if len(field_list) != 3: | |
| 1756 return | |
| 1757 else: # B)Family Parametric record | |
| 1758 # The record must have 3 fields | |
| 1759 if len(field_list) > 3: | |
| 1760 field_list = field_list[0:3] | |
| 1761 field_list = field_list[1:] | |
| 1762 if len(field_list) != 2: | |
| 1763 print _("PyArq hates parametric DLLs") | |
| 1764 return | |
| 1765 else: | |
| 1766 return | |
| 1767 # _____Description_____ | |
| 1768 _description = field_list[1] | |
| 1769 if _description == "": | |
| 1770 print _("PyArq hates parametric DLLs") | |
| 1771 return | |
| 1772 # Adding last end of line | |
| 1773 _description = _description + "\r\n" | |
| 1774 # Delete comments | |
| 1775 # "comment" : "#.*\r\n" | |
| 1776 _description = self.__pattern["comment"].sub("\r\n",_description) | |
| 1777 # Tabs to spaces | |
| 1778 _description = _description.replace("\t"," ") | |
| 1779 # Delete empty lines | |
| 1780 # "empty_line": r"(\r\n) *\r\n" | |
| 1781 while self.__pattern["empty_line"].search(_description): | |
| 1782 _description = self.__pattern["empty_line"].sub( | |
| 1783 lambda x: x.groups()[0], _description) | |
| 1784 # Delete spaces before and after / | |
| 1785 # "space_before_backslash" : r"( )+\\" | |
| 1786 _description = self.__pattern["space_before_backslash"].sub( | |
| 1787 r"\\",_description) | |
| 1788 # "space_after_backslash" : r"\\( )+" | |
| 1789 _description = self.__pattern["space_after_backslash"].sub( | |
| 1790 r"\\",_description) | |
| 1791 # Join lines that start but not end with / | |
| 1792 _description = "\r\n" + _description # add leading end of line | |
| 1793 # "start_noend_backslash": "(\r\n\\\.*[^\\\])\r\n" | |
| 1794 while self.__pattern["start_noend_backslash"].search(_description): | |
| 1795 _description = self.__pattern["start_noend_backslash"].sub( | |
| 1796 lambda x: x.groups()[0], _description) | |
| 1797 # Join lines that end with a + - * / ^ and @ & < > <= >= = <> ! | |
| 1798 # "end_oper" : "(\+|-|\*|/|/^|@|&|<|>|<=|>=|=|!) *\r\n" | |
| 1799 _description = self.__pattern["end_oper"].sub( | |
| 1800 lambda x: x.groups()[0], _description) | |
| 1801 # Join lines for matricial vars | |
| 1802 # matricial_var : "(\r\n *[%|\$][A-ZÑ].*=.*,) *\r\n" | |
| 1803 while self.__pattern["matricial_var"].search(_description): | |
| 1804 _description = self.__pattern["matricial_var"].sub( | |
| 1805 lambda x: x.groups()[0], _description) | |
| 1806 _description = _description[2:] # remove leading end of line | |
| 1807 #_description = re.sub(r"\\( )+",r"\\",_description) | |
| 1808 _lines = _description.split("\r\n") | |
| 1809 _final_description = "" | |
| 1810 _pass_line = 0 | |
| 1811 for index in range(len(_lines)): | |
| 1812 _line = _lines[index] | |
| 1813 # Parse lines | |
| 1814 if len(_line) != 0: # Delete empty lines | |
| 1815 if _pass_line > 0: | |
| 1816 _pass_line = _pass_line -1 | |
| 1817 _line = "" | |
| 1818 elif _line.isspace(): | |
| 1819 _line = "" | |
| 1820 elif _line[0] != "\\": | |
| 1821 # Delete spaces out "" delimiter | |
| 1822 _list = _line.split('"') | |
| 1823 _final_line = "" | |
| 1824 for index1 in range(len(_list)): | |
| 1825 if index1 % 2 != 0: | |
| 1826 _parcial_line = '"' + _list[index1] | |
| 1827 else: | |
| 1828 _parcial_line = '"' + _list[index1].replace(" ","") | |
| 1829 _final_line = _final_line + _parcial_line | |
| 1830 _line = _final_line[1:] | |
| 1831 _lines[index] = _line | |
| 1832 # parse data | |
| 1833 if len(_line) > 2 and _line[:2] == "::": | |
| 1834 # Delete spaces out " delimiter | |
| 1835 #print "__PRECIO__" + _line[2:] | |
| 1836 pass | |
| 1837 elif len(_line) > 2 and _line[:2] == "%:": | |
| 1838 # Delete spaces out " delimiter | |
| 1839 #print "__%AUX__" + _line[2:] | |
| 1840 pass | |
| 1841 elif len(_line) > 3 and _line[:2] == "%%:": | |
| 1842 # Delete spaces out " delimiter | |
| 1843 #print "__%%AUX__" + _line[2:] | |
| 1844 pass | |
| 1845 elif self.__pattern["var"].search(_line): | |
| 1846 # Delete spaces out " delimiter | |
| 1847 #print "line =", _line | |
| 1848 while _line.count('"') % 2 == 1 and \ | |
| 1849 index + _pass_line + 1 < len(_lines) -1: | |
| 1850 _line = _line + _lines[index + _pass_line + 1] | |
| 1851 _pass_line = _pass_line + 1 | |
| 1852 _search = self.__pattern["var"].search(_line) | |
| 1853 if _search is not None: | |
| 1854 _var = _search.groups()[0] + " = " + _search.groups()[1] | |
| 1855 #print "__VAR__" + str(_var) | |
| 1856 pass | |
| 1857 else: | |
| 1858 #print "no __VAR__", _line | |
| 1859 pass | |
| 1860 elif self.__pattern["descomposition"].search(_line): | |
| 1861 # Delete spaces out " delimiter | |
| 1862 #_patern = "(^[^:]*):(.*)$" | |
| 1863 _search = self.__pattern["descomposition"].search(_line) | |
| 1864 if _search is not None: | |
| 1865 _var = _search.groups()[0] + ":" + _search.groups()[1] | |
| 1866 #print "__Descomposición__" + str(_var) | |
| 1867 pass | |
| 1868 else: | |
| 1869 #print "no __Descomposición__", _line | |
| 1870 pass | |
| 1871 else: | |
| 1872 print "Parametric: code: " + _family_code | |
| 1873 print "******* Desconocido *** : " + _line | |
| 1874 if index-10 > 0: print "-11 :", _lines[index-11] | |
| 1875 if index-10 > 0: print "-10 :", _lines[index-10] | |
| 1876 if index-9 > 0: print "-9 :", _lines[index-9] | |
| 1877 if index-8 > 0: print "-8 :", _lines[index-8] | |
| 1878 if index-7 > 0: print "-7 :", _lines[index-7] | |
| 1879 if index-6 > 0: print "-6 :", _lines[index-6] | |
| 1880 if index-5 > 0: print "-5 :", _lines[index-5] | |
| 1881 if index-4 > 0: print "-4 :", _lines[index-4] | |
| 1882 if index-3 > 0: print "-3 :", _lines[index-3] | |
| 1883 if index-2 > 0: print "-2 :", _lines[index-2] | |
| 1884 if index-1 > 0: print "-1 :", _lines[index-1] | |
| 1885 print "-0 :", _lines[index-0] | |
| 1886 pass | |
| 1887 else: | |
| 1888 _parameter_list = _line.split("\\")[1:-1] | |
| 1889 if len(_parameter_list) >= 2: | |
| 1890 if _parameter_list[0] == "C" or \ | |
| 1891 _parameter_list[0] == "COMENTARIO": | |
| 1892 #print "__COMENTARIO__" + _parameter_list[1] | |
| 1893 self.__budget.setParametricSelectComment( | |
| 1894 _family_code, _parameter_list[1]) | |
| 1895 elif _parameter_list[0] == "R" or \ | |
| 1896 _parameter_list[0] == "RESUMEN": | |
| 1897 #print "__RESUMEN__" + _parameter_list[1] | |
| 1898 self.__budget.setParametricSummary(_family_code, | |
| 1899 _parameter_list[1]) | |
| 1900 elif _parameter_list[0] == "T" or \ | |
| 1901 _parameter_list[0] == "TEXTO": | |
| 1902 #print "__TEXTO__" + _parameter_list[1] | |
| 1903 self.__budget.setParametricText(_family_code, | |
| 1904 _parameter_list[1]) | |
| 1905 elif _parameter_list[0] == "P" or \ | |
| 1906 _parameter_list[0] == "PLIEGO": | |
| 1907 #print "__PLIEGO__" + str(_parameter_list[1:]) | |
| 1908 pass | |
| 1909 elif _parameter_list[0] == "K" or \ | |
| 1910 _parameter_list[0] == "CLAVES": | |
| 1911 #print "__CLAVES__" + str(_parameter_list[1:]) | |
| 1912 pass | |
| 1913 elif _parameter_list[0] == "F" or \ | |
| 1914 _parameter_list[0] == "COMERCIAL": | |
| 1915 #print "__COMERCIAL__" + str(_parameter_list[1:]) | |
| 1916 pass | |
| 1917 else: | |
| 1918 #print "==PARAMETRO==" + str(_parameter_list[:]) | |
| 1919 pass | |
| 1920 _final_description = _final_description + _line + "\r\n" | |
| 1921 | |
| 1922 #print _line | |
| 1923 # Delete last empty line | |
| 1924 _description = _final_description[:-2] | |
| 1925 _lines = _description.split("\r\n") | |
| 1926 for _line in _lines: | |
| 1927 pass | |
| 1928 #print _line | |
| 1929 self.num_valid_record = self.num_valid_record + 1 | |
| 1930 | |
| 1931 def readFile(self, budget=None, filename=None, interface=None): | |
| 1932 """readFile(self, budget=None, filename=None) | |
| 1933 | |
| 1934 filename: the filename of the fiebdc file | |
| 1935 budget: base.obra object | |
| 1936 interface: a object to send messages | |
| 1937 must have printf(message) progress(percent) | |
| 1938 recordStatistics(...) | |
| 1939 Return the budget objetc or None if the file can be readed | |
| 1940 """ | |
| 1941 if filename != None and budget != None: | |
| 1942 self.__filename = filename | |
| 1943 self.__budget = budget | |
| 1944 self.__budget.filename = self.__filename | |
| 1945 if self.__filename is None or self.__budget is None or \ | |
| 1946 self.__cancel == True: | |
| 1947 return None | |
| 1948 if not os.path.exists(self.__filename): | |
| 1949 return None | |
| 1950 _time = time.time() | |
| 1951 try: | |
| 1952 _file = open(self.__filename, 'r') | |
| 1953 except IOError: | |
| 1954 print utils.mapping("IOError: $1", (self.__filename,)) | |
| 1955 return None | |
| 1956 self.__budget.filename = self.__filename | |
| 1957 self._record_number = 0 | |
| 1958 self.num_valid_record = 0 | |
| 1959 self._record_V_number = 0 | |
| 1960 self._record_C_number = 0 | |
| 1961 self._record_D_number = 0 | |
| 1962 self._record_Y_number = 0 | |
| 1963 self._record_M_number = 0 | |
| 1964 self._record_N_number = 0 | |
| 1965 self._record_T_number = 0 | |
| 1966 self._record_K_number = 0 | |
| 1967 self._record_W_number = 0 | |
| 1968 self._record_L_number = 0 | |
| 1969 self._record_Q_number = 0 | |
| 1970 self._record_J_number = 0 | |
| 1971 self._record_G_number = 0 | |
| 1972 self._record_E_number = 0 | |
| 1973 self._record_O_number = 0 | |
| 1974 self._record_P_number = 0 | |
| 1975 self._record_X_number = 0 | |
| 1976 self._record_B_number = 0 | |
| 1977 self._record_F_number = 0 | |
| 1978 self._record_A_number = 0 | |
| 1979 self._record_Unknow_number = 0 | |
| 1980 print utils.mapping(_("Loading file $1"), (self.__filename,)) | |
| 1981 _filesize = float(os.path.getsize(self.__filename)) | |
| 1982 interface.progress(_file.tell() / _filesize) | |
| 1983 _buffer = _file.read(1000) | |
| 1984 # set codepage from V record | |
| 1985 _record_list = _buffer.split("~") | |
| 1986 registro_V = _record_list[1] | |
| 1987 # ~V|[PROPIEDAD_ARCHIVO]|VERSION_FORMATO[\DDMMAAAA]|[PROGRAMA_EMISION]| | |
| 1988 # [CABECERA]\{ ROTULO_IDENTIFICACION \}|[JUEGO_CARACTERES]| | |
| 1989 # [COMENTARIO]|[TIPO INFORMACIÓN]|[NÚMERO CERTIFICACIÓN]| | |
| 1990 # [FECHA CERTIFICACIÓN ] | | |
| 1991 registro_V = registro_V.split("|") | |
| 1992 if registro_V[0] == "V": | |
| 1993 #_codepage = registro_V[5] | |
| 1994 if len(registro_V) > 5: | |
| 1995 _version = registro_V[5].strip() | |
| 1996 # remove leading spaces | |
| 1997 if _version in self.__character_sets_dict: | |
| 1998 self.__character_set = self.__character_sets_dict[_version] | |
| 1999 else: | |
| 2000 print utils.mapping(_("This codepage do not exist in "\ | |
| 2001 "FIEBDC3! Default codepage: $1"), | |
| 2002 (self.__character_set,)) | |
| 2003 else: | |
| 2004 print utils.mapping(_("This V record dot have a codepage! "\ | |
| 2005 "Default codepage: $1"), | |
| 2006 (self.__character_set,)) | |
| 2007 else: | |
| 2008 print utils.mapping(_("Not 'V' record in File! Default codepage: "\ | |
| 2009 "$1"), (self.__character_set,)) | |
| 2010 if self.__character_set != "utf8": | |
| 2011 _buffer = unicode(_buffer, self.__character_set) | |
| 2012 _buffer = _buffer.encode("utf8") | |
| 2013 # Any INFORMATION between the beginning of the file and the | |
| 2014 # beginning of the first registry “~” is ignored | |
| 2015 #"after_first_tilde" : "^[^~]*~" | |
| 2016 _buffer = self.__pattern["after_first_tilde"].sub("",_buffer) | |
| 2017 while _buffer != "" and self.__cancel != True: | |
| 2018 #-# the blank characters (32), tabs (9) and end of line (13 and 10) | |
| 2019 # before the separators '~', '|' are erased. | |
| 2020 # Before separator \ not deleted because it affects the reading of | |
| 2021 # the record ~P | |
| 2022 _buffer = self.eraseControlCharacters(_buffer) | |
| 2023 _record_list = _buffer.split("~") | |
| 2024 # The last record can be incomplete unless it is the last one of | |
| 2025 # the file | |
| 2026 if len(_record_list) > 1: | |
| 2027 # not the end | |
| 2028 _last_record = _record_list.pop() | |
| 2029 else: | |
| 2030 # the end record | |
| 2031 # The blank characters (32), tabs (9) and end of line | |
| 2032 # (13 and 10) at the end of the file are ignored. | |
| 2033 #"end_control" : "((\r\n)| |\t)+$" | |
| 2034 _record_list[-1] = self.__pattern["end_control"].sub("", | |
| 2035 _record_list[-1]) | |
| 2036 _last_record = "" | |
| 2037 for record in _record_list: | |
| 2038 if self.__cancel == True: | |
| 2039 break | |
| 2040 self.parseRecord(record) | |
| 2041 interface.progress(_file.tell() / _filesize) | |
| 2042 _buffer2 = _file.read(100000) | |
| 2043 if self.__character_set != "utf8": | |
| 2044 _buffer2 = unicode(_buffer2, self.__character_set) | |
| 2045 _buffer2 = _buffer2.encode("utf8") | |
| 2046 _buffer = _last_record + _buffer2 | |
| 2047 _file.close() | |
| 2048 if self.__cancel == True: | |
| 2049 print _("Cancelled process") | |
| 2050 return None | |
| 2051 else: | |
| 2052 print utils.mapping(_("Time to load: $1 seconds"), | |
| 2053 (("%.2f" %(time.time()-_time)),)) | |
| 2054 print utils.mapping(_("Records/Valid Records: $1/$2"), | |
| 2055 (self._record_number, self.num_valid_record)) | |
| 2056 if self._record_O_number > 0: | |
| 2057 print utils.mapping(_("$1 unsuported record type O: "\ | |
| 2058 "Comercial Relationship"), (self._record_O_number,)) | |
| 2059 if self.num_valid_record == 0: | |
| 2060 print _("This file is not a valid FIBDC3 file") | |
| 2061 return None | |
| 2062 _str = "" | |
| 2063 for type in \ | |
| 2064 [("V", self._record_V_number), | |
| 2065 ("C", self._record_C_number), | |
| 2066 ("D", self._record_D_number), | |
| 2067 ("Y", self._record_Y_number), | |
| 2068 ("M", self._record_M_number), | |
| 2069 ("N", self._record_N_number), | |
| 2070 ("T", self._record_T_number), | |
| 2071 ("K", self._record_K_number), | |
| 2072 ("W", self._record_W_number), | |
| 2073 ("L", self._record_L_number), | |
| 2074 ("Q", self._record_Q_number), | |
| 2075 ("J", self._record_J_number), | |
| 2076 ("G", self._record_G_number), | |
| 2077 ("E", self._record_E_number), | |
| 2078 ("O", self._record_O_number), | |
| 2079 ("P", self._record_P_number), | |
| 2080 ("X", self._record_X_number), | |
| 2081 ("B", self._record_B_number), | |
| 2082 ("F", self._record_F_number), | |
| 2083 ("A", self._record_A_number), | |
| 2084 ("?", self._record_Unknow_number)]: | |
| 2085 _str = _str + "%s: %s\n" %(type[0], type[1]) | |
| 2086 print _str | |
| 2087 self._testBudget(self.__budget) | |
| 2088 return self.__budget | |
| 2089 | |
| 2090 def _testBudget(self, budget): | |
| 2091 """testBudget(self,budget) | |
| 2092 | |
| 2093 budget: base.obra object | |
| 2094 Test and repair budget object after read it from bc3 file | |
| 2095 """ | |
| 2096 # TODO: more to do here | |
| 2097 print _("Testing budget ...") | |
| 2098 # Add price to records without price | |
| 2099 _iter = budget.iter() | |
| 2100 _titlelist = budget.getTitleList()[1] | |
| 2101 if len(_titlelist) == 0: | |
| 2102 _titlenum = 1 | |
| 2103 else: | |
| 2104 _titlenum = len(_titlelist) | |
| 2105 for _code in _iter: | |
| 2106 _record = budget.getRecord(_code) | |
| 2107 _prices = _record.getPrices() | |
| 2108 _len_prices = len(_prices) | |
| 2109 if _titlenum > _len_prices: | |
| 2110 _leftprices = _titlenum - _len_prices | |
| 2111 for _index in range(0,_leftprices): | |
| 2112 _root = budget.getRecord(budget.getRoot()) | |
| 2113 _price = [0.0, _root.getDate(_len_prices + _index)] | |
| 2114 budget.addPriceToRecord(_price,_record) | |
| 2115 print _("End Test") | |
| 2116 | |
| 2117 def delete_control_space(self, text): | |
| 2118 text = self.delete_control(text) | |
| 2119 text = text.replace(" ", "") | |
| 2120 return text | |
| 2121 | |
| 2122 def delete_control(self, text): | |
| 2123 text = text.replace("\t", "") | |
| 2124 text = text.replace("\r", "") | |
| 2125 text = text.replace("\n", "") | |
| 2126 return text |
