# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/util/properties.py
# class ClassProperty(property):
# class NonDataProperty(object):
#     def __get__(self, cls, owner):
#     def __init__(self, fget):
#     def __get__(self, obj, objtype=None):
# 
# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/backend.py
# class KeyringBackend(object):
#     """The abstract base class of the keyring, every backend must implement
#     this interface.
#     """
# 
#     #@abc.abstractproperty
#     def priority(cls):
#         """
#         Each backend class must supply a priority, a number (float or integer)
#         indicating the priority of the backend relative to all other backends.
#         The priority need not be static -- it may (and should) vary based
#         attributes of the environment in which is runs (platform, available
#         packages, etc.).
# 
#         A higher number indicates a higher priority. The priority should raise
#         a RuntimeError with a message indicating the underlying cause if the
#         backend is not suitable for the current environment.
# 
#         As a rule of thumb, a priority between zero but less than one is
#         suitable, but a priority of one or greater is recommended.
#         """
# 
#     @properties.ClassProperty
#     @classmethod
#     def viable(cls):
#         with errors.ExceptionRaisedContext() as exc:
#             cls.priority
#         return not bool(exc)
# 
#     @abc.abstractmethod
#     def get_password(self, service, username):
#         """Get password of the username for the service
#         """
#         return None
# 
#     @abc.abstractmethod
#     def set_password(self, service, username, password):
#         """Set password for the username of the service
#         """
#         raise errors.PasswordSetError("reason")
# 
#     # for backward-compatibility, don't require a backend to implement
#     #  delete_password
#     #@abc.abstractmethod
#     def delete_password(self, service, username):
#         """Delete the password for the username of the service.
#         """
#         raise errors.PasswordDeleteError("reason")
# 
# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/errors.py
# class InitError(Exception):
#     """Raised when the keyring could not be initialised
#     """
# 
# class PasswordDeleteError(Exception):
#     """Raised when the password can't be deleted.
#     """
# 
# class ExceptionRaisedContext(object):
#     """
#     An exception-trapping context that indicates whether an exception was
#     raised.
#     """
#     def __init__(self, ExpectedException=Exception):
#         self.ExpectedException = ExpectedException
#         self.exc_info = None
# 
#     def __enter__(self):
#         self.exc_info = object.__new__(ExceptionInfo)
#         return self.exc_info
# 
#     def __exit__(self, *exc_info):
#         self.exc_info.__init__(*exc_info)
#         return self.exc_info.type and issubclass(
#             self.exc_info.type, self.ExpectedException)


import logging
    import secretstorage
    import secretstorage.exceptions as exceptions
from ..util import properties
from ..backend import KeyringBackend
from ..errors import (InitError, PasswordDeleteError,
    ExceptionRaisedContext)

class Keyring(KeyringBackend):
    """Secret Service Keyring"""

    @properties.ClassProperty
    @classmethod
    def priority(cls):
        with ExceptionRaisedContext() as exc:
            secretstorage.__name__
        if exc:
            raise RuntimeError("SecretStorage required")
        if not hasattr(secretstorage, 'get_default_collection'):
            raise RuntimeError("SecretStorage 1.0 or newer required")
        try:
            bus = secretstorage.dbus_init()
            list(secretstorage.get_all_collections(bus))
        except exceptions.SecretServiceNotAvailableException as e:
            raise RuntimeError(
                "Unable to initialize SecretService: %s" % e)
        return 5

    def get_default_collection(self):
        bus = secretstorage.dbus_init()
        try:
            collection = secretstorage.get_default_collection(bus)
        except exceptions.SecretStorageException as e:
            raise InitError("Failed to create the collection: %s." % e)
        if collection.is_locked():
            collection.unlock()
            if collection.is_locked(): # User dismissed the prompt

# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/util/properties.py
# class ClassProperty(property):
# class NonDataProperty(object):
#     def __get__(self, cls, owner):
#     def __init__(self, fget):
#     def __get__(self, obj, objtype=None):
# 
# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/backend.py
# class KeyringBackend(object):
#     """The abstract base class of the keyring, every backend must implement
#     this interface.
#     """
# 
#     #@abc.abstractproperty
#     def priority(cls):
#         """
#         Each backend class must supply a priority, a number (float or integer)
#         indicating the priority of the backend relative to all other backends.
#         The priority need not be static -- it may (and should) vary based
#         attributes of the environment in which is runs (platform, available
#         packages, etc.).
# 
#         A higher number indicates a higher priority. The priority should raise
#         a RuntimeError with a message indicating the underlying cause if the
#         backend is not suitable for the current environment.
# 
#         As a rule of thumb, a priority between zero but less than one is
#         suitable, but a priority of one or greater is recommended.
#         """
# 
#     @properties.ClassProperty
#     @classmethod
#     def viable(cls):
#         with errors.ExceptionRaisedContext() as exc:
#             cls.priority
#         return not bool(exc)
# 
#     @abc.abstractmethod
#     def get_password(self, service, username):
#         """Get password of the username for the service
#         """
#         return None
# 
#     @abc.abstractmethod
#     def set_password(self, service, username, password):
#         """Set password for the username of the service
#         """
#         raise errors.PasswordSetError("reason")
# 
#     # for backward-compatibility, don't require a backend to implement
#     #  delete_password
#     #@abc.abstractmethod
#     def delete_password(self, service, username):
#         """Delete the password for the username of the service.
#         """
#         raise errors.PasswordDeleteError("reason")
# 
# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/errors.py
# class InitError(Exception):
#     """Raised when the keyring could not be initialised
#     """
# 
# class PasswordDeleteError(Exception):
#     """Raised when the password can't be deleted.
#     """
# 
# class ExceptionRaisedContext(object):
#     """
#     An exception-trapping context that indicates whether an exception was
#     raised.
#     """
#     def __init__(self, ExpectedException=Exception):
#         self.ExpectedException = ExpectedException
#         self.exc_info = None
# 
#     def __enter__(self):
#         self.exc_info = object.__new__(ExceptionInfo)
#         return self.exc_info
# 
#     def __exit__(self, *exc_info):
#         self.exc_info.__init__(*exc_info)
#         return self.exc_info.type and issubclass(
#             self.exc_info.type, self.ExpectedException)


# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/backends/SecretService.py
import logging
    import secretstorage
    import secretstorage.exceptions as exceptions
from ..util import properties
from ..backend import KeyringBackend
from ..errors import (InitError, PasswordDeleteError,
    ExceptionRaisedContext)


class Keyring(KeyringBackend):
    """Secret Service Keyring"""

    @properties.ClassProperty
    @classmethod
    def priority(cls):
        with ExceptionRaisedContext() as exc:
            secretstorage.__name__
        if exc:
            raise RuntimeError("SecretStorage required")
        if not hasattr(secretstorage, 'get_default_collection'):
            raise RuntimeError("SecretStorage 1.0 or newer required")
        try:
            bus = secretstorage.dbus_init()
            list(secretstorage.get_all_collections(bus))
        except exceptions.SecretServiceNotAvailableException as e:
            raise RuntimeError(
                "Unable to initialize SecretService: %s" % e)
        return 5

    def get_default_collection(self):
        bus = secretstorage.dbus_init()
        try:
            collection = secretstorage.get_default_collection(bus)
        except exceptions.SecretStorageException as e:
            raise InitError("Failed to create the collection: %s." % e)
        if collection.is_locked():
            collection.unlock()
            if collection.is_locked(): # User dismissed the prompt

                raise InitError("Failed to unlock the collection!")