Earlier, I wrote about using PureEdge Viewer, which is Windows software from IBM on Linux through Wine. This got me thinking, do we need to use Windows software. A quick look at the file and through Google and it’s easy to see that an *.xfdl file is a gzipped, base64 encoded xml file. So this is part one of what I hope to be a tutorial into designing software on Linux using python to open, read and write xfdl files in the same way as PureEdge Viewer. It gets annoying, to say the least, to need to open Windows in VirtualBox, or an actual install to read and edit *.xfdl files. The barriers I see at this preliminary point is to convert the xml to a readable image and then to make that editable where possible.
So, in this first part, we will do the very basic converting an *.xfdl file to an *.xml file. The code should be self explanatory but if there are questions, post them through comments and I’ll do my best at getting an answer to you.
#!/usr/bin/python """ IMPORTS """ from base64 import * import gzip, os, sys """ DEATH!!! """ # Standard way to die... def die(msg=None): if msg == None: msg = "Unknown error." print " [*] ERROR - %s" % msg sys.exit(1) """ CHECK FOR FILE """ # No file name, then we have nothing to do! if len(sys.argv) < 2: die("Did not specifiy a file name.") """ GET FILE """ # In a more advanced version, this will check the magic value of the file as well to # ensure it is an *.xfdl file. filename = sys.argv print "Using %s" % filename """ OPEN FILE AND SPLIT """ # Nothing tough, grab the magic number (1st line) and then store the rest as a variable. f = open(filename,'r').read() magic = f.splitlines() print "magic: %s" % magic data = f.split(magic) print "Got Data." del f """ BASE64 DECODE """ # First we decode the base64. f = open('temp.gz','wb') f.write(b64decode(data)) f.close() print "Base64 Decoded." """ GUNZIP DATA """ # Yes, I know this writing to a file and then deleting it is ugly but I have not found # a way to gunzip from a data stream. f = gzip.open('temp.gz','rb') gunzip_data = f.read() f.close() os.remove('temp.gz') print "Gunzipped Data." """ SAVE XML FILE """ # As this gets more advanced, it should be able to stay as a data stream for editing. filename = filename.split(".") + ".xml" f = open(filename,'wb') f.write(gunzip_data) f.close() print "Saved to temporary file '%s'" % filename
Nothing too involved here, simply open the file, strip out the first line and the decode the rest from base64 and gunzip that data to get the xml inside. In the next tutorial, we’ll look at the structure of that xml, once I actually understand it or find decent documentation on it!