def column_total_by_list(queryset, columns, format='decimal'): """takes a list of columns, returns a list of totals for those columns """ ret = [] for cn in columns: total = queryset.agg(cn) if not total == "??": if cn in ['night_l','day_l','app']: ret.append(str(total)) # write as int else: if format == "decimal": ret.append( "%.1f" % total ) # write as decimal else: ret.append( to_minutes(total) ) # write as HH:MM return ret
def column_total_by_list(queryset, columns, format='decimal'): """takes a list of columns, returns a list of totals for those columns """ ret = [] for cn in columns: total = queryset.agg(cn) if not total == "??": if cn in ['night_l', 'day_l', 'app']: ret.append(str(total)) # write as int else: if format == "decimal": ret.append("%.1f" % total) # write as decimal else: ret.append(to_minutes(total)) # write as HH:MM return ret
async def cmd_calmdown(self, ctx, user: disnake.Member, duration): if re.match(r"^[0-9]+$", duration): duration = f"{duration}m" if not utils.is_valid_time(duration): await ctx.channel.send("Fehler! Wiederholung in ungültigem Format!" ) return else: guild = ctx.guild role = guild.get_role(self.role_id) if not role: ctx.channel.send("Fehler! Rolle nicht vorhanden!") return duration = utils.to_minutes(duration) if duration == 0: await ctx.channel.send( f"{ctx.author.mention} hat {user.mention} aus der **Auszeit** geholt." ) await self.unsilence(user.id, guild.id, inform_user=False) return now = datetime.datetime.now() till = now + datetime.timedelta(minutes=duration) self.silenced_users[str(user.id)] = { "duration": till.strftime(self.fmt), "guild_id": guild.id } self.save() await ctx.channel.send( f"{ctx.author.mention} hat an {user.mention} die **Calmdown-Rolle** vergeben." ) await user.add_roles(role) if duration < 300: await utils.send_dm( user, f"Dir wurde für {duration} Minuten die **Calmdown-Rolle** zugewiesen. Du kannst weiterhin alle Kanäle lesen, aber erst nach Ablauf der Zeit wieder an Gesprächen teilnehmen." ) else: await utils.send_dm( user, f"Bis {till.strftime(self.fmt)} Uhr trägst du die Calmdown-Rolle. Du kannst weiterhin alle Kanäle lesen, aber erst nach Ablauf der Zeit wieder an Gesprächen teilnehmen." )
async def cmd_calmdown(self, ctx, user: discord.Member, duration): if re.match(r"^[0-9]+$", duration): duration = f"{duration}m" if not utils.is_valid_time(duration): await ctx.channel.send("Fehler! Wiederholung in ungültigem Format!" ) return else: guild = ctx.guild role = guild.get_role(self.role_id) if not role: ctx.channel.send("Fehler! Rolle nicht vorhanden!") return duration = utils.to_minutes(duration) if duration == 0: await ctx.channel.send( f"{ctx.author.mention} hat {user.mention} von der **stillen Treppe** geholt." ) await self.unsilence(user, guild) return now = datetime.datetime.now() till = now + datetime.timedelta(minutes=duration) self.silenced_users[user.id] = { "duration": till.strftime(self.fmt), "guild_id": guild.id } self.save() await ctx.channel.send( f"{ctx.author.mention} hat {user.mention} auf die **stille Treppe** geschickt." ) await user.add_roles(role) if duration < 300: await utils.send_dm( user, f"Du wurdest für {duration} Minuten auf die **stille Treppe** verbannt. Du kannst weiterhin alle Kanäle lesen, aber erst nach Ablauf der Zeit wieder an Gesprächen teilnehmen." ) else: await utils.send_dm( user, f"Du wurdest bis {till.strftime(self.fmt)} Uhr auf die **stille Treppe** verbannt. Du kannst weiterhin alle Kanäle lesen, aber erst nach Ablauf der Zeit wieder an Gesprächen teilnehmen." )
async def add_appointment(self, channel, author_id, date, time, reminder, title, recurring: int = None): """ Add appointment to a channel """ try: date_time = datetime.datetime.strptime(f"{date} {time}", self.fmt) except ValueError: await channel.send("Fehler! Ungültiges Datums und/oder Zeit Format!") return if not utils.is_valid_time(reminder): await channel.send("Fehler! Benachrichtigung in ungültigem Format!") return else: reminder = utils.to_minutes(reminder) embed = disnake.Embed(title="Neuer Termin hinzugefügt!", description=f"Wenn du eine Benachrichtigung zum Beginn des Termins" f"{f', sowie {reminder} Minuten vorher, ' if reminder > 0 else f''} " f"erhalten möchtest, reagiere mit :thumbsup: auf diese Nachricht.", color=19607) embed.add_field(name="Titel", value=title, inline=False) embed.add_field(name="Startzeitpunkt", value=f"{date_time.strftime(self.fmt)}", inline=False) if reminder > 0: embed.add_field(name="Benachrichtigung", value=f"{reminder} Minuten vor dem Start", inline=False) if recurring: embed.add_field(name="Wiederholung", value=f"Alle {recurring} Tage", inline=False) message = await channel.send(embed=embed, file=disnake.File(get_ics_file(title, date_time, reminder, recurring), filename=f"{title}.ics")) await message.add_reaction("👍") await message.add_reaction("🗑️") if str(channel.id) not in self.appointments: self.appointments[str(channel.id)] = {} channel_appointments = self.appointments.get(str(channel.id)) channel_appointments[str(message.id)] = {"date_time": date_time.strftime(self.fmt), "reminder": reminder, "title": title, "author_id": author_id, "recurring": recurring} self.save_appointments()
def column(self, cn, format="decimal", ret=0.0): """ Returns a string that represents the column being passed All output in strings except for date, which will be formatted later """ if cn in NUMERIC_FIELDS: #all fields that are always 100% numeric ret = getattr(self, cn) #################### return these immediately because they are strings elif cn == "remarks": return self.disp_events() + self.remarks elif cn == "r_remarks": return self.remarks elif cn == "plane": return str(self.plane) elif cn == "reg": return self.plane.tailnumber elif cn == "type": return self.plane.type elif cn == "f_route": if self.route.fancy_rendered: # mark_safe because theres HTML code within return mark_safe(self.route.fancy_rendered or "") else: # or "" to prevent "None" from getting printed return self.route_string or "" elif cn == "s_route": if self.route.simple_rendered: return self.route.simple_rendered or "" else: return self.route_string or "" elif cn == "r_route": return self.route_string or "" elif cn == "route": return self.route_string or "" ######## elif cn == "date": return self.date elif cn == "tailnumber" and self.plane: return self.plane.tailnumber elif cn == "plane_type" and self.plane: return self.plane.type elif cn == "app": return self.disp_app() elif cn == "app_num_only": #for the backup file, no 'H', or 'T' if self.app > 0: return self.app else: return "" ###################################### elif cn == 'person': return self.person elif cn == "fo": if self.pic and (self.dual_g <= 0 and self.dual_r <= 0): return self.person else: return "" elif cn == "captain": if self.sic and (self.dual_g <= 0 and self.dual_r <= 0): return self.person else: return "" elif cn == "student": if self.dual_g: return self.person else: return "" elif cn == "instructor": if self.dual_r: return self.person else: return "" elif cn == "flying": ret = "" if self.pilot_checkride: ret += "P" if self.cfi_checkride: ret += "C" if self.ipc: ret += "I" if self.flight_review: ret += "B" if self.holding: ret += "H" if self.tracking: ret += "T" return ret # return these immediately because # they are not times, so no hh:mm formatting elif cn == 'line_dist' and self.route: ret = "%.1f" % self.route.total_line_all if ret == "0.0": return "" return ret elif cn == 'km_line_dist': ret = "%.1f" % (self.route.total_line_all * 1.85200) if ret == "0.0": return "" return ret ########## elif cn == 'max_width' and self.route: ret = "%.1f" % self.route.max_width_all if ret == "0.0": return "" return ret elif cn == 'km_max_width' and self.route: ret = "%.1f" % (self.route.max_width_all * 1.85200) if ret == "0.0": return "" return ret ########## elif cn == 'speed': if self.speed: return "%.1f" % self.speed else: return "" elif cn == 'kmh_speed': if self.speed: return "%.1f" % (self.speed * 1.85200) else: return "" ######### elif cn in ('liters', 'gallons', 'gph', 'mpg'): try: disp = self.get_fuel_burn().as_unit(cn) except: return "" if not self.fuel_burn: ## wrap the output in a span because this value did not come ## directly from the user, it was calculated implictly ## from the plane. Determined by checking to see if the ## fuel burn field on the flight is empty t = '<span class="indirect_fuel_burn">{disp}</span>' return t.format(disp=disp) return disp elif cn == 'fuel_burn': return self.fuel_burn or "" ###################################### elif cn == 'atp_xc' and self.route.max_width_all > 49: ret = self.total elif cn == 'p61_xc' and self.route.max_width_land > 49: ret = self.total elif cn == 'raw_total': ret = self.total elif cn == "total" and not self.plane.is_sim(): #total ret = self.total elif cn == "sim" and self.plane.is_sim(): #sim ret = self.total elif cn == "total_s" and not self.plane.is_sim(): #total (sim) ret = self.total elif cn == "total_s" and self.plane.is_sim(): ret = "(%s)" % self.total ###################################### elif cn == 'day' and not self.plane.is_sim(): ret = self.total - self.night if ret < 0: ret = 0 elif cn == "t_pic" and self.plane.is_turbine(): ret = self.pic elif cn == "mt" and self.plane.is_multi() and self.plane.is_turbine(): ret = self.total elif cn == "mt_pic" and self.plane.is_multi() and self.plane.is_turbine(): ret = self.pic elif cn == "m_pic" and self.plane.is_multi(): ret = self.pic elif cn == "multi" and self.plane.is_multi(): ret = self.total elif cn == "single" and self.plane.is_single(): ret = self.total elif cn == "single_pic" and self.plane.is_single(): ret = self.pic elif cn == "sea" and self.plane.is_sea(): ret = self.total elif cn == "sea_pic" and self.plane.is_sea(): ret = self.pic elif cn == "mes" and self.plane.is_mes(): ret = self.total elif cn == "mes_pic" and self.plane.is_mes(): ret = self.total elif cn == "turbine" and self.plane.is_turbine(): ret = self.total elif cn == "complex" and self.plane.is_complex(): ret = self.total elif cn == "hp" and self.plane.is_hp(): ret = self.total elif cn == "tail" and self.plane.is_tail(): ret = self.total elif cn == "jet" and self.plane.is_jet(): ret = self.total elif cn == "jet_pic" and self.plane.is_jet(): ret = self.pic elif cn == "p2p" and self.route: if self.route.p2p: ret = self.total ##################################### if ret == "0" or ret == "0.0" or ret == 0: return "" elif format == "decimal" and type(ret) == float: # decimals are padded to one decimal, then converted to string if ("%.2f" % ret)[-1] == '0': # number is just a one decimal float return "%.1f" % ret else: # number was entered as a HH:MM, return more precise value return "%.3f" % ret elif type(ret) == int: # int's are straight converted to string and returned # (no decimals to deal with) return str(ret) elif format == "minutes" and type(ret) == float: # convert to HH:MM return to_minutes(ret) return ret
def column(self, cn, format="decimal", ret=0.0): """ Returns a string that represents the column being passed All output in strings except for date, which will be formatted later """ if cn in NUMERIC_FIELDS: #all fields that are always 100% numeric ret = getattr(self, cn) #################### return these immediately because they are strings elif cn == "remarks": return self.disp_events() + self.remarks elif cn == "r_remarks": return self.remarks elif cn == "plane": return str(self.plane) elif cn == "reg": return self.plane.tailnumber elif cn == "type": return self.plane.type elif cn == "f_route": if self.route.fancy_rendered: # mark_safe because theres HTML code within return mark_safe(self.route.fancy_rendered or "") else: # or "" to prevent "None" from getting printed return self.route_string or "" elif cn == "s_route": if self.route.simple_rendered: return self.route.simple_rendered or "" else: return self.route_string or "" elif cn == "r_route": return self.route_string or "" elif cn == "route": return self.route_string or "" ######## elif cn == "date": return self.date elif cn == "tailnumber" and self.plane: return self.plane.tailnumber elif cn == "plane_type" and self.plane: return self.plane.type elif cn == "app": return self.disp_app() elif cn == "app_num_only": #for the backup file, no 'H', or 'T' if self.app > 0: return self.app else: return "" ###################################### elif cn == 'person': return self.person elif cn == "fo": if self.pic and (self.dual_g <= 0 and self.dual_r <= 0): return self.person else: return "" elif cn == "captain": if self.sic and (self.dual_g <= 0 and self.dual_r <= 0): return self.person else: return "" elif cn == "student": if self.dual_g: return self.person else: return "" elif cn == "instructor": if self.dual_r: return self.person else: return "" elif cn == "flying": ret = "" if self.pilot_checkride: ret += "P" if self.cfi_checkride: ret += "C" if self.ipc: ret += "I" if self.flight_review: ret += "B" if self.holding: ret += "H" if self.tracking: ret += "T" return ret # return these immediately because # they are not times, so no hh:mm formatting elif cn == 'line_dist' and self.route: ret = "%.1f" % self.route.total_line_all if ret == "0.0": return "" return ret elif cn == 'km_line_dist': ret = "%.1f" % (self.route.total_line_all * 1.85200) if ret == "0.0": return "" return ret ########## elif cn == 'max_width' and self.route: ret = "%.1f" % self.route.max_width_all if ret == "0.0": return "" return ret elif cn == 'km_max_width' and self.route: ret = "%.1f" % (self.route.max_width_all * 1.85200) if ret == "0.0": return "" return ret ########## elif cn == 'speed': if self.speed: return "%.1f" % self.speed else: return "" elif cn == 'kmh_speed': if self.speed: return "%.1f" % (self.speed * 1.85200) else: return "" ######### elif cn in ('liters', 'gallons', 'gph', 'mpg'): try: disp = self.get_fuel_burn().as_unit(cn) except: return "" if not self.fuel_burn: ## wrap the output in a span because this value did not come ## directly from the user, it was calculated implictly ## from the plane. Determined by checking to see if the ## fuel burn field on the flight is empty t = '<span class="indirect_fuel_burn">{disp}</span>' return t.format(disp=disp) return disp elif cn == 'fuel_burn': return self.fuel_burn or "" ###################################### elif cn == 'atp_xc' and self.route.max_width_all > 49: ret = self.total elif cn == 'p61_xc' and self.route.max_width_land > 49: ret = self.total elif cn == 'raw_total': ret = self.total elif cn == "total" and not self.plane.is_sim(): #total ret = self.total elif cn == "sim" and self.plane.is_sim(): #sim ret = self.total elif cn == "total_s" and not self.plane.is_sim(): #total (sim) ret = self.total elif cn == "total_s" and self.plane.is_sim(): ret = "(%s)" % self.total ###################################### elif cn == 'day' and not self.plane.is_sim(): ret = self.total - self.night if ret < 0: ret = 0 elif cn == "t_pic" and self.plane.is_turbine(): ret = self.pic elif cn == "mt" and self.plane.is_multi() and self.plane.is_turbine(): ret = self.total elif cn == "mt_pic" and self.plane.is_multi( ) and self.plane.is_turbine(): ret = self.pic elif cn == "m_pic" and self.plane.is_multi(): ret = self.pic elif cn == "multi" and self.plane.is_multi(): ret = self.total elif cn == "single" and self.plane.is_single(): ret = self.total elif cn == "single_pic" and self.plane.is_single(): ret = self.pic elif cn == "sea" and self.plane.is_sea(): ret = self.total elif cn == "sea_pic" and self.plane.is_sea(): ret = self.pic elif cn == "mes" and self.plane.is_mes(): ret = self.total elif cn == "mes_pic" and self.plane.is_mes(): ret = self.total elif cn == "turbine" and self.plane.is_turbine(): ret = self.total elif cn == "complex" and self.plane.is_complex(): ret = self.total elif cn == "hp" and self.plane.is_hp(): ret = self.total elif cn == "tail" and self.plane.is_tail(): ret = self.total elif cn == "jet" and self.plane.is_jet(): ret = self.total elif cn == "jet_pic" and self.plane.is_jet(): ret = self.pic elif cn == "p2p" and self.route: if self.route.p2p: ret = self.total ##################################### if ret == "0" or ret == "0.0" or ret == 0: return "" elif format == "decimal" and type(ret) == float: # decimals are padded to one decimal, then converted to string if ("%.2f" % ret)[-1] == '0': # number is just a one decimal float return "%.1f" % ret else: # number was entered as a HH:MM, return more precise value return "%.3f" % ret elif type(ret) == int: # int's are straight converted to string and returned # (no decimals to deal with) return str(ret) elif format == "minutes" and type(ret) == float: # convert to HH:MM return to_minutes(ret) return ret