Dynamic modification#

This document describes how the framework can be modified dynamically.

Modifying the shilling list#

See Shilling list modification for more information about the functions mentioned below.

While the shilling list can be defined statically (pre-defined) by creating a list and using the server_list parameter in the run() function (see Quickstart and run() (or initialize())), the framework also allows the objects to be added or removed dynamically from the user’s program after the framework has already been started and initialized.

Dynamically adding objects#

Objects can be dynamically added using the daf.core.add_object() coroutine function. The function can be used to add the following object types:

Messages

daf.message.TextMESSAGE

daf.message.VoiceMESSAGE

daf.message.DirectMESSAGE

Note

Messages can also be added thru the daf.guild.GUILD.add_message() / daf.guild.USER.add_message() method.

Caution

The guild must already be added to the framework, otherwise this method will fail.

...
my_guild = daf.GUILD(guild.id, logging=True)
await daf.add_object(my_guild)
await my_guild.add_message(daf.TextMESSAGE(...))
...
"""
The following example automatically generates the shilling list if the channel name matches
any of the allowed_strings words.

It then dynamically adds an object, and later calls .update() method to change the initialization parameters
passed at the start.
"""
from datetime import timedelta
import daf


# Create a list in which we will automatically add guilds
allowed_strings = {"shill", "advert", "promo"}
data_to_shill = (     # Example data set
                "Hello World", 
                daf.discord.Embed(title="Example Embed",
                         color=daf.discord.Color.blue(),
                         description="This is a test embed")
                )

async def user_task():
    # Returns the client to send commands to discord, for more info about client see https://docs.pycord.dev/en/master/api.html?highlight=discord%20client#discord.Client
    client = daf.get_client()  
    for guild in client.guilds:  # Iterate thru all the guilds where the bot is in
        await daf.add_object(
            daf.GUILD(guild.id, logging=True)
        )

        # Find channels that match allowed_strings
        channels = []
        for channel in guild.text_channels: # Iterate thru all the text channels in the guild
            if any([x in channel.name for x in allowed_strings]): # Check if any of the strings in allowed_strings are in the channel name
                channels.append(channel)

        text_msg = daf.TextMESSAGE(None, timedelta(seconds=5), data_to_shill, channels, "send", timedelta(seconds=0))

        # Dynamically add a message to the list
        await daf.add_object(text_msg, guild.id)


############################################################################################
if __name__ == "__main__":
    daf.run(token="OOFOAFO321o3oOOAOO$Oo$o$@O4242",
           user_callback=user_task)  
    

Dynamically removing objects#

As the framework supports dynamically adding new objects to the shilling list, it also supports dynamically removing those objects. Objects can be removed with the daf.core.remove_object().

"""
The following example uses a predefined list of messages to shill.
When the user task is run, it removes the message from the shill list dynamically.
"""
import daf

servers = [
    daf.GUILD(snowflake=213323123, messages=[]) # No messages as not needed for this demonstration
]


async def user_task():
    daf.trace("Removing the GUILD")
    guild = servers[0]
    await daf.remove_object(guild)
    daf.trace("Finished")


############################################################################################
if __name__ == "__main__":
    daf.run(token="OOFOAFO321o3oOOAOO$Oo$o$@O4242",
            user_callback=user_task,
            server_list=servers)  
    

Modifying objects#

Some objects in the framework can be dynamically updated thru the .update() method. The principle is the same for all objects that support this and what this method does is it updates the original parameters that can be passed during object creation.

../_images/update_process.png

Fig. 2 Object update process.#

Warning

This completely resets the state of the object you are updating, meaning that if you do call the .update() method, the object will act like it was recreated.

For example if I wanted to change the shilling period of a daf.message.TextMESSAGE, I would call the daf.message.TextMESSAGE.update() method in the following way:

... # Other code
# Fixed sending period of 5 seconds
my_message = daf.message.TextMESSAGE(
                                        start_period=None,
                                        end_period=timedelta(seconds=5),
                                        ... # Other parameters
                                    )


await daf.add_object(my_message, 123456789)

# Randomized sending period between 3 and 5 seconds
await my_message.update(start_period=timedelta(seconds=3))
... # Other code

For a full list of objects that support .update search “.update” in the search bar or click on the image below.

../_images/search_update_method.png
"""
The following example automatically generates the shilling list if the channel name matches
any of the allowed_strings words.

It then dynamically adds an object, and later calls .update() method to change the initialization parameters
passed at the start.
"""
from datetime import timedelta
import asyncio
import daf



# Create a list in which we will automatically add guilds
allowed_strings = {"shill", "advert", "promo"}
data_to_shill = (     # Example data set
                "Hello World", 
                daf.discord.Embed(title="Example Embed",
                         color=daf.discord.Color.blue(),
                         description="This is a test embed")
                )


async def user_task():
    client = daf.get_client()  
    for guild in client.guilds:  # Iterate thru all the guilds where the bot is in
        await daf.add_object(daf.GUILD(guild.id, logging=True))
        channels = []
        for channel in guild.text_channels: # Iterate thru all the text channels in the guild
            if any([x in channel.name for x in allowed_strings]): # Check if any of the strings in allowed_strings are in the channel name
                channels.append(channel)
        text_msg = daf.TextMESSAGE(None, timedelta(seconds=5), data_to_shill, channels, "send", timedelta(seconds=0))
        # Dynamically add a message to the list
        await daf.add_object(text_msg, guild.id)

    #########################################################################
    #   Dynamic text message modification of the shill data and send period
    #########################################################################
    await asyncio.sleep(10)
    daf.trace("Updating the TextMESSAGE object")
    # Update the object
    await text_msg.update(data="Updated Data", end_period=timedelta(seconds=60)) 

    daf.trace("Now shilling 'Updated Data' with period of 60 seconds")
    #########################################################################

############################################################################################################################################################################


############################################################################################
if __name__ == "__main__":
    daf.run(token="OOFOAFO321o3oOOAOO$Oo$o$@O4242",
           user_callback=user_task)