Hello there,
I've created an application using perspective. I use it to record data into a database, and then download the recorded data. I'm able to download the data in a csv file, but I can only download one csv file / one table of the database at a time. Now what I'd like to do is to be able to download a zip file with csv files inside that corresponds to the tables of the database.
My question is: is it possible possible to do that with the command "system.perspective.download" (the one that I use to download the csv file for now) or I need to use a library ?
Thanks!
I happen to do something very similar:
import io
import zipfile
import jarray
def bytestring_to_jarray(bstring):
"""
Convert a Python byte string into a Java jarray
It's saner to consistently pass byte streams as either the Java-based jarray
or the Python-based bytearray, but don't mix and match. In particular, Ignition's
system.file.writeFile doesn't handle the Python types properly. But, Jython's
file.write doesn't handle the Java types properly.
I recommend sticking with the Java jarray as much as possible when working in Ignition.
This function provides a quick way to convert from the Python types to a Java jarray.
It should've been possible to just do jarray.array(bytearray(), 'b') but Jython seems
to have a bug.
If you need to convert back, it's as simple as bytearray(javaTypeData)
"""
return jarray.array(((x if x < 128 else (x - 256)) for x in bytearray(bstring)),'b')
def datasets_to_zip(filenames, datasets):
with io.BytesIO() as tmp_buff:
with zipfile.ZipFile(tmp_buff, 'w', zipfile.ZIP_DEFLATED) as zfile:
for file_name, dset in zip(filenames, datasets):
zfile.writestr(file_name, system.dataset.toCSV(dset))
tmp_buff.flush()
byte_result = bytestring_to_jarray(tmp_buff.getvalue())
return byte_result
In my case I was keeping the content in dataset form until the last moment, but you could pass a bunch of CSV strings around as easily as datasets and remove the toCSV
function.
I hope this helps.
Oh, and you might not need to convert from the Python bytearray to the Java jarray for system.perspective.download, but it's probably safer and I definitely had to before passing the data to system.file.writeFile. When I didn't have that conversion step, the file still wrote okay and looked almost right, but it was corrupted.
2 Likes
Thanks for you answer I'll see if I can solve my problem with it!
Just wanted to say a quick thank you to justin.brzozoski, I definitely would have taken me a long time to figure out to convert from the Python bytearray to the Java jarray.
Thank you very much for sharing!
1 Like
As an exercise to myself, I wanted to see if I could do the same thing with the standard Java library. It produces a jarray as output automatically, and should be more efficient in Jython since it is java-based.
import java.util.zip.ZipOutputStream as ZipOutputStream
import java.io.ByteArrayOutputStream as ByteArrayOutputStream
import java.util.zip.ZipEntry as ZipEntry
def datasets_to_zip(filenames, datasets):
byte_stream = ByteArrayOutputStream()
zip_stream = ZipOutputStream(byte_stream)
for file_name, dset in zip(filenames, datasets):
zip_stream.putNextEntry(ZipEntry(file_name))
zip_stream.write(system.dataset.toCSV(dset))
zip_stream.close()
return byte_stream.toByteArray()
7 Likes
That is working very well, thank you so much!
Thanks for sharing, this is really great