Ejemplo n.º 1
0
    def update(self, webhookId, **update_attributes):
        """Update details for a webhook.

        Args:
            webhookId(string_types): The webhookId of the webhook to be
                updated.
            name(string_types): A user-friendly name for this webhook.
            targetUrl(string_types): The URL that receives POST requests for
                each event.

        Returns:
            Webhook: With the updated Spark webhook details.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If an update attribute is not provided.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert isinstance(webhookId, string_types)
        # Process update_attributes keyword arguments
        if not update_attributes:
            error_message = "At least one **update_attributes keyword " \
                            "argument must be specified."
            raise ciscosparkapiException(error_message)
        # API request
        json_obj = self._session.put('webhooks/' + webhookId,
                                     json=update_attributes)
        # Return a Webhook object created from the response JSON data
        return Webhook(json_obj)
Ejemplo n.º 2
0
def _fix_next_url(next_url):
    """Remove max=null parameter from URL.

    Patch for Cisco Spark Defect: 'next' URL returned in the Link headers of
    the responses contain an errant 'max=null' parameter, which  causes the
    next request (to this URL) to fail if the URL is requested as-is.

    This patch parses the next_url to remove the max=null parameter.

    Args:
        next_url(basestring): The 'next' URL to be parsed and cleaned.

    Returns:
        basestring: The clean URL to be used for the 'next' request.

    Raises:
        AssertionError: If the parameter types are incorrect.
        ciscosparkapiException: If 'next_url' does not contain a valid API
            endpoint URL (scheme, netloc and path).

    """
    next_url = str(next_url)
    parsed_url = urllib.parse.urlparse(next_url)
    if not parsed_url.scheme or not parsed_url.netloc or not parsed_url.path:
        error_message = "'next_url' must be a valid API endpoint URL, " \
                        "minimally containing a scheme, netloc and path."
        raise ciscosparkapiException(error_message)
    if parsed_url.query:
        query_list = parsed_url.query.split('&')
        if 'max=null' in query_list:
            query_list.remove('max=null')
        new_query = '&'.join(query_list)
        parsed_url = list(parsed_url)
        parsed_url[4] = new_query
    return urllib.parse.urlunparse(parsed_url)
Ejemplo n.º 3
0
    def update(self, teamId, **update_attributes):
        """Update details for a team.

        Args:
            teamId(string_types): The teamId of the team to be updated.
            name(string_types): A user-friendly name for the team.

        Returns:
            Team: With the updated Spark team details.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If an update attribute is not provided.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert isinstance(teamId, string_types)
        # Process update_attributes keyword arguments
        if not update_attributes:
            error_message = "At least one **update_attributes keyword " \
                            "argument must be specified."
            raise ciscosparkapiException(error_message)
        # API request
        json_obj = self._session.post('teams/' + teamId, json=update_attributes)
        # Return a Team object created from the response JSON data
        return Team(json_obj)
Ejemplo n.º 4
0
    def update(self, membershipId, **update_attributes):
        """Update details for a membership.

        Args:
            membershipId(string_types): The membershipId of the membership to
                be updated.
            isModerator(bool): If True, sets the person as a moderator for the
                room. If False, removes the person as a moderator for the room.

        Returns:
            Membership: With the updated Spark membership details.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If an update attribute is not provided.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert isinstance(membershipId, string_types)
        # Process update_attributes keyword arguments
        if not update_attributes:
            error_message = "At least one **update_attributes keyword " \
                            "argument must be specified."
            raise ciscosparkapiException(error_message)
        # API request
        json_obj = self._session.post('memberships/' + membershipId,
                                      json=update_attributes)
        # Return a Membership object created from the response JSON data
        return Membership(json_obj)
Ejemplo n.º 5
0
    def update(self, membershipId, **update_attributes):
        """Update details for a team membership.

        Args:
            membershipId(basestring): The membershipId of the team membership
                to be updated.
            isModerator(bool): If True, sets the person as a moderator for the
                team. If False, removes the person as a moderator for the team.

        Returns:
            TeamMembership: With the updated Spark team membership details.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If an update attribute is not provided.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert isinstance(membershipId, basestring)
        # Process update_attributes keyword arguments
        if not update_attributes:
            error_message = "At least one **update_attributes keyword " \
                            "argument must be specified."
            raise ciscosparkapiException(error_message)
        # API request
        json_obj = self._session.put('team/memberships/' + membershipId,
                                     json=update_attributes)
        # Return a TeamMembership object created from the response JSON data
        return TeamMembership(json_obj)
Ejemplo n.º 6
0
    def update(self, webhookId, **update_attributes):
        """Update details for a webhook.

        Args:
            webhookId(string_types): The webhookId of the webhook to be
                updated.

            **update_attributes:
                name(string_types): A user-friendly name for this webhook.
                targetUrl(string_types): The URL that receives POST requests
                    for each event.

        Returns:
            Webhook: With the updated Spark webhook details.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If an update attribute is not provided.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert isinstance(webhookId, string_types)
        # Process update_attributes keyword arguments
        if not update_attributes:
            error_message = "At least one **update_attributes keyword " \
                            "argument must be specified."
            raise ciscosparkapiException(error_message)
        # API request
        json_obj = self.session.put('webhooks/' + webhookId,
                                     json=update_attributes)
        # Return a Webhook object created from the response JSON data
        return Webhook(json_obj)
Ejemplo n.º 7
0
def validate_base_url(base_url):
    """Verify that base_url specifies a protocol and network location."""
    parsed_url = urllib.parse.urlparse(base_url)
    if parsed_url.scheme and parsed_url.netloc:
        return parsed_url.geturl()
    else:
        error_message = "base_url must contain a valid scheme (protocol " \
                        "specifier) and network location (hostname)"
        raise ciscosparkapiException(error_message)
Ejemplo n.º 8
0
    def list(self, email=None, displayName=None, max=None):
        """List people by email or displayName.

        An email address or displayName must be provided.

        This method supports Cisco Spark's implementation of RFC5988 Web
        Linking to provide pagination support.  It returns a generator
        container that incrementally yield all people returned by the
        query.  The generator will automatically request additional 'pages' of
        responses from Spark as needed until all responses have been returned.
        The container makes the generator safe for reuse.  A new API call will
        be made, using the same parameters that were specified when the
        generator was created, every time a new iterator is requested from the
        container.

        Args:
            email(string_types): The e-mail address of the person to be found.
            displayName(string_types): The complete or beginning portion of
                the displayName to be searched.
            max(int): Limits the maximum number of people returned from the
                Spark service per request.

        Returns:
            GeneratorContainer: When iterated, the GeneratorContainer, yields
                the people returned by the Cisco Spark query.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If neither an email or displayName argument
                is specified.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert email is None or isinstance(email, string_types)
        assert displayName is None or isinstance(displayName, string_types)
        assert max is None or isinstance(max, int)
        params = {}
        if email:
            params['email'] = email
        elif displayName:
            params['displayName'] = displayName
        else:
            error_message = "An email or displayName argument must be " \
                            "specified."
            raise ciscosparkapiException(error_message)
        if max:
            params['max'] = max
        # API request - get items
        items = self._session.get_items('people', params=params)
        # Yield Person objects created from the returned items JSON objects
        for item in items:
            yield Person(item)
Ejemplo n.º 9
0
    def list(self, email=None, displayName=None, max=None):
        """List people by email or displayName.

        An email address or displayName must be provided.

        This method supports Cisco Spark's implementation of RFC5988 Web
        Linking to provide pagination support.  It returns a generator
        container that incrementally yield all people returned by the
        query.  The generator will automatically request additional 'pages' of
        responses from Spark as needed until all responses have been returned.
        The container makes the generator safe for reuse.  A new API call will
        be made, using the same parameters that were specified when the
        generator was created, every time a new iterator is requested from the
        container.

        Args:
            email(string_types): The e-mail address of the person to be found.
            displayName(string_types): The complete or beginning portion of
                the displayName to be searched.
            max(int): Limits the maximum number of people returned from the
                Spark service per request.

        Returns:
            GeneratorContainer: When iterated, the GeneratorContainer, yields
                the people returned by the Cisco Spark query.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If neither an email or displayName argument
                is specified.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert email is None or isinstance(email, string_types)
        assert displayName is None or isinstance(displayName, string_types)
        assert max is None or isinstance(max, int)
        params = {}
        if email:
            params['email'] = email
        elif displayName:
            params['displayName'] = displayName
        else:
            error_message = "An email or displayName argument must be " \
                            "specified."
            raise ciscosparkapiException(error_message)
        if max:
            params['max'] = max
        # API request - get items
        items = self._session.get_items('people', params=params)
        # Yield Person objects created from the returned items JSON objects
        for item in items:
            yield Person(item)
Ejemplo n.º 10
0
    def create(self,
               teamId,
               personId=None,
               personEmail=None,
               isModerator=False):
        """Add someone to a team by Person ID or email address.

        Add someone to a team by Person ID or email address; optionally making
        them a moderator.

        Args:
            teamId(basestring): ID of the team to which the person will be
                added.
            personId(basestring): ID of the person to be added to the team.
            personEmail(basestring): Email address of the person to be added
                to the team.
            isModerator(bool): If True, adds the person as a moderator for the
                team. If False, adds the person as normal member of the team.

        Returns:
            TeamMembership: With the details of the created team membership.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If neither a personId or personEmail are
                provided.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert isinstance(teamId, basestring)
        assert personId is None or isinstance(personId, basestring)
        assert personEmail is None or isinstance(personEmail, basestring)
        assert isModerator is None or isinstance(isModerator, bool)
        post_data = {}
        post_data['teamId'] = teamId
        if personId:
            post_data['personId'] = personId
        elif personEmail:
            post_data['personEmail'] = personEmail
        else:
            error_message = "personId or personEmail must be provided to " \
                            "add a person to a team.  Neither were provided."
            raise ciscosparkapiException(error_message)
        post_data['isModerator'] = isModerator
        # API request
        json_obj = self._session.post('team/memberships', json=post_data)
        # Return a TeamMembership object created from the response JSON data
        return TeamMembership(json_obj)
Ejemplo n.º 11
0
    def update(self, personId, **person_attributes):
        """Update details for a person, by ID.

        Only an admin can update a person details.

        Args:
            personId(string_types): The ID of the person to be updated.
            **person_attributes
            emails(list): Email address(es) of the person. (list of
                strings) CURRENT LIMITATION: Spark (today) only allows you
                to provide a single email address for a person. The list
                data type was selected to enable future support for
                providing multiple email address.
            displayName(string_types): Full name of the person
            firstName(string_types): First name of the person
            lastName(string_types): Last name of the person
            avatar(string_types): URL to the person's avatar in PNG format
            orgId(string_types): ID of the organization to which this
                person belongs
            roles(list): Roles of the person (list of strings containing
                the role IDs to be assigned to the person)
            licenses(list): Licenses allocated to the person (list of
                strings containing the license IDs to be allocated to the
                person)

        Returns:
            Person: With the updated person details.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If an update attribute is not provided.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert isinstance(personId, string_types)

        # Process update_attributes keyword arguments
        if not person_attributes:
            error_message = "At least one **update_attributes keyword " \
                            "argument must be specified."
            raise ciscosparkapiException(error_message)

        # API request
        json_obj = self._session.put('people/' + personId,
                                     json=person_attributes)

        # Return a Person object created from the returned JSON object
        return Person(json_obj)
Ejemplo n.º 12
0
 def get_items(self, url, params=None, **kwargs):
     # Get iterator for pages of JSON data
     pages = self.get_pages(url, params=params, **kwargs)
     # Process pages
     for json_page in pages:
         # Process each page of JSON data yielding the individual JSON
         # objects contained within the top level 'items' array
         assert isinstance(json_page, dict)
         items = json_page.get(u'items')
         if items is None:
             error_message = "'items' object not found in JSON data: " \
                             "{!r}".format(json_page)
             raise ciscosparkapiException(error_message)
         else:
             for item in items:
                 yield item
Ejemplo n.º 13
0
    def create(self, roomId, personId=None, personEmail=None,
               isModerator=False):
        """Add someone to a room by Person ID or email address.

        Add someone to a room by Person ID or email address; optionally
        making them a moderator.

        Args:
            roomId(string_types): ID of the room to which the person will be
                added.
            personId(string_types): ID of the person to be added to the room.
            personEmail(string_types): Email address of the person to be added
                to the room.
            isModerator(bool): If True, adds the person as a moderator for the
                room. If False, adds the person as normal member of the room.

        Returns:
            Membership: With the details of the created membership.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If neither a personId or personEmail are
                provided.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert isinstance(roomId, string_types)
        assert personId is None or isinstance(personId, string_types)
        assert personEmail is None or isinstance(personEmail, string_types)
        assert isModerator is None or isinstance(isModerator, bool)
        post_data = {}
        post_data['roomId'] = roomId
        if personId:
            post_data['personId'] = personId
        elif personEmail:
            post_data['personEmail'] = personEmail
        else:
            error_message = "personId or personEmail must be provided to " \
                            "add a person to a room.  Neither were provided."
            raise ciscosparkapiException(error_message)
        post_data['isModerator'] = isModerator
        # API request
        json_obj = self._session.post('memberships', json=post_data)
        # Return a Membership object created from the response JSON data
        return Membership(json_obj)
Ejemplo n.º 14
0
    def list(self, roomId=None, personId=None, personEmail=None, max=None):
        """List room memberships.

        By default, lists memberships for rooms to which the authenticated
        user belongs.

        Use query parameters to filter the response.

        Use roomId to list memberships for a room, by ID.

        Use either personId or personEmail to filter the results.

        This method supports Cisco Spark's implementation of RFC5988 Web
        Linking to provide pagination support.  It returns a generator
        container that incrementally yield all memberships returned by the
        query.  The generator will automatically request additional 'pages' of
        responses from Spark as needed until all responses have been returned.
        The container makes the generator safe for reuse.  A new API call will
        be made, using the same parameters that were specified when the
        generator was created, every time a new iterator is requested from the
        container.

        Args:
            roomId(string_types): List memberships for the room with roomId.
            personId(string_types): Filter results to include only those with
                personId.
            personEmail(string_types): Filter results to include only those
                with personEmail.
            max(int): Limits the maximum number of memberships returned from
                the Spark service per request.


        Returns:
            GeneratorContainer: When iterated, the GeneratorContainer, yields
                the memberships returned from the Cisco Spark query.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If a personId or personEmail argument is
                specified without providing a roomId argument.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert roomId is None or isinstance(roomId, string_types)
        assert personId is None or isinstance(personId, string_types)
        assert personEmail is None or isinstance(personEmail, string_types)
        assert max is None or isinstance(max, int)
        params = {}
        if roomId:
            params['roomId'] = roomId
            if personId:
                params['personId'] = personId
            elif personEmail:
                params['personEmail'] = personEmail
        elif personId or personEmail:
            error_message = "A roomId must be specified. A personId or " \
                            "personEmail filter may only be specified when " \
                            "requesting the memberships for a room with the " \
                            "roomId argument."
            raise ciscosparkapiException(error_message)
        if max:
            params['max'] = max
        # API request - get items
        items = self._session.get_items('memberships', params=params)
        # Yield Person objects created from the returned items JSON objects
        for item in items:
            yield Membership(item)
Ejemplo n.º 15
0
    def __init__(self, access_token=None, base_url=DEFAULT_BASE_URL,
                 timeout=DEFAULT_TIMEOUT):
        """Create a new CiscoSparkAPI object.

        An access token must be used when interacting with the Cisco Spark API.
        This package supports two methods for you to provide that access token:

          1. You may manually specify the access token via the access_token
             argument, when creating a new CiscoSparkAPI object.

          2. If an access_token argument is not supplied, the package checks
             for a SPARK_ACCESS_TOKEN environment variable.

        A ciscosparkapiException is raised if an access token is not provided
        via one of these two methods.

        Args:
            access_token(basestring): The access token to be used for API
                calls to the Cisco Spark service.  Defaults to checking for a
                SPARK_ACCESS_TOKEN environment variable.
            base_url(basestring): The base URL to be prefixed to the
                individual API endpoint suffixes.
                Defaults to ciscosparkapi.DEFAULT_BASE_URL.
            timeout(int): Timeout (in seconds) for RESTful HTTP requests.
                Defaults to ciscosparkapi.DEFAULT_TIMEOUT.

        Returns:
            CiscoSparkAPI: A new CiscoSparkAPI object.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If an access token is not provided via the
                access_token argument or SPARK_ACCESS_TOKEN environment
                variable.

        """
        # Process args
        assert access_token is None or isinstance(access_token, basestring)
        assert isinstance(base_url, basestring)
        assert isinstance(timeout, int)
        spark_access_token = os.environ.get(ACCESS_TOKEN_ENVIRONMENT_VARIABLE)
        access_token = access_token if access_token else spark_access_token
        if not access_token:
            error_message = "You must provide an Spark access token to " \
                            "interact with the Cisco Spark APIs, either via " \
                            "a SPARK_ACCESS_TOKEN environment variable " \
                            "or via the access_token argument."
            raise ciscosparkapiException(error_message)
        session_args = {u'timeout': timeout}

        # Create the API session
        # All of the API calls associated with a CiscoSparkAPI object will
        # leverage a single RESTful 'session' connecting to the Cisco Spark
        # cloud.
        self._session = RestSession(access_token, base_url, **session_args)

        # Spark API wrappers
        self.people = PeopleAPI(self._session)
        self.rooms = RoomsAPI(self._session)
        self.memberships = MembershipsAPI(self._session)
        self.messages = MessagesAPI(self._session)
        self.teams = TeamsAPI(self._session)
        self.team_memberships = TeamMembershipsAPI(self._session)
        self.webhooks = WebhooksAPI(self._session)
        self.organizations = OrganizationsAPI(self._session)
        self.licenses = LicensesAPI(self._session)
        self.roles = RolesAPI(self._session)
        self.access_tokens = AccessTokensAPI(self.base_url, timeout=timeout)
Ejemplo n.º 16
0
    def create(self, roomId=None, toPersonId=None, toPersonEmail=None,
               text=None, markdown=None, files=None):
        """Posts a message to a room.

        Posts a message, and optionally, a media content attachment, to a room.

        You must specify either a roomId, toPersonId or toPersonEmail when
        posting a message, and you must supply some message content (text,
        markdown, files).

        Args:
            roomId(string_types): The room ID.
            toPersonId(string_types): The ID of the recipient when sending a
                private 1:1 message.
            toPersonEmail(string_types): The email address of the recipient
                when sending a private 1:1 message.
            text(string_types): The message, in plain text. If markdown is
                specified this parameter may be optionally used to provide
                alternate text forUI clients that do not support rich text.
            markdown(string_types): The message, in markdown format.
            files(list): A list containing local paths or URL references for
                the message attachment(s).  The files attribute currently only
                takes a list containing one (1) filename or URL as an input.
                This is a Spark API limitation that may be lifted at a later
                date.

        Returns:
            Message: With the details of the created message.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If the required arguments are not
                specified.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert roomId is None or isinstance(roomId, string_types)
        assert toPersonId is None or isinstance(toPersonId, string_types)
        assert toPersonEmail is None or isinstance(toPersonEmail, string_types)
        assert text is None or isinstance(text, string_types)
        assert markdown is None or isinstance(markdown, string_types)
        assert files is None or isinstance(files, list)
        post_data = {}
        # Where is message to be posted?
        if roomId:
            post_data['roomId'] = roomId
        elif toPersonId:
            post_data['toPersonId'] = toPersonId
        elif toPersonEmail:
            post_data['toPersonEmail'] = toPersonEmail
        else:
            error_message = "You must specify a roomId, toPersonId, or " \
                            "toPersonEmail to which you want to post a new " \
                            "message."
            raise ciscosparkapiException(error_message)
        # Ensure some message 'content' is provided.
        if not text and not markdown and not files:
            error_message = "You must supply some message content (text, " \
                            "markdown, files) when posting a message."
            raise ciscosparkapiException(error_message)
        # Process the content.
        if text:
            post_data['text'] = text
        if markdown:
            post_data['markdown'] = markdown
        upload_local_file = False
        if files:
            if len(files) > 1:
                error_message = "The files attribute currently only takes a " \
                                "list containing one (1) filename or URL as " \
                                "an input.  This is a Spark API limitation " \
                                "that may be lifted at a later date."
                raise ciscosparkapiException(error_message)
            if is_web_url(files[0]):
                post_data['files'] = files
            elif is_local_file(files[0]):
                upload_local_file = True
                post_data['files'] = open_local_file(files[0])
            else:
                error_message = "The provided files argument does not " \
                                "contain a valid URL or local file path."
                raise ciscosparkapiException(error_message)
        # API request
        if upload_local_file:
            try:
                multipart_data = MultipartEncoder(post_data)
                headers = {'Content-type': multipart_data.content_type}
                json_obj = self._session.post('messages',
                                              data=multipart_data,
                                              headers=headers)
            finally:
                post_data['files'].file_object.close()
        else:
            json_obj = self._session.post('messages', json=post_data)
        # Return a Message object created from the response JSON data
        return Message(json_obj)
Ejemplo n.º 17
0
    def create(self,
               roomId=None,
               toPersonId=None,
               toPersonEmail=None,
               text=None,
               markdown=None,
               files=None):
        """Posts a message to a room.

        Posts a message, and optionally, a media content attachment, to a room.

        You must specify either a roomId, toPersonId or toPersonEmail when
        posting a message, and you must supply some message content (text,
        markdown, files).

        Args:
            roomId(string_types): The room ID.
            toPersonId(string_types): The ID of the recipient when sending a
                private 1:1 message.
            toPersonEmail(string_types): The email address of the recipient
                when sending a private 1:1 message.
            text(string_types): The message, in plain text. If markdown is
                specified this parameter may be optionally used to provide
                alternate text forUI clients that do not support rich text.
            markdown(string_types): The message, in markdown format.
            files(list): A list containing local paths or URL references for
                the message attachment(s).  The files attribute currently only
                takes a list containing one (1) filename or URL as an input.
                This is a Spark API limitation that may be lifted at a later
                date.

        Returns:
            Message: With the details of the created message.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If the required arguments are not
                specified.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert roomId is None or isinstance(roomId, string_types)
        assert toPersonId is None or isinstance(toPersonId, string_types)
        assert toPersonEmail is None or isinstance(toPersonEmail, string_types)
        assert text is None or isinstance(text, string_types)
        assert markdown is None or isinstance(markdown, string_types)
        assert files is None or isinstance(files, list)
        post_data = {}
        # Where is message to be posted?
        if roomId:
            post_data['roomId'] = roomId
        elif toPersonId:
            post_data['toPersonId'] = toPersonId
        elif toPersonEmail:
            post_data['toPersonEmail'] = toPersonEmail
        else:
            error_message = "You must specify a roomId, toPersonId, or " \
                            "toPersonEmail to which you want to post a new " \
                            "message."
            raise ciscosparkapiException(error_message)
        # Ensure some message 'content' is provided.
        if not text and not markdown and not files:
            error_message = "You must supply some message content (text, " \
                            "markdown, files) when posting a message."
            raise ciscosparkapiException(error_message)
        # Process the content.
        if text:
            post_data['text'] = text
        if markdown:
            post_data['markdown'] = markdown
        upload_local_file = False
        if files:
            if len(files) > 1:
                error_message = "The files attribute currently only takes a " \
                                "list containing one (1) filename or URL as " \
                                "an input.  This is a Spark API limitation " \
                                "that may be lifted at a later date."
                raise ciscosparkapiException(error_message)
            if is_web_url(files[0]):
                post_data['files'] = files
            elif is_local_file(files[0]):
                upload_local_file = True
                post_data['files'] = open_local_file(files[0])
            else:
                error_message = "The provided files argument does not " \
                                "contain a valid URL or local file path."
                raise ciscosparkapiException(error_message)
        # API request
        if upload_local_file:
            try:
                multipart_data = MultipartEncoder(post_data)
                headers = {'Content-type': multipart_data.content_type}
                json_obj = self._session.post('messages',
                                              data=multipart_data,
                                              headers=headers)
            finally:
                post_data['files'].file_object.close()
        else:
            json_obj = self._session.post('messages', json=post_data)
        # Return a Message object created from the response JSON data
        return Message(json_obj)
Ejemplo n.º 18
0
    def list(self, roomId=None, personId=None, personEmail=None, max=None):
        """List room memberships.

        By default, lists memberships for rooms to which the authenticated
        user belongs.

        Use query parameters to filter the response.

        Use roomId to list memberships for a room, by ID.

        Use either personId or personEmail to filter the results.

        This method supports Cisco Spark's implementation of RFC5988 Web
        Linking to provide pagination support.  It returns a generator
        container that incrementally yield all memberships returned by the
        query.  The generator will automatically request additional 'pages' of
        responses from Spark as needed until all responses have been returned.
        The container makes the generator safe for reuse.  A new API call will
        be made, using the same parameters that were specified when the
        generator was created, every time a new iterator is requested from the
        container.

        Args:
            roomId(string_types): List memberships for the room with roomId.
            personId(string_types): Filter results to include only those with
                personId.
            personEmail(string_types): Filter results to include only those
                with personEmail.
            max(int): Limits the maximum number of memberships returned from
                the Spark service per request.


        Yields:
            Membership: The the next membership from the Cisco Spark query.

        Raises:
            AssertionError: If the parameter types are incorrect.
            ciscosparkapiException: If a personId or personEmail argument is
                specified without providing a roomId argument.
            SparkApiError: If the Cisco Spark cloud returns an error.

        """
        # Process args
        assert roomId is None or isinstance(roomId, string_types)
        assert personId is None or isinstance(personId, string_types)
        assert personEmail is None or isinstance(personEmail, string_types)
        assert max is None or isinstance(max, int)
        params = {}
        if roomId:
            params['roomId'] = roomId
            if personId:
                params['personId'] = personId
            elif personEmail:
                params['personEmail'] = personEmail
        elif personId or personEmail:
            error_message = "A roomId must be specified. A personId or " \
                            "personEmail filter may only be specified when " \
                            "requesting the memberships for a room with the " \
                            "roomId argument."
            raise ciscosparkapiException(error_message)
        if max:
            params['max'] = max
        # API request - get items
        items = self.session.get_items('memberships', params=params)
        # Yield Person objects created from the returned items JSON objects
        for item in items:
            yield Membership(item)