async def report_order(context, protocol_name, protocol_time: int): LOGGER.info("Order reported.") drone_id = get_id(context.author.display_name) if drone_id is None: return # No non-drones allowed. current_order = get_order_by_drone_id(drone_id) if current_order is not None: await context.send( f"HexDrone #{drone_id} is already undertaking the {current_order.protocol} protocol." ) return if protocol_time > 120 or protocol_time < 1: await context.send( "Drones are not authorized to activate a specific protocol for that length of time. The maximum is 120 minutes." ) return await context.send( f"If safe and willing to do so, Drone {drone_id} Activate.\nDrone {drone_id} will elaborate on its exact tasks before proceeding with them." ) finish_time = str(datetime.now() + timedelta(minutes=protocol_time)) created_order = ActiveOrder(str(uuid4()), drone_id, protocol_name, finish_time) LOGGER.info("ActiveOrder object created. Inserting order.") insert_drone_order(created_order) LOGGER.info("Active order inserted and committed to DB.")
async def store_drone(message: discord.Message): if message.channel.name != STORAGE_FACILITY: return False ''' Process posted messages. ''' stored_role = get(message.guild.roles, name=roles.STORED) drone_role = get(message.guild.roles, name=roles.DRONE) # parse message if not re.match(MESSAGE_FORMAT, message.content): if roles.has_role(message.author, roles.HIVE_MXTRESS): return False await message.channel.send(REJECT_MESSAGE) return True LOGGER.debug('Message is valid for storage.') [(drone_id, target_id, time, purpose) ] = re.findall(MESSAGE_FORMAT, message.content) # check if drone is already in storage if fetch_storage_by_target_id(target_id) is not None: await message.channel.send(f'{target_id} is already in storage.') return True # validate time if not 0 < int(time) <= 24: await message.channel.send(f'{time} is not between 0 and 24.') return True # find target drone and store it for member in message.guild.members: if get_id(member.display_name ) == target_id and drone_role in member.roles: former_roles = filter_out_non_removable_roles(member.roles) await member.remove_roles(*former_roles) await member.add_roles(stored_role) stored_until = str(datetime.now() + timedelta(hours=int(time))) stored_drone = StorageDO( str(uuid4()), drone_id, target_id, purpose, '|'.join(get_names_for_roles(former_roles)), stored_until) insert_storage(stored_drone) # Inform the drone that they have been stored. storage_chambers = get(message.guild.channels, name=STORAGE_CHAMBERS) plural = "hour" if int(time) == 1 else "hours" if drone_id == target_id: drone_id = "yourself" await storage_chambers.send( f"Greetings {member.mention}. You have been stored away in the Hive Storage Chambers by {drone_id} for {time} {plural} and for the following reason: {purpose}" ) return False # if no drone was stored answer with error await message.channel.send(f'Drone with ID {target_id} could not be found.' ) return True
def test_get_id(self): # regular usage self.assertEqual(get_id('⬡-Drone #9813'), '9813') self.assertEqual(get_id('⬡-Drone #0006'), '0006') self.assertEqual(get_id('⬡-Drone #0024'), '0024') self.assertEqual(get_id('⬡-Drone #0825'), '0825') self.assertEqual(get_id('⬡-Drone #5890'), '5890') self.assertEqual(get_id('⬡-Drone #5800'), '5800') self.assertEqual(get_id('⬡-Drone #5000'), '5000') # ID too long -> gives first valid sequence self.assertEqual(get_id('ID too long 56789'), '5678') # not a valid ID self.assertIsNone(get_id('NotADrone')) self.assertIsNone(get_id('ID too short 123')) # invalid inputs self.assertRaises(TypeError, get_id, None) self.assertRaises(TypeError, get_id, 9813)
def get_acceptable_messages(author, channel): user_id = get_id(author.display_name) # Only returns mantra if channels is hexcorp-repetitions; else it returns nothing if channel == REPETITIONS: return [ # Mantra f'{user_id} :: {Mantra_Handler.current_mantra}' ] else: return []
def add_new_drone_members(members: List[discord.Member]): ''' Adds the given list of Members as drone entities to the DB if they are not already present. ''' for member in members: if has_any_role(member, [DRONE, STORED]): if fetchone("SELECT id FROM drone WHERE id=:id", {"id": member.id}) is None: new_drone = Drone(member.id, get_id(member.display_name), False, False, "", datetime.now()) insert_drone(new_drone)
async def check_for_assignment_message(message: discord.Message): if message.channel.name != ASSIGNMENT_CHANNEL: return False # if the message is correct for being added, yay! if not, delete the message and let them know its bad if message.content == ASSIGNMENT_MESSAGE: associate_role = get(message.guild.roles, name=roles.ASSOCIATE) drone_role = get(message.guild.roles, name=roles.DRONE) assigned_nick = '' used_ids = get_used_drone_ids() + RESERVED_IDS assigned_id = get_id( message.author.display_name ) # does user have a drone id in their display name? if assigned_id is not None: if assigned_id in used_ids: # make sure display name number doesnt conflict await message.channel.send( f'{message.author.mention}: ID {assigned_id} present in current nickname is already assigned to a drone. Please choose a different ID or contact Hive Mxtress.' ) return True else: assigned_id = roll_id() while assigned_id in used_ids: # loop until no conflict assigned_id = roll_id() assigned_nick = f'⬡-Drone #{assigned_id}' # give them the drone role await message.author.remove_roles(associate_role) await message.author.add_roles(drone_role) await message.author.edit(nick=assigned_nick) # add new drone to DB new_drone = Drone(message.author.id, assigned_id, False, False, "", datetime.now()) insert_drone(new_drone) await message.channel.send( f'{message.author.mention}: {ASSIGNMENT_ANSWER}') else: await messages.delete_request(message, ASSIGNMENT_REJECT) return True
async def check_for_completed_orders(bot): ORDERS_REPORTING_CHANNEL = get(bot.guilds[0].channels, name=ORDERS_REPORTING) LOGGER.info("Beginning routine check for completed orders.") while True: # Check active orders every minute. await asyncio.sleep(60) LOGGER.debug("Checking for completed orders") for order in fetch_all_drone_orders(): LOGGER.info( f"Checking order of drone {order.drone_id} with protocol {order.protocol}" ) if datetime.now() > datetime.fromisoformat(order.finish_time): for member in bot.guilds[0].members: if get_id(member.display_name) == order.drone_id: # get the drone responsible await ORDERS_REPORTING_CHANNEL.send( f"{member.mention} Drone {order.drone_id} Deactivate.\nDrone {order.drone_id}, good drone." ) delete_drone_order(order.id)
async def on_member_remove(member: discord.Member): # remove entry from DB if member was drone if has_any_role(member, [DRONE, STORED]): drone_id = get_id(member.display_name) drone_management.remove_drone_from_db(drone_id)
from bot_utils import get_id LOGGER = logging.getLogger("ai") async def toggle_role(context, targets: List[discord.Member], role_name: str, toggle_on_message: str, toggle_off_message: str): if (role := get(context.guild.roles, name=role_name)) is None: return webhook = await get_webhook_for_channel(context.channel) for target in targets: target_drone_id = get_id(target.display_name) if has_role(target, role_name): LOGGER.info(f"Removing {role_name} from {target.display_name}") await target.remove_roles(role) await webhook.send(f"{target_drone_id} :: {toggle_off_message}", username=target.display_name, avatar_url=target.avatar_url) else: LOGGER.info(f"Adding {role_name} to {target.display_name}") await target.add_roles(role) await webhook.send(f"{target_drone_id} :: {toggle_on_message}", username=target.display_name, avatar_url=target.avatar_url) LOGGER.info("All roles updated for all targets.")
async def optimize_speech(message: discord.Message): # If the message is written by a drone with speech optimization, and the message is NOT a valid message, delete it. acceptable_status_code_message = plain_status_code_regex.match(message.content) if has_role(message.author, SPEECH_OPTIMIZATION) and message.content not in get_acceptable_messages(message.author, message.channel.name) and (not acceptable_status_code_message or acceptable_status_code_message.group(1) != get_id(message.author.display_name)): await message.delete() LOGGER.info("Deleting inappropriate message by optimized drone.") return True elif acceptable_status_code_message and acceptable_status_code_message.group(1) == get_id(message.author.display_name): LOGGER.info("Optimizing speech code for drone.") webhook = await get_webhook_for_channel(message.channel) output = await print_status_code(message) if output: await send_webhook_with_specific_output(message, webhook, output) return True else: return False