<file_sep>##############################################################################
# Copyright (c) 2003 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
##############################################################################
"""File-system representation interfaces

The interfaces defined here are used for file-system and file-system-like
representations of objects, such as file-system synchronization, FTP, PUT, and
WebDAV.

There are three issues we need to deal with:

* File system representation

    Every object is either a directory or a file.

* Properties

    There are two kinds of properties:

    - Data properties

      Data properties are handled directly by the object implementation.

    - Meta-data properties

      Meta data properties are handled via annotations.

* Completeness

    We must have a complete lossless data representation for file-system
    synchronization. This is achieved through serialization of:

    - All annotations (not just properties), and

    - Extra data.

Strategies for common access mechanisms:

* FTP

    For getting directory info (static) information:

        - Use Zope DublinCore to get modification times

        - Show as readable if we can access a read method.

        - Show as writable if we can access a write method.

* FTP and WebDAV

    - Treat as a directory if there is an adapter to :class:`IReadDirectory`.
      Treat as a file otherwise.

    - For creating objects:

        - Directories:

          Look for an :class:`IDirectoryFactory` adapter.

        - Files

          First look for a :class:`IFileFactory` adapter with a name that is
          the same as the extention (e.g. ".pt").

          Then look for an unnamed :class:`IFileFactory` adapter.


* File-system synchronization

      Because this must be lossless, we will use class-based adapters for this,
      but we want to make it as easy as possible to use other adapters as well.

      For reading, there must be a class adapter to :class:`IReadSync`.  We
      will then apply rules similar to those above.
"""
__docformat__ = 'restructuredtext'

# Pylint helpfully catches class definition errors, but they don't apply to
# interfaces.
# pylint:disable=inherit-non-class,no-method-argument,no-self-argument
# pylint:disable=unexpected-special-method-signature

from zope.interface import Interface
from zope.interface.common.mapping import IEnumerableMapping

from zope import schema


class IReadFile(Interface):
    """Provide read access to file data
    """

    def read():
        """Return the file data
        """

    def size():
        """Return the data length in bytes.
        """


class IWriteFile(Interface):
    """Provide write access to file data."""

    def write(data):
        """Update the file data
        """


class ICommonFileOperations(Interface):
    """Common file operations used by :class:`IRawReadFile` and
    :class:`IRawWriteFile`
    """

    mimeType = schema.ASCIILine(
        title="File MIME type",
        description=("Provided if it makes sense for this file data. "
                     "May be set prior to writing data to a file that "
                     "is writeable. It is an error to set this on a "
                     "file that is not writable."),
        readonly=True,
    )

    encoding = schema.Bool(
        title="The encoding that this file uses",
        description=("Provided if it makes sense for this file data. "
                     "May be set prior to writing data to a file that "
                     "is writeable. It is an error to set this on a "
                     "file that is not writable."),
        required=False,
    )

    closed = schema.Bool(
        title="Is the file closed?",
        required=True,
    )

    name = schema.TextLine(
        title="A representative file name",
        description=("Provided if it makes sense for this file data. "
                     "May be set prior to writing data to a file that "
                     "is writeable. It is an error to set this on a "
                     "file that is not writable."),
        required=False,
    )

    def seek(offset, whence=None):
        """Seek the file. See Python documentation for :class:`io.IOBase` for
        details.
        """

    def tell():
        """Return the file's current position.
        """

    def close():
        """Close the file. See Python documentation for :class:`io.IOBase` for
        details.
        """


class IRawReadFile(IReadFile, ICommonFileOperations):
    """Specialisation of IReadFile to make it act more like a Python file
    object.
    """

    def read(size=None):
        """Read at most ``size`` bytes of file data. If ``size`` is None,
        return all the file data.
        """

    def readline(size=None):
        """Read one entire line from the file. See Python documentation for
        :class:`io.IOBase` for details.
        """

    def readlines(sizehint=None):
        """Read until EOF using readline() and return a list containing the
        lines thus read. See Python documentation for :class:`io.IOBase` for
        details.
        """

    def __iter__():
        """Return an iterator for the file.

        Note that unlike a Python standard :class:`file`, this does not
        necessarily have to return data line-by-line if doing so is
        inefficient.
        """

    def next():
        """Iterator protocol. See Python documentation for :class:`io.IOBase`
        for details.
        """


class IRawWriteFile(IWriteFile, ICommonFileOperations):
    """Specialisation of IWriteFile to make it act more like a Python file
    object.
    """

    def write(data):
        """Write a chunk of data to the file. See Python documentation for
        :class:`io.RawIOBase` for details.
        """

    def writelines(sequence):
        """Write a sequence of strings to the file. See Python documentation
        for :class:`io.IOBase` for details.
        """

    def truncate(size):
        """Truncate the file. See Python documentation for :class:`io.IOBase`
        for details.
        """

    def flush():
        """Flush the file. See Python documentation for :class:`io.IOBase` for
        details.
        """


class IReadDirectory(IEnumerableMapping):
    """Objects that should be treated as directories for reading
    """


class IWriteDirectory(Interface):
    """Objects that should be treated as directories for writing
    """

    def __setitem__(name, object):  # pylint:disable=redefined-builtin
        """Add the given *object* to the directory under the given name."""

    def __delitem__(name):
        """Delete the named object from the directory."""


class IDirectoryFactory(Interface):
    """Factory for :class:`IReadDirectory`/:class:`IWriteDirectory` objects."""

    def __call__(name):  # pylint:disable=signature-differs
        """Create a directory

        where a directory is an object with adapters to IReadDirectory
        and IWriteDirectory.

        """


class IFileFactory(Interface):
    """Factory for :class:`IReadFile`/:class:`IWriteFile` objects."""

    def __call__(name, content_type, data):  # pylint:disable=signature-differs
        """Create a file

        where a file is an object with adapters to `IReadFile`
        and `IWriteFile`.

        The file `name`, content `type`, and `data` are provided to help
        create the object.
        """

# TODO: we will add additional interfaces for WebDAV and File-system
# synchronization.
<file_sep>pip>=9.0.0
sphinx>=1.4
setuptools>=31.0.1
repoze.sphinx.autointerface
sphinx_rtd_theme
<file_sep>.. include:: ../README.rst

Contents:

.. toctree::
   :maxdepth: 2

   api
   changelog

Development
===========

zope.filerepresentation is hosted at GitHub:

    https://github.com/zopefoundation/zope.filerepresentation/

Project URLs
============

* http://pypi.python.org/pypi/zope.filerepresentation       (PyPI entry and downloads)

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
<file_sep>====================================
 :mod:`zope.filerepresentation` API
====================================

.. automodule:: zope.filerepresentation.interfaces
<file_sep>=========
 Changes
=========

6.0 (unreleased)
================

- Add support for Python 3.11.

- Drop support for Python 2.7, 3.5, 3.6.

- Add support for Python 3.9, 3.10.


5.0.0 (2020-03-31)
==================

- Drop support for Python 3.4.

- Add support for Python 3.7 and 3.8.

- Ensure all objects have a consistent interface resolution order.
  See `issue 7 <https://github.com/zopefoundation/zope.filerepresentation/issues/7>`_.


4.2.0 (2017-08-10)
==================

- Add support for Python 3.5 and 3.6.

- Drop support for Python 2.6 and 3.3.


4.1.0 (2014-12-27)
==================

- Add support for PyPy3.

- Add support for Python 3.4.


4.0.2 (2013-03-08)
==================

- Add Trove classifiers indicating CPython and PyPy support.


4.0.1 (2013-02-11)
==================

- Add tox.ini to release.


4.0.0 (2013-02-11)
==================

- Add support for Python 3.3 and PyPy.

- Drop support for Python 2.4 / 2.5.

3.6.1 (2011-11-29)
==================

- Add undeclared ``zope.schema`` dependency.
- Remove ``zope.testing`` test dependency and ``test`` extra.

3.6.0 (2009-10-08)
==================

- Add ``IRawReadFile`` and ``IRawWriteFile`` interfaces. These extend
  ``IReadFile`` and ``IWritefile``, respectively, to behave pretty much like a
  standard Python file object with a few embellishments. This in turn allows
  efficient, iterator- based implementations of file reading and writing.

- Remove dependency on ``zope.container``: ``IReadDirectory`` and
  ``IWriteDirectory`` inherit only from interfaces defined in ``zope.interface``
  and ``zope.interface.common.mapping``.

3.5.0 (2009-01-31)
==================

- Change use of ``zope.app.container`` to ``zope.container``.

3.4.0 (2007-10-02)
==================

- Initial Zope-independent release.
<file_sep>=============================
 ``zope.filerepresentation``
=============================

.. image:: https://img.shields.io/pypi/v/zope.filerepresentation.svg
        :target: https://pypi.python.org/pypi/zope.filerepresentation/
        :alt: Latest release

.. image:: https://img.shields.io/pypi/pyversions/zope.filerepresentation.svg
        :target: https://pypi.org/project/zope.filerepresentation/
        :alt: Supported Python versions

.. image:: https://github.com/zopefoundation/zope.filerepresentation/actions/workflows/tests.yml/badge.svg
        :target: https://github.com/zopefoundation/zope.filerepresentation/actions/workflows/tests.yml

.. image:: https://coveralls.io/repos/github/zopefoundation/zope.filerepresentation/badge.svg?branch=master
        :target: https://coveralls.io/github/zopefoundation/zope.filerepresentation?branch=master

.. image:: https://readthedocs.org/projects/zopefilerepresentation/badge/?version=latest
        :target: https://zopefilerepresentation.readthedocs.io/en/latest/
        :alt: Documentation Status


The interfaces defined here are used for file-system and file-system-like
representations of objects, such as file-system synchronization, FTP, PUT, and
WebDAV.

Documentation is hosted at https://zopefilerepresentation.readthedocs.io/
