imagedata.archives.abstractarchive — imagedata 1.3.0 documentation

# Source code for imagedata.archives.abstractarchive

    """Abstract class for image archives.

    Defines generic functions.
    """

    # Copyright (c) 2018 Erling Andersen, Haukeland University Hospital, Bergen, Norway

    from abc import ABCMeta, abstractmethod

    class NoOtherInstance(Exception):
        pass

    class WriteMultipleArchives(Exception):
        pass

    class AbstractArchive(object, metaclass=ABCMeta):
        """Abstract base class definition for imagedata archive plugins.
        Plugins must be a subclass of AbstractPlugin and
        must define the atttributes set in __init__() and
        the following methods:

        __init__() method
        use_query() method
        getnames() method
        basename() method
        open() method
        getmembers() method
        to_localfile() method
        read() method
        write() method
        """

        def __init__(self, name, description, authors, version, url, _mimetypes):
            object.__init__(self)
            self.__name = name
            self.__description = description
            self.__authors = authors
            self.__version = version
            self.__url = url
            self.__mimetypes = _mimetypes
            self.__transport = None
            """Return an archive object for filehandle."""

        @abstractmethod
        def use_query(self):
            """Do the plugin need the ?query part of the url?"""
            pass

        @property
        def name(self):
            """Plugin name

            Single word string describing the image format.
            Typical names: dicom, nifti, itk.
            """
            return self.__name

        @property
        def description(self):
            """Plugin description

            Single line string describing the image format.
            """
            return self.__description

        @property
        def authors(self):
            """Plugin authors

            Multi-line string naming the author(s) of the plugin.
            """
            return self.__authors

        @property
        def version(self):
            """Plugin version

            String giving the plugin version.
            Version scheme: 1.0.0
            """
            return self.__version

        @property
        def url(self):
            """Plugin URL

            URL string to the site of the plugin or the author(s).
            """
            return self.__url

        @property
        def transport(self):
            """Underlying transport plugin
            """
            return self.__transport

        @property
        def mimetypes(self):
            """MIME types supporte by this plugin.

            List of strings.
            """
            return self.__mimetypes

        @abstractmethod
        def getnames(self, files=None):
            """Get name list of the members.

            Returns:
                The members as a list of their names.
                    It has the same order as the members of the archive.
            """
            pass

        @abstractmethod
        def basename(self, filehandle):
            """Basename of file.

            Examples:
                if archive.basename(filehandle) == "DICOMDIR":

            Args:
                filehandle: reference to member object
            """
            pass

        @abstractmethod
        def open(self, filehandle, mode='rb'):
            """Open file.

            Returns:
                 a member object for member given its filehandle.
            """
            pass

        @abstractmethod
        def getmembers(self, files=None):
            """Get the members of the archive.

            Returns:
                The members of the archive as an OrderedDict of member objects.
                    The keys are the member names as given by getnames().
            """
            pass

        @abstractmethod
        def to_localfile(self, filehandle):
            """Access a member object through a local file.
            """
            pass

        @abstractmethod
        def add_localfile(self, local_file, filename):
            """Add a local file to the archive.

            Args:
                local_file: named local file
                filename: filename in the archive
            Returns:
                filehandle to file in the archive
            """
            pass

        @abstractmethod
        def writedata(self, filename, data):
            """Write data to a named file in the archive.

            Args:
                filename: named file in the archive
                data: data to write
            """
            pass

        @abstractmethod
        def close(self):
            """Close archive.
            """
            pass

        @abstractmethod
        def is_file(self, filehandle):
            """Determine whether the named file is a single file.
            """
            pass

        @abstractmethod
        def __enter__(self):
            """Enter context manager.
            """
            pass

        @abstractmethod
        def __exit__(self, exc_type, exc_val, exc_tb):
            """Leave context manager, cleaning up any open files.
            """
            pass

    # class ArchiveCollection(AbstractArchive):
    #     """A collection of one or more archives, providing the same interface as
    #     a single archive.
    #     """
    #
    # import os.path
    # import collections
    # import logging
    # import mimetypes
    # import urllib.parse
    # import imagedata.archives
    # import imagedata.transports
    #
    #     name = "archivecollection"
    #     description = "A collection of one or more archives"
    #     authors = "Erling Andersen"
    #     version = "1.0.0"
    #     url = "www.helse-bergen.no"
    #     mimetypes = None
    #
    #     def __init__(self, transport=None, url=None, mode="r", read_directory_only=True,
    #                  opts=None):
    #         super(ArchiveCollection, self).__init__(self.name, self.description,
    #                                                 self.authors, self.version, self.url,
    #                                                 self.mimetypes)
    #
    #         if opts is None:
    #             opts = {}
    #         # Handle both single url, a url tuple, and a url list
    #         if isinstance(urls, list):
    #             self.__urls = urls
    #         elif isinstance(urls, tuple):
    #             self.__urls = list(urls)
    #         else:
    #             self.__urls = [urls]
    #         if len(self.__urls) < 1:
    #             raise ValueError("No URL(s) where given")
    #
    #         self.__archives = []
    #         # Collect list of archives
    #         for url in self.__urls:
    #             logging.debug("ArchiveCollection: url: '{}'".format(url))
    #             urldict = urllib.parse.urlsplit(url, scheme="file")
    #             # dirname = os.path.dirname(urldict.path)
    #             basename = os.path.basename(urldict.path)
    #             logging.debug("ArchiveCollection: transport root: '{}'".format(os.curdir))
    #             # transport = imagedata.transports.Transport(
    #             #     urldict.scheme, root=os.curdir)
    #             logging.debug("ArchiveCollection: archive url: '{}'".format(url))
    #             archive = imagedata.archives.find_mimetype_plugin(
    #                 mimetypes.guess_type(basename)[0],
    #                 # transport,
    #                 url,
    #                 mode=mode)
    #             self.__archives.append(archive)
    #
    #         # Construct the member dict (archive,filehandle) for all archives
    #         self.__memberlist = collections.OrderedDict()
    #         for archive in self.__archives:
    #             logging.debug("ArchiveCollection: construct archive {}".format(archive))
    #             filedict = archive.getnames()
    #             logging.debug("ArchiveCollection: construct filelist {} {}".format(type(filedict), filedict))
    #             for key in filedict.keys():
    #                 self.__memberlist[key] = (archive, filedict[key])
    #
    #     def getnames(self, files=None):
    #         """Return the members as a list of their names.
    #         It has the same order as the members of the archive.
    #
    #         Chain the references (archive,filehandle) from each archive
    #         """
    #         return self.__memberlist
    #
    #     def basename(self, filehandle):
    #         """Basename of file.
    #
    #         Typical use:
    #             if archive.basename(filehandle) == "DICOMDIR":
    #
    #         Input:
    #         - filehandle: reference to member object
    #         """
    #         archive, name = filehandle
    #         return archive.basename(name)
    #
    #     def getmember(self, filehandle):
    #         """Return the members of the archive as an OrderedDict of member objects.
    #         The keys are the member names as given by getnames().
    #         """
    #         archive, fh = filehandle
    #         return archive.getmember(fh)
    #
    #     def getmembers(self, files=None):
    #         """Return the members of the archive as a list of member objects.
    #         The list has the same order as the members in the archive.
    #         """
    #         return self.__memberlist
    #
    #     def to_localfile(self, filehandle):
    #         """Access a member object through a local file.
    #         """
    #         archive, name = filehandle
    #         return archive.to_localfile(name)
    #
    #     def writedata(self, filename, data):
    #         """Write data to a named file in the archive.
    #         Input:
    #         - filename: named file in the archive
    #         - data: data to write
    #         """
    #         if len(self.__archives) > 1:
    #             raise WriteMultipleArchives("Cannot write data to multiple archives")
    #         self.__archives[0].writedata(filename, data)
    #
    #     def close(self):
    #         """Close archive.
    #         """
    #         for archive in self.__archives:
    #             archive.close()
    #
    #     def __enter__(self):
    #         """Enter context manager.
    #         """
    #         return self
    #
    #     def __exit__(self):
    #         """Leave context manager, cleaning up any open files.
    #         """
    #         self.close()
    #
    #     @abstractmethod
    #     def use_query(self):
    #         pass
    #
    #     @abstractmethod
    #     def open(self, filehandle, mode='rb'):
    #         pass
    #
    #     @abstractmethod
    #     def add_localfile(self, local_file, filename):
    #         pass
    #
    #     @abstractmethod
    #     def is_file(self):
    #         pass