async def editClockEmbed(message, payload): embed = message.embeds[0] if payload: # is None from createClock detail = await getDetailFromHistory(message, payload.user_id) if detail: if payload.emoji.name == RandomSupport.numberEmojis[1]: if detail in time_zones: embed = RandomSupport.updateDetailInURL( embed, "time_zone", detail.replace("/", "|")) embed = RandomSupport.updateFieldValue( embed, "Time Zone", f"{space_char* 2}{detail}") else: await message.channel.send( f"The time zone `{detail}` is not availble.", delete_after=7) elif payload.emoji.name == RandomSupport.numberEmojis[2]: embed = RandomSupport.updateDetailInURL( embed, "time_format", detail.replace(" ", "_")) clock = getClockFromURL(embed.author.url) embed = RandomSupport.updateFieldValue( embed, "Time Format", "%s%s -> %s " % (space_char * 2, detail, timezone("UTC").localize( datetime.utcnow()).astimezone(timezone( clock.time_zone)).strftime(clock.time_format))) await message.edit(embed=embed) for i in range(2): await message.add_reaction(RandomSupport.numberEmojis[i + 1]) await message.add_reaction(RandomSupport.FLOPPY_DISK_EMOJI)
async def getFile(member, moBotMessage, embed, client): def checkEmoji(payload): return payload.user_id == member.id and payload.channel_id == moBotMessage.channel.id and payload.emoji.name in RandomSupport.numberEmojis # end checkEmoji embed["description"] = "*Salaries Files:*" await editEmbed(moBotMessage, embed) dkSalariesDir = os.getcwd() + "\\DKSalaries" files = [] for dir in os.walk(dkSalariesDir): for file in dir[-1]: if (file[-3:] == "csv" and str(weekNumber + 1) in file): files.append(file) emojiNumber = RandomSupport.numberToEmojiNumbers(len(files)) embed[ "description"] += "\n" + spaceChar + emojiNumber + " - " + file await moBotMessage.add_reaction(emojiNumber) embed["description"] += "\n**Select a File Number:**" await editEmbed(moBotMessage, embed) try: payload = await client.wait_for("raw_reaction_add", timeout=60, check=checkEmoji) file = files[RandomSupport.emojiNumbertoNumber(payload.emoji.name) - 1] except asyncio.TimeoutError: await moBotMessage.channel.send("**TIMED OUT**") file = files[0] embed["fields"][0]["value"] = file await editEmbed(moBotMessage, embed) await moBotMessage.clear_reactions() return dkSalariesDir + "\\" + file
def getTiersSpreadsheet(key_info_range, overall_lap_time_range, vehicle): key_info = RandomSupport.arrayFromRange(key_info_range) key_info = key_info[2:] # row 3:end overall_lap_times = RandomSupport.arrayFromRange(overall_lap_time_range) overall_lap_times = overall_lap_times[2:] # row 3:end # tiers = {S : [[car1, delta], ...], A : []} delta is difference between car and og vehicle tiers = {} for i in range(len(overall_lap_times)): if overall_lap_times[i][2].value != vehicle._Class: # class match continue for j in range(len(key_info)): if key_info[j][0].value != vehicle._Class: # class match continue veh_name = key_info[j][1].value if veh_name == overall_lap_times[i][3].value: # vehicle match race_tier = key_info[j][5].value race_tier = "S+" if race_tier == "" else race_tier if race_tier == "-": break if race_tier not in tiers: tiers[race_tier] = [] tiers[race_tier].append([ getDelta(overall_lap_times[i][4].value, vehicle._Lap_Time__m_ss_000_), veh_name ]) return tiers
async def getLineupType(member, moBotMessage, embed, client): def checkEmoji(payload): return payload.user_id == member.id and payload.channel_id == moBotMessage.channel.id and payload.emoji.name in RandomSupport.numberEmojis # end checkEmoji lineupTypes = ["Classic", "Showdown"] embed["description"] = "*Lineup Types:*" for i in range(len(lineupTypes)): emojiNumber = RandomSupport.numberToEmojiNumbers(i + 1) embed[ "description"] += "\n" + spaceChar + emojiNumber + " - " + lineupTypes[ i] await moBotMessage.add_reaction(emojiNumber) embed["description"] += "\n**Select a Lineup Type:**" await editEmbed(moBotMessage, embed) try: payload = await client.wait_for("raw_reaction_add", timeout=60, check=checkEmoji) lineupType = lineupTypes[ RandomSupport.emojiNumbertoNumber(payload.emoji.name) - 1] except asyncio.TimeoutError: await moBotMessage.channel.send("**TIMED OUT**") lineupType = lineupTypes[0] embed["fields"][1]["value"] = lineupType await editEmbed(moBotMessage, embed) await moBotMessage.clear_reactions() return lineupType
async def toggleTierList(message, tier, toggle): url_tier = f"tier_{tier.upper()}" embed = message.embeds[0] cars = RandomSupport.getDetailFromURL(embed.author.url, url_tier).split("&") for i, car in enumerate(cars): car = car.split(" ") delta = car[0] car = " ".join(car[1:]) if RandomSupport.getDetailFromURL(embed.author.url, "vehicle") == car: car = f"**{car}**" cars[i] = f"`{delta.rjust(6, ' ')}` {car}" cars = "\n".join(cars) tier = "S+" if tier == "+" else tier tier_name = f"{tier.upper()} Tier" check = RandomSupport.getValueFromField(embed, tier_name) if not check: # not check is True if tier is not present if toggle == "add": embed.add_field(name=f"**__{tier_name}__**", value=cars) await message.edit(embed=embed) elif toggle == "remove": embed = embed.to_dict() for i, field in enumerate(embed["fields"]): if tier_name in embed["fields"][i]["name"]: del embed["fields"][i] break await message.edit(embed=discord.Embed.from_dict(embed))
def getClockFromURL(url): return Clock( RandomSupport.getDetailFromURL(url, "message_id"), RandomSupport.getDetailFromURL(url, "channel_id"), RandomSupport.getDetailFromURL(url, "guild_id"), RandomSupport.getDetailFromURL(url, "time_format"), RandomSupport.getDetailFromURL(url, "time_zone"), )
def getVehicleInfo(key_info_range, handling_data_basic_range, overall_lap_time_range, vehicles): key_info = RandomSupport.arrayFromRange(key_info_range) key_info[1][0].value = "Class" key_info[1][1].value = "Vehicle" handling_data_basic_info = RandomSupport.arrayFromRange( handling_data_basic_range) handling_data_basic_info[1][0].value = "Class" handling_data_basic_info[1][1].value = "Vehicle" overall_lap_time_info = RandomSupport.arrayFromRange( overall_lap_time_range) overall_lap_time_info[0][0].value = "Overall Position" overall_lap_time_info[0][1].value = "In Class Position" def fix_attr(attr): return re.sub(r"[\s\-\(\):.]", "_", attr) for i, attr in enumerate( key_info[1] + handling_data_basic_info[1] + overall_lap_time_info[0]): # add attributes to class if attr.value.strip() != "": attr = fix_attr(attr.value) exec(f"Vehicle._{attr} = None") Vehicle._key_info_row = None Vehicle._handling_data_basic_row = None Vehicle._overall_lap_time_row = None for vehicle in vehicles: for i, v in enumerate(key_info): if v[1].value == vehicle._name: for j, prop in enumerate(key_info[i]): attr = fix_attr(key_info[1][j].value) exec(f'vehicle._{attr} = "{prop.value}"') vehicle._key_info_row = i + 2 # + 2 is for headers for i, v in enumerate(handling_data_basic_info): if v[1].value == vehicle._name: for j, prop in enumerate(handling_data_basic_info[i]): attr = fix_attr(handling_data_basic_info[1][j].value) exec(f'vehicle._{attr} = "{prop.value}"') vehicle._handling_data_basic_row = i + 2 # + 2 is for headers for i, v in enumerate(overall_lap_time_info): if v[3].value == vehicle._name: for j, prop in enumerate(overall_lap_time_info[i]): attr = fix_attr(overall_lap_time_info[0][j].value) exec(f'vehicle._{attr} = "{prop.value}"') vehicle._overall_lap_time_row = i + 2 # + 2 is for headers return vehicles
async def printLineup(lineup, moBotMessage, embed): embed["fields"][5][ "value"] = "__Pos. - Player Name - Appg. - Price - Team__" playerCount = 0 remSalary = 50000 totalAppg = 0 lineupIDs = "" for position in lineup: for player in lineup[position]: try: playerCount += 1 emojiNumber = RandomSupport.numberToEmojiNumbers(playerCount) game = player.game.replace(player.team, "**" + player.team + "**") embed["fields"][5]["value"] += ( "\n%s %s - **%s** - %s - %s - %s" % (emojiNumber, position, player.name, player.appg, player.price, game)) lineupIDs += player.id + "," remSalary -= int(player.price) totalAppg += float(player.appg) await moBotMessage.add_reaction(emojiNumber) except AttributeError: # when not printing full lineup print(position, None) await moBotMessage.add_reaction(CHECKMARK_EMOJI) await moBotMessage.add_reaction(COUNTERCLOCKWISE_ARROWS_EMOJI) await moBotMessage.add_reaction(X_EMOJI) embed["fields"][5]["value"] += "```%s%s,%.3f```" % (lineupIDs, remSalary, totalAppg) embed["footer"]["text"] = ("REM. SALARY: $%s TOTAL FPPG: %.3f" % (remSalary, totalAppg)) await editEmbed(moBotMessage, embed)
async def setTableRange(message, embed, creator): moBotMember = message.guild.get_member(moBot) url = embed.author.url tableDetails = getTableFromEmbedURL(url) workbook = await openUserSpreadsheet(tableDetails.workbookKey, message.channel, creator, moBotMember) if (workbook is not None): tableRange = await getDetailFromHistory(message, creator) if (tableRange is not None): tableRange = numericToA1( a1ToNumeric(tableRange)) # validated range embed = updateDetailInURL(embed, "tableRange", tableRange) embed = updateFieldValue( embed, "Table Range", spaceChar * 2 + " " + RandomSupport.stripZero(tableRange)) await message.edit(embed=embed) else: await messageNotFound(message, creator, "Table Range", RandomSupport.numberEmojis[2]) else: return
def getTracks(platform): workbook = GTACCHub.openSpreadsheet() sheets = workbook.worksheets() plat_sheet = None if (platform == "xbox"): plat_sheet = [ sheet for sheet in sheets if sheet.id == GTACCHub.XBOX_SHEET_ID ][0] elif (platform == "ps"): plat_sheet = [ sheet for sheet in sheets if sheet.id == GTACCHub.PS_SHEET_ID ][0] elif (platform == "pc"): plat_sheet = [ sheet for sheet in sheets if sheet.id == GTACCHub.PC_SHEET_ID ][0] jobs_and_types = plat_sheet.range(f"A12:B{plat_sheet.row_count-1}") jobs_and_types = RandomSupport.arrayFromRange(jobs_and_types) i = 0 while i > -1: if (jobs_and_types[i][0].value == "" or len(jobs_and_types[i][0].value == 1) or "Jobs by" in jobs_and_types[i][0].value or "N" in jobs_and_types[i][1].value): del jobs_and_types[i] i -= 1 return [jobs_and_types, plat_sheet]
async def checkForDiv(msg, member): reactions = msg.reactions for reaction in reactions: async for user in reaction.users(): if (user.id == member.id): try: div = RandomSupport.emojiNumbertoNumber(reaction.emoji) return div if div <= getEventDetails( ).numberOfDivs else False except ValueError: # when a number is not clicked pass return False
async def getVehicleFromReactions(message, member): for reaction in message.reactions: async for user in reaction.users(): if (user.id == member.id): try: vehicle = event.qualiVehicles[ RandomSupport.emojiNumbertoNumber(reaction.emoji) - 1] return [vehicle] except ValueError: # when reaction is not a number pass await moBotMessage.edit( content="**<@%s>, click a vehicle number, then click the %s.**" % (member.id, STOPWATCH_EMOJI), delete_after=10) return []
async def createClock(message): await message.channel.trigger_typing() mobot_member = message.guild.get_member(mobot) time_zone = "UTC" time_format = "%H:%M %Z" embed = discord.Embed() embed.color = mobot_member.roles[-1].color embed.set_author( name="UTC", url= f"https://google.com/message_id=None/channel_id={message.channel.id}/guild_id={message.guild.id}/time_format={time_format.replace(' ', '_')}/time_zone={time_zone.replace('/', '|')}/" ) time = timezone(time_zone).localize(datetime.utcnow()).astimezone( timezone(time_zone)).strftime(time_format) embed.description = time msg = await message.channel.send(embed=embed) embed = RandomSupport.updateDetailInURL(embed, "message_id", msg.id) await msg.edit(embed=embed) clock = getClockFromURL(embed.author.url) mobot_db = connectDatabase() mobot_db.cursor.execute(f""" INSERT INTO clocks ( `message_id`, `channel_id`, `guild_id`, `guild_name`, `time_format`, `time_zone` ) VALUES ( '{clock.message_id}', '{clock.channel_id}', '{clock.guild_id}', '{message.guild.name.replace(chr(39),chr(39)+chr(39))}', '{clock.time_format.replace("_", " ")}', '{clock.time_zone}' ) """) mobot_db.connection.commit() mobot_db.connection.close() embed = defaultEditClockEmbed(message, clock) msg = await message.channel.send(embed=embed) await editClockEmbed(msg, None) await message.channel.send( "```fix\nMo: Yes I know it looks complicated; it's not. Look at the instructions and the examples for guidance.```", delete_after=60)
async def editTable(message): tableMessageID = message.content.split("edit")[-1].strip() moBotDB = connectDatabase() tables = getSavedTables(moBotDB) tableExists = False for table in tables: if (tableMessageID in table.messageIDs): tableExists = True moBotMember = message.guild.get_member(moBot) if (table.creatorID == message.author.id): embed = defaultEmbed( moBotMember, await openUserSpreadsheet( table.workbookKey, message.guild.get_channel(table.channelID), message.author, moBotMember), table.workbookKey, table.guildID, table.channelID, message.author) tableDict = vars(table) for var in tableDict: # update the embed with table values print(var, tableDict[var]) if (var != "tableID"): # convert alignments and message ids to strings not arrays embed = RandomSupport.updateDetailInURL( embed, var, tableDict[var]) await message.channel.send(embed=embed) else: await message.channel.send( "**Not Authorizied**\n%s, currently only the creator of the table is authorized to edit a table. The creator for the given table is `%s`." % (message.author.id, message.guild.get_member(table.creatorID).display_name)) if (not tableExists): await message.channel.send( "**Table Not Found**\n%s, the `message_id` given was not found in any of MoBot's existing tables. Make sure the given `message_id` was actually an id of a table." ) moBotDB.connection.close()
async def handleUserVehicleInput(message, client): moBotMember = message.guild.get_member(moBot) # used for role color embed = discord.Embed() # make base embed embed.set_author( name="GTA V Vehicle Search", url= f"https://google.com/vehicle=None/{'/'.join(f'tier_{c}=None' for c in '+SABCDEFGHIJ')}/", icon_url=moBotMember.avatar_url) embed.color = moBotMember.roles[-1].color vehicle = message.content.split( "car ")[1].strip() # get vehicle update user on status embed.description = f"Searching for `{vehicle}`..." embed = RandomSupport.updateDetailInURL(embed, "vehicle", vehicle) msg = await message.channel.send(embed=embed) vehicles = [] try: # search for possible vehicles workbook = openSpreadsheet() sheets = workbook.worksheets() key_vehicle_info_sheet = [ sheet for sheet in sheets if sheet.id == KEY_VEHICLE_INFO_SHEET_ID ][0] handling_data_basic_info_sheet = [ sheet for sheet in sheets if sheet.id == HANDLING_DATA_BASIC_SHEET_ID ][0] overall_lap_time_sheet = [ sheet for sheet in sheets if sheet.id == OVERALL_LAP_TIME_SHEET_ID ][0] key_info_range = key_vehicle_info_sheet.range( f"A2:M{key_vehicle_info_sheet.row_count}") handling_data_basic_range = handling_data_basic_info_sheet.range( f"A2:T{handling_data_basic_info_sheet.row_count}") overall_lap_time_range = overall_lap_time_sheet.range( f"A2:F{overall_lap_time_sheet.row_count}") poss_vehicles = searchVehicle(key_vehicle_info_sheet, vehicle) if poss_vehicles: vehicles = getVehicleInfo( key_info_range, handling_data_basic_range, overall_lap_time_range, [Vehicle(v) for v in poss_vehicles[:9]] ) # list of complete vehicle objects, just waiting for user selection now poss_vehicles = [ poss_vehicles[0] ] if poss_vehicles[0].lower() == vehicle.lower() else poss_vehicles except: # likely issue with gspread print("CAUGHT EXCEPTION") print(traceback.format_exc()) embed.description = "There were technical difficulties searching for your vehicle. Please try again in a minute or so." await msg.edit(embed=embed) return if vehicles: # ask user which vehicle is correct emojis = [] embed.description = "**Which Vehicle?**\n" for i, v in enumerate(poss_vehicles[:9]): e = RandomSupport.numberEmojis[i + 1] embed.description += f"{e} {v}\n" emojis.append(e) if emojis[1:]: # if more than one option get selection from user for e in emojis: await msg.add_reaction(e) await msg.edit(embed=embed) try: # handle user selection def check(payload): return payload.user_id == message.author.id and payload.emoji.name in emojis payload = await client.wait_for("raw_reaction_add", timeout=60.0, check=check) await msg.clear_reactions() vehicle = vehicles[emojis.index(payload.emoji.name)] except asyncio.TimeoutError: embed.description += "\n\n**TIMED OUT WAITING FOR USER INPUT**" await msg.clear_reactions() await msg.edit(embed=embed) return else: vehicle = vehicles[0] embed = RandomSupport.updateDetailInURL(embed, "vehicle", vehicle._Vehicle) wiki_urls = getVehicleImage(vehicle) try: embed.set_thumbnail(url=wiki_urls["image_url"]) except: # not sure what could go wrong here... may not find correct page i guess print("CAUGHT EXCEPTION") print(traceback.format_exc()) embed.description = ":boom: MoBot's GTA functions are being depreciated in the winter. Invite the bot version of [GTALens](https://discord.com/api/oauth2/authorize?client_id=872899427457716234&permissions=36507511808&scope=bot) for similar functionailty (tracks/cars/weather... - `.lens help`).\n\n" embed.description += f"**Vehicle:** {vehicle._Vehicle} - [__wiki__]({wiki_urls['wiki_url']})\n" embed.description += f"**Manufacturer:** {vehicle._Manufacturer}\n" embed.description += f"**Class:** {vehicle._Class}\n" embed.description += f"[__Overall (Lap Time)__](https://docs.google.com/spreadsheets/d/1nQND3ikiLzS3Ij9kuV-rVkRtoYetb79c52JWyafb4m4/edit#gid=60309153&range=B{vehicle._overall_lap_time_row}) - " embed.description += f"[__Key Info__](https://docs.google.com/spreadsheets/d/1nQND3ikiLzS3Ij9kuV-rVkRtoYetb79c52JWyafb4m4/edit#gid=1689972026&range=B{vehicle._key_info_row}) - " embed.description += f"[__Handling Data (Basic)__](https://docs.google.com/spreadsheets/d/1nQND3ikiLzS3Ij9kuV-rVkRtoYetb79c52JWyafb4m4/edit#gid=110431106&range=D{vehicle._handling_data_basic_row})\n{space_char}\n" v = "" v += f"**Drivetrain:** {vehicle._Drivetrain}\n" v += f"**Seats:** {vehicle._Seats}\n" v += f"**Source:** {vehicle._Source}\n" v += f"**Cost:** {vehicle._Cost}\n" embed.add_field(name="**__Basic Information__**", value=f"{v}{space_char}") v = "" v += f"**Race Tier:** {vehicle._Race_Tier}\n" v += f"**Lap Time:** {vehicle._Lap_Time__m_ss_000_}\n" v += f"**Top Speed:** {vehicle._Top_Speed__mph_}\n" embed.add_field(name="**__Basic Performance__**", value=f"{v}{space_char}") v = "" v += f"**Spoiler:** {vehicle._Spoiler}\n".replace( "✔", RandomSupport.CHECKMARK_EMOJI) v += f"**Off-Roads:** {vehicle._Off_Roads}\n".replace( "✔", RandomSupport.CHECKMARK_EMOJI) v += f"**Suspension:** {vehicle._Suspension}\n".replace( "✔", RandomSupport.CHECKMARK_EMOJI) v += f"**Boost:** {vehicle._Boost}\n".replace( "✔", RandomSupport.CHECKMARK_EMOJI) v += f"**Drift Tyres:** {vehicle._Drift_Tyres}\n".replace( "✔", RandomSupport.CHECKMARK_EMOJI) embed.add_field(name="**__Improvements__**", value=f"{v}{space_char}") v = "" v += f"**Bouncy:** {vehicle._Bouncy}\n".replace( "✔", RandomSupport.CHECKMARK_EMOJI) v += f"**Engine:** {vehicle._Engine}\n".replace( "✔", RandomSupport.CHECKMARK_EMOJI) embed.add_field(name="**__Adv. Handling Flags__**", value=f"{v}{space_char}") embed.set_footer( text= "All information is retrieved from Broughy's Spreadsheet, \"GTA V/Online Vehicle Info, Lap Times, and Top Speeds\". Information may not be absolutely accurate." ) try: await msg.edit(embed=embed) except discord.errors.HTTPException: # bad thumbnail embed = embed.to_dict() del embed["thumbnail"] await msg.edit(embed=discord.Embed.from_dict(embed)) # add tier lists to url try: tiers = getTiersSpreadsheet(key_info_range, overall_lap_time_range, vehicle) for tier in tiers: detail = f"tier_{tier}" value = '&'.join(["%20".join(a) for a in tiers[tier] ]) # value is Car%20Time&... try: embed = RandomSupport.updateDetailInURL( embed, detail, value) await msg.add_reaction( RandomSupport.letter_emojis[tier.lower()]) except (KeyError, IndexError) as e: # S+ tier embed = RandomSupport.updateDetailInURL( embed, detail.replace("S+", "+"), value) await msg.add_reaction( RandomSupport.symbol_emojis[tier.replace("S+", "+")]) except: # likely vehicle selected is not raceable print(traceback.format_exc()) pass await msg.edit(embed=embed) else: embed.description = f"No vehicles with a name close to `{vehicle}` could be found." await msg.edit(embed=embed)
async def editTable(message): await message.channel.trigger_typing() tableMessageID = message.content.split("edit")[-1].strip() moBotDB = connectDatabase() table = findTable(moBotDB, tableMessageID, message.author.id) if (table): # exists if (type(table) != int): # is creator moBotMember = message.guild.get_member(moBot) embed = defaultEmbed( moBotMember, await openUserSpreadsheet(table.workbookKey, message.guild.get_channel(table.channelID), message.author, moBotMember), table.workbookKey, table.guildID, table.channelID, message.author) tableDict = vars(table) for var in tableDict: # update the embed with table values if (var != "tableID"): tableDict[var] = ",".join(tableDict[var]) if type( tableDict[var]) == list else tableDict[ var] # converts arrays to csv strings embed = updateDetailInURL(embed, var, tableDict[var]) workbook = await openUserSpreadsheet(table.workbookKey, message.channel, message.author, moBotMember) for sheet in workbook.worksheets(): if (sheet.id == table.worksheetID): embed = updateFieldValue(embed, 'Sheet Name', spaceChar * 2 + " " + sheet.title) break embed = updateFieldValue( embed, 'Table Range', spaceChar * 2 + " " + RandomSupport.stripZero(table.tableRange)) embed = updateFieldValue( embed, 'Auto Updating', spaceChar * 2 + " " + ("Yes" if table.autoUpdating == 1 else "No")) embed = updateFieldValue( embed, 'Number of Buffer Messages', spaceChar * 2 + " " + str(table.bufferMessages)) embed = updateFieldValue( embed, 'Left Aligned Ranges', spaceChar * 2 + " " + RandomSupport.stripZero(table.leftAligned)) embed = updateFieldValue( embed, 'Right Aligned Ranges', spaceChar * 2 + " " + RandomSupport.stripZero(table.rightAligned)) embed = updateFieldValue( embed, 'Centered Ranges', spaceChar * 2 + " " + RandomSupport.stripZero(table.centered)) embed = updateFieldValue(embed, 'Number of Headers', spaceChar * 2 + " " + str(table.headers)) embed = updateFieldValue( embed, 'Smart Merging', spaceChar * 2 + " " + ("Yes" if table.smartMerging == 1 else "No")) msg = await message.channel.send(embed=embed) await addReactions(msg) else: # is not creator creatorID = table await message.channel.send( "**Not Authorizied**\n%s, currently only the creator of the table is authorized to edit a table. The creator for the given table is `%s`." % (message.author.mention, message.guild.get_member(creatorID).display_name)) else: # doesn't exist await message.channel.send( "**Table Not Found**\n%s, the `message_id` given was not found in any of MoBot's existing tables. Make sure the given `message_id` was actually an id of a table." % message.author.mention) moBotDB.connection.close()
def getMMRs(platform, id): urlID = id.lower().replace(" ", "%20") url1 = 'https://rocketleague.tracker.network/profile/' + platform + '/' + urlID url2 = 'https://rocketleague.tracker.network/profile/mmr/' + platform + '/' + ( urlID.replace("%20", "-") if platform != "steam" else RandomSupport.steamIDToSteam64(urlID)) currentMMRHtml = str(bsoup(requests.get(url1).text, "html.parser")) peaksMMRHtml = str(bsoup(requests.get(url2).text, "html.parser")) seasons = [x for x in range(getCurrentRocketLeagueSeason(), 0, -1) ] # current season first mmrs = {} ''' for example 13: { // season 2: mmr // twos }''' for season in seasons: mmrs[season] = { 2: { "current": 0, "peak": 0 }, 3: { "current": 0, "peak": 0 } } # 2v2s : mmr, 3v3s : mmr splitOnTwos = "Ranked Doubles 2v2" splitOnThrees = "Ranked Standard 3v3" reg1 = r"(\n\d,\d\d\d)|(\n\d\d\d\d)|(\n\d\d\d)" mmrsAboveThis = "<img" # get the text where the mmr is, not quite on its own yet try: seasonRanks = currentMMRHtml.split("id=\"season-%s\"" % season)[1] except IndexError: # when season isn't available for the player continue def getMMR(splitOn): return re.sub( r"\n|,", "", "".join(x for x in re.findall( reg1, seasonRanks.split("<td>\n" + splitOn)[1].split( mmrsAboveThis)[0].replace(" ", ""))[0])) # end getMMR def getPeak(splitOn): data = peaksMMRHtml.split("name: '%s'," % splitOn)[1].split("};")[0] mmrs = data.split("rating: [")[1].split("]")[0].split(",") tiers = data.split("tier: [")[1].split("]")[0].split(",") for tier in tiers: if (tier != "0"): return max([ int(mmr) for mmr in mmrs[tiers.index(tier) + 1:] ]) # peak baby return 0 # end getPeak() try: mmrs[season][2]["peak"] = getPeak( splitOnTwos) # shouldn't ever give error mmrs[season][2]["current"] = int(getMMR(splitOnTwos)) except IndexError: # if player has no mmr pass try: mmrs[season][3]["peak"] = getPeak( splitOnThrees) # shouldn't ever give error mmrs[season][3]["current"] = int(getMMR(splitOnThrees)) except IndexError: # if player has no mmr pass return mmrs, url1
async def handlePitMarshall(message, member, payload): await message.channel.trigger_typing() moBotMessage = await waitForUpdate(message) async def checkForDiv(msg, member): reactions = msg.reactions for reaction in reactions: async for user in reaction.users(): if (user.id == member.id): try: div = RandomSupport.emojiNumbertoNumber(reaction.emoji) return div if div <= getEventDetails( ).numberOfDivs else False except ValueError: # when a number is not clicked pass return False # end checkForDiv def insertPitMarshall(member, div, payload): moBotDB = connectDatabase() try: moBotDB.cursor.execute(""" INSERT INTO pit_marshalls( discord_id, display_name, host, pit_marshall ) VALUES ( '%s', '%s', '%s', '%s' ) """ % ( member.id, member.display_name, div if (payload.emoji.name == CROWN_EMOJI) else None, div if (payload.emoji.name == WRENCH_EMOJI) else None, )) moBotDB.connection.commit() moBotDB.connection.close() return True except mysql.connector.IntegrityError: moBotDB.connection.close() return False # end insertPitMarshall def removePitMarshall(member, div, payload): # find current person, then remove if same moBotDB = connectDatabase() moBotDB.cursor.execute(""" SELECT discord_id, display_name FROM pit_marshalls WHERE host = %s AND pit_marshall = %s """ % (div if payload.emoji.name == CROWN_EMOJI else 0, div if payload.emoji.name == WRENCH_EMOJI else 0)) delete = True for record in moBotDB.cursor: if (int(record[0]) == member.id): break if (delete): moBotDB.cursor.execute(""" DELETE FROM pit_marshalls WHERE host = %s AND pit_marshall = %s """ % (div if payload.emoji.name == CROWN_EMOJI else 0, div if payload.emoji.name == WRENCH_EMOJI else 0)) moBotDB.connection.commit() moBotDB.connection.close() return False else: moBotDB.connection.close() return True # end removePitMarshall div = await checkForDiv(message, member) if (div): if (insertPitMarshall(member, div, payload)): await message.edit(embed=buildPitMarshallEmbed()) await moBotMessage.edit( content="**<@%s> is now a %s for Division %s.**" % (member.id, "Host" if payload.emoji.name == CROWN_EMOJI else "Pit-Marshall", div), delete_after=10) await member.add_roles( RandomSupport.getRole(message.guild, pitMarshallRole)) else: if (removePitMarshall(member, div, payload)): await moBotMessage.edit( content="**<@%s>, there is already a %s for Division %s.**" % (member.id, "Host" if payload.emoji.name == CROWN_EMOJI else "Pit-Marshall", div), delete_after=10) else: await message.edit(embed=buildPitMarshallEmbed()) await moBotMessage.edit( content="**<@%s> is no longer a %s for Division %s.**" % (member.id, "Host" if payload.emoji.name == CROWN_EMOJI else "Pit-Marshall", div), delete_after=10) await member.remove_roles( RandomSupport.getRole(message.guild, pitMarshallRole)) else: await moBotMessage.edit( content= "**<@%s>, click a division number, and then click the %s or the %s.**" % (member.id, CROWN_EMOJI, WRENCH_EMOJI), delete_after=10) await message.remove_reaction(payload.emoji.name, member) for reaction in message.reactions: async for user in reaction.users(): if (user.id == member.id): await message.remove_reaction(reaction.emoji, member) await message.channel.edit( name=message.channel.name.replace("updating", ""))
def createTable(tableDetails, workbook): worksheetID = tableDetails.worksheetID tableRange = tableDetails.tableRange if ("-1" not in [worksheetID, tableRange]): # if we have 2 valid inputs sheet = None for worksheet in workbook.worksheets(): if (str(worksheet.id) == str(worksheetID)): sheet = worksheet rnge = None if (sheet is not None): tableRange = a1ToNumeric(tableRange) cols = tableRange[0] rows = tableRange[1] cols[1] = sheet.col_count if cols[1] == 0 else cols[1] rows[1] = sheet.row_count if rows[1] == 0 else rows[1] rnge = sheet.range(rows[0], cols[0], rows[1], cols[1]) table = RandomSupport.arrayFromRange( rnge) # table[row[col, ...], row[col, ...]] / table[row][col] maxWidths = [1 for cell in table[0]] # set widths to 1 for i in range(len(table)): # loop rows, skipping the headers if ("".join([table[i][k].value for k in range(len(table[i]))]) == ""): break for j in range(len(table[0])): # loop columns maxWidths[j] = len(table[i][j].value) if len( table[i][j].value) > maxWidths[j] else maxWidths[j] headerWidths = [[1 for cell in row] for row in table[:tableDetails.headers]] for i in range(tableDetails.headers): # loop row j = 0 while j < len(headerWidths[i]): # loop col countAdjBlanks = 0 for k in range(j + 1, len(table[i])): if (table[i][k].value.strip() == ""): countAdjBlanks += 1 else: break if (countAdjBlanks > 0 and tableDetails.smartMerging == 1): headerWidths[i][j] = sum( maxWidths[j:j + 1 + countAdjBlanks]) + countAdjBlanks * 3 for k in range(j + 1, j + 1 + countAdjBlanks): table[i][k].value = "MoBot Merged" else: # need to figure out when header width > table width headerWidths[i][j] = maxWidths[j] j += 1 tables = [ ] # will be completed tables seperated to fit in a single message lines = [] for row in table: isHeader = table.index(row) < tableDetails.headers if ("".join([cell.value for cell in row]) == ""): # if blank row break line = "" for cell in row: tempLines = [ ["" for i in range(3)] for i in range(3) ] # templines[i][0 and 1] are for top and bottom border, but not in use right now... if (not isHeader): for r in tableDetails.leftAligned: if ( RandomSupport.cellInRange( cell, a1ToNumeric(r)) and not any( RandomSupport.cellInRange( cell, a1ToNumeric(r2)) for r2 in tableDetails. leftAligned[:tableDetails. leftAligned.index(r)]) ): # in range but not in any other ranges before this one... tempLines[0][1] += " %s " % (cell.value.ljust( maxWidths[row.index(cell)], " ")) tempLines[0][1] += '|' if ( row.index(cell) + 1 != len(row)) else "" for r in tableDetails.rightAligned: if ( RandomSupport.cellInRange( cell, a1ToNumeric(r)) ): # in range but not in any other ranges before this one... tempLines[1][1] += " %s " % (cell.value.rjust( maxWidths[row.index(cell)], " ")) tempLines[1][1] += '|' if ( row.index(cell) + 1 != len(row)) else "" for r in tableDetails.centered: if ( RandomSupport.cellInRange( cell, a1ToNumeric(r)) and not any( RandomSupport.cellInRange( cell, a1ToNumeric(r2)) for r2 in tableDetails. centered[:tableDetails.centered. index(r)]) ): # in range but not in any other ranges before this one... tempLines[2][1] += " %s " % (cell.value.center( maxWidths[row.index(cell)], " ")) tempLines[2][1] += '|' if ( row.index(cell) + 1 != len(row)) else "" else: if (cell.value != "MoBot Merged"): tempLines[2][1] += " %s " % (cell.value.center( headerWidths[table.index(row)][row.index( cell)], " ")) try: tempLines[2][1] += '|' if table[table.index( row)][row.index(cell) + 1:][0].value != "MoBot Merged" else "" except IndexError: # when last cell in row pass line += tempLines[-1][1] if tempLines[-1][1] != "" else ( tempLines[-2][1] if tempLines[-2][1] != "" else tempLines[-3][1]) line = "`%s`" % line if (isHeader): line += "\n` %s `" % "".center(len(line) - 4, "-") # borders for headers, if (len("\n".join(lines) + line) < 2000): lines.append(line) else: tables.append("\n".join(lines)) lines = [line] tables.append("\n".join(lines)) return tables
async def updateDanioTables(): channel = client.get_channel(815004525160562728) class Table: def __init__(self, title, key, messageID): self.title = title self.key = key.split("d/")[1].split("/")[0] self.messageID = messageID # end Table tables = [ Table( "S9 F1 PC", "https://docs.google.com/spreadsheets/d/130OKPmOe_A6GXPQMFPpE-TDdPOhFDW3tifcU1hAflpU/edit#gid=118", 815363972449959987), '''Table("S6 PC F2", "https://docs.google.com/spreadsheets/d/1nm_jHpJwzNs7eZAMy1pDUIth04aMdgyNI6ML_9bLvjw/edit#gid=118", 668326016929759233), Table("S6 PS4 F1", "https://docs.google.com/spreadsheets/d/1pkQzfRiRjXYdBFFDzqX-zskudrOta5ViI6PsXrpUQTk/edit#gid=118", 668326026635509787), Table("S6 PS4 F2", "https://docs.google.com/spreadsheets/d/12O4hvzO0kmGVJ-qNMi5J67ElL6TKVhon8mQfus5eSdY/edit?usp=sharing", 668326030892728330), Table("S6 PS4 F3", "https://docs.google.com/spreadsheets/d/1J6O0XpH07IjzwHirQ4sR4dfC0lHwWkPSrhHqSQfAqFE/edit?usp=sharing", 668326045182722048), Table("S6 PS4 F4", "https://docs.google.com/spreadsheets/d/1ehG4d5B7VsiXNfoRjldfWyqSBbmtgc21QBvakvUxii0/edit?usp=sharing", 668326050710683658), Table("S6 PS4 F5", "https://docs.google.com/spreadsheets/d/1ZOQEYO_8dSIx30Uq-y1x4hSigzyW5nhNDH7lC0AsYRA/edit?usp=sharing", 668326105735757824),''' ] for table in tables: r = random.random() if (r < 1 / 50): # once an hour print("\nUpdating Danio#3620 Table") try: message = await channel.fetch_message(table.messageID) moBotMember = message.guild.get_member(moBot) embed = discord.Embed(color=moBotMember.roles[-1].color) embed.set_author(name=table.title, icon_url=message.guild.icon_url) workbook = RandomSupport.openSpreadsheet(table.key) sheet = workbook.worksheet("Discord Table") r = sheet.range("A1:D22") widths = {"names": int(r[2].value), "points": int(r[3].value)} flags = AOR.getFlags() des = "**__%s__**\n" % r[4].value for i in range(8, len(r), 4): if (r[i].value != ""): des += "`%s` %s `%s` `%s`\n" % ( r[i].value.rjust(3, " "), flags[r[i + 1].value], r[i + 2].value.ljust(widths["names"], " "), r[i + 3].value.rjust(widths["points"], " ")) des += "[__Results Spreadsheet__](https://docs.google.com/spreadsheets/d/%s/)" % table.key embed.description = des embed.set_footer(text=datetime.strftime( datetime.utcnow(), "| Refreshed: %b %d %H:%M UTC |")) await message.edit(embed=embed) except AttributeError: # no channel?? pass