def scorers(self, driver) -> typing.List[Player]: xp = ".//div[@class='tabs__group']" clicks = [(By.ID, "tabitem-top_scorers")] src = selenium_driver.get_html(driver, self.link + "/standings", xp, clicks=clicks) tree = html.fromstring(src) rows = tree.xpath('.//div[@id="table-type-10"]//div[contains(@class,"table__row")]') players = [] for i in rows: items = i.xpath('.//text()') items = [i.strip() for i in items if i.strip()] uri = "".join(i.xpath(".//span[@class='team_name_span']//a/@onclick")).split("'") try: tm_url = "http://www.flashscore.com/" + uri[3] except IndexError: tm_url = "" try: p_url = "http://www.flashscore.com/" + uri[1] except IndexError: p_url = "" rank, name, tm, goals, assists = items country = "".join(i.xpath('.//span[contains(@class,"flag")]/@title')).strip() flag = transfer_tools.get_flag(country) players.append(Player(rank=rank, flag=flag, name=name, link=p_url, team=tm, team_link=tm_url, goals=int(goals), assists=assists)) self.fetch_logo(driver) return players
async def get_rumours(self, ctx, e, target): e.description = "" target = target.replace('startseite', 'geruechte') async with self.bot.session.get(f"{target}") as resp: if resp.status != 200: return await ctx.send( f"Error {resp.status} connecting to {resp.url}") tree = html.fromstring(await resp.text()) e.url = str(resp.url) e.set_author(name=tree.xpath('.//head/title[1]/text()')[0], url=str(resp.url)) e.set_footer(text=discord.Embed.Empty) rumours = tree.xpath( './/div[@class="large-8 columns"]/div[@class="box"]')[0] rumours = rumours.xpath('.//tbody/tr') rumorlist = [] for i in rumours: pname = "".join( i.xpath( './/td[@class="hauptlink"]/a[@class="spielprofil_tooltip"]/text()' )) if not pname: continue player_link = "".join( i.xpath( './/td[@class="hauptlink"]/a[@class="spielprofil_tooltip"]/@href' )) player_link = f"http://transfermarkt.co.uk{player_link}" ppos = "".join(i.xpath('.//td[2]//tr[2]/td/text()')) mv = "".join(i.xpath('.//td[6]//text()')).strip() flag = transfer_tools.get_flag(i.xpath('.//td[3]/img/@title')[0]) age = "".join(i.xpath('./td[4]/text()')).strip() team = "".join(i.xpath('.//td[5]//img/@alt')) tlink = "".join(i.xpath('.//td[5]//img/@href')) odds = "".join(i.xpath('./td[8]//text()')).strip().replace( ' ', '') source = "".join(i.xpath('./td[7]//@href')) odds = f"[{odds}likely]({source})" if odds != "-" else f"[rumor info]({source})" rumorlist.append( f"{flag} **[{pname}]({player_link})** {age}, {ppos} ({mv})\n*[{team}]({tlink})*, {odds}\n" ) output = "" count = 0 if not rumorlist: output = "No rumours about new signings found." for i in rumorlist: if len(i) + len(output) < 1985: output += i else: output += f"And {len(rumorlist) - count} more..." break count += 1 e.description = output await ctx.send(embed=e)
def players(self, driver, tab=0) -> typing.List[Player]: xp = './/div[contains(@class,"playerTable")]' src = selenium_driver.get_html(driver, self.link + "/squad", xp) tree = html.fromstring(src) tab += 1 # tab is Indexed at 0 but xpath indexes from [1] rows = tree.xpath(f'.//div[contains(@class, "playerTable")][{tab}]//div[contains(@class,"profileTable__row")]') players = [] position = "" for i in rows: pos = "".join(i.xpath('./text()')).strip() if pos: # The way the data is structured contains a header row with the player's position. try: position = pos.strip('s') except IndexError: position = pos continue # There will not be additional data. name = "".join(i.xpath('.//div[contains(@class,"")]/a/text()')) try: # Name comes in reverse order. player_split = name.split(' ', 1) name = f"{player_split[1]} {player_split[0]}" except IndexError: pass country = "".join(i.xpath('.//span[contains(@class,"flag")]/@title')) flag = transfer_tools.get_flag(country) number = "".join(i.xpath('.//div[@class="tableTeam__squadNumber"]/text()')) try: age, apps, g, y, r = i.xpath( './/div[@class="playerTable__icons playerTable__icons--squad"]//div/text()') except ValueError: age = "".join(i.xpath('.//div[@class="playerTable__icons playerTable__icons--squad"]//div/text()')) apps = g = y = r = 0 injury = "".join(i.xpath('.//span[contains(@class,"absence injury")]/@title')) if injury: injury = f"<:injury:682714608972464187> " + injury # I really shouldn't hard code emojis. link = "".join(i.xpath('.//div[contains(@class,"")]/a/@href')) link = f"http://www.flashscore.com{link}" if link else "" try: number = int(number) except ValueError: number = 00 pl = Player(name=name, number=number, country=country, link=link, position=position, age=age, apps=apps, goals=int(g), yellows=y, reds=r, injury=injury, flag=flag) players.append(pl) return players
async def get_transfers(self, ctx, e, target): e.description = "" target = target.replace('startseite', 'transfers') # Winter window, Summer window. if datetime.datetime.now().month < 7: period = "w" season_id = datetime.datetime.now().year - 1 else: period = "s" season_id = datetime.datetime.now().year target = f"{target}/saison_id/{season_id}/pos//detailpos/0/w_s={period}" p = {"w_s": period} async with self.bot.session.get(target, params=p) as resp: if resp.status != 200: return await ctx.reply( f"Error {resp.status} connecting to {resp.url}", mention_author=False) tree = html.fromstring(await resp.text()) e.set_author(name="".join(tree.xpath('.//head/title/text()')), url=target) e.set_footer(text=discord.Embed.Empty) ignore, intable, outtable = tree.xpath( './/div[@class="large-8 columns"]/div[@class="box"]') intable = intable.xpath('.//tbody/tr') outtable = outtable.xpath('.//tbody/tr') inlist, inloans, outlist, outloans = [], [], [], [] for i in intable: pname = "".join( i.xpath( './/td[@class="hauptlink"]/a[@class="spielprofil_tooltip"]/text()' )) player_link = "".join( i.xpath( './/td[@class="hauptlink"]/a[@class="spielprofil_tooltip"]/@href' )) player_link = f"http://transfermarkt.co.uk{player_link}" age = "".join(i.xpath('.//td[3]/text()')) ppos = "".join(i.xpath('.//td[2]//tr[2]/td/text()')) try: flag = transfer_tools.get_flag( i.xpath('.//td[4]/img[1]/@title')[0]) except IndexError: flag = "" fee = "".join(i.xpath('.//td[6]//text()')) if "loan" in fee.lower(): inloans.append( f"{flag} [{pname}]({player_link}) {ppos}, {age}\n") continue inlist.append( f"{flag} [{pname}]({player_link}) {ppos}, {age} ({fee})\n") for i in outtable: pname = "".join( i.xpath( './/td[@class="hauptlink"]/a[@class="spielprofil_tooltip"]/text()' )) player_link = "".join( i.xpath( './/td[@class="hauptlink"]/a[@class="spielprofil_tooltip"]/@href' )) player_link = f"http://transfermarkt.co.uk{player_link}" flag = transfer_tools.get_flag(i.xpath('.//td/img[1]/@title')[1]) fee = "".join(i.xpath('.//td[6]//text()')) if "loan" in fee.lower(): outloans.append(f"{flag} [{pname}]({player_link}), ") continue outlist.append(f"{flag} [{pname}]({player_link}), ") def write_field(title, input_list): output = "" for item in input_list.copy(): if len(item) + len(output) < 1009: output += item input_list.remove(item) else: output += f"And {len(input_list)} more..." break e.add_field(name=title, value=output.strip(","), inline=False) for x, y in [("Players in", inlist), ("Loans In", inloans), ("Players out", outlist), ("Loans Out", outloans)]: write_field(x, y) if y else "" await ctx.reply(embed=e, mention_author=False)
async def transfer_ticker(self): src = 'https://www.transfermarkt.co.uk/transfers/neuestetransfers/statistik' flags = "?minMarktwert=1" async with self.bot.session.get(src + flags) as resp: if resp.status != 200: return tree = html.fromstring(await resp.text()) skip_output = True if not self.parsed else False # skip_output = False for i in tree.xpath( './/div[@class="responsive-table"]/div/table/tbody/tr'): player_name = "".join( i.xpath('.//td[1]//tr[1]/td[2]/a/text()')).strip() # DEBUG_RESTART # if "Hashimoto" in player_name: # skip_output = True if not player_name or player_name in self.parsed: continue # skip when duplicate / void. else: self.parsed.append(player_name) # We don't need to output when populating after a restart. if skip_output: continue # Player Info player_link = "".join(i.xpath('.//td[1]//tr[1]/td[2]/a/@href')) age = "".join(i.xpath('./td[2]//text()')).strip() pos = "".join(i.xpath('./td[1]//tr[2]/td/text()')) nat = i.xpath('.//td[3]/img/@title') flags = [] for j in nat: flags.append(transfer_tools.get_flag(j)) # nationality = ", ".join([f'{j[0]} {j[1]}' for j in list(zip(flags,nat))]) nationality = "".join(flags) # Leagues & Fee new_team = "".join( i.xpath('.//td[5]/table//tr[1]/td/a/text()')).strip() new_team_link = "".join( i.xpath('.//td[5]/table//tr[1]/td/a/@href')).strip() new_league = "".join( i.xpath('.//td[5]/table//tr[2]/td/a/text()')).strip() new_league_link = "".join( i.xpath('.//td[5]/table//tr[2]/td/a/@href')).strip() new_league_flag = transfer_tools.get_flag("".join( i.xpath('.//td[5]/table//tr[2]/td//img/@alt'))) old_team = "".join( i.xpath('.//td[4]/table//tr[1]/td/a/text()')).strip() old_team_link = "".join( i.xpath('.//td[4]/table//tr[1]/td/a/@href')).strip() old_league = "".join( i.xpath('.//td[4]/table//tr[2]/td/a/text()')).strip() old_league_link = "".join( i.xpath('.//td[4]/table//tr[2]/td/a/@href')).strip() old_league_flag = transfer_tools.get_flag("".join( i.xpath('.//td[4]/table//tr[2]/td//img/@alt'))) # Fix Links if "transfermarkt" not in new_team_link: new_team_link = "https://www.transfermarkt.co.uk" + new_team_link if new_team_link else "" if "transfermarkt" not in new_league_link: new_league_link = f"https://www.transfermarkt.co.uk" + new_league_link if new_league_link else "" if "transfermarkt" not in old_team_link: old_team_link = "https://www.transfermarkt.co.uk" + old_team_link if old_team_link else "" if "transfermarkt" not in old_league_link: old_league_link = "https://www.transfermarkt.co.uk" + old_league_link if old_league_link else "" # Markdown. new_league_markdown = "" if "None" in new_league else f"{new_league_flag} [{new_league}]({new_league_link})" new_team_markdown = f"[{new_team}]({new_team_link})" old_league_markdown = "" if "None" in old_league else f"{old_league_flag} [{old_league}]({old_league_link})" old_team_markdown = f"[{old_team}]({old_team_link})" if new_league == old_league: move = f"{old_team} to {new_team} ({new_league_flag} {new_league})" else: move = f"{old_team} ({old_league_flag} {old_league}) to {new_team} ({new_league_flag} {new_league})" move_info = move.replace(" (None )", "") fee = "".join(i.xpath('.//td[6]//a/text()')) fee_link = "https://www.transfermarkt.co.uk" + "".join( i.xpath('.//td[6]//a/@href')) fee_markdown = f"[{fee}]({fee_link})" e = discord.Embed() e.description = "" e.colour = 0x1a3151 e.title = f"{nationality} {player_name} | {age}" e.url = f"https://www.transfermarkt.co.uk{player_link}" e.description = f"{pos}\n" e.description += f"**To**: {new_team_markdown} {new_league_markdown}\n" e.description += f"**From**: {old_team_markdown} {old_league_markdown}" if fee: e.add_field(name="Reported Fee", value=fee_markdown, inline=False) # Get picture and re-host on imgur. th = "".join(i.xpath('.//td[1]//tr[1]/td[1]/img/@src')) th = await self.imgurify(th) if th is not None: e.set_thumbnail(url=th) shortstring = f"{player_name} | {fee} | <{fee_link}>\n{move_info}" for (guild_id, channel_id, mode), whitelist in self.cache.copy().items(): ch = self.bot.get_channel(channel_id) if ch is None: continue # rip. if whitelist: # Iterate through every whitelist item, if there is not a match, we iterate to the next channel. for (item, item_type, alias) in whitelist: if item_type == "league": item = item.replace( 'startseite', 'transfers').strip() # Fix for link. if item in new_league_link or item in old_league_link: break else: if item in new_team_link or item in old_team_link: break else: continue try: if mode: await ch.send(shortstring) else: await ch.send(embed=e) except (discord.Forbidden, discord.HTTPException): pass # dumb f***s can't set a channel right, server issues. except AttributeError: print( f"AttributeError transfer-ticker {channel_id} check for channel deletion." )
async def transfer_ticker(self): try: async with self.bot.session.get( 'https://www.transfermarkt.co.uk/statistik/neuestetransfers' ) as resp: if resp.status != 200: return tree = html.fromstring(await resp.text()) except Exception as e: print("Error fetching transfermarkt data.") print( e ) # Find out what this error is and narrow the exception down. return skip_output = True if not self.parsed else False for i in tree.xpath( './/div[@class="responsive-table"]/div/table/tbody/tr'): player_name = "".join( i.xpath('.//td[1]//tr[1]/td[2]/a/text()')).strip() if not player_name or player_name in self.parsed: continue # skip when duplicate / void. else: self.parsed.append(player_name) # We don't need to output when populating after a restart. if skip_output: continue # Player Info player_link = "".join(i.xpath('.//td[1]//tr[1]/td[2]/a/@href')) age = "".join(i.xpath('./td[2]//text()')).strip() pos = "".join(i.xpath('./td[1]//tr[2]/td/text()')) nat = i.xpath('.//td[3]/img/@title') flags = [] for j in nat: flags.append(transfer_tools.get_flag(j)) # nationality = ", ".join([f'{j[0]} {j[1]}' for j in list(zip(flags,nat))]) nationality = "".join(flags) # Leagues & Fee new_team = "".join(i.xpath('.//td[5]/table//tr[1]/td/a/text()')) new_team_link = "".join( i.xpath('.//td[5]/table//tr[1]/td/a/@href')) new_league = "".join(i.xpath('.//td[5]/table//tr[2]/td/a/text()')) new_league_link = "".join( i.xpath('.//td[5]/table//tr[2]/td/a/@href')) new_league_link = f"https://www.transfermarkt.co.uk{new_league_link}" if new_league_link else "" new_league_flag = transfer_tools.get_flag("".join( i.xpath('.//td[5]/table//tr[2]/td//img/@alt'))) old_team = "".join(i.xpath('.//td[4]/table//tr[1]/td/a/text()')) old_team_link = "".join( i.xpath('.//td[4]/table//tr[1]/td/a/@href')) old_league = "".join(i.xpath('.//td[4]/table//tr[2]/td/a/text()')) old_league_link = "".join( i.xpath('.//td[4]/table//tr[2]/td/a/@href')) old_league_link = f"https://www.transfermarkt.co.uk{new_league_link}" if old_league_link else "" old_league_flag = transfer_tools.get_flag("".join( i.xpath('.//td[4]/table//tr[2]/td//img/@alt'))) # Markdown. new_league_markdown = f"{new_league_flag} [{new_league}]({new_league_link})" if new_league != "None" \ else "" new_team_markdown = f"[{new_team}]({new_team_link})" old_league_markdown = f"{old_league_flag} [{old_league}]({old_league_link})" if old_league != "None" \ else "" old_team_markdown = f"[{old_team}]({old_team_link})" if new_league == old_league: move_info = f"{old_team} to {new_team} ({new_league_flag} {new_league})" else: move_info = f"{old_team} ({old_league_flag} {old_league}) to {new_team} ({new_league_flag} " \ f"{new_league})" move_info = move_info.replace(" (None )", "") fee = "".join(i.xpath('.//td[6]//a/text()')) fee_link = "https://www.transfermarkt.co.uk" + "".join( i.xpath('.//td[6]//a/@href')) fee_markdown = f"[{fee}]({fee_link})" e = discord.Embed() e.description = "" e.colour = 0x1a3151 e.title = f"{nationality} {player_name} | {age}" e.url = f"https://www.transfermarkt.co.uk{player_link}" e.description = f"{pos}\n" e.description += f"**To**: {new_team_markdown} {new_league_markdown}\n" e.description += f"**From**: {old_team_markdown} {old_league_markdown}" if fee: e.add_field(name="Reported Fee", value=fee_markdown, inline=False) # Get picture and re-host on imgur. th = "".join(i.xpath('.//td[1]//tr[1]/td[1]/img/@src')) th = await self.imgurify(th) e.set_thumbnail(url=th) shortstring = f"{player_name} | {fee} | <{fee_link}>\n{move_info}" for g, cl in self.channel_cache.items(): for c, k in cl.items(): ch = self.bot.get_channel(c) whitelisted = self.whitelist_cache[c] if whitelisted: this_whitelist = whitelisted[i] values = [i['item'] for i in this_whitelist] if not any([ new_team_link, old_team_link, new_league_link, old_league_link ]) in values: continue short_mode = self.channel_cache[g][c]["short_mode"] try: if short_mode: await ch.send(shortstring) else: await ch.send(embed=e) except discord.Forbidden: print( f"Discord.Forbidden while trying to send new transfer to {c}" ) except AttributeError: print( f"AttributeError while trying to send new transfer to {c} - Check for channel " f"deletion.")