async def boss_configure(self, author, channel, raid_id): bot = self.bot def check(msg): return author == msg.author msg = await channel.send(_("Please specify the new aim.")) try: response = await bot.wait_for('message', check=check, timeout=30) except asyncio.TimeoutError: return else: try: await response.delete() except discord.NotFound: pass except discord.Forbidden: await channel.send( _("Missing permissions to clean up your response. Please grant me the 'Manage messages' permission in this channel." )) finally: try: await msg.delete() except discord.NotFound: pass boss = response.content char_limit = 255 if len(boss) > char_limit: await channel.send( _("Please use less than {0} characters.").format(char_limit), delete_after=20) return upsert(self.conn, 'Raids', ['boss'], [boss], ['raid_id'], [raid_id]) return
async def post_raid(self, name, tier, boss, timestamp, roster, guild_id, channel, author_id): full_name = self.get_raid_name(name) raid_time = datetime.datetime.utcfromtimestamp(timestamp) # Check if time is in near future. Otherwise parsed date was likely unintended. current_time = int(time.time()) if current_time + 604800 < timestamp: error_message = _( "Please check the date <@{0}>. You are posting a raid for: {1} UTC." ).format(author_id, raid_time) await channel.send(error_message, delete_after=30) post = await channel.send('\u200B') raid_id = post.id raid_columns = [ 'channel_id', 'guild_id', 'organizer_id', 'name', 'tier', 'boss', 'time', 'roster' ] raid_values = [ channel.id, guild_id, author_id, full_name, tier, boss, timestamp, roster ] upsert(self.conn, 'Raids', raid_columns, raid_values, ['raid_id'], [raid_id]) self.roster_init(raid_id) embed = self.build_raid_message(raid_id, "\u200B", None) await post.edit(embed=embed, view=RaidView(self)) self.raids.append(raid_id) await self.create_guild_event(channel, raid_id) self.conn.commit() logger.info("Created new raid: {0} at {1} for guild {2}.".format( full_name, raid_time, guild_id)) await self.calendar_cog.update_calendar(guild_id)
async def select(self, button: discord.ui.Button, interaction: discord.Interaction): if not await self.raid_cog.has_raid_permission( interaction.user, interaction.guild, interaction.message.id): perm_msg = _( "You do not have permission to change the raid settings.") await interaction.response.send_message(perm_msg, ephemeral=True) return raid_id = interaction.message.id available = select(self.conn, 'Players', ['player_id, byname'], ['raid_id', 'unavailable'], [raid_id, False]) if not available: msg = _("There are no players to assign for this raid!") await interaction.response.send_message(msg, ephemeral=True) return msg = _("Please first select the player. The roster is updated when a class is selected. " "You can select a slot manually or leave it on automatic.\n") \ + _("(This selection message is ephemeral and will cease to work after 60s without interaction.)") view = SelectView(self.raid_cog, raid_id) await interaction.response.send_message(msg, view=view, ephemeral=True) roster = select_one(self.conn, 'Raids', ['roster'], ['raid_id'], [raid_id]) if not roster: upsert(self.conn, 'Raids', ['roster'], [True], ['raid_id'], [raid_id])
async def time_configure(self, author, channel, raid_id): bot = self.bot def check(msg): return author == msg.author msg = await channel.send(_("Please specify the new raid time.")) try: response = await bot.wait_for('message', check=check, timeout=30) except asyncio.TimeoutError: return else: try: await response.delete() except discord.NotFound: pass except discord.Forbidden: await channel.send( _("Missing permissions to clean up your response. Please grant me the 'Manage messages' permission in this channel." )) finally: try: await msg.delete() except discord.NotFound: pass try: timestamp = Time().converter(bot, channel.guild.id, author.id, response.content) except commands.BadArgument: error_msg = _("Failed to parse time argument: ") + response.content await channel.send(error_msg, delete_after=20) else: upsert(self.conn, 'Raids', ['time'], [timestamp], ['raid_id'], [raid_id]) return
async def sign_up_cancel(self, i): await i.response.defer() raid_id = i.message.id timestamp = int(time.time()) assigned_slot = select_one(self.conn, 'Assignment', ['slot_id'], ['player_id', 'raid_id'], [i.user.id, raid_id]) if assigned_slot is not None: class_name = select_one(self.conn, 'Assignment', ['class_name'], ['player_id', 'raid_id'], [i.user.id, raid_id]) error_msg = _( "Dearest raid leader, {0} has cancelled their availability. " "Please note they were assigned to {1} in the raid.").format( i.user.mention, class_name) await i.channel.send(error_msg) class_names = ','.join( self.raid_cog.slots_class_names[assigned_slot]) assign_columns = ['player_id', 'byname', 'class_name'] assign_values = [None, _("<Open>"), class_names] upsert(self.conn, 'Assignment', assign_columns, assign_values, ['raid_id', 'slot_id'], [raid_id, assigned_slot]) r = select_one(self.conn, 'Players', ['byname'], ['player_id', 'raid_id'], [i.user.id, raid_id]) if r: delete(self.conn, 'Players', ['player_id', 'raid_id'], [i.user.id, raid_id]) else: byname = self.process_name(i.guild.id, i.user) upsert(self.conn, 'Players', ['byname', 'timestamp', 'unavailable'], [byname, timestamp, True], ['player_id', 'raid_id'], [i.user.id, raid_id]) self.conn.commit() await self.raid_cog.update_raid_post(raid_id, i.channel)
def on_message(client, userdata, msg): topic = msg.topic payload = msg.payload.decode() # print(topic, payload) # save new states from this message save_states(topic, payload) # get all values from database temperature = database.get("sensor", "iot/sensors/section0/temperature") humidity = database.get("sensor", "iot/sensors/section0/humidity") HI = 0.0 # heatindex makes only sense if temperature is over 25 if temperature > 25: HI = heat_index.calculate(float(temperature), float(humidity)) pers_s0 = float(database.get("sensor", person_counter_0)) pers_s1 = float(database.get("sensor", person_counter_1)) pers_s2 = float(database.get("sensor", person_counter_2)) shelf_s1 = float(database.get("sensor", "iot/sensors/section1/shelf")) shelf_s2 = float(database.get("sensor", "iot/sensors/section2/shelf")) print(HI) # save all value to file export.to_problem_file(HI, pers_s0, pers_s1, pers_s2, shelf_s1, shelf_s2, shelf_s1 + shelf_s2) # run ff plan = subprocess.run([ "./ff", "-o", "domain_supermarket.pddl", "-f", "problem_supermarket_generated.pddl" ], stdout=subprocess.PIPE).stdout.decode('utf-8') # parse resulting file new_states = parser.get_states(plan) print(new_states) for (topic, new) in new_states.items(): # get value for matrix leds if topic.startswith("iot/actuators/section") and topic.endswith( "/gate"): section_id = topic.replace("iot/actuators/section", "").replace("/gate", "") value = database.get( "sensor", "iot/sensors/section" + section_id + "/counter") if new: value = "-" new = value # check what should get updated with database old = database.get("actuator", topic) # make sure both datatypes are the same old = str(old) new = str(new) if new != old: database.upsert("actuator", topic, new) mqtt_publish.sendValue(new, topic)
async def on_command_completion(self, ctx): timestamp = int(datetime.now().timestamp()) upsert(self.conn, 'Settings', ['last_command'], [timestamp], ['guild_id'], [ctx.guild.id]) increment(self.conn, 'Settings', 'command_count', ['guild_id'], [ctx.guild.id]) self.conn.commit() await ctx.send(_("**DEPRECATED**: Consider using the new / command."), delete_after=60)
def roster_init(self, raid_id): available = _("<Open>") assignment_columns = ['player_id', 'byname', 'class_name'] for i in range(len(self.slots_class_names)): assignment_values = [ None, available, ','.join(self.slots_class_names[i]) ] upsert(self.conn, 'Assignment', assignment_columns, assignment_values, ['raid_id', 'slot_id'], [raid_id, i])
async def callback(self, interaction: discord.Interaction): tier = self.values[0] upsert(self.view.conn, 'Raids', ['tier'], [tier], ['raid_id'], [self.view.raid_id]) await self.view.raid_cog.update_raid_post(self.view.raid_id, interaction.channel) await self.view.calendar_cog.update_calendar(interaction.guild.id, new_run=False) try: self.view.calendar_cog.modify_guild_event(self.view.raid_id) except requests.HTTPError as e: logger.warning(e.response.text)
async def callback(self, interaction: discord.Interaction): raid_id = self.view.raid_id if self.view.player is None: msg = _("Please select a player first.") await interaction.response.send_message(msg, ephemeral=True) return slot = select_one(self.view.conn, 'Assignment', ['slot_id', 'byname'], ['player_id', 'raid_id'], [self.view.player, raid_id]) if slot is not None: assignment_columns = ['player_id', 'byname', 'class_name'] class_names = ','.join( self.view.raid_cog.slots_class_names[slot[0]]) assignment_values = [None, _("<Open>"), class_names] upsert(self.view.conn, 'Assignment', assignment_columns, assignment_values, ['raid_id', 'slot_id'], [raid_id, slot[0]]) await self.view.raid_cog.update_raid_post(raid_id, interaction.channel) if self.values[0] == 'remove': return signup = select_one(self.view.conn, 'Players', [self.values[0], 'byname'], ['player_id', 'raid_id'], [self.view.player, raid_id]) if not signup[0]: msg = _("{0} did not sign up with {1}.").format( signup[1], self.values[0]) await interaction.response.send_message(msg, ephemeral=True) return if self.view.slot == -1: search = '%' + self.values[0] + '%' slot_id = select_one(self.view.conn, 'Assignment', ['slot_id'], ['raid_id'], [raid_id], ['player_id'], ['class_name'], [search]) else: slot_id = self.view.slot if slot_id is None: msg = _( "There are no slots available for the selected class. " "Please select the slot manually or pick a different class.") await interaction.response.send_message(msg, ephemeral=True) return assignment_columns = ['player_id', 'byname', 'class_name'] assignment_values = [self.view.player, signup[1], self.values[0]] upsert(self.view.conn, 'Assignment', assignment_columns, assignment_values, ['raid_id', 'slot_id'], [raid_id, slot_id]) await self.view.raid_cog.update_raid_post(raid_id, interaction.channel)
def upsert_data(): try: google_sheet_id = request.json['sheet_id'] sheet_info = resource_store.get_sheet_info(google_sheet_id) city, resource_type = itemgetter('city', 'resource_type')(sheet_info) resource_info = resource_store.get_sheet_data(google_sheet_id, resource_store.API_KEY) except Exception as err: return f"Invalid sheet_id: {request.json.get('sheet_id') if isinstance(request.json, object) else ''}", 417 resource_store.upsert(city, resource_type, resource_info, google_sheet_id) return "Successfull"
async def create_guild_event(self, channel, raid_id): try: event_id = self.calendar_cog.create_guild_event(raid_id) except requests.HTTPError as e: logger.warning(e.response.text) err_msg = _( "Failed to create the discord event. Please check the bot has the manage event permission." ) await channel.send(err_msg, delete_after=20) except requests.exceptions.JSONDecodeError as e: err_msg = _("Invalid response from Discord.") await channel.send(err_msg, delete_after=20) else: upsert(self.conn, 'Raids', ['event_id'], [event_id], ['raid_id'], [raid_id])
def parse_priority_slash_command(self, guild_id, user, options): if not user.guild_permissions.administrator: content = _("You must be an admin to change the kin role.") return content if not options: res = upsert(self.conn, 'Settings', ['priority'], [None], ['guild_id'], [guild_id]) content = _("Kin role removed.") return content priority_id = options['role'] res = upsert(self.conn, 'Settings', ['priority'], [priority_id], ['guild_id'], [guild_id]) self.conn.commit() content = _("Successfully updated the kin role!") return content
async def get_new_tweets(self, user_id, last_tweet_id=None): url = "https://api.twitter.com/2/users/{}/tweets".format(user_id) params = {"exclude": "retweets,replies"} if last_tweet_id: params["since_id"] = last_tweet_id json_response = self.connect_to_endpoint(url, params) if not json_response: return count = json_response['meta']['result_count'] if count: for i in range(count - 1, -1, -1): tweet_id = json_response['data'][i]['id'] upsert(self.conn, 'Twitter', ['user_id', 'tweet_id'], [self.twitter_id, tweet_id]) await self.post_tweet_to_servers(tweet_id) self.conn.commit()
async def post_calendar(self, guild_id, channel): embed = self.calendar_cog.calendar_embed(guild_id) msg = await channel.send(embed=embed) ids = "{0}/{1}".format(channel.id, msg.id) res = upsert(self.conn, 'Settings', ['calendar'], [ids], ['guild_id'], [guild_id]) self.conn.commit()
async def timezone(self, ctx, timezone): """Sets the user's default timezone to be used for raid commands.""" conn = self.bot.conn if timezone in [_("delete"), _("reset"), _("default")]: res = delete(conn, 'Timezone', ['player_id'], [ctx.author.id]) if res: conn.commit() await ctx.send( _("Deleted timezone information for {0}.").format( ctx.author.mention)) else: await ctx.send(_("An error occurred.")) return try: tz = pytz.timezone(timezone) except pytz.UnknownTimeZoneError as e: await ctx.send(str(e) + _(" is not a valid timezone!")) else: tz = str(tz) res = upsert(conn, 'Timezone', ['timezone'], [tz], ['player_id'], [ctx.author.id]) if res: conn.commit() await ctx.send( _("Set default timezone for {0} to {1}.").format( ctx.author.mention, tz)) else: await ctx.send(_("An error occurred.")) return
def test_update_category(self): query = {"name": category1.get("name")} set = {"name": "Upsert New", "color": "black"} found = upsert(CategoryModel, query=query, update=set) assert found.name == set.get("name") assert found.color == set.get("color")
async def post_tweet(self, guild_id, chn_id, url): chn = self.bot.get_channel(chn_id) if chn: try: await chn.send(url) except discord.Forbidden: logger.warning( "Missing write access to Twitter channel for guild {0}.". format(guild_id)) upsert(self.conn, 'Settings', ['twitter'], [None], ['guild_id'], [guild_id]) else: logger.warning( "Twitter channel not found for guild {0}.".format(guild_id)) upsert(self.conn, 'Settings', ['twitter'], [None], ['guild_id'], [guild_id])
async def on_guild_join(self, guild): logger.info("We have joined {0}.".format(guild)) timestamp = int(datetime.datetime.now().timestamp()) upsert(self.conn, 'Settings', ['last_command'], [timestamp], ['guild_id'], [guild.id]) self.conn.commit() channels = guild.text_channels channel = find(lambda x: x.name == 'welcome', channels) if not channel or not channel.permissions_for(guild.me).send_messages: channel = find(lambda x: x.name == 'general', channels) # Otherwise pick the first channel the bot can send a message in. if not channel or not channel.permissions_for(guild.me).send_messages: for ch in channels: if ch.permissions_for(guild.me).send_messages: channel = ch break if channel and channel.permissions_for(guild.me).send_messages: msg = self.welcome_msg(guild.name) await channel.send(msg)
def parse_leader_slash_command(self, guild_id, user, options): if not user.guild_permissions.administrator: content = _("You must be an admin to change the raid leader role.") return content leader_id = options['role'] res = upsert(self.conn, 'Settings', ['raid_leader'], [leader_id], ['guild_id'], [guild_id]) self.conn.commit() content = _("Successfully updated the raid leader role!") return content
def test_create_category(self): query = {"name": category1.get("name")} create_category1 = upsert(CategoryModel, query=query, update=category1) assert create_category1.name == category1.get("name") assert create_category1.color == category1.get("color") found = CategoryModel.objects(**query).first() assert found.name == category1.get("name") assert found.color == category1.get("color")
async def sign_up_class(self, i, class_name): try: role = await get_role(i.guild, class_name) if role not in i.user.roles: await i.user.add_roles(role) except discord.Forbidden: err_msg = _( "Error: Missing 'Manage roles' permission to assign the class role." ) await i.response.send_message(err_msg) else: await i.response.defer() raid_id = i.message.id timestamp = int(time.time()) byname = self.process_name(i.guild.id, i.user) upsert(self.conn, 'Players', ['byname', 'timestamp', 'unavailable', class_name], [byname, timestamp, False, True], ['player_id', 'raid_id'], [i.user.id, raid_id]) self.conn.commit() await self.raid_cog.update_raid_post(raid_id, i.channel)
async def leader(self, ctx, *raid_leader): """Sets the role to be used as raid leader in this guild.""" if not ctx.author.guild_permissions.administrator: await ctx.send( _("You must be an admin to change the raid leader role.")) return raid_leader = " ".join(raid_leader) leader_role = discord.utils.get(ctx.guild.roles, name=raid_leader) if leader_role: upsert(self.conn, 'Settings', ['raid_leader'], [leader_role.id], ['guild_id'], [ctx.guild.id]) await ctx.send( _("Raid Leader role set to `{0}`.").format(leader_role)) else: if raid_leader: await ctx.send(_("No role `{0}` found.").format(raid_leader)) else: upsert(self.conn, 'Settings', ['raid_leader'], [None], ['guild_id'], [ctx.guild.id]) await ctx.send(_("Raid leader role deleted.")) self.conn.commit()
async def update_calendar(self, guild_id, new_run=True): conn = self.bot.conn res = select_one(conn, 'Settings', ['calendar'], ['guild_id'], [guild_id]) if not res: return result = res.split("/") chn_id = int(result[0]) msg_id = int(result[1]) chn = self.bot.get_channel(chn_id) try: msg = chn.get_partial_message(msg_id) except AttributeError: logger.warning("Calendar channel not found for guild {0}.".format(guild_id)) res = upsert(conn, 'Settings', ['calendar'], [None], ['guild_id'], [guild_id]) if res: conn.commit() return embed = self.calendar_embed(guild_id) try: await msg.edit(embed=embed) except discord.Forbidden: logger.warning("Calendar access restricted for guild {0}.".format(guild_id)) return except discord.NotFound: logger.warning("Calendar post not found for guild {0}.".format(guild_id)) upsert(conn, 'Settings', ['calendar'], [None], ['guild_id'], [guild_id]) conn.commit() return except discord.HTTPException as e: logger.warning("Failed to update calendar for guild {0}.".format(guild_id)) logger.warning(e) return if new_run: try: await chn.send(_("A new run has been posted!"), delete_after=3600) except discord.Forbidden: logger.warning("No write access to calendar channel for guild {0}.".format(guild_id))
async def sign_up_all(self, i): raid_id = i.message.id role_names = [ role.name for role in i.user.roles if role.name in self.raid_cog.role_names ] if role_names: await i.response.defer() timestamp = int(time.time()) columns = ['byname', 'timestamp', 'unavailable'] columns.extend(role_names) byname = self.process_name(i.guild.id, i.user) values = [byname, timestamp, False] values.extend([True] * len(role_names)) upsert(self.conn, 'Players', columns, values, ['player_id', 'raid_id'], [i.user.id, raid_id]) self.conn.commit() await self.raid_cog.update_raid_post(raid_id, i.channel) else: err_msg = _( "You have not assigned yourself any class roles yet, please sign up with a class first." ) await i.response.send_message(err_msg, ephemeral=True)
def save_states(topic, payload): if topic == "iot/sensors/section0/button/in": if payload == "1": database.increment("sensor", person_counter_0) elif topic == "iot/sensors/section0/button/out": if payload == "1": database.decrement("sensor", person_counter_0) elif topic == "iot/sensors/section1/button/in": if payload == "1": database.increment("sensor", person_counter_1) elif topic == "iot/sensors/section1/button/out": if payload == "1": database.decrement("sensor", person_counter_1) elif topic == "iot/sensors/section2/button/in": if payload == "1": database.increment("sensor", person_counter_2) elif topic == "iot/sensors/section2/button/out": if payload == "1": database.decrement("sensor", person_counter_2) else: if topic.endswith("/shelf"): payload = calculate_items_in_shelf(payload) database.upsert("sensor", topic, payload)
async def prefix(self, ctx, prefix): """Sets the command prefix to be used in this guild.""" conn = self.bot.conn if not ctx.author.guild_permissions.administrator: await ctx.send( _("You must be an admin to change the command prefix.")) return res = upsert(conn, 'Settings', ['prefix'], [prefix], ['guild_id'], [ctx.guild.id]) if res: conn.commit() self.bot.prefixes[ctx.guild.id] = prefix await ctx.send(_("Command prefix set to `{0}`.").format(prefix)) else: await ctx.send(_("An error occurred.")) return
async def calendar(self, ctx): """ Sets the channel to post the calendar in. """ if not await self.is_raid_leader(ctx): return conn = self.bot.conn try: await ctx.message.delete() except discord.Forbidden as e: logger.info(e) embed = self.calendar_embed(ctx.guild.id) msg = await ctx.send(embed=embed) ids = "{0}/{1}".format(ctx.channel.id, msg.id) res = upsert(conn, 'Settings', ['calendar'], [ids], ['guild_id'], [ctx.guild.id]) if res: conn.commit() await ctx.send(_("The Calendar will be updated in this channel."), delete_after=20) else: await ctx.send(_("An error occurred.")) return
async def servertime(self, ctx, timezone): """Sets the timezone to be displayed as server time.""" if not await self.is_raid_leader(ctx): return conn = self.bot.conn try: tz = pytz.timezone(timezone) except pytz.UnknownTimeZoneError as e: await ctx.send(str(e) + _(" is not a valid timezone!")) else: tz = str(tz) res = upsert(conn, 'Settings', ['server'], [tz], ['guild_id'], [ctx.guild.id]) if res: conn.commit() await ctx.send(_("Set server time to {0}.").format(tz)) else: await ctx.send(_("An error occurred.")) return
def process_time_zones_personal(self, user_id, options): conn = self.conn try: timezone = options['custom_timezone'] except KeyError: timezone = options['timezone'] try: tz = pytz.timezone(timezone) except pytz.UnknownTimeZoneError as e: content = _("{0} is not a valid time zone!").format(e) else: tz = str(tz) res = upsert(conn, 'Timezone', ['timezone'], [tz], ['player_id'], [user_id]) if res: conn.commit() content = _("Set your time zone to {0}.").format(tz) else: content = _("An error occurred.") return content
#! /usr/local/bin/python import argparse from reader import ShoeboxedCSVReader import psycopg2 import database desc = 'Extract the transaction section of a Shoeboxed CSV export.' ap = argparse.ArgumentParser(description=desc) ap.add_argument('--version', action='version', version='SettleUp 0.1') desc = 'The source CSV file. If omitted will read from STDIN.' ap.add_argument('source_csv', metavar='FILE', help=desc) args = ap.parse_args() with open(args.source_csv, 'r') as f: reader = ShoeboxedCSVReader(f) for t in reader: database.upsert(t)