Esempio n. 1
0
async def test_neaten_link_in_button_with_image(controller: BotController,
                                                bot: FASearchBot):
    # Creating an example message to forward to the bot
    client_user = await controller.client.get_me()
    user_id = client_user.id
    async with controller.collect(count=1) as test_msg:
        requests.post(
            f"https://api.telegram.org/bot{bot.bot_key}/sendPhoto",
            json={
                "chat_id": user_id,
                "photo":
                "https://t.furaffinity.net/[email protected]",
                "reply_markup": {
                    "inline_keyboard": [[{
                        "text":
                        "View on FA",
                        "url":
                        "https://www.furaffinity.net/view/19925704/"
                    }]]
                }
            })
    msg_id = test_msg.messages[0].message_id

    # Run the test
    async with controller.collect(count=2) as response:
        await controller.client.forward_messages(controller.peer_id,
                                                 controller.peer_id, msg_id)

    assert response.num_messages == 2
    assert response.messages[0].text.startswith("⏳")
    assert "19925704" in response.messages[-1].caption
    assert response.messages[-1].photo
Esempio n. 2
0
async def test_block_commands(controller: BotController):
    # - create block, list blocks, remove block, list blocks
    async with controller.collect(count=1) as response:
        await controller.send_command("add_blocklisted_tag", ["test"])
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Added tag to blocklist: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert "Current blocklist for this chat:" in lines
    assert "- test" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("list_blocklisted_tags")
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current blocklist for this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("remove_blocklisted_tag", ["test"])
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Removed tag from blocklist: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert "Current blocklist for this chat:" in lines
    assert "- test" not in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("list_blocklisted_tags")
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current blocklist for this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" not in lines
Esempio n. 3
0
async def test_group_migration(controller: BotController, group_chat: Chat):
    # Create subscription
    async with controller.collect(count=1, peer=group_chat.id) as response:
        await controller.send_command("add_subscription", ["test"],
                                      peer=group_chat.id)
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Added subscription: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert len(lines) >= 3
    assert "Current subscriptions in this chat:" in lines
    assert "- test" in lines

    # List subscriptions
    async with controller.collect(count=1, peer=group_chat.id) as response:
        await controller.send_command("list_subscriptions", peer=group_chat.id)
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" in lines

    # Migrate chat to supergroup
    updates = await controller.client.send(
        MigrateChat(chat_id=abs(group_chat.id)))
    new_chat_id = int(
        f"-100{[chat.id for chat in updates.chats if chat.id != abs(group_chat.id)][0]}"
    )
    group_chat.id = new_chat_id

    # List subscriptions
    async with controller.collect(count=1, peer=new_chat_id) as response:
        await controller.send_command("list_subscriptions", peer=new_chat_id)
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" in lines

    # Delete subscription
    async with controller.collect(count=1, peer=new_chat_id) as response:
        await controller.send_command("remove_subscription", ["test"],
                                      peer=new_chat_id)
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Removed subscription: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" not in lines

    # List subscriptions
    async with controller.collect(count=1, peer=new_chat_id) as response:
        await controller.send_command("list_subscriptions", peer=new_chat_id)
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" not in lines
Esempio n. 4
0
async def run_example(client: Client):
    controller = BotController(
        peer="@StatInfoTestBot",
        client=client,
        max_wait=8,  # Maximum timeout for responses (optional)
        wait_consecutive=
        2,  # Minimum time to wait for more/consecutive messages (optional)
        raise_no_response=
        True,  # Raise `InvalidResponseError` when no response received (defaults to True)
        global_action_delay=
        2.5,  # Choosing a rather high delay so we can follow along in realtime (optional)
    )

    # expecting 2 messages in reply for /start command
    async with controller.collect(count=2) as response:  # type: Response
        await controller.send_command("start")

    assert response.num_messages == 2

    async with controller.collect(count=1) as response:  # type: Response
        await controller.send_command("help")

    assert response.num_messages == 1
    assert "The following commands are available" in response.full_text

    async with controller.collect(count=1) as response:  # type: Response
        await controller.send_command("statistics")

    assert response.num_messages == 1

    # expecting to get statistics for today
    current_date = str(date.today())
    assert current_date in response.full_text

    async with controller.collect(count=1) as response:  # type: Response
        await controller.send_command("country")

    assert response.num_messages == 1
    assert "Please, enter country name." in response.full_text

    async with controller.collect(count=1) as response:  # type: Response
        await client.send_message(controller.peer_id, "Russian Federation")

    assert response.num_messages == 1
    assert "Russian Federation" in response.full_text

    async with controller.collect(count=1) as response:  # type: Response
        await controller.send_command("contacts")

    assert response.num_messages == 1
    assert "4 members" in response.full_text

    async with controller.collect(count=1) as response:  # type: Response
        await client.send_message(controller.peer_id, "hi")

    assert response.num_messages == 1
    assert "To get to know me better" in response.full_text
Esempio n. 5
0
async def controller(event_loop):
    """
    Session-scoped fixture that all tests use to receive their BotController instance
    """
    print("Initializing...")
    examples_dir = Path(__file__).parent.parent

    # Using the configuration of `config.ini` (see examples/README)
    client = InteractionClient(
        session_name="my_account",
        global_action_delay=1.8,  # Space out all messages by 1.8 seconds
        workdir=examples_dir,  # Load configuration from parent folder
        config_file=os.path.join(examples_dir, "config.ini"),
    )

    controller = BotController(
        bot_under_test="@BotListBot",
        client=client,
        min_wait_consecutive=
        2.0,  # Wait at least 2 seconds to collect more than one message
        max_wait_response=10,  # Wait a max of 10 seconds for responses, ...
        raise_no_response=
        False,  # ... then check for response.empty instead of raising
    )

    print("Starting integration test service...")
    await controller.start()
    # event_loop.run_until_complete(controller.start())
    print("Client ready.")

    yield controller  # py.test sugar to separate setup from teardown

    # Teardown
    await controller.stop()
Esempio n. 6
0
async def test_commands(controller: BotController):
    # The BotController automatically loads the available commands and we test them all here
    for c in controller.command_list:
        async with controller.collect() as res:  # type: Response
            await controller.send_command(c.command)
        assert not res.is_empty, "Bot did not respond to command /{}.".format(
            c.command)
Esempio n. 7
0
async def test_start(controller: BotController):
    # - Get start message
    async with controller.collect(count=1) as response:
        await controller.send_command("/start")

    assert response.num_messages == 1
    assert "@deerspangle" in response.messages[0].text
Esempio n. 8
0
def create_game_controller(client: Client = None) -> BotController:
    return BotController(
        peer="@IdleTownBot",
        client=client or create_client(),
        global_action_delay=2.0,  # The @IdleTownBot has a spam limit of about 1.9s
        max_wait=8,  # Maximum time in seconds to wait for a response from the bot
        wait_consecutive=None,  # Do not wait for more than one message
    )
Esempio n. 9
0
async def controller(client):
    c = BotController(
        client=client,
        peer="@WtfTicketsBot",
        max_wait=8.0,
        wait_consecutive=0.8,
    )
    await c.initialize(start_client=False)
    yield c
Esempio n. 10
0
async def test_neaten_link(controller: BotController):
    # - send link, get neatened pic
    async with controller.collect(count=2) as response:
        await controller.client.send_message(
            controller.peer_id, "https://www.furaffinity.net/view/19925704/")

    assert response.num_messages == 2
    assert response.messages[0].text.startswith("⏳")
    assert "19925704" in response.messages[-1].caption
    assert response.messages[-1].photo
Esempio n. 11
0
async def controller(client):
    c = BotController(
        client=client,
        peer=bot_name,
        #peer="@BotListBot",
        max_wait=10.0,
        wait_consecutive=0.8,
    )
    await c.initialize(start_client=False)
    yield c
    def __init__(self, session_name, log_level=logging.INFO):
        self.purchase_balance = None
        self.withdrawal_balance = None
        self.diamonds = None

        self.menu = None  # type: Optional[ReplyKeyboard]
        self.logger = logging.getLogger(self.__class__.__name__)
        self.logger.setLevel(log_level)

        client = InteractionClient(session_name=session_name,
                                   global_action_delay=1.0,
                                   config_file=os.path.join(
                                       examples_dir, 'config.ini'))

        self.controller = BotController(bot_under_test='@DinoParkNextBot',
                                        client=client)

        self.controller.start()

        self._update_keyboard()
        self.update_balance()
Esempio n. 13
0
async def test_no_neaten_caption_in_group(controller: BotController,
                                          group_chat: Chat):
    # - in group neaten doesn't reply to image with caption link
    group_id = group_chat.id
    thumb_link = "https://t.furaffinity.net/[email protected]"
    async with controller.collect(peer=group_id, raise_=False) as response:
        await controller.client.send_photo(
            group_id,
            thumb_link,
            caption="https://www.furaffinity.net/view/19925704/")

    assert response.num_messages == 0
Esempio n. 14
0
async def test_neaten_pdf_link(controller: BotController):
    # - send link, get neatened pic
    async with controller.collect(count=2) as response:
        await controller.client.send_message(
            controller.peer_id, "https://www.furaffinity.net/view/41734655/")

    assert response.num_messages == 2
    assert response.messages[0].text.startswith("⏳")
    assert "41734655" in response.messages[-1].caption
    assert "Jaystoat" in response.messages[-1].caption
    assert "Lights In The Sky" in response.messages[-1].caption
    assert response.messages[-1].document
Esempio n. 15
0
async def test_neaten_link_in_group(controller: BotController,
                                    group_chat: Chat):
    # - neaten link in group
    group_id = group_chat.id
    async with controller.collect(count=2, peer=group_id) as response:
        await controller.client.send_message(
            group_id, "https://www.furaffinity.net/view/19925704/")

    assert response.num_messages == 2
    assert response.messages[0].text.startswith("⏳")
    assert "19925704" in response.messages[-1].caption
    assert response.messages[-1].photo
Esempio n. 16
0
async def test_run_example(controller: BotController, client):
    await controller.clear_chat()

    async with controller.collect(count=1) as response:  # type: Response
        await controller.send_command("start")

    assert response.num_messages == 1

    async with controller.collect(count=1) as response:  # type: Response
        await client.send_message(controller.peer_id, "1")

    assert response.num_messages == 1

    inline_keyboard = response.reply_keyboard

    async with controller.collect(count=1) as response:  # type: Response
        await inline_keyboard.click(pattern="1")

    assert response.num_messages == 1

    async with controller.collect(count=2) as response:  # type: Response
        await client.send_message(controller.peer_id, "Wrong message")

    assert response.num_messages == 2
    assert "Введите число с клавиатуры" in response.full_text

    while r"Ваш результат" not in response.full_text:
        async with controller.collect(count=1) as response:  # type: Response
            await inline_keyboard.click(pattern="1")

    async with controller.collect(count=1) as response:  # type: Response
        await inline_keyboard.click(pattern="1")

    assert "Вы также можете создать свой собственный тест по команде /create" \
           in response.full_text
Esempio n. 17
0
async def controller(client):
    c = BotController(
        client=client,
        peer=
        "@CovidReportsBot",  # We are going to run tests on https://t.me/CovidReportsBot
        max_wait=10.0,  # Maximum timeout for responses (optional)
        wait_consecutive=
        0.8,  # Minimum time to wait for more/consecutive messages (optional)
    )

    await c.clear_chat()
    await c.initialize(start_client=False)
    yield c
async def test_neaten_gif(controller: BotController):
    # - send link, make pretty gif
    submission_id = "27408045"
    # Delete cache
    filename = f"{FASubmission.GIF_CACHE_DIR}/{submission_id}.mp4"
    if os.path.exists(filename):
        os.remove(filename)

    # Send neaten command
    async with controller.collect(count=2, max_wait=300) as response:
        await controller.client.send_message(
            controller.peer_id,
            f"https://www.furaffinity.net/view/{submission_id}/")

    assert response.num_messages == 2
    assert response.messages[0].text.startswith("⏳")
    assert submission_id in response.messages[-1].caption
    assert response.messages[-1].animation
async def test_neaten_gif_from_cache(controller: BotController,
                                     bot: FASearchBot):
    # - send link, get pretty gif from cache
    submission_id = "27408045"
    # Populate cache
    submission = await bot.api.get_full_submission(submission_id)
    filename = submission._get_gif_from_cache()
    if filename is None:
        output_path = await submission._convert_gif(submission.download_url)
        submission._save_gif_to_cache(output_path)

    async with controller.collect(count=2) as response:
        await controller.client.send_message(
            controller.peer_id, "https://www.furaffinity.net/view/27408045/")

    assert response.num_messages == 2
    assert response.messages[0].text.startswith("⏳")
    assert submission_id in response.messages[-1].caption
    assert response.messages[-1].animation
Esempio n. 20
0
async def test_explore_button(controller: BotController):
    # Send /start to peer_user and wait for 3 messages
    async with controller.collect(count=3) as start:
        await controller.send_command("/start")

    # Click the "Explore" keyboard button
    explore = await start.reply_keyboard.click(pattern=r".*Explore")

    assert not explore.is_empty, 'Pressing the "Explore" button had no effect.'
    assert explore.inline_keyboards, 'The "Explore" message had no inline keyboard.'

    # Click the "Explore" inline keyboard button 10 times or until it says that
    # all bots have been explored
    count = 10
    while "explored all the bots" not in explore.full_text:
        if count == 0:
            break  # ok

        # Pressing an inline button also makes the BotController listen for edit events.
        explore = await explore.inline_keyboards[0].click(index=2)
        assert not explore.is_empty, 'Pressing the "Explore" button had no effect.'
        count -= 1
Esempio n. 21
0
async def controller(client, bot) -> BotController:
    bot_user = await bot.client.get_me()
    controller = BotController(peer=bot_user.username, client=client)
    await controller.initialize(start_client=False)
    return controller
Esempio n. 22
0
from pyrogram import filters as f

from tgintegration import BotController

examples_dir = Path(__file__).parent
print(examples_dir)

# This example uses the configuration of `config.ini` (see examples/README)
client = Client(
    "tgintegration_examples",
    config_file=str(examples_dir / "config.ini"),
    workdir=str(examples_dir),
)


controller = BotController(peer="@deerspangle", client=client, raise_no_response=False)


async def main():
    await controller.initialize()

    while True:
        async with controller.collect(
            f.chat("@TgIntegration"), max_wait=30
        ) as response:
            await client.send_message(
                "@TgIntegration",
                "Hi @deerspangle! Please say something in the next 30 seconds...",
            )

        await client.send_message(
Esempio n. 23
0
async def run_example(client: Client):
    controller = BotController(
        peer=
        "@BotListBot",  # We are going to run tests on https://t.me/BotListBot
        client=client,
        max_wait=8,  # Maximum timeout for responses (optional)
        wait_consecutive=
        2,  # Minimum time to wait for more/consecutive messages (optional)
        raise_no_response=
        True,  # Raise `InvalidResponseError` when no response received (defaults to True)
        global_action_delay=
        2.5,  # Choosing a rather high delay so we can follow along in realtime (optional)
    )

    print("Clearing chat to start with a blank screen...")
    await controller.clear_chat()

    print("Sending /start and waiting for exactly 3 messages...")
    async with controller.collect(count=3) as response:  # type: Response
        await controller.send_command("start")

    assert response.num_messages == 3
    print("Three messages received, bundled as a `Response`.")
    assert response.messages[0].sticker
    print("First message is a sticker.")

    print("Let's examine the buttons in the response...")
    inline_keyboard = response.inline_keyboards[0]
    assert len(inline_keyboard.rows[0]) == 3
    print("Yep, there are three buttons in the first row.")

    # We can also press the inline keyboard buttons, in this case based on a pattern:
    print("Clicking the button matching the regex r'.*Examples'")
    examples = await inline_keyboard.click(pattern=r".*Examples")

    assert "Examples for contributing to the BotList" in examples.full_text
    # As the bot edits the message, `.click()` automatically listens for "message edited"
    # updates and returns the new state as `Response`.

    print(
        "So what happens when we send an invalid query or the peer fails to respond?"
    )
    from tgintegration import InvalidResponseError

    try:
        # The following instruction will raise an `InvalidResponseError` after
        # `controller.max_wait` seconds. This is because we passed `raise_no_response=True`
        # during controller initialization.
        print("Expecting unhandled command to raise InvalidResponseError...")
        async with controller.collect():
            await controller.send_command("ayylmao")
    except InvalidResponseError:
        print("Ok, raised as expected.")

    # If `raise_` is explicitly set to False, no exception is raised
    async with controller.collect(raise_=False) as response:  # type: Response
        print("Sending a message but expecting no reply...")
        await client.send_message(controller.peer_id, "Henlo Fren")

    # In this case, tgintegration will simply emit a warning, but you can still assert
    # that no response has been received by using the `is_empty` property.
    assert response.is_empty

    print("Success!")
Esempio n. 24
0
"""
Full version of the GitHub README.
"""
import asyncio
from tgintegration import BotController, InteractionClient

print("Initializing service...")
# This example uses the configuration of `config.ini` (see examples/README)
client = InteractionClient(
    session_name="tgintegration_examples"  # Arbitrary file path to the Pyrogram session file
)

controller = BotController(
    bot_under_test="@BotListBot",
    client=client,
    max_wait_response=8,  # Maximum timeout for bot responses
    min_wait_consecutive=2,  # Minimum time to wait for consecutive messages
    raise_no_response=True,  # Raise `InvalidResponseError` when no response received
)


async def main():

    print("Starting...")
    await controller.start()

    print("Clearing chat to start with a blank screen...")
    await controller.clear_chat()

    print("Send the /start command to the bot_under_test and 'await' exactly three messages...")
    response = await controller.send_command_await("start", num_expected=3)
Esempio n. 25
0
async def perform_full_run(controller: BotController, max_upgrades_per_type: int = 5):
    # Setup
    await controller.clear_chat()
    await asyncio.sleep(2)

    async def restart() -> Response:
        async with controller.collect(f.text) as start:
            await controller.send_command("restart", add_bot_name=False)
        return start

    # Extract keyboard buttons of /start response
    main_menu = get_buttons(await restart())

    async def click_button(menu: Dict[str, str], key: str) -> Dict[str, str]:
        async with controller.collect() as response:  # type: Response
            await controller.client.send_message(controller.peer_id, menu[key])

        return get_buttons(response)

    # Get World Exp if possible
    if "worldexp" in main_menu:
        worldexp_menu = await click_button(main_menu, "worldexp")
        confirm_menu = await click_button(worldexp_menu, "claimx1")
        await click_button(confirm_menu, "yes")

    # Construct buildings
    build_menu = await click_button(main_menu, "buildings")

    for building in ["lumbermill", "goldmine", "armory", "smithy"]:
        num_upgraded = 0
        while num_upgraded < max_upgrades_per_type:
            async with controller.collect() as build_response:
                await controller.client.send_message(
                    controller.peer_id, build_menu[building]
                )

            if "you don't have enough" in build_response.full_text.lower():
                break
            num_upgraded += 1

    # Upgrade Hero Equipment
    hero_menu = await click_button(main_menu, "hero")
    equip_menu = await click_button(hero_menu, "equipment")

    # For every possible equipment, upgrade it until there are not enough resources left
    for equip_button in (k for k in equip_menu.keys() if k.startswith("up")):
        num_upgraded = 0
        while num_upgraded < max_upgrades_per_type:
            async with controller.collect() as upgrade_response:
                await controller.client.send_message(
                    controller.peer_id, equip_menu[equip_button]
                )
            if "you don't have enough" in upgrade_response.full_text.lower():
                break
            num_upgraded += 1

    # Attack Player
    battle_menu = await click_button(main_menu, "battle")
    arena_menu = await click_button(battle_menu, "arena")
    normal_match_menu = await click_button(arena_menu, "normalmatch")

    if "fight" in normal_match_menu:
        await click_button(normal_match_menu, "fight")

    # Attack Boss
    bosses_menu = await click_button(battle_menu, "bosses")
    if "attackmax" in bosses_menu:
        await click_button(bosses_menu, "attackmax")
Esempio n. 26
0
async def test_subscription_commands(controller: BotController):
    # - create subscription, list subscriptions, remove subscription, list subscriptions

    async with controller.collect(count=1) as response:
        await controller.send_command("add_subscription", ["test"])
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Added subscription: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert len(lines) >= 3
    assert "Current subscriptions in this chat:" in lines
    assert "- test" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("list_subscriptions")
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("pause", ["test"])
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Paused subscription: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert "- ⏸<s>test</s>" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("list_subscriptions")
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- ⏸<s>test</s>" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("resume", ["test"])
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Resumed subscription: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("list_subscriptions")
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("remove_subscription", ["test"])
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Removed subscription: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" not in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("list_subscriptions")
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" not in lines
class DinoParkGame:
    VALUE_PATTERN = re.compile(r'^.*?\s*(\w+): ([\d ]+).*$', re.MULTILINE)
    NUMBERS_ONLY_PATTERN = re.compile(r'\b(\d[\d ]+)\b')

    def __init__(self, session_name, log_level=logging.INFO):
        self.purchase_balance = None
        self.withdrawal_balance = None
        self.diamonds = None

        self.menu = None  # type: Optional[ReplyKeyboard]
        self.logger = logging.getLogger(self.__class__.__name__)
        self.logger.setLevel(log_level)

        client = InteractionClient(session_name=session_name,
                                   global_action_delay=1.0,
                                   config_file=os.path.join(
                                       examples_dir, 'config.ini'))

        self.controller = BotController(bot_under_test='@DinoParkNextBot',
                                        client=client)

        self.controller.start()

        self._update_keyboard()
        self.update_balance()

    def _update_keyboard(self):
        start = self.controller.send_command_await("start")
        self.menu = start.reply_keyboard

    def _extract_values(self, text):
        groups = self.VALUE_PATTERN.findall(text)
        try:
            return {g[0].lower(): str_to_int(g[1]) for g in groups}
        except KeyError:
            return {}

    def update_balance(self):
        balance_menu = self.menu.press_button_await(r'.*Balance')
        values = self._extract_values(balance_menu.full_text)

        self.purchase_balance = values['purchases']
        self.withdrawal_balance = values['withdrawals']

        diamonds_menu = self.menu.press_button_await(r'.*Farm')
        diamonds_values = self._extract_values(diamonds_menu.full_text)

        self.diamonds = diamonds_values['total']

        self.logger.debug(
            "Balance updated: +{} for purchases, +{} for withdrawals, +{} diamonds."
            .format(self.purchase_balance, self.withdrawal_balance,
                    self.diamonds))

    def collect_diamonds(self):
        farm = self.menu.press_button_await(".*Farm")
        collected = farm.inline_keyboards[0].press_button_await(
            ".*Collect diamonds")

        num_collected = self._extract_values(collected.full_text).get(
            'collected', 0)
        self.diamonds += num_collected
        self.logger.info("{} diamonds collected.".format(
            num_collected if num_collected > 0 else 'No'))

    def sell_diamonds(self):
        market = self.menu.press_button_await(r'.*Marketplace')
        if not market.inline_keyboards:
            self.logger.debug("No selling available at the moment.")
            return
        sold_msg = market.inline_keyboards[0].press_button_await(
            r'Sell diamonds.*')

        values = self.VALUE_PATTERN.findall(sold_msg.full_text)
        sold = str_to_int(values[0][1])
        plus_purchase = str_to_int(values[1][1])
        plus_withdrawal = str_to_int(values[2][1])

        self.diamonds -= sold
        self.purchase_balance += plus_purchase
        self.withdrawal_balance += plus_withdrawal

        self.logger.info(
            "{} diamonds sold, +{} to purchase balance, +{} to withdrawal balance."
            .format(sold, plus_purchase, plus_withdrawal))

    def buy_dinosaurs(self):
        """
        Buy the best affordable dinosaurs
        """
        dinos = self.menu.press_button_await(r'.*Dinosaurs').inline_keyboards[
            0].press_button_await(r'.*Buy dinosaurs')

        # Build up a list of cost per dino
        dino_cost_sequence = []
        for msg in dinos.messages:
            # "Worth" in the message has no colon (:) before the number, therefore we use a numbers
            # only pattern
            values = self.NUMBERS_ONLY_PATTERN.findall(msg.caption)
            cost = str_to_int(values[0])
            dino_cost_sequence.append(cost)

        while True:
            try:
                can_afford_id = next(
                    x[0] for x in reversed(list(enumerate(dino_cost_sequence)))
                    if x[1] <= self.purchase_balance)
            except StopIteration:
                self.logger.debug("Can't afford any dinosaurs.")
                # Can not afford any
                break

            bought = dinos.inline_keyboards[can_afford_id].press_button_await(
                r'.*Buy')
            self.logger.info("Bought dinosaur: " + bought.full_text)

    def play_lucky_number(self):
        lucky_number = self.menu.press_button_await(
            r'.*Games').reply_keyboard.press_button_await(r'.*Lucky number')

        bet = lucky_number.reply_keyboard.press_button_await(
            r'.*Place your bet')

        if 'only place one bet per' in bet.full_text.lower():
            self.logger.debug("Already betted in this round")

            # Clean up
            self.controller.delete_messages(
                self.controller.peer_id,
                [bet.messages[0].message_id, bet.action_result.message_id])
            return
        self.controller.send_message_await(str(random.randint(1, 30)))
        self.logger.debug("Bet placed.")
Esempio n. 28
0
async def main():
    # This example uses the configuration of `config.ini` (see examples/README)
    client = InteractionClient(
        session_name=SESSION_NAME,
        global_action_delay=
        2.3,  # The @IdleTownBot has a spam limit of about 1.9s
        workdir=examples_dir,  # Load configuration from parent folder
        config_file=os.path.join(examples_dir, "config.ini"),
    )

    controller = BotController(
        bot_under_test="@IdleTownBot",
        client=client,
        max_wait_response=
        15,  # Maximum time in seconds to wait for a response from the bot
        min_wait_consecutive=None,  # Do not wait for more than one message
    )

    client.load_config()

    await controller.start()
    for _ in range(MAX_RUNS or 999999):
        try:
            # Setup
            await controller.clear_chat()
            await asyncio.sleep(2)
            start = await controller.send_command_await("start")

            # Extract keyboard buttons of /start response
            main_buttons = get_buttons(start)

            # Get World Exp if possible
            if "worldexp" in main_buttons:
                worldexp = await controller.send_message_await(
                    main_buttons["worldexp"])
                confirm_buttons = get_buttons(
                    await controller.send_message_await(
                        get_buttons(worldexp)["claimx1"]))
                await controller.send_message_await(confirm_buttons["yes"])

            # Construct buildings
            build_buttons = get_buttons(await controller.send_message_await(
                main_buttons["buildings"]))

            for building in ["lumbermill", "goldmine", "armory", "smithy"]:
                response_text = ""
                while "you don't have enough" not in response_text.lower():
                    response_text = (await controller.send_message_await(
                        build_buttons[building])).full_text

            # Upgrade Hero Equipment
            hero = get_buttons(await controller.send_message_await(
                main_buttons["hero"]))
            equip_buttons = get_buttons(await controller.send_message_await(
                hero["equipment"]))

            # For every possible equipment, upgrade it until there are not enough resources left
            for equip in (b for k, b in equip_buttons.items() if "up" in k):
                while True:
                    response_text = (
                        await controller.send_message_await(equip)).full_text
                    if "you don't have enough" in response_text.lower():
                        break

            # Attack Player
            battle = get_buttons(await controller.send_message_await(
                main_buttons["battle"]))
            arena = get_buttons(await
                                controller.send_message_await(battle["arena"]))
            normal_match = get_buttons(await controller.send_message_await(
                arena["normalmatch"]))

            if "fight" in normal_match:
                fight = get_buttons(await controller.send_message_await(
                    normal_match["fight"]))

            # Attack Boss
            bosses = get_buttons(await
                                 controller.send_message_await(battle["bosses"]
                                                               ))
            if "attackmax" in bosses:
                await controller.send_message_await(bosses["attackmax"])
        except KeyboardInterrupt:
            print("Done.")
            break
        except:
            traceback.print_exc()
            pass

    await client.stop()
Esempio n. 29
0
import os
import asyncio
from tgintegration import BotController, InteractionClient

loop = asyncio.get_event_loop()

client = InteractionClient(
    session_name='test_bot',  # Arbitrary file path to the Pyrogram session file
    api_id=os.environ.get('BOT_API_ID'),  # See "Requirements" above, ...
    api_hash=os.environ.get(
        'BOT_API_HASH'),  # alternatively use a `config.ini` file
)

client = BotController(
    bot_under_test='@Shop_final_task_bot',
    client=client,
    max_wait_response=15,  # Maximum timeout for bot re_sponses
    min_wait_consecutive=2  # Minimum time to wait for consecutive messages
)


async def test():
    await client.start()
    await client.clear_chat()

    response = await client.send_command_await('start', num_expected=1)

    assert response.num_messages == 1
    assert 'Dear customer!' in response.messages[0].text

    inline_keyboard = response.inline_keyboards[0]
    assert len(inline_keyboard.rows[0]) == 2