Source code for khoros.objects.settings

# -*- coding: utf-8 -*-
"""
:Module:            khoros.objects.settings
:Synopsis:          This module contains functions specific to settings for various structures and objects
:Usage:             ``from khoros.objects import settings``
:Example:           ``value = settings.get_node_settings(khoros_object, 'custom.purpose', 'my-board')``
:Created By:        Jeff Shurtliff
:Last Modified:     Jeff Shurtliff
:Modified Date:     20 May 2021
"""

import json

from .. import api, liql, errors
from ..utils import log_utils

# Initialize the logger for this module
logger = log_utils.initialize_logging(__name__)


[docs] def get_node_setting(khoros_object, setting_name, node_id, node_type='board', v1=None, convert_json=False): """This function retrieves the value of a specific node setting. .. versionchanged:: 4.0.0 The node type validation has been moved form this function to the lower-level private functions. .. versionchanged:: 3.3.2 The ``convert_json`` parameter has been introduced which optionally converts a JSON string into a dictionary. .. versionadded:: 3.2.0 :param khoros_object: The core :py:class:`khoros.Khoros` object :type khoros_object: class[khoros.Khoros] :param setting_name: The name of the setting field for which to retrieve the value :type setting_name: str :param node_id: The ID of the node associated with the setting to retrieve :type node_id: str :param node_type: Defines the node as a ``board`` (default), ``category`` or ``grouphub`` :type node_type: str :param v1: Optionally defines a specific Community API version to use when retrieving the value :type v1: bool, None :param convert_json: Optionally converts a JSON string into a Python dictionary (``False`` by default) :type convert_json: bool :returns: The value of the setting for the node :raises: :py:exc:`ValueError`, :py:exc:`TypeError`, :py:exc:`khoros.errors.exceptions.APIConnectionError`, :py:exc:`khoros.errors.exceptions.GETRequestError`, :py:exc:`khoros.errors.exceptions.InvalidNodeTypeError`, :py:exc:`khoros.errors.exceptions.LiQLParseError` """ # Determine which API version to utilize if v1 is None: # Leverage APIv2 if the setting name follows the standard v2 naming convention for custom metadata fields v1 = False if setting_name.startswith("c_") else True # Perform the appropriate API request based on required version if v1: setting_value = _get_v1_node_setting(khoros_object, setting_name, node_id, node_type) else: setting_value = _get_v2_node_setting(khoros_object, setting_name, node_id, node_type) # Convert the setting value to a dictionary when requested and applicable if convert_json and isinstance(setting_value, str): if setting_value.startswith('{"') and setting_value.endswith('}'): try: setting_value = json.loads(setting_value) except json.decoder.JSONDecodeError: logger.error(f"Failed to convert the setting value for '{setting_name}' from a JSON string to a " "dictionary and therefore it will remain a string when returned.") return setting_value
def _validate_node_type(_node_type): """This function checks to ensure that a valid node type has been provided for viewing or defining node settings. .. versionadded:: 3.2.0 :param _node_type: Defines the node as a ``board`` (default), ``category`` or ``grouphub`` :type _node_type: str :returns: The node type value which may or may not have been updated :raises: :py:exc:`khoros.errors.exceptions.InvalidNodeTypeError` """ _node_type_map = { 'board': 'boards', 'category': 'categories', 'grouphub': 'grouphubs' } if _node_type not in _node_type_map.keys() and _node_type not in _node_type_map.values(): raise errors.exceptions.InvalidNodeTypeError(val=_node_type) elif _node_type in _node_type_map: _node_type = _node_type_map.get(_node_type) return _node_type def _get_v1_node_setting(_khoros_object, _setting_name, _node_id, _node_type): """This function retrieves a node setting value using the Community API v1. .. versionchanged:: 4.0.0 Support has been introduced for group hubs by leveraging the :py:func:`khoros.api.get_v1_node_collection` function. .. versionchanged:: 3.3.1 Fixed an issue with the :py:func:`khoros.api.make_v1_request` function call that was resulting in :py:exc:`IndexError` exceptions. .. versionadded:: 3.2.0 :param _khoros_object: The core :py:class:`khoros.Khoros` object :type _khoros_object: class[khoros.Khoros] :param _setting_name: The name of the setting field for which to retrieve the value :type _setting_name: str :param _node_id: The ID of the node associated with the setting to retrieve :type _node_id: str :param _node_type: Defines the node as a ``board`` (default), ``category`` or ``grouphub`` :type _node_type: str :returns: The value of the setting in its original format :raises: :py:exc:`ValueError`, :py:exc:`TypeError`, :py:exc:`khoros.errors.exceptions.APIConnectionError`, :py:exc:`khoros.errors.exceptions.GETRequestError` """ _collection_uri = api.get_v1_node_collection(_node_type) _uri = f"/{_collection_uri}/id/{_node_id}/settings/name/{_setting_name}" _settings_data = api.make_v1_request(_khoros_object, _uri, request_type='GET')['response'] if _settings_data.get('status') == 'error': raise errors.exceptions.GETRequestError(status_code=_settings_data['error']['code'], message=_settings_data['error']['message']) return _settings_data['value']['$'] def _get_v2_node_setting(_khoros_object, _setting_name, _node_id, _node_type): """This function retrieves a node setting value using the Community API v2 and LiQL. .. versionchanged:: 4.0.0 The node type is now validated before constructing the LiQL query. .. versionchanged:: 3.3.3 Error handling has been introduced to avoid an :py:exc:`AttributeError` exception. .. versionchanged:: 3.3.1 Error handling has been introduced to avoid an :py:exc:`KeyError` exception if the setting field is not found, and to return a ``None`` value in that situation. .. versionadded:: 3.2.0 :param _khoros_object: The core :py:class:`khoros.Khoros` object :type _khoros_object: class[khoros.Khoros] :param _setting_name: The name of the setting field for which to retrieve the value :type _setting_name: str :param _node_id: The ID of the node associated with the setting to retrieve :type _node_id: str :param _node_type: Defines the node as a ``board`` (default), ``category`` or ``grouphub`` :type _node_type: str :returns: The value of the setting in its original format :raises: :py:exc:`ValueError`, :py:exc:`TypeError`, :py:exc:`khoros.errors.exceptions.APIConnectionError`, :py:exc:`khoros.errors.exceptions.GETRequestError` """ _node_type = _validate_node_type(_node_type) _query = f"SELECT {_setting_name} FROM {_node_type} WHERE id = '{_node_id}'" _settings_data = liql.perform_query(_khoros_object, liql_query=_query) _returned_items = liql.get_returned_items(_settings_data, only_first=True) try: _setting_value = _returned_items.get(_setting_name) if _returned_items.get(_setting_name) else None except AttributeError: _setting_value = None return _setting_value
[docs] def define_node_setting(khoros_object, setting_name, setting_val, node_id, node_type='board', return_json=True): """This function defines a particular setting value for a given node. .. versionchanged:: 4.0.0 The default value for the ``return_json`` parameter is now ``True`` and group hubs are now supported. .. versionchanged:: 3.3.2 The ``return_json`` parameter has been introduced which returns a simple JSON object (as a ``dict``) indicating whether the operation was successful. (Currently ``False`` by default) .. versionchanged:: 3.3.1 A minor fix was made to the docstring to correct a Sphinx parsing issue. The function itself was not changed. .. versionadded:: 3.2.0 :param khoros_object: The core :py:class:`khoros.Khoros` object :type khoros_object: class[khoros.Khoros] :param setting_name: The name of the setting field for which to retrieve the value :type setting_name: str :param setting_val: The value of the setting to be defined :type setting_val: str :param node_id: The ID of the node associated with the setting to retrieve :type node_id: str :param node_type: Defines the node as a ``board`` (default), ``category`` or ``grouphub`` :type node_type: str :param return_json: Returns a simple JSON dictionary indicating the operation result (``True`` by default) .. caution:: An unsuccessful REST call will result in the raising of the :py:exc:`khoros.errors.exceptions.PostRequestError` exception if the ``return_json`` parameter is set to ``False``. :type return_json: bool :returns: The API response as a dictionary :raises: :py:exc:`ValueError`, :py:exc:`TypeError`, :py:exc:`khoros.errors.exceptions.APIConnectionError`, :py:exc:`khoros.errors.exceptions.POSTRequestError`, :py:exc:`khoros.errors.exceptions.InvalidNodeTypeError`, :py:exc:`khoros.errors.exceptions.PayloadMismatchError` """ collection_uri = api.get_v1_node_collection(node_type) uri = f'/{collection_uri}/id/{node_id}/settings/name/{setting_name}/set' payload = {'value': str(setting_val)} response = api.make_v1_request(khoros_object, uri, payload, 'POST')['response'] if response.get('status') != "success" and not return_json: raise errors.exceptions.POSTRequestError(status_code=response['error']['code'], message=response['error']['message']) response = None if not return_json else response return response