/
opt
/
cloudlinux
/
venv
/
lib64
/
python3.11
/
site-packages
/
xray
/
analytics
/
Upload Filee
HOME
# -*- coding: utf-8 -*- # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2021 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENSE.TXT import json import logging import dataclasses from typing import Any, Optional, Union from xray.apiclient import get_client from .models.analytics_data import AnalyticsData from xray.internal.utils import read_sys_id def report_analytics(data: str, advice_id: Optional[Union[str, int]], source: str, event: Optional[str] = None, feature: Optional[str] = None, variant_id: Optional[str] = None) -> Any: """ Receives analytics data as a JSON string """ logger = logging.getLogger('analytics') logger.info('Prepare analytics report: ' 'data: "%s", ' 'advice_id: "%s", ' 'source: "%s", ' 'event: "%s", ' 'feature: "%s"', str(data), str(advice_id), str(source), str(event), str(feature)) if data is None: return data = _parse(data, logger) if not data: return # if advice_id passed -> add it to analytics report if advice_id: advice_id = _filter_advice(advice_id) if not advice_id: return data['advice_id'] = str(advice_id) try: system_id = read_sys_id() except Exception: logger.exception('Cannot obtain system_id for analytics report') system_id = None data['system_id'] = system_id if feature: data['feature'] = feature if variant_id: data['variant_id'] = variant_id if 'source' not in data: data['source'] = source if source == 'WORDPRESS_PLUGIN': data['source'] = 'wp_smartadvice' if event is not None: data['event'] = event validated_data = _validate(data, logger) if validated_data is not None: api_client_object = get_client('adviser') client = api_client_object() return client.report(validated_data) def _parse(data: str, logger: logging.Logger) -> Optional[dict]: """ Trying to parse receiving JSON """ try: v = json.loads(data) except ValueError as e: logger.error('[Analytics] Decoding analytics JSON has failed', extra={'err': str(e)}) else: return v def _validate(data: dict, logger: logging.Logger) -> Optional[dict]: """ Validates data. """ try: validated_data = AnalyticsData(**data) except TypeError as e: logger.error('[Analytics] Not supported field detected', extra={'err': str(e)}) else: return dataclasses.asdict(validated_data) def _filter_advice(advice_ids: Union[str, int]) -> Union[str, int]: """ Remove IM360 advisements from the list """ if advice_ids.isnumeric(): return advice_ids advice_dict = advice_ids.split(',') advice_dict = filter(lambda id: not id.startswith('IM360'), advice_dict) return ','.join(advice_dict)