Skip to content

Commit

Permalink
Merge pull request #4 from amosbastian/0.3.0
Browse files Browse the repository at this point in the history
0.3.0
  • Loading branch information
Amos Bastian committed Feb 19, 2019
2 parents d2809ba + c0a1837 commit a1f0f32
Show file tree
Hide file tree
Showing 8 changed files with 333 additions and 69 deletions.
115 changes: 52 additions & 63 deletions FPLbot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
from pymongo import MongoClient

from constants import fpl_team_names, versus_pattern
from utils import create_logger, get_player_table, to_fpl_team, update_players
from utils import (create_logger, find_player, get_player_table,
player_vs_player_table, player_vs_team_table, to_fpl_team,
update_players, get_relevant_fixtures)

dirname = os.path.dirname(os.path.realpath(__file__))
logger = create_logger()
Expand Down Expand Up @@ -81,75 +83,58 @@ async def post_price_changes(self):
self.subreddit.submit(post_title, selftext=post_body)
await update_players()

def player_vs_team_table(self, fixtures):
"""Returns a Markdown table showing the player's performance in the
given fixtures.
"""
table = ("|Fixture|Date|MP|G|xG|A|xA|NPG|NPxG|KP|\n"
"|:-|:-:|-:|-:|-:|-:|-:|-:|-:|-:|\n")

for fixture in fixtures:
home_team = f"{fixture['h_team']} {fixture['h_goals']}"
away_team = f"{fixture['a_goals']} {fixture['a_team']}"

# Highlight the winning team
if int(fixture["h_goals"]) > int(fixture["a_goals"]):
home_team = f"**{home_team}**"
elif int(fixture["h_goals"]) < int(fixture["a_goals"]):
away_team = f"**{away_team}**"

# Highlight whether the player was a starter or not
if fixture["position"].lower() != "sub":
fixture["time"] = f"**{fixture['time']}**"

table += (
f"|{home_team}-{away_team}"
f"|{fixture['date']}"
f"|{fixture['time']}"
f"|{fixture['goals']}"
f"|{float(fixture['xG']):.2f}"
f"|{fixture['assists']}"
f"|{float(fixture['xA']):.2f}"
f"|{fixture['npg']}"
f"|{float(fixture['npxG']):.2f}"
f"|{fixture['key_passes']}|\n"
)

return table
def versus_player_handler(self, player_A_name, player_B_name,
number_of_fixtures):
"""Function for handling player vs. player comment."""
player_A = find_player(player_A_name)
player_B = find_player(player_B_name)

if not player_A or not player_B:
return

player_A_fixtures = get_relevant_fixtures(player_A)
player_B_fixtures = get_relevant_fixtures(player_B)

if not number_of_fixtures:
number_of_fixtures = max(len(player_A_fixtures),
len(player_B_fixtures))

fixtures = zip(player_A_fixtures[:number_of_fixtures],
player_B_fixtures[:number_of_fixtures])

post_template = open(f"{dirname}/../comment_template.md").read()
table_header = (
f"# {player_A['web_name']}{player_A['now_cost'] / 10.0:.1f}) "
f"vs. {player_B['web_name']}{player_B['now_cost'] / 10.0:.1f}) "
f"(last {number_of_fixtures} fixtures)")
table_body = player_vs_player_table(fixtures)

return post_template.format(
comment_header=table_header,
comment_body=table_body
)

def versus_team_handler(self, player_name, team_name, number_of_fixtures):
"""Function for handling player vs. team comment."""
# Find most relevant player using text search
players = self.database.players.find(
{"$text": {"$search": player_name}},
{"score": {"$meta": "textScore"}}
).sort([("score", {"$meta": "textScore"})])

try:
player = list(players.limit(1))[0]
except IndexError:
logger.error(f"Player {player_name} could not be found!")
player = find_player(player_name)
if not player:
return

if not number_of_fixtures:
number_of_fixtures = len(player["understat_history"])

fixture_count = 0
relevant_fixtures = []
team_name = to_fpl_team(team_name)
for fixture in player["understat_history"]:
if fixture_count >= int(number_of_fixtures):
break

if (team_name != fixture["h_team"].lower() and
team_name != fixture["a_team"].lower()):
continue

fixture_count += 1
relevant_fixtures.append(fixture)

player_vs_team_table = self.player_vs_team_table(relevant_fixtures)
return player_vs_team_table
fixtures = get_relevant_fixtures(
player, team_name=to_fpl_team(team_name))[:number_of_fixtures]
post_template = open(f"{dirname}/../comment_template.md").read()
table_header = (
f"# {player_name.title()} vs. {team_name.title()} (last "
f"{len(fixtures)} fixtures)")
table_body = player_vs_team_table(fixtures)

return post_template.format(
comment_header=table_header,
comment_body=table_body
)

def add_comment_to_database(self, comment):
logger.info(f"Adding comment with ID {comment.id} to the database.")
Expand All @@ -172,11 +157,15 @@ def comment_handler(self, comment):
opponent_name = match.group(2).lower().replace(".", "").strip()
number = match.group(3)

if number:
number = int(number)

if to_fpl_team(opponent_name) in fpl_team_names:
reply_text = self.versus_team_handler(
player_name, opponent_name, number)
else:
return
reply_text = self.versus_player_handler(
player_name, opponent_name, number)

if reply_text:
logger.info(f"Replying ({player_name} vs. {opponent_name}) to "
Expand Down
2 changes: 1 addition & 1 deletion FPLbot/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"understat_history"
]

versus_pattern = re.compile(r"!fplbot\s+([^\W\d]+(?:[\s-][^\W\d]+)*)\s+(?:vs.|vs)\s+([a-zA-Z ]+)(\d+)?")
versus_pattern = re.compile(r"!fplbot\s+([A-zÀ-ÿ]+(?:[\s-][A-zÀ-ÿ]+)*)\s+(?:vs.|vs)\s+([A-zÀ-ÿ]+(?:[\s-][A-zÀ-ÿ]+)*)\s*(\d+)?")

to_fpl_team_dict = {
"arsenal fc": "arsenal",
Expand Down
21 changes: 21 additions & 0 deletions FPLbot/init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import asyncio

from pymongo import MongoClient

from utils import update_players

client = MongoClient()
database = client.fpl


async def main():
await update_players()


if __name__ == "__main__":
try:
asyncio.run(main())
except AttributeError:
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
25 changes: 25 additions & 0 deletions FPLbot/price_changes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import asyncio
import json
import os

import aiohttp

from bot import FPLBot

dirname = os.path.dirname(os.path.realpath(__file__))

async def main(config):
async with aiohttp.ClientSession() as session:
fpl_bot = FPLBot(config, session)

await fpl_bot.post_price_changes()


if __name__ == "__main__":
config = json.loads(open(f"{dirname}/../config.json").read())
try:
asyncio.run(main(config))
except AttributeError:
loop = asyncio.get_event_loop()
loop.run_until_complete(main(config))
loop.close()
Loading

0 comments on commit a1f0f32

Please sign in to comment.