<commit_before>"""Basic contact management functions.

Contacts are linked to monitors and are used to determine where to send
alerts for monitors.

Contacts are basic name/email/phone sets.

Contacts are only stored in the database and not in memory, they are loaded
from the database each time an alert is sent.
"""

from typing import Dict, Iterable, Optional, Any
from irisett import errors
from irisett.sql import DBConnection
from irisett.object_exists import (
    contact_exists,
    active_monitor_exists,
    contact_group_exists,
)


async def create_contact(dbcon: DBConnection, name: Optional[str], email: Optional[str],
                         phone: Optional[str], active: bool) -> str:
    """Add a contact to the database."""
    q = """insert into contacts (name, email, phone, active) values (%s, %s, %s, %s)"""
    q_args = (name, email, phone, active)
    contact_id = await dbcon.operation(q, q_args)
    return contact_id


async def update_contact(dbcon: DBConnection, contact_id: int, data: Dict[str, str]):
    """Update a contacts information in the database.

    Data is a dict with name/email/phone/active values that
    will be updated.
    """

    async def _run(cur):
        for key, value in data.items():
            if key not in ['name', 'email', 'phone', 'active']:
                raise errors.IrisettError('invalid contact key %s' % key)
            q = """update contacts set %s=%%s where id=%%s""" % key
            q_args = (value, contact_id)
            await cur.execute(q, q_args)

    if not contact_exists(dbcon, contact_id):
        raise errors.InvalidArguments('contact does not exist')
    await dbcon.transact(_run)


async def delete_contact(dbcon: DBConnection, contact_id: int):
    """Remove a contact from the database."""
    if not contact_exists(dbcon, contact_id):
        raise errors.InvalidArguments('contact does not exist')
    q = """delete from contacts where id=%s"""
    await dbcon.operation(q, (contact_id,))


async def create_contact_group(dbcon: DBConnection, name: str, active: bool) -> str:
    """Add a contact group to the database."""
    q = """insert into contact_groups (name, active) values (%s, %s)"""
    q_args = (name, active)
    contact_group_id = await dbcon.operation(q, q_args)
    return contact_group_id


async def update_contact_group(dbcon: DBConnection, contact_group_id: int, data: Dict[str, str]):
    """Update a contact groups information in the database.

    Data is a dict with name/active values that will be updated.
    """

    async def _run(cur):
        for key, value in data.items():
            if key not in ['name', 'active']:
                raise errors.IrisettError('invalid contact key %s' % key)
            q = """update contact_groups set %s=%%s where id=%%s""" % key
            q_args = (value, contact_group_id)
            await cur.execute(q, q_args)

    if not contact_group_exists(dbcon, contact_group_id):
        raise errors.InvalidArguments('contact group does not exist')
    await dbcon.transact(_run)


async def delete_contact_group(dbcon: DBConnection, contact_group_id: int):
    """Remove a contact group from the database."""
    if not contact_group_exists(dbcon, contact_group_id):
        raise errors.InvalidArguments('contact group does not exist')
    q = """delete from contact_groups where id=%s"""
    await dbcon.operation(q, (contact_group_id,))


async def get_all_contacts_for_active_monitor(dbcon: DBConnection, monitor_id: int) -> Iterable[Dict[str, Any]]:<commit_msg>Added missing awaits.<commit_after>"""Basic contact management functions.

Contacts are linked to monitors and are used to determine where to send
alerts for monitors.

Contacts are basic name/email/phone sets.

Contacts are only stored in the database and not in memory, they are loaded
from the database each time an alert is sent.
"""

from typing import Dict, Iterable, Optional, Any
from irisett import errors
from irisett.sql import DBConnection
from irisett.object_exists import (
    contact_exists,
    active_monitor_exists,
    contact_group_exists,
)


async def create_contact(dbcon: DBConnection, name: Optional[str], email: Optional[str],
                         phone: Optional[str], active: bool) -> str:
    """Add a contact to the database."""
    q = """insert into contacts (name, email, phone, active) values (%s, %s, %s, %s)"""
    q_args = (name, email, phone, active)
    contact_id = await dbcon.operation(q, q_args)
    return contact_id


async def update_contact(dbcon: DBConnection, contact_id: int, data: Dict[str, str]):
    """Update a contacts information in the database.

    Data is a dict with name/email/phone/active values that
    will be updated.
    """

    async def _run(cur):
        for key, value in data.items():
            if key not in ['name', 'email', 'phone', 'active']:
                raise errors.IrisettError('invalid contact key %s' % key)
            q = """update contacts set %s=%%s where id=%%s""" % key
            q_args = (value, contact_id)
            await cur.execute(q, q_args)

    if not await contact_exists(dbcon, contact_id):
        raise errors.InvalidArguments('contact does not exist')
    await dbcon.transact(_run)


async def delete_contact(dbcon: DBConnection, contact_id: int):
    """Remove a contact from the database."""
    if not await contact_exists(dbcon, contact_id):
        raise errors.InvalidArguments('contact does not exist')
    q = """delete from contacts where id=%s"""
    await dbcon.operation(q, (contact_id,))


async def create_contact_group(dbcon: DBConnection, name: str, active: bool) -> str:
    """Add a contact group to the database."""
    q = """insert into contact_groups (name, active) values (%s, %s)"""
    q_args = (name, active)
    contact_group_id = await dbcon.operation(q, q_args)
    return contact_group_id


async def update_contact_group(dbcon: DBConnection, contact_group_id: int, data: Dict[str, str]):
    """Update a contact groups information in the database.

    Data is a dict with name/active values that will be updated.
    """

    async def _run(cur):
        for key, value in data.items():
            if key not in ['name', 'active']:
                raise errors.IrisettError('invalid contact key %s' % key)
            q = """update contact_groups set %s=%%s where id=%%s""" % key
            q_args = (value, contact_group_id)
            await cur.execute(q, q_args)

    if not await contact_group_exists(dbcon, contact_group_id):
        raise errors.InvalidArguments('contact group does not exist')
    await dbcon.transact(_run)


async def delete_contact_group(dbcon: DBConnection, contact_group_id: int):
    """Remove a contact group from the database."""
    if not await contact_group_exists(dbcon, contact_group_id):
        raise errors.InvalidArguments('contact group does not exist')
    q = """delete from contact_groups where id=%s"""
    await dbcon.operation(q, (contact_group_id,))


async def get_all_contacts_for_active_monitor(dbcon: DBConnection, monitor_id: int) -> Iterable[Dict[str, Any]]:
{'fraction_non_alphanumeric': 0.10690140845070423, 'fraction_numerical': 0.0, 'mean_word_length': 3.488621997471555, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '763119', 'n_tokens_mistral': 2078, 'n_tokens_neox': 2049, 'n_words': 733}