diff --git a/src/ifccsv/ifccsv.py b/src/ifccsv/ifccsv.py index de505d676a..04d18727e2 100755 --- a/src/ifccsv/ifccsv.py +++ b/src/ifccsv/ifccsv.py @@ -247,10 +247,11 @@ class IfcCsv: if not self.results: return if sort: + def natural_sort(value): if isinstance(value, str): convert = lambda text: int(text) if text.isdigit() else text.lower() - return [convert(c) for c in re.split('([0-9]+)', value)] + return [convert(c) for c in re.split("([0-9]+)", value)] return value # Sort least important keys first, then more important keys. @@ -370,7 +371,9 @@ class IfcCsv: results.update([p.Name for p in element.Quantities]) return ["{}.{}".format(pset_qto_name, n) for n in results] - def Import(self, ifc_file, table, attributes=None, delimiter=",", null="-", empty="", bool_true="YES", bool_false="NO"): + def Import( + self, ifc_file, table, attributes=None, delimiter=",", null="-", empty="", bool_true="YES", bool_false="NO" + ): ext = table.split(".")[-1].lower() if ext == "csv": @@ -380,7 +383,9 @@ class IfcCsv: elif ext == "xlsx": self.import_xlsx(ifc_file, table, attributes, null, empty, bool_true, bool_false) - def import_csv(self, ifc_file, table, attributes=None, delimiter=",", null="-", empty="", bool_true="YES", bool_false="NO"): + def import_csv( + self, ifc_file, table, attributes=None, delimiter=",", null="-", empty="", bool_true="YES", bool_false="NO" + ): with open(table, newline="", encoding="utf-8") as f: reader = csv.reader(f, delimiter=delimiter) headers = [] @@ -441,7 +446,10 @@ if __name__ == "__main__": parser.add_argument("-f", "--format", type=str, default="csv", help="The format, chosen from csv, ods, or xlsx") parser.add_argument("-d", "--delimiter", type=str, default=",", help="The delimiter in CSV. Defaults to a comma.") parser.add_argument( - "-n", "--null", type=str, default="-", help="How to represent null values. Defaults to a hyphen." + "-n", "--null", type=str, default="N/A", help="How to represent null values. Defaults to N/A." + ) + parser.add_argument( + "-e", "--empty", type=str, default="-", help="How to represent empty strings. Defaults to a hyphen." ) parser.add_argument("--bool_true", type=str, default="YES", help="How to represent true values. Defaults to YES.") parser.add_argument("--bool_false", type=str, default="NO", help="How to represent false values. Defaults to NO.") @@ -452,9 +460,7 @@ if __name__ == "__main__": nargs="+", help="Specify attributes that are part of the extract, using the IfcQuery syntax such as 'class', 'Name' or 'Pset_Foo.Bar'", ) - parser.add_argument( - "--headers", nargs="+", help="Specify human readable headers that correlate to each attribute." - ) + parser.add_argument("--headers", nargs="+", help="Specify human readable headers that correlate to each attribute.") parser.add_argument("--sort", nargs="+", help="Specify one or more attributes to sort by.") parser.add_argument("--order", nargs="+", help="Choose the sort order from ASC or DESC for each sorted attribute.") parser.add_argument("--export", action="store_true", help="Export from IFC to the desired format.") @@ -477,6 +483,7 @@ if __name__ == "__main__": format=args.format, delimiter=args.delimiter, null=args.null, + empty=args.empty, bool_true=args.bool_true, bool_false=args.bool_false, sort=sort, @@ -485,6 +492,11 @@ if __name__ == "__main__": ifc_csv = IfcCsv() ifc_file = ifcopenshell.open(args.ifc) ifc_csv.Import( - ifc_file, args.spreadsheet, attributes=args.attributes or [], delimiter=args.delimiter, null=args.null + ifc_file, + args.spreadsheet, + attributes=args.attributes or [], + delimiter=args.delimiter, + null=args.null, + empty=args.empty, ) ifc_file.write(args.ifc) diff --git a/src/ifcopenshell-python/docs/ifccsv.rst b/src/ifcopenshell-python/docs/ifccsv.rst index 54ef0a4b6a..154a0fcae5 100644 --- a/src/ifcopenshell-python/docs/ifccsv.rst +++ b/src/ifcopenshell-python/docs/ifccsv.rst @@ -66,8 +66,8 @@ utility: :: $ python -m ifccsv -h - usage: ifccsv.py [-h] -i IFC [-s SPREADSHEET] [-f FORMAT] [-d DELIMITER] [-n NULL] [--bool_true BOOL_TRUE] [--bool_false BOOL_FALSE] [-q QUERY] [-a ATTRIBUTES [ATTRIBUTES ...]] [--headers HEADERS [HEADERS ...]] [--sort SORT [SORT ...]] - [--order ORDER [ORDER ...]] [--export] [--import] + usage: ifccsv.py [-h] -i IFC [-s SPREADSHEET] [-f FORMAT] [-d DELIMITER] [-n NULL] [-e EMPTY] [--bool_true BOOL_TRUE] [--bool_false BOOL_FALSE] [-q QUERY] [-a ATTRIBUTES [ATTRIBUTES ...]] [--headers HEADERS [HEADERS ...]] + [--sort SORT [SORT ...]] [--order ORDER [ORDER ...]] [--export] [--import] Exports IFC data to and from CSV @@ -80,7 +80,9 @@ utility: The format, chosen from csv, ods, or xlsx -d DELIMITER, --delimiter DELIMITER The delimiter in CSV. Defaults to a comma. - -n NULL, --null NULL How to represent null values. Defaults to a hyphen. + -n NULL, --null NULL How to represent null values. Defaults to N/A. + -e EMPTY, --empty EMPTY + How to represent empty strings. Defaults to a hyphen. --bool_true BOOL_TRUE How to represent true values. Defaults to YES. --bool_false BOOL_FALSE