Tools: More options to fcinfo tool
This commit is contained in:
156
src/Tools/fcinfo
156
src/Tools/fcinfo
@@ -27,44 +27,74 @@
|
||||
__title__="FreeCAD File info utility"
|
||||
__author__ = "Yorik van Havre"
|
||||
__url__ = ["http://www.freecadweb.org"]
|
||||
__doc__ = '''This utility prints information about a given FreeCAD file (*.FCStd)
|
||||
on screen, including document properties, number of included objects
|
||||
and object sizes.
|
||||
__doc__ = '''
|
||||
This utility prints information about a given FreeCAD file (*.FCStd)
|
||||
on screen, including document properties, number of included objects,
|
||||
object sizes and properties and values
|
||||
|
||||
It can be used as a textconv tool for git diff by configuring your git folder as follows:
|
||||
1) add to .gitattributes:
|
||||
*.fcstd diff=fcinfo
|
||||
2) add to .git/config (or .gitconfig for user-wide):
|
||||
[diff "fcinfo"]
|
||||
textconv = /path/to/fcinfo
|
||||
Usage:
|
||||
|
||||
Usage: fcinfo myfile.FCStd'''
|
||||
fcinfo [options] myfile.FCStd
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help: Prints this help text
|
||||
-s, --short: Do not print all the properties contents of objects
|
||||
-vs --veryshort: Only prints the document info, not objects info
|
||||
|
||||
Git usage:
|
||||
|
||||
This script can be used as a textconv tool for git diff by
|
||||
configuring your git folder as follows:
|
||||
|
||||
1) add to .gitattributes:
|
||||
*.fcstd diff=fcinfo
|
||||
|
||||
2) add to .git/config (or ~/.gitconfig for user-wide):
|
||||
[diff "fcinfo"]
|
||||
textconv = /path/to/fcinfo
|
||||
|
||||
With this, when committing a .FCStd file with Git,
|
||||
'git diff' will show you the difference between the two
|
||||
texts obtained by fcinfo
|
||||
|
||||
'''
|
||||
|
||||
|
||||
import sys, zipfile, xml.sax, os, hashlib
|
||||
|
||||
|
||||
|
||||
|
||||
class FreeCADFileHandler(xml.sax.ContentHandler):
|
||||
|
||||
def __init__(self,zfile):
|
||||
|
||||
|
||||
def __init__(self, zfile, short = 0): # short 0=normal, 1=short, 2=veryshort
|
||||
|
||||
xml.sax.ContentHandler.__init__(self)
|
||||
self.zfile = zfile
|
||||
self.obj = None
|
||||
self.prop = None
|
||||
self.count = "0"
|
||||
self.contents = {}
|
||||
self.short = short
|
||||
|
||||
def startElement(self, tag, attributes):
|
||||
|
||||
if tag == "Document":
|
||||
self.obj = tag
|
||||
self.contents = {}
|
||||
self.contents["ProgramVersion"] = attributes["ProgramVersion"]
|
||||
self.contents["FileVersion"] = attributes["FileVersion"]
|
||||
|
||||
elif tag == "Object":
|
||||
if not (attributes["name"] in self.contents):
|
||||
self.contents[attributes["name"]] = ""
|
||||
if "type" in attributes:
|
||||
self.contents[attributes["name"]] += attributes["type"]
|
||||
self.obj = attributes["name"]
|
||||
if ("name" in attributes):
|
||||
name = self.clean(attributes["name"])
|
||||
self.obj = name
|
||||
if ("type" in attributes):
|
||||
self.contents[name] = attributes["type"]
|
||||
|
||||
elif tag == "Part":
|
||||
if self.obj:
|
||||
s = self.zfile.read(attributes["file"]).__sizeof__()
|
||||
@@ -74,54 +104,98 @@ class FreeCADFileHandler(xml.sax.ContentHandler):
|
||||
s = str(s/1048576)+"M"
|
||||
else:
|
||||
s = str(s/1024)+"K"
|
||||
|
||||
self.contents[self.obj] += " (" + s + ")"
|
||||
|
||||
elif tag == "Property":
|
||||
self.prop = attributes["name"]
|
||||
elif tag in ["String","Uuid"]:
|
||||
if (self.obj == "Document") and self.prop:
|
||||
self.contents[self.prop] = attributes["value"]
|
||||
|
||||
elif tag in ["String","Uuid","Float","Integer","Bool","Link"]:
|
||||
if self.prop and ("value" in attributes):
|
||||
if self.obj == "Document":
|
||||
self.contents[self.prop] = attributes["value"]
|
||||
elif self.short == 0:
|
||||
if tag == "Float":
|
||||
self.contents[self.obj+"00000000::"+self.prop] = str(float(attributes["value"]))
|
||||
else:
|
||||
self.contents[self.obj+"00000000::"+self.prop] = attributes["value"]
|
||||
|
||||
elif tag == "Objects":
|
||||
self.count = attributes["Count"]
|
||||
self.obj = None
|
||||
|
||||
# Print all the contents of the document properties
|
||||
items = self.contents.items()
|
||||
items.sort()
|
||||
for key,val in items:
|
||||
print (" " + key.encode("utf-8").strip() + " : " + val.encode("utf-8").strip())
|
||||
for key,value in items:
|
||||
key = self.clean(key)
|
||||
value = self.clean(value)
|
||||
print(" " + key + " : " + value)
|
||||
print(" Objects: ("+self.count+")")
|
||||
self.contents = {}
|
||||
print (" Objects: ("+self.count+")")
|
||||
|
||||
def endElement(self,tag):
|
||||
if tag == "Document":
|
||||
if self.contents:
|
||||
items = self.contents.items()
|
||||
items.sort()
|
||||
for key,val in items:
|
||||
print (" " + key + " : " + val)
|
||||
|
||||
def endElement(self, tag):
|
||||
|
||||
if (tag == "Document") and (self.short != 2):
|
||||
items = self.contents.items()
|
||||
items.sort()
|
||||
for key,value in items:
|
||||
key = self.clean(key)
|
||||
if "00000000::" in key:
|
||||
key = " "+key.split("00000000::")[1]
|
||||
value = self.clean(value)
|
||||
if value:
|
||||
print(" " + key + " : " + value)
|
||||
|
||||
def clean(self,value):
|
||||
|
||||
value = value.strip()
|
||||
if sys.version_info.major < 3:
|
||||
value = value.encode("utf8")
|
||||
return value
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print __doc__
|
||||
sys.exit(1)
|
||||
if len(sys.argv) < 2:
|
||||
print(__doc__)
|
||||
sys.exit()
|
||||
|
||||
zfile=zipfile.ZipFile(sys.argv[1])
|
||||
files=zfile.namelist()
|
||||
if ("-h" in sys.argv[1:]) or ("--help" in sys.argv[1:]):
|
||||
print(__doc__)
|
||||
sys.exit()
|
||||
|
||||
if files[0] != "Document.xml":
|
||||
if not sys.argv[-1].lower().endswith(".fcstd"):
|
||||
print(__doc__)
|
||||
sys.exit()
|
||||
|
||||
if ("-vs" in sys.argv[1:]) or ("--veryshort" in sys.argv[1:]):
|
||||
short = 2
|
||||
elif ("-s" in sys.argv[1:]) or ("--short" in sys.argv[1:]):
|
||||
short = 1
|
||||
else:
|
||||
short = 0
|
||||
|
||||
if ("-g" in sys.argv[1:]) or ("--gui" in sys.argv[1:]):
|
||||
gui = True
|
||||
else:
|
||||
gui = False
|
||||
|
||||
zfile = zipfile.ZipFile(sys.argv[-1])
|
||||
|
||||
if not "Document.xml" in zfile.namelist():
|
||||
sys.exit(1)
|
||||
doc = zfile.read("Document.xml")
|
||||
s = os.path.getsize(sys.argv[1])
|
||||
s = os.path.getsize(sys.argv[-1])
|
||||
if s < 1024:
|
||||
s = str(s)+"B"
|
||||
elif s > 1048576:
|
||||
s = str(s/1048576)+"M"
|
||||
else:
|
||||
s = str(s/1024)+"K"
|
||||
print("Document: "+sys.argv[1]+" ("+s+")")
|
||||
print (" SHA1: "+str(hashlib.sha1(open(sys.argv[1],'rb').read()).hexdigest()))
|
||||
xml.sax.parseString(doc,FreeCADFileHandler(zfile))
|
||||
|
||||
print("Document: "+sys.argv[-1]+" ("+s+")")
|
||||
print(" SHA1: "+str(hashlib.sha1(open(sys.argv[-1],'rb').read()).hexdigest()))
|
||||
xml.sax.parseString(doc,FreeCADFileHandler(zfile,short))
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user