Is there any way to export all the component event scripts? I would like to be able to see all event code in one place so I know what can be safely re-factored. I’m hoping to end up with text files, but I don’t mind writing an XML decoder or a python script to get there.
To my understanding, no, your still not able to do this. I found another thread in the forums related to this where it was suggested to do a copy and paste. I don’t see any other alternative to this.
No, unfortunately there isn’t a method to extract just the component event handlers. You can select all of the components inside of the window and press Ctrl-C to copy. If you paste it in a text editor you can see the underlying XML. You might be able to write something to get the event handlers if you can understand the XML.
Is there any way to get that XML for all windows at once? If I use any of the export options I get a ‘.proj’ file with XML CDATA. I presume it is just compressed, but what format does it use?
The .proj file itself is XML, but all of the project resources are Base64-encoded binary. In Ignition 7.3+, the format is binary, which can be transcoded into XML via the XMLSerializer.
I’m getting “java.lang.ClassNotFoundException: str” when trying to use the XMLDeserialiser.
It looks like that’s the Python ‘str’ class that it’s trying to find, which leads me to suspect some sort of problem with Jython, but this happens even within the designer environment so I’m not sure where to proceed from here.
This has nothing to do with Python’s ‘str’. How are you creating the XMLDeserializer? Where is this code running? Are you compiling against the SDK? If so, are you in the Designer?
I’m currently making this using the module SDK and running in within the designer.
Very basic test code to read from a manually extracted and base64-decoded chunk of binary data from my ‘.proj’ file:
import com.inductiveautomation.ignition.common.xmlserialization.deserialization.XMLDeserializer;
import com.inductiveautomation.ignition.common.xmlserialization.serialization.XMLSerializer;
import java.io.*;
public class Decoder {
public static String run() throws Exception {
XMLDeserializer xml = new XMLDeserializer();
return xml.transcodeToXML(new FileInputStream("/tmp/foo.bin"), new XMLSerializer());
}
}
Registered in the designer like this:
public class DesignerHook extends AbstractDesignerModuleHook {
public void initializeScriptManager(ScriptManager manager) {
manager.addScriptModule("decoder", Decoder.class);
}
}
The project I’m working with is open in the designer, so I can probably simplify this by working with the Project object directly. I was originally going to write a standalone script to convert a .proj file into something human readable, but it looks like the binary serialisation system won’t allow that.
If I use context.getProject().toXML() it produces the same as the exported .proj file. How can I serialise resources as plain XML (i.e. no binary data)? The copy/paste system uses plain XML- that’s more what I’m looking for.
I tried this, but it produces a blank file:
XMLSerializer xml = this.context.createSerializer();
for (ProjectResource resource : this.context.getProject().getResources()) {
xml.addObject(resource);
}
xml.serializeXML(new FileOutputStream("/tmp/ignition.xml"), "UTF-8");
Also, how can I obtain the data for a ProjectResource without locking (or unlocking??) the resource for other developers? Similarly, can I still read the data for a resource that is locked by another developer?
Thanks.
EDIT: The output file is blank because I was ignoring exceptions. I’m getting “com.inductiveautomation.ignition.common.xmlserialization.SerializationException: Unable to create clean copy of class com.inductiveautomation.ignition.common.project.ProjectResource”. Any idea what I’m doing wrong?
Ok, so once you get a Project object via Project.fromXML(), you can loop through it’s ProjectResources.
Each of ProjectResource has a byte[] of data on it. This will be serialized data (binary or gzipped, base64’ed xml - the XMLDeserializer will auto-detect between these anyhow).
If you want to inspect the project resource in memory, create an XMLDeserializer and call deserialize(byte[]) on the ProjectResource.getData(), and then look at the root objects on the deserialization context.
If you want to inspect the project resource as xml, create an XMLDeserializer and an XMLSerializer, and call XMLDeserializer.transcodeToXML()
To get the actual data for a window, a second deserialization step must be performed on the result of getSerializedCode(). Unfortunately the module SDK doesn’t expose any types with getSerializedCode(), making this somewhat tricky.
Is there a chance this will ever be an official way to import and export data?
It will give so many advantages, like version control to keep track of GUI modifications (not only when something changed, but also who changed what exactly). Or grepping for certain functions or variable names or UDT types (which will work a lot faster than text search through SQLite BLOBs).
In my quest to do ALL my script editing in Kate, I am copying & save all scripts to text files. However, I can’t do that with anything in Component Scripting windows, below is an example:
But I have found no way to copy all lines of a script.
I’m on 7.9.12
My dirty work-around is to maximize window, screen-capture to GIF (1 pg at a time), upload to https://www.newocr.com/, paste into Kate, reformat & fixup OCR mistakes, etc. I’m about 15 scripts in and got 30+ to go, hence the question. Please have pity on me
P.S. I understand this is an old thread but I didn’t see anything more recent.
The solution hasn’t really changed since this thread was written, and likely won’t, at least for Vision.
If you’re able to migrate to 8.0 (and change visualization to Perspective), every view is just a plain-text JSON file, including all scripts :). Project scripts and webdev endpoints are also .py files on disk, and in a future release we’re hoping to make client & gateway events (and the new session events added by Perspective) into text resources as well.