HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //proc/1233/root/home/arjun/projects/buyercall/buyercall/blueprints/notification/endpoints.py
import json
from sqlalchemy.sql.expression import desc
from buyercall.blueprints.notification.models import ActivitySettings
from buyercall.blueprints.user.decorators import role_required
from buyercall.blueprints.partnership.models import Partnership, PartnershipAccount
from flask import Blueprint, request, current_app, jsonify
from flask_login import login_required, current_user
from buyercall.blueprints.user.models import User
from buyercall.integrations.elasticsearch.utilities import create_notification_data, search_data
from buyercall.blueprints.notification.utilities import create_notification_message, get_user_sids_by_roles
from buyercall.extensions import es_client
from buyercall.blueprints import flask_environment
from elasticsearch_dsl import Q
import logging as log


notification_api = Blueprint('notificationapi', __name__, url_prefix='/api')
log = log.getLogger(__name__)


def insert_notification():
    try:
        response = {'success': True, 'message': 'Successfully inserted the notification.'}
        data = request.get_json()

        notify_message_type = data.get('notify_message_type', 'MISSED_CALL')
        notify_type = data.get('notify_type', 'LEAD')
        triggered_user_id = data.get('user_id', '8ce3921e-3744-4fbd-af82-bcfe7653389a')

        user = User.query.filter(User.sid == triggered_user_id).first()
        if user:
            partnership = Partnership.query.filter(Partnership.id == user.partnership_id).first()
            if not partnership:
                partnership = Partnership.query.get(1)
            partnership_account = PartnershipAccount.query.filter(PartnershipAccount.id == user.partnership_account_id).first()

            user_ip = user.current_sign_in_ip
            user_device = request.headers.get('User-Agent', None)
            hyperlink = f"{current_app.config.get('SERVER_DOMAIN', 'http://localhost:8000')}/settings"

            activity_settings = ActivitySettings.query.filter(ActivitySettings.activity_message_type == notify_message_type).first()
            if activity_settings:
                valid_user_roles = activity_settings.valid_user_roles
            
                notification_user_ids = get_user_sids_by_roles(user, valid_user_roles)
                user_desc_variables = ["You've", "+7466523221"]
                other_user_desc_variables = ["John Doe", "+7466523221"]
                for sid in notification_user_ids:
                    if triggered_user_id == sid:
                        # description_variables = activity_settings.self_notify_variables
                        description = activity_settings.user_message_description
                        _new_desc_variables = user_desc_variables
                    else:
                        # description_variables = activity_settings.other_user_notify_variables
                        description = activity_settings.other_user_description
                        _new_desc_variables = other_user_desc_variables

                    # Replace static variables with db varibles
                    # large_list = None
                    # small_list = None
                    # description_variables = [] if not description_variables else description_variables

                    # if len(_new_desc_variables) != len(description_variables):
                    #     small_list = _new_desc_variables if len(_new_desc_variables) < len(description_variables) else description_variables
                    #     large_list = _new_desc_variables if small_list == description_variables else description_variables

                    # if large_list:
                    #     if small_list == description_variables:
                    #         for index in range(len(description_variables)):
                    #             if description_variables[index]:
                    #                 _new_desc_variables[index] = description_variables[index]
                    #     else:
                    #         _new_desc_variables = description_variables

                    
                    payload = {
                        "triggered_user_id": triggered_user_id,
                        "details": _new_desc_variables
                    }

                    message = create_notification_message(description, _new_desc_variables)

                    data = create_notification_data(partnership, partnership_account, user_ip, user_device, message['message'],
                            payload, notify_type, notify_message_type, user.sid, hyperlink)

                    log_state = flask_environment()
                    index_name = f'buyercall-notification-log-{log_state}'
                    from buyercall.blueprints.user.tasks import put_to_elasticsearch
                    es_response = put_to_elasticsearch(data, es_client, index_name)

                if not es_response['status']:
                    response = {'success': False, 'message': es_response['message']}
            else:
                response = {'success': False, 'message': f'Activity {notify_message_type} not found.'}
        else:
            response = {'success': False, 'message': f'User not found with given id: {triggered_user_id}'}

    except Exception as e:
        response = {'success': False, 'message': str(e)}

    return jsonify(response)


@login_required
def get_notifications():
    try:
        response = {
            'statusCode': 200,
            'success': True,
            'message': 'Notifications fetched successfully!',
        }
        limit = int(request.args.get('limit', 10))
        offset = int(request.args.get('offset', 0))
        log_state = flask_environment()
        index_name = f'buyercall-notification-log-{log_state}'
        sort_string = '-created_at'

        activity_settings = ActivitySettings.query.filter(ActivitySettings.is_notification == True).all()
        notification_message_types = []
        for message_types in activity_settings:
            notification_message_types.append(message_types.activity_message_type)

        query = Q('bool', must=[
                    Q('range', created_at={'gt': 'now-90d/d'}),
                    Q('term', is_read=False) | Q('term', is_viewed=False),
                    Q('term', **{'user_id.keyword': str(current_user.sid)}),
                    Q('terms', **{'notification_message_type.keyword': notification_message_types})
                    ])

        es_response = search_data(q=query, es_client=es_client, index=index_name, limit=limit, offset=offset, sort=sort_string)

        notifications = []
        data = {}

        if es_response:
            data = {
                'totalRecordCount': es_response["hits"]["total"]["value"]
            }

            for hit in es_response["hits"]["hits"]:

                _notification = {}
                _notification['type'] = hit['_source']['notification_message_type']
                if 'message' in hit['_source']:
                    _notification['message'] = hit['_source']['message']
                else:
                    _notification['message'] = ' '
                _notification['createdAt'] = hit['_source']['created_at']
                _notification['notificationId'] = hit['_source']['notification_id']
                _notification['hyperLink'] = hit['_source']['hyperLink'] if 'hyperLink' in hit['_source'] else None
                _notification['is_viewed'] = hit['_source']['is_viewed']
                notifications.append(_notification)

            data['notifications'] = notifications

        response['data'] = data
    except Exception as e:
        print(e)
        response = {
            'success': False,
            'statusCode': 500,
            'message': f'Error: {str(e)}'}

    return jsonify(response)


@login_required
def get_unviewed_count():
    try:
        response = {
        'statusCode': 200,
        'success': True,
        'message': 'Count fetched successfully!',
        }
        sort_string = '-created_at'

        activity_settings = ActivitySettings.query.filter(ActivitySettings.is_notification == True).all()
        notification_message_types = []
        for message_types in activity_settings:
            notification_message_types.append(message_types.activity_message_type)

        query = Q('bool', must=[
                Q('range', created_at={'gt': 'now-90d/d'}),
                Q('term', is_viewed=False),
                Q('term', **{'user_id.keyword': str(current_user.sid)}),
                Q('terms', **{'notification_message_type.keyword': notification_message_types})
                ])
        
        log_state = flask_environment()
        index_name = f'buyercall-notification-log-{log_state}'

        es_response = search_data(q=query, es_client=es_client, index=index_name, limit=1, offset=0, sort=sort_string)

        _notification = {}
        for hit in es_response["hits"]["hits"]:
            _notification['createdAt'] = hit['_source']['created_at']
            _notification['lastFetchedNotficationId'] = hit['_source']['notification_id']
            
        _notification['count'] = es_response["hits"]["total"]['value']
        response['data'] = _notification

    except Exception as e:
        response = {
            'statusCode': 500,
            'success': False,
            'message': f'Count fetching failed! {str(e)}',
            'data': []
        }

    return jsonify(response)


@login_required
def update_viewed():
    try:
        response = {
        'statusCode': 200,
        'success': True,
        'message': 'Updated viewed notifications successfully!',
        'data': []
        }
        form_data = request.get_json()
        notification_ids = form_data.get('notificationIds', [])

        update_query = {"query": {"terms": {"notification_id.keyword": notification_ids}}}

        script = "ctx._source.is_viewed=true"
        log_state = flask_environment()
        index_name = f'buyercall-notification-log-{log_state}'
        from buyercall.blueprints.user.tasks import update_to_elasticsearch
        resp = update_to_elasticsearch(update_query, es_client, index_name=index_name, script=script)

        log.info(resp)

        if not resp['status']:
            response['statusCode'] = 500
            response['success'] = False
        
        response['message'] = resp['message']

    except Exception as e:
        response = {
            'statusCode': 500,
            'success': False,
            'message': 'Viewd notifications updation failed!',
            'data': 0
        }

    return jsonify(response)

@login_required
def update_read():
    try:
        response = {
        'statusCode': 200,
        'success': True,
        'message': 'Updated read notifications successfully!',
        'data': []
        }
        form_data = request.get_json()
        notification_ids = form_data.get('notificationIds', [])

        update_query = {"query": {"terms": {"notification_id.keyword": notification_ids}}}

        script = "ctx._source.is_read=true;ctx._source.is_viewed=true;"
        
        log_state = flask_environment()
        index_name = f'buyercall-notification-log-{log_state}'
        from buyercall.blueprints.user.tasks import update_to_elasticsearch
        resp = update_to_elasticsearch(update_query, es_client, index_name=index_name, script=script)

        log.info(resp)

        if not resp['status']:
            response['statusCode'] = 500
            response['success'] = False
        
        response['message'] = resp['message']

    except Exception as e:
        response = {
            'statusCode': 500,
            'success': False,
            'message': 'Read notifications updation failed!',
            'data': []
        }

    return jsonify(response)


@login_required
def update_user_status():
    try:
        response = {
        'statusCode': 200,
        'success': True,
        'message': 'Updated user notification status successfully!',
        }
        form_data = request.get_json()
        push_notify_subs = form_data.get('isSubscribed', True)
        current_user.push_notification_subscription = push_notify_subs
        current_user.save()

    except Exception as e:
        response = {
            'statusCode': 500,
            'success': False,
            'message': f'User notification status updation failed! Error: {e}',
            'data': 0
        }

    return jsonify(response)