コード例 #1
0
ファイル: organizer.py プロジェクト: diffpy/diffpy.pdfgui
    def save(self, z, subpath):
        """save data from a zipped project file

        z -- zipped project file
        subpath -- path to its own storage within project file
        """
        # strucs and datasets
        from diffpy.pdfgui.utils import quote_plain
        for struc in self.strucs:
            struc.save(z, subpath + 'structure/' + quote_plain(struc.name) + '/')
        for dataset in self.datasets:
            dataset.save(z, subpath + 'dataset/' + quote_plain(dataset.name) + '/')
        for calc in self.calcs:
            calc.save(z, subpath + 'calculation/' + quote_plain(calc.name) + '/')
        return
コード例 #2
0
    def save(self, z, subpath):
        """save data from a zipped project file

        z -- zipped project file
        subpath -- path to its own storage within project file
        """
        # strucs and datasets
        from diffpy.pdfgui.utils import quote_plain
        for struc in self.strucs:
            struc.save(z,
                       subpath + 'structure/' + quote_plain(struc.name) + '/')
        for dataset in self.datasets:
            dataset.save(
                z, subpath + 'dataset/' + quote_plain(dataset.name) + '/')
        for calc in self.calcs:
            calc.save(z,
                      subpath + 'calculation/' + quote_plain(calc.name) + '/')
        return
コード例 #3
0
    def save(self, projfile=None):
        """Save project to projfile, default projfile is self.projfile

        This method first writes to a temporary file and only when
        successful, it overwrites projfile with the temporary file content.
        These steps prevent corruption of existing projects should
        something go wrong in the middle of save.  As an added benefit,
        all permissions and ownership flags in an existing projfile
        are preserved.
        """
        if projfile is not None:
            self.projfile = projfile

        # self.projfile is unset here only due to a bug.
        assert self.projfile is not None

        import zipfile
        import shutil
        from cPickle import PickleError
        import tempfile
        from diffpy.pdfgui.utils import quote_plain

        projbase = os.path.basename(self.projfile)
        projName = os.path.splitext(projbase)[0]
        # prepare to write
        fitnames = []
        z = None
        tmpfilename = None
        try:
            tmpfd, tmpfilename = tempfile.mkstemp()
            os.close(tmpfd)
            z = zipfile.ZipFile(tmpfilename, 'w', zipfile.ZIP_DEFLATED)
            # fits also contain calculations
            for fit in self.fits:
                name = fit.name
                fit.save(z, projName + '/' + quote_plain(fit.name) + '/')
                fitnames.append(name)
            if self.journal:
                z.writestr(projName + '/journal', self.journal.encode('utf8'))
            ftxt = '\n'.join(fitnames)
            z.writestr(projName + '/fits', ftxt.encode('utf8'))
            z.close()
            shutil.copyfile(tmpfilename, self.projfile)

        except (IOError, PickleError):
            emsg = "Error when writing to %s" % self.projfile
            raise ControlFileError(emsg)

        finally:
            if z is not None:
                z.close()
            if tmpfilename is not None:
                os.remove(tmpfilename)

        return
コード例 #4
0
    def load(self, projfile):
        """load project from projfile.

        projfile -- a zip file of everything
        """
        def _nameParser(namelist):
            """parse the zipfile name list to get a file tree"""
            fileTree = {}
            for name in namelist:
                subs = name.split('/')
                pathDict = fileTree
                for x in subs[:-1]:
                    # if no node has been created
                    if not pathDict.has_key(x):
                        pathDict[x] = {}
                    pathDict = pathDict[x]

                # check if the entry is a leaf(file, not folder)
                if subs[-1] != '':
                    pathDict[subs[-1]] = None
            return fileTree

        self.projfile = projfile
        organizations = []
        import zipfile
        from cPickle import PickleError
        from diffpy.pdfgui.utils import quote_plain

        # IOError can be raised when reading invalid zipfile
        # check for file existence here.
        if not os.path.isfile(projfile):
            emsg = "Project file %s does not exist." % projfile
            raise ControlFileError(emsg)

        emsg_invalid_file = "Invalid or corrupted project %s." % projfile
        z = None
        try:
            z = zipfile.ZipFile(projfile, 'r')
            z.fileTree = _nameParser(z.namelist())

            if len(z.fileTree) == 0:
                raise ControlFileError(emsg_invalid_file)
            # The first layer has only one folder
            rootDict = z.fileTree.values()[0]
            projName = z.fileTree.keys()[0]

            if rootDict.has_key('journal'):
                self.journal = z.read(projName + '/journal').decode('utf8')

            # all the fitting and calculations
            #NOTE: It doesn't hurt to keep backward compatibility
            # old test project may not have file 'fits'
            if rootDict.has_key('fits'):
                ftxt = z.read(projName + '/fits').decode('utf8')
                fitnames = ftxt.splitlines()
            else:
                fitnames = [
                    x for x in rootDict.keys() if rootDict[x] is not None
                ]

            for name in fitnames:
                if not name:  # empty string
                    continue
                fit = Fitting(name)
                # fitting name stored in rootDict should be quoted
                rdname = quote_plain(name)
                # but let's also handle old project files
                if rdname not in rootDict:
                    rdname = name
                if rootDict.has_key(rdname):
                    org = fit.load(z, projName + '/' + rdname + '/')
                else:
                    # it's simply a blank fitting, has no info in proj file yet
                    org = fit.organization()
                organizations.append(org)
                self.add(fit)

        except (IOError, zipfile.error, PickleError):
            raise ControlFileError(emsg_invalid_file)

        # close input file if opened
        finally:
            if z: z.close()

        return organizations