def addFilesToCombineArchive(archive_path, file_names, entry_locations, file_formats, master_attributes, out_archive_path): """ Add multiple files to an existing COMBINE archive on disk and save the result as a new archive. :param archive_path: The path to the archive. :param file_names: List of extra files to add. :param entry_locations: List of destination locations for the files in the output archive. :param file_format: List of formats for the resp. files. :param master_attributes: List of true/false values for the resp. master attributes of the files. :param out_archive_path: The path to the output archive. """ import tecombine, tempfile input_archive = tecombine.CombineArchive() if not input_archive.initializeFromArchive(archive_path): raise RuntimeError('Failed to initialize archive') tempfiles = [] output_archive = tecombine.CombineArchive() description = input_archive.getMetadataForLocation('.') if description: output_archive.addMetadata('.', description) for entry in (input_archive.getEntry(k) for k in range(input_archive.getNumEntries())): fhandle, fname = tempfile.mkstemp() tempfiles.append(fname) input_archive.extractEntry(entry.getLocation(), fname) if not entry.getLocation() in entry_locations: output_archive.addFile(fname, entry.getLocation(), entry.getFormat(), entry.getMaster()) # add the extra files for file_name, entry_location, file_format, master in zip( file_names, entry_locations, file_formats, master_attributes): output_archive.addFile(file_name, entry_location, file_format, master) # if the archive already exists, clear it if os.path.exists(out_archive_path): if os.path.isfile(out_archive_path): os.remove(out_archive_path) elif os.path.isdir(out_archive_path): raise RuntimeError( 'Tried to write archive to {}, which is a directory.'.format( out_archive_path)) else: raise RuntimeError( 'Could not write archive to {}.'.format(out_archive_path)) # write archive output_archive.writeToFile(out_archive_path) # delete temp files for t in tempfiles: os.remove(t)
def createCombineArchive(archive_path, file_names, entry_locations, file_formats, master_attributes, description=None): """ Create a new COMBINE archive containing the provided entries and locations. :param archive_path: The path to the archive. :param file_names: List of extra files to add. :param entry_locations: List of destination locations for the files in the output archive. :param file_format: List of formats for the resp. files. :param master_attributes: List of true/false values for the resp. master attributes of the files. :param out_archive_path: The path to the output archive. :param description: A libcombine description structure to be assigned to the combine archive, if desired. """ import tecombine output_archive = tecombine.CombineArchive() if description is not None: output_archive.addMetadata('.', description) # add the extra files for file_name, entry_location, file_format, master in zip(file_names, entry_locations, file_formats, master_attributes): output_archive.addFile(file_name, entry_location, file_format, master) # if the archive already exists, clear it if os.path.exists(archive_path): if os.path.isfile(archive_path): os.remove(archive_path) elif os.path.isdir(archive_path): raise RuntimeError('Tried to write archive to {}, which is a directory.'.format(archive_path)) else: raise RuntimeError('Could not write archive to {}.'.format(archive_path)) # write archive output_archive.writeToFile(archive_path)
def exportToCombine(self, outfile): """ Export Omex instance as combine archive. :param outfile: A path to the output file""" import phrasedml phrasedml.clearReferencedSBML() archive = libcombine.CombineArchive() description = libcombine.OmexDescription() description.setAbout(self.about) description.setDescription(self.description) time_now = libcombine.OmexDescription.getCurrentDateAndTime() description.setCreated(time_now) # TODO: pass in creator if self.creator is not None: creator = libcombine.VCard() creator.setFamilyName(self.creator['last_name']) creator.setGivenName(self.creator['first_name']) creator.setEmail(self.creator['email']) creator.setOrganization(self.creator['organization']) description.addCreator(creator) archive.addMetadata('.', description) # Write out to temporary files # TODO: can add content via strings now workingDir = tempfile.mkdtemp(suffix="_sedml") files = [] # Keep a list of files to remove def addAssetToArchive(asset, format): """ Helper to add asset of given format. """ fname = os.path.join(workingDir, os.path.normpath(asset.getLocation())) dname = os.path.dirname(fname) if not os.path.exists(dname): os.makedirs(dname) with open(fname, 'w') as f: files.append(fname) f.write(t.getContent()) archive.addFile(fname, asset.getLocation(), libcombine.KnownFormats.lookupFormat(format), asset.getMaster()) try: for t in self.getSedmlAssets(): addAssetToArchive(t, 'sedml') for t in self.getSbmlAssets(): addAssetToArchive(t, 'sbml') archive.writeToFile(outfile) finally: # put this in finally to make sure files are removed even under Exception for f in files: os.remove(f)
def fromFile(cls, path): """ Initialize from a combine archive. :param path: The path to the omex file """ if not os.path.isfile(path): raise IOError('No such file: {}'.format(path)) omex = libcombine.CombineArchive() if not omex.initializeFromArchive(path): raise IOError('Could not read COMBINE archive.') return inlineOmexImporter(omex)
def extractFileFromCombineArchive(archive_path, entry_location): """ Extract a single file from a COMBINE archive and return it as a string. """ import tecombine archive = tecombine.CombineArchive() if not archive.initializeFromArchive(archive_path): raise RuntimeError('Failed to initialize archive') try: entry = archive.getEntryByLocation(entry_location) except: raise RuntimeError('Could not find entry {}'.format(entry_location)) return archive.extractEntryToString(entry_location)
def fromFile(cls, path): """ Initialize from a combine archive. :param path: The path to the omex file """ if not os.path.isfile(path): raise IOError('No such file: {}'.format(path)) d = None if not os.access(os.getcwd(), os.W_OK): d = os.getcwd() os.chdir(tempfile.gettempdir()) omex = libcombine.CombineArchive() if not omex.initializeFromArchive(path): raise IOError('Could not read COMBINE archive.') importer = inlineOmexImporter(omex) # if d is not None: # os.chdir(d) return importer