# Path: devicecloud/apibase.py
# class APIBase(object):
#     """Base class for all API Classes
# 
#     :type _conn: devicecloud.DeviceCloudConnection
#     """
#     def __init__(self, conn):
#         self._conn = conn
# 
# Path: devicecloud/conditions.py
# class Attribute(object):
#     """An attribute is a piece of data on which we may perform comparisons
# 
#     Comparisons performed to attributes will in turn generate new
#     :class:`.Comparison` instances.
#     """
# 
#     def __init__(self, name):
#         self.name = name
# 
#     def __str__(self):
#         return self.name
# 
#     def __gt__(self, value):
#         return Comparison(self, '>', value)
# 
#     def __lt__(self, value):
#         return Comparison(self, '<', value)
# 
#     def __eq__(self, value):
#         return Comparison(self, '=', value)
# 
#     def like(self, value):
#         return Comparison(self, ' like ', value)
# 
# class Expression(object):
#     r"""A condition is an evaluable filter
# 
#     Examples of conditions would include the following:
#     * fdType='file'
#     * fdName like 'sample%gas'
# 
#     Conditions may also be compound.  E.g.
#     * (fdType='file' and fdName like 'sample%gas')
# 
#     """
# 
#     def __init__(self):
#         pass
# 
#     def __and__(self, rhs):
#         return Combination(self, " and ", rhs)
# 
#     def __or__(self, rhs):
#         return Combination(self, " or ", rhs)
# 
#     and_ = __and__  # alternate syntax
#     or_ = __or__  # alternate syntax
# 
#     def compile(self):
#         raise NotImplementedError("Should be implemented in subclass")
# 
# Path: devicecloud/util.py
# def iso8601_to_dt(iso8601):
#     """Given an ISO8601 string as returned by Device Cloud, convert to a datetime object"""
#     # We could just use arrow.get() but that is more permissive than we actually want.
#     # Internal (but still public) to arrow is the actual parser where we can be
#     # a bit more specific
#     parser = DateTimeParser()
#     try:
#         arrow_dt = arrow.Arrow.fromdatetime(parser.parse_iso(iso8601))
#         return arrow_dt.to('utc').datetime
#     except ParserError as pe:
#         raise ValueError("Provided was not a valid ISO8601 string: %r" % pe)
# 
# def validate_type(input, *types):
#     """Raise TypeError if the type of ``input`` is one of the args
# 
#     If the input value is one of the types specified, just return
#     the input value.
# 
#     """
#     if not isinstance(input, types):
#         raise TypeError("Input expected to one of following types: %s" % (types, ))
#     return input


import base64
import six
from devicecloud.apibase import APIBase
from devicecloud.conditions import Attribute, Expression
from devicecloud.util import iso8601_to_dt, validate_type
        """

        condition = validate_type(condition, type(None), Expression, *six.string_types)
        page_size = validate_type(page_size, *six.integer_types)
        if condition is None:
            condition = (fd_path == "~/")  # home directory

        params = {"embed": "true", "condition": condition.compile()}
        for fd_json in self._conn.iter_json_pages("/ws/FileData", page_size=page_size, **params):
            yield FileDataObject.from_json(self, fd_json)

    def write_file(self, path, name, data, content_type=None, archive=False,
                   raw=False):
        """Write a file to the file data store at the given path

        :param str path: The path (directory) into which the file should be written.
        :param str name: The name of the file to be written.
        :param data: The binary data that should be written into the file.
        :type data: str (Python2) or bytes (Python3)
        :param content_type: The content type for the data being written to the file.  May
             be left unspecified.
        :type content_type: str or None
        :param bool archive: If true, history will be retained for various revisions of this
            file.  If this is not required, leave as false.
        :param bool raw: If true, skip the FileData XML headers (necessary for binary files)

        """
        path = validate_type(path, *six.string_types)
        name = validate_type(name, *six.string_types)
        data = validate_type(data, six.binary_type)

# Path: devicecloud/apibase.py
# class APIBase(object):
#     """Base class for all API Classes
# 
#     :type _conn: devicecloud.DeviceCloudConnection
#     """
#     def __init__(self, conn):
#         self._conn = conn
# 
# Path: devicecloud/conditions.py
# class Attribute(object):
#     """An attribute is a piece of data on which we may perform comparisons
# 
#     Comparisons performed to attributes will in turn generate new
#     :class:`.Comparison` instances.
#     """
# 
#     def __init__(self, name):
#         self.name = name
# 
#     def __str__(self):
#         return self.name
# 
#     def __gt__(self, value):
#         return Comparison(self, '>', value)
# 
#     def __lt__(self, value):
#         return Comparison(self, '<', value)
# 
#     def __eq__(self, value):
#         return Comparison(self, '=', value)
# 
#     def like(self, value):
#         return Comparison(self, ' like ', value)
# 
# class Expression(object):
#     r"""A condition is an evaluable filter
# 
#     Examples of conditions would include the following:
#     * fdType='file'
#     * fdName like 'sample%gas'
# 
#     Conditions may also be compound.  E.g.
#     * (fdType='file' and fdName like 'sample%gas')
# 
#     """
# 
#     def __init__(self):
#         pass
# 
#     def __and__(self, rhs):
#         return Combination(self, " and ", rhs)
# 
#     def __or__(self, rhs):
#         return Combination(self, " or ", rhs)
# 
#     and_ = __and__  # alternate syntax
#     or_ = __or__  # alternate syntax
# 
#     def compile(self):
#         raise NotImplementedError("Should be implemented in subclass")
# 
# Path: devicecloud/util.py
# def iso8601_to_dt(iso8601):
#     """Given an ISO8601 string as returned by Device Cloud, convert to a datetime object"""
#     # We could just use arrow.get() but that is more permissive than we actually want.
#     # Internal (but still public) to arrow is the actual parser where we can be
#     # a bit more specific
#     parser = DateTimeParser()
#     try:
#         arrow_dt = arrow.Arrow.fromdatetime(parser.parse_iso(iso8601))
#         return arrow_dt.to('utc').datetime
#     except ParserError as pe:
#         raise ValueError("Provided was not a valid ISO8601 string: %r" % pe)
# 
# def validate_type(input, *types):
#     """Raise TypeError if the type of ``input`` is one of the args
# 
#     If the input value is one of the types specified, just return
#     the input value.
# 
#     """
#     if not isinstance(input, types):
#         raise TypeError("Input expected to one of following types: %s" % (types, ))
#     return input


# Path: devicecloud/filedata.py
import base64
import six
from devicecloud.apibase import APIBase
from devicecloud.conditions import Attribute, Expression
from devicecloud.util import iso8601_to_dt, validate_type

        """

        condition = validate_type(condition, type(None), Expression, *six.string_types)
        page_size = validate_type(page_size, *six.integer_types)
        if condition is None:
            condition = (fd_path == "~/")  # home directory

        params = {"embed": "true", "condition": condition.compile()}
        for fd_json in self._conn.iter_json_pages("/ws/FileData", page_size=page_size, **params):
            yield FileDataObject.from_json(self, fd_json)

    def write_file(self, path, name, data, content_type=None, archive=False,
                   raw=False):
        """Write a file to the file data store at the given path

        :param str path: The path (directory) into which the file should be written.
        :param str name: The name of the file to be written.
        :param data: The binary data that should be written into the file.
        :type data: str (Python2) or bytes (Python3)
        :param content_type: The content type for the data being written to the file.  May
             be left unspecified.
        :type content_type: str or None
        :param bool archive: If true, history will be retained for various revisions of this
            file.  If this is not required, leave as false.
        :param bool raw: If true, skip the FileData XML headers (necessary for binary files)

        """
        path = validate_type(path, *six.string_types)
        name = validate_type(name, *six.string_types)
        data = validate_type(data, six.binary_type)

        content_type = validate_type(content_type, type(None), *six.string_types)