Beispiel #1
0
def test_slash_command_update(text, expected, client):
    Command.create(
        name="test_update",
        channel_id="1234",
        label="label",
        description="description",
        pick_list=["1", "2"],
        weight_list=[1 / 2, 1 / 2],
        strategy=Strategy.uniform.name,
        self_exclude=True,
        only_active_users=False,
        created_by_user_id="4321",
    )
    response, slack_message = call_webhook(client, text)

    assert response.status_code == 200
    assert "4321 updated *test_update*." in slack_message

    updated_command = (Command.find_one_by_name_and_chanel(
        "test_update", "1234").to_son().to_dict())

    for key in expected:
        func_to_apply = lambda x: x  # noqa: E731
        if type(expected[key]) == list:
            func_to_apply = sorted
        assert func_to_apply(updated_command[key]) == func_to_apply(
            expected[key])
Beispiel #2
0
def test_update(
    input_data, expected_command, expected_message, non_expected_message, client
):
    Command.create(**default_expected_command)
    response = update_command_processor(
        user_id=user_id,
        team_id=team_id,
        channel_id=channel_id,
        command_to_update=command_name,
        **input_data,
    )

    message = response.get("message")

    if expected_message:
        assert expected_message in message.content
    if non_expected_message:
        assert non_expected_message not in message.content
    assert message.status == MessageStatus.INFO
    assert message.visibility == MessageVisibility.NORMAL

    updated_command = (
        Command.find_one_by_name_and_chanel(name=command_name, channel_id=channel_id)
        .to_son()
        .to_dict()
    )

    for key in expected_command:
        assert updated_command[key] == expected_command[key]
Beispiel #3
0
def randomness_command_processor(
    *,
    channel_id: str,
    command_to_show_randomness: str,
) -> dict[str, any]:
    Command.find_one_by_name_and_chanel(command_to_show_randomness,
                                        channel_id=channel_id)

    api_url = current_app.config["API_URL"]
    params = {
        "command_name": command_to_show_randomness,
        "channel_id": channel_id,
        "t": datetime.now().timestamp(),
    }
    image_url = construct_url(f"{api_url}/chart/heat-map", params)
    message = "*Randomness of the command*\n"
    message += "Each color represents a different item of the pick list"

    return {
        "message":
        Message(
            content=message,
            status=MessageStatus.INFO,
            visibility=MessageVisibility.HIDDEN,
            as_attachment=True,
            image_url=image_url,
        )
    }
Beispiel #4
0
def command_for_self_exclude_error(client):
    input = {
        **default_command,
        "pick_list": ["<@1234|name>"],
        "weight_list": [1],
        "self_exclude": True,
    }
    command = create_and_return_command(**input)
    yield command
    Command.delete_command(command)
Beispiel #5
0
def command_with_no_active_users(client):
    input = {
        **default_command,
        "pick_list": ["<@4321|name>"],
        "weight_list": [1],
        "only_active_users": True,
    }
    command = create_and_return_command(**input)
    yield command
    Command.delete_command(command)
Beispiel #6
0
def update_command_processor(
    *,
    user_id: str,
    team_id: str,
    channel_id: str,
    command_to_update: str,
    new_channel_id: str = None,
    new_command_name: str = None,
    label: str = None,
    description: str = None,
    pick_list: list[str] = None,
    strategy: str = None,
    add_to_pick_list: list[str] = None,
    remove_from_pick_list: list[str] = None,
    self_exclude: bool = None,
    only_active_users: bool = None,
) -> dict[str, any]:
    command = Command.find_one_by_name_and_chanel(command_to_update,
                                                  channel_id)

    new_values = compute_new_values(
        command,
        name=new_command_name or command_to_update,
        label=label,
        description=description,
        strategy=strategy,
        pick_list=pick_list,
        add_to_pick_list=add_to_pick_list,
        remove_from_pick_list=remove_from_pick_list,
        self_exclude=self_exclude,
        only_active_users=only_active_users,
        user_id=user_id,
        team_id=team_id,
        channel_id=new_channel_id or channel_id,
    )
    Command.update(command_to_update, channel_id, user_id, new_values)
    updated_command = Command.find_one_by_name_and_chanel(
        new_command_name or command_to_update, new_channel_id or channel_id)

    fields_updated = compute_fields_updated(command, updated_command)
    message_content = format_updated_fields_mesage(
        command_name=updated_command.name,
        team_id=team_id,
        fields_updated=fields_updated,
        current_user_id=user_id,
    )

    return {
        "message":
        Message(
            content=message_content,
            status=MessageStatus.INFO,
            visibility=MessageVisibility.NORMAL,
        )
    }
Beispiel #7
0
def update_weight_list(command: Command, selected_items: list[str]) -> None:
    strategy = get_strategy(command.strategy, command.weight_list)
    strategy.update(indices_selected=[
        command.pick_list.index(selected_item)
        for selected_item in selected_items
    ])
    Command.update(
        command.name,
        command.channel_id,
        command.updated_by_user_id,
        {"weight_list": strategy.weight_list},
    )
Beispiel #8
0
def create_command_processor(
    *,
    user_id: str,
    team_id: str,
    channel_id: str,
    new_command_name: str,
    label: str = "",
    description: str = "",
    pick_list: list[str],
    strategy: str = Strategy.uniform.name,
    self_exclude: bool = False,
    only_active_users: bool = False,
) -> dict[str, any]:
    pick_list = format_pick_list(pick_list, team_id, channel_id)
    strategy_enum = Strategy[strategy]
    weight_list = strategy_enum.value.create_weight_list(len(pick_list))

    Command.create(
        name=new_command_name,
        channel_id=channel_id,
        label=label,
        description=description,
        pick_list=pick_list,
        self_exclude=self_exclude,
        only_active_users=only_active_users,
        weight_list=weight_list,
        strategy=strategy_enum.name,
        created_by_user_id=user_id,
    )
    created_command = Command.find_one_by_name_and_chanel(
        new_command_name, channel_id)

    message_content = format_new_command_message(
        command_name=created_command.name,
        team_id=team_id,
        pick_list=created_command.pick_list,
        command_description=created_command.description,
        current_user_id=user_id,
    )

    return {
        "message":
        Message(
            content=message_content,
            status=MessageStatus.SUCCESS,
            visibility=MessageVisibility.NORMAL,
        )
    }
Beispiel #9
0
def build_command_text(command: Command) -> str:
    name = f"*{command['name']}*"
    description = (
        command["description"]
        if command.get("description")
        else "_No description provided_ :smiling_face_with_tear:"
    )
    return f"{name}\n{description}"
Beispiel #10
0
def custom_command_processor(
    *,
    user_id: str,
    team_id: str,
    channel_id: str,
    command_name: str,
    additional_text: str = "",
    number_of_items_to_select: int = 1,
    should_update_weight_list: bool = False,
    with_wheel: bool = False,
) -> dict[str, any]:
    command = Command.find_one_by_name_and_chanel(command_name, channel_id)
    pick_list = command.pick_list[:]
    weight_list = command.weight_list[:]

    selected_items = clean_and_select_from_pick_list(
        pick_list=pick_list,
        weight_list=weight_list,
        user_id=user_id,
        strategy_name=command.strategy,
        number_of_items_to_select=number_of_items_to_select,
        team_id=team_id,
        only_active_users=command.only_active_users,
        self_exclude=command.self_exclude,
    )
    assert_selected_items(selected_items, command.only_active_users,
                          command_name)

    gif_frames = None
    if with_wheel:
        users_names = get_user_names_from_ids(pick_list, team_id)
        gif_frames = build_wheel(
            weight_list, users_names,
            users_names[pick_list.index(selected_items[0])])
    label = create_custom_command_label(command.label, additional_text)

    if should_update_weight_list:
        update_weight_list(command, selected_items)

    return {
        "message":
        Message(
            content=format_custom_command_message(user_id, selected_items,
                                                  label),
            visibility=MessageVisibility.NORMAL,
            as_attachment=False,
        ),
        "selected_items":
        selected_items,
        "additional_text":
        additional_text,
        "number_of_items_to_select":
        number_of_items_to_select,
        "gif_frames":
        gif_frames,
        "with_wheel":
        with_wheel,
    }
Beispiel #11
0
def test_slash_command_custom(client):
    Command.create(
        name="test_custom",
        channel_id="1234",
        label="label",
        description="description",
        pick_list=["pick_1", "pick_2"],
        weight_list=[1 / 2, 1 / 2],
        strategy=Strategy.uniform.name,
        self_exclude=False,
        only_active_users=False,
        created_by_user_id="4321",
    )
    text = "test_custom"
    response, slack_message = call_webhook(client, text)

    assert response.status_code == 200
    assert "Hey !" in slack_message
Beispiel #12
0
def delete_command_processor(
    *,
    channel_id: str,
    command_to_delete: str,
) -> dict[str, any]:
    command = Command.find_one_by_name_and_chanel(command_to_delete,
                                                  channel_id)
    Command.delete_command(command)

    message_content = f"Command {command_to_delete} successfully deleted."

    return {
        "message":
        Message(
            content=message_content,
            status=MessageStatus.INFO,
            visibility=MessageVisibility.NORMAL,
        )
    }
Beispiel #13
0
def open_main_modal_processor(
    *,
    channel_id: str,
    **kwargs,
) -> dict[str, any]:
    commands = Command.find_all_in_chanel(channel_id)
    modal = build_main_modal(channel_id=channel_id,
                             commands=commands,
                             **kwargs)

    return {"modal": modal}
Beispiel #14
0
def compute_fields_updated_for_standard_fields(
        previous_command: Command, new_command: Command) -> dict[str, any]:
    standard_fields_to_track = [
        "name",
        "label",
        "description",
        "self_exclude",
        "only_active_users",
        "strategy",
    ]

    fields_updated = {}
    previous_command_dict, new_command_dict = (
        previous_command.to_son(),
        new_command.to_son(),
    )
    for field in standard_fields_to_track:
        if previous_command_dict[field] != new_command_dict[field]:
            fields_updated[field] = new_command_dict[field]

    return fields_updated
Beispiel #15
0
def test_delete(client):
    Command.create(
        name=command_name,
        channel_id=channel_id,
        label="label",
        description="description",
        pick_list=["1", "2"],
        weight_list=[1 / 2, 1 / 2],
        strategy=Strategy.uniform.name,
        self_exclude=True,
        only_active_users=False,
        created_by_user_id="4321",
    )
    response = delete_command_processor(channel_id=channel_id,
                                        command_to_delete=command_name)

    message = response.get("message")

    assert "Command test_delete successfully deleted." == message.content
    assert message.status == MessageStatus.INFO
    assert message.visibility == MessageVisibility.NORMAL
Beispiel #16
0
def main_modal_delete_command_processor(
    *,
    command_id: str,
    channel_id: str,
    **kwargs,
) -> dict[str, any]:
    command = Command.find_by_id(command_id)

    return delete_command_processor(
        channel_id=channel_id,
        command_to_delete=command.name,
    )
Beispiel #17
0
def test_slash_command_delete(client):
    Command.create(
        name="test_delete",
        channel_id="1234",
        label="label",
        description="description",
        pick_list=["1", "2"],
        weight_list=[1 / 2, 1 / 2],
        strategy=Strategy.uniform.name,
        self_exclude=True,
        only_active_users=False,
        created_by_user_id="4321",
    )
    text = "delete test_delete"
    response, slack_message = call_webhook(client, text)

    assert response.status_code == 200
    assert "Command test_delete successfully deleted." in slack_message

    with pytest.raises(Command.DoesNotExist):
        Command.find_one_by_name_and_chanel("test_delete", "1234", catch=False)
Beispiel #18
0
def test_slash_command_delete_fail(client):
    Command.create(
        name="test_delete",
        channel_id="1234",
        label="label",
        description="description",
        pick_list=["1", "2"],
        weight_list=[1 / 2, 1 / 2],
        strategy=Strategy.uniform.name,
        self_exclude=True,
        only_active_users=False,
        created_by_user_id="4321",
    )
    text = "delete test_delete_unknown_command"
    response, slack_message = call_webhook(client, text)

    assert response.status_code == 200
    assert "Command test_delete_unknown_command does not exist" in slack_message

    command = Command.find_one_by_name_and_chanel("test_delete", "1234")
    assert command is not None
Beispiel #19
0
def test_command() -> Command:
    return Command.create(
        name=TEST_COMMAND_NAME,
        channel_id=TEST_COMMAND_CHANNEL_ID,
        label=TEST_COMMAND_LABEL,
        description=TEST_COMMAND_DESCRIPTION,
        pick_list=TEST_COMMAND_PICK_LIST,
        weight_list=TEST_WEIGHT_LIST,
        strategy=TEST_STRATEGY,
        self_exclude=False,
        only_active_users=False,
        created_by_user_id=TEST_COMMAND_CREATED_BY,
    )
Beispiel #20
0
def test_slash_command_custom_update_weight_list(client):
    name = "test_custom"
    channel_id = "1234"
    Command.create(
        name="test_custom",
        channel_id="1234",
        label="label",
        description="description",
        pick_list=["pick_1", "pick_2"],
        weight_list=[1, 0],
        strategy=Strategy.round_robin.name,
        self_exclude=False,
        only_active_users=False,
        created_by_user_id="4321",
    )
    response, slack_message = call_webhook(client, name)

    assert response.status_code == 200
    assert "Hey !" in slack_message

    command = Command.find_one_by_name_and_chanel(name=name,
                                                  channel_id=channel_id)
    assert command.weight_list == [0, 1]
Beispiel #21
0
def main_modal_update_command_processor(
    *,
    command_id: str,
    **kwargs,
) -> dict[str, any]:
    command = Command.find_by_id(command_id)

    modal = build_upsert_command_modal(
        True,
        channel_id=command.channel_id,
        command_name=command.name,
        description=command.description,
        label=command.label,
        pick_list=command.pick_list,
        strategy=command.strategy,
        self_exclude=command.self_exclude,
        only_active_users=command.only_active_users,
    )
    return {"modal": modal}
Beispiel #22
0
def build_custom_command_modal_processor(
    *,
    command_name: str,
    channel_id: str,
    additional_text: str = None,
    number_of_items_to_select: int = None,
    with_wheel: bool = False,
    **kwargs,
) -> dict[str, any]:
    command = Command.find_one_by_name_and_chanel(command_name, channel_id)
    modal = build_custom_command_modal(
        command_id=command._id,
        command_name=command.name,
        size_of_pick_list=len(command.pick_list),
        additional_text=additional_text,
        number_of_items_to_select=number_of_items_to_select,
        with_wheel=with_wheel,
    )
    return {"modal": modal}
Beispiel #23
0
def create_heat_map(command_name: str, channel_id: str) -> tuple[any, str]:
    command = Command.find_one_by_name_and_chanel(command_name, channel_id)
    item_to_color = map_item_to_color(command.pick_list)
    strategy = get_strategy(command.strategy, command.weight_list)

    n = len(command.pick_list)
    initial_img_size = max(100 / n, math.ceil(100 / n)) * n
    img_final_size = 5 * initial_img_size

    img = Image.new("HSV", (initial_img_size, initial_img_size), "black")
    pixels = img.load()
    for i in range(img.size[0]):
        for j in range(img.size[1]):
            [selected_item] = select_from_pick_list(
                initial_pick_list=command.pick_list,
                initial_weight_list=strategy.weight_list,
                strategy_name=command.strategy,
                number_of_items_to_select=1,
                team_id=None,
                only_active_users=False,
            )
            pixels[i, j] = (
                item_to_color[selected_item],
                saturation,
                lightness,
            )
            strategy.update(
                indices_selected=[command.pick_list.index(selected_item)])

    img = img.resize((img_final_size, img_final_size), Image.NEAREST)
    img = img.convert(mode="RGB")

    file_buffer = io.BytesIO()
    img.save(file_buffer, "png")
    file_buffer.seek(0)

    mimetype = "image/png"

    return file_buffer, mimetype
Beispiel #24
0
def test_create(input_data, expected_command, expected_message, client):
    if not input_data.get("pick_list"):
        input_data["pick_list"] = default_pick_list

    response = create_command_processor(
        user_id=user_id,
        team_id=team_id,
        channel_id=channel_id,
        new_command_name=command_name,
        **input_data,
    )

    message = response.get("message")
    if expected_message:
        assert expected_message in message.content
    assert message.status == MessageStatus.SUCCESS
    assert message.visibility == MessageVisibility.NORMAL

    created_command = (Command.find_one_by_name_and_chanel(
        name=command_name, channel_id=channel_id).to_son().to_dict())

    for key in expected_command:
        assert created_command[key] == expected_command[key]
Beispiel #25
0
def get_basic_data_from_command_id(command_id: str):
    command = Command.find_by_id(command_id)
    return {
        "channel_id": command.channel_id,
        "command_name": command.name,
    }
Beispiel #26
0
def basic_command(client):
    command = create_and_return_command(**default_command)
    yield command
    Command.delete_command(command)
Beispiel #27
0
import numpy as np

from scripts.connection import *  # noqa F401, F403
from server.orm.command import Command

commands = Command.objects.raw({})

print(f"RECOVERING DATA {commands.count()} COMMANDS !")

for command in commands:
    weight_list = command.weight_list
    try:
        if weight_list and np.sum(weight_list) != 1:
            Command.update(
                command.name,
                command.channel_id,
                command.updated_by_user_id,
                {
                    "weight_list": list(np.array(weight_list) / np.sum(weight_list)),
                },
            )
    except Exception as err:
        print(err)
Beispiel #28
0
def create_and_return_command(**kwargs):
    Command.create(**kwargs)
    return Command.find_one_by_name_and_chanel(kwargs["name"],
                                               kwargs["channel_id"])
from scripts.connection import *  # noqa F401, F403
from server.orm.command import Command
from server.service.strategy.enum import Strategy

commands = Command.objects.raw({"strategy": None})

print(f"UPDATING {commands.count()} COMMANDS !")

for command in commands:
    try:
        Command.update(
            command.name,
            command.channel_id,
            command.updated_by_user_id,
            {
                "strategy":
                Strategy.uniform.name,
                "weight_list":
                [1 / len(command.pick_list) for _ in command.pick_list],
            },
        )
    except Exception as err:
        print(err)