示例#1
0
def get_player(pid=0):
    '''
    Create a Player tuple from an ID
    Request the Dotabuff, join the ID and scan the page with BS4
    '''
    if not isinstance(pid, int):
        raise Exception("Invalid Player ID type given")

    s   = "http://www.dotabuff.com/players"
    uri = "/".join([s, str(pid)])
    doc = re_get(uri, headers={'User-Agent':'Mozilla/5.0'})
    bs  = BeautifulSoup(doc.text, 'html.parser')
    pnm = bs.title.string.split(" ").pop(0) # should fetch the player's Name

    # row finding block
    rws = bs.find_all('div', class_='r-row')

    # first 10  have to retrieve a-href URIs
    hrs = [parse_hero(x.find('a').get('href')) for x in rws[:10]]

    # fetch match URIs after the 10th row
    mts = [parse_id(h.get('data-link-to')) for h in rws[10:]]

    # finish
    return Player(pid, pnm, hrs, mts)
示例#2
0
def get_player(pid=0):
    '''
    Create a Player tuple from an ID
    Request the Dotabuff, join the ID and scan the page with BS4
    '''
    if not isinstance(pid, int):
        raise Exception("Invalid Player ID type given")

    s = "http://www.dotabuff.com/players"
    uri = "/".join([s, str(pid)])
    doc = re_get(uri, headers={'User-Agent': 'Mozilla/5.0'})
    bs = BeautifulSoup(doc.text, 'html.parser')
    pnm = bs.title.string.split(" ").pop(0)  # should fetch the player's Name

    # row finding block
    rws = bs.find_all('div', class_='r-row')

    # first 10  have to retrieve a-href URIs
    hrs = [parse_hero(x.find('a').get('href')) for x in rws[:10]]

    # fetch match URIs after the 10th row
    mts = [parse_id(h.get('data-link-to')) for h in rws[10:]]

    # finish
    return Player(pid, pnm, hrs, mts)
示例#3
0
def get_bs(url):
    """
    Return a parser of the given URL fragment
    /content/something-id -> BS(ROOT_URL/content/something-id)
    Applies a ton of filtering/replacing so we don't get bad characters
    """
    text = re_get(craft_url(url)).text
    text = "".join([c for c in text if c in printable])
    text = text.replace("\n", " ").replace("\xa0", " ")
    return BS(text, 'html.parser')
示例#4
0
async def dota_id(msg, mobj):
    """
    Registers a user's Discord ID with a Dota 2 player ID
    This will be used by the automated Dota 2 match parser service
    The string given is tested against OpenDota's API to see if it's valid
    """
    if len(msg) > 30:
        return await client.send_message(mobj.channel, "Bro that's too long")

    r = re_get(f"{OPENDOTA_API}/players/{msg.strip()}")
    if r.status_code != 200:
        return await client.send_message(mobj.channel, "Invalid Dota 2 ID")

    fname = shared_data(f"{mobj.author.id}.dota")
    with open(fname, 'w') as f:
        f.write(msg.strip())

    return await client.send_message(mobj.channel,
                                     "Registered Player ID {msg.strip()}")
示例#5
0
async def dota_id(msg, mobj):
    """
    Register's a user's Discord ID and associates it with a Dota ID
    This is used to retrieve a user's last played match from OpenDota 
    The string must be tested against OpenDota's API to see if it's valid
    """
    if len(msg) > 30:
        return await client.send_message(mobj.channel, "Bro that's too long")

    r = re_get(f"{OPENDOTA_API}/players/{msg.strip()}")
    if r.status_code != 200:
        return await client.send_message(mobj.channel, "Invalid Dota ID")

    fname = bot_data(f"{mobj.author.id}.txt")
    print(fname)
    with open(fname, 'w') as f:
        f.write(msg.strip())

    print("Returning")
    return await client.send_message(mobj.channel, "Registered your Dota ID")
    def db_sample_request():
        """Retrieve data of many products using a Search Requests"""

        url = "https://fr.openfoodfacts.org/cgi/search.pl?"
        params = {
            "action": "process",
            "tagtype_0": "purchase_places",
            "tag_contains_0": "contains",
            "tag_0": "france",
            "sort_by": "unique_scans_n",
            "page_size": 1000,
            "json": 1
        }

        res = re_get(url, params=params)

        if res.status_code != 200:
            raise ConnectionError()

        return res.json()
示例#7
0
async def hoogle(msg, mobj):
    """
    Send a Haskell type signature to Hoogle and return the first result
    If no results, error string
    Ex1: !hoogle (a -> b) -> M a -> M b
    Ex2: !hoogle >>=
    """
    if contains_badwords(msg):
        return
    if msg == "":
        return await client.send_message(mobj.channel, "Nothing sent")
    base_url = "https://www.haskell.org/hoogle/?hoogle={}"
    search = BS(re_get(base_url.format(url_replace(msg))).text, "html.parser")
    answers = search.find_all("div", class_="ans")
    if not answers:
        return await client.send_message(mobj.channel,
                                         "Nothing was found, bud")
    res = answers[0]
    text = res.text
    url = res.find("a", class_="a")["href"]
    return await client.send_message(mobj.channel, "{}\n{}".format(text, url))
示例#8
0
def get_match(mid):
    '''
    '''
    if not isinstance(mid, int):
        raise Exception("Invalid Match ID type given")

    s   = "http://www.dotabuff.com/matches"
    uri = "/".join([s, str(mid)])
    doc = re_get(uri, headers={'User-Agent':'Mozilla/5.0'})
    bs  = BeautifulSoup(doc.text, 'html.parser')

    # Get the winning team
    winner = bs.find('div', class_='match-result').text.split(' ').pop(0)

    # Get the player rows
    radi_rows = bs.find_all('tr', class_='faction-radiant')
    dire_rows = bs.find_all('tr', class_='faction-dire')

    # Convert the rows into PStats for the teams
    radi_team = [to_pstat(row) for row in radi_rows]
    dire_team = [to_pstat(row) for row in dire_rows]
    return Match(mid, radi_team, dire_team, winner) 
示例#9
0
def get_match(mid):
    '''
    '''
    if not isinstance(mid, int):
        raise Exception("Invalid Match ID type given")

    s = "http://www.dotabuff.com/matches"
    uri = "/".join([s, str(mid)])
    doc = re_get(uri, headers={'User-Agent': 'Mozilla/5.0'})
    bs = BeautifulSoup(doc.text, 'html.parser')

    # Get the winning team
    winner = bs.find('div', class_='match-result').text.split(' ').pop(0)

    # Get the player rows
    radi_rows = bs.find_all('tr', class_='faction-radiant')
    dire_rows = bs.find_all('tr', class_='faction-dire')

    # Convert the rows into PStats for the teams
    radi_team = [to_pstat(row) for row in radi_rows]
    dire_team = [to_pstat(row) for row in dire_rows]
    return Match(mid, radi_team, dire_team, winner)
示例#10
0
async def ddg(msg, mobj):
    """
    Search DuckDuckGo and post the first result
    Example: !ddg let me google that for you
    """
    try:
        if msg == "":
            return await client.send_message(
                mobj.channel, "You didn't search for anything!")
        msg.replace(" ", "%20")  # replace spaces
        url = "https://duckduckgo.com/html/?q={0}".format(msg)
        bs = BS(re_get(url).text, "html.parser")
        results = bs.find_all("div", class_="web-result")
        if not results:
            return await client.send_message(mobj.channel,
                                             "Couldn't find anything")
        a = results[0].find("a", class_="result__a")
        title, link = a.text, a["href"]
        return await client.send_message(mobj.channel,
                                         "{} - {}".format(title, link))
    except Exception as ex:
        logger("Fail: {}".format(ex))
    return await client.send_message(mobj.channel, "Failed to get the search")
示例#11
0
async def yt(msg, mobj):
    """
    Do a youtube search and yield the first result
    Example: !yt how do I take a screenshot
    """
    try:
        if msg == "":
            return await client.send_message(
                mobj.channel, "You didn't search for anything!")
        msg.replace(" ", "+")
        url = "https://www.youtube.com/results?search_query={}".format(msg)
        bs = BS(re_get(url).text, "html.parser")
        items = bs.find("div",
                        id="results").find_all("div",
                                               class_="yt-lockup-content")
        if not items:
            return await client.send_message(mobj.channel,
                                             "Couldn't find any results")

        # Search for a proper youtube url, has to start with /watch
        # TODO: rewrite this with a list comp/filter
        i, found = 0, False
        while not found and i < 20:
            href = items[i].find("a", class_="yt-uix-sessionlink")["href"]
            if href.startswith("/watch"):
                found = True
            i += 1
        if not found:
            return await client.send_message(mobj.channel,
                                             "Couldn't find a link")
        return await client.send_message(mobj.channel,
                                         "https://youtube.com{}".format(href))
    except Exception as ex:
        logger("Fail: {}".format(ex))
    return await client.send_message(mobj.channel,
                                     "Failed to request the search")
示例#12
0
def get_bs(url):
    return BeautifulSoup(re_get("{}{}".format(base_url, url)).text, 'html.parser')
示例#13
0
async def lastmatch(msg, mobj):
    """
    Fetch a user's ID from the FS and yield the last played match
    from the OpenDota API
    The user must first associate a Dota ID with !dota_id to use this
    """
    fname = bot_data(f"{mobj.author.id}.txt")
    if not fname:
        return await client.send_message(mobj.channel,
                                         "Register your ID first")
    dota_id = None
    with open(fname, 'r') as f:
        dota_id = f.read().strip("\n")

    r = re_get(f"{OPENDOTA_API}/players/{dota_id}/matches?limit=1")
    if r.status_code != 200:
        return await client.send_message(mobj.channel, "Failed to get matches")
    data = r.json()

    mid = data[0]['match_id']
    mr = re_get(f"{OPENDOTA_API}/matches/{mid}")
    if mr.status_code != 200:
        return await client.send_message(mobj.channel, "Error retrieving data")

    # Find the player object in the players property
    mdata = mr.json()
    players = mdata["players"]
    pfilter = [p for p in players if str(p["account_id"]) == dota_id]
    if not pfilter:
        return await client.send_message(mobj.channel,
                                         f"Couldn't find user (???)")
    player = pfilter[0]
    victory = "won" if player["win"] == 1 else "lost"

    # Start grabbing details
    pname = player["personaname"]
    heroid = player["hero_id"]
    k = player["kills"]
    d = player["deaths"]
    a = player["assists"]
    kda = player["kda"]
    gpm = player["gold_per_min"]
    damage_dealt = player["hero_damage"]
    team = player["isRadiant"]  # t if Rad, f if Dire

    hero_filter = [h for h in hero_data if h["id"] == heroid]
    if not hero_filter:
        return await client.send_message(mobj.channel,
                                         f"Can't find hero {heroid}")
    hero_name = hero_filter[0]["localized_name"]

    # Grab Ping details of entire team
    ppings = player["pings"]
    total_pings = sum([p["pings"] for p in players if p["isRadiant"] == team])
    pingpc = round((float(ppings) / total_pings) * 100.0, 2)

    # Grab bounty runes picked up (bounty is ID# 5)
    bounties = player["runes"].get("5", 0)
    all_bounties = sum([p["runes"].get("5", 0) for p in players])
    bcp = round((float(bounties) / all_bounties) * 100.0, 2)

    # Grab messages sent in all chat
    allchat = mdata["chat"]
    allchat_msgs = sorted([m for m in allchat if m["unit"] == pname],
                          key=lambda d: len(d["key"]),
                          reverse=True)
    acp = round((float(len(allchat_msgs)) / len(allchat)) * 100.0, 2)

    allchat_longest = ""
    if allchat_msgs:
        allchat_longest = allchat_msgs[0]['key']

    # Get team's kills and calculate kill participation
    ts = mdata["radiant_score"] if team else mdata["dire_score"]
    kp = round(float(k + a) / ts, 2)

    # Create an embed inside of Discord
    emb = Embed(title=f"Match {mid}",
                url=f"{OPENDOTA_URL}/{mid}",
                description=f"{pname} {victory} as **{hero_name}**",
                color=0x993925)

    # Set the embed image in the corner
    # emb.set_thumbnail(url="https://lol.com/lol.jpg")

    emb.add_field(name="Score", value=f"{k}/{d}/{a} (KDA:{kda}, GPM:{gpm})")

    if bounties:
        emb.add_field(name="Bounty Runes Collected",
                      value=f"{bounties} ({bcp}% of all bounties)")

    if ppings:
        emb.add_field(name="Ping Stats", value=f"{ppings} ({pingpc}% of team)")

    if allchat_msgs:
        emb.add_field(name="Allchat Stats",
                      value=f"{len(allchat_msgs)} ({acp}% of allchat)")
        emb.add_field(name="Longest Quote",
                      value=f"*'{allchat_longest}'* -{pname}")

    emb.set_footer(text=f"Provided by OpenDota API")

    return await client.send_message(mobj.channel, embed=emb)
示例#14
0
OPENDOTA_URL = "https://opendota.com/matches"
OPENDOTA_API = "https://api.opendota.com/api"

# Prefetch a list of heroes from OpenDota
# Cache it to disk just to avoid making too many reqs
hero_data_cached = False
hero_dataf = Path(bot_data("heroes.json"))

# Check if the file exists in the system
# Else load the JSON from a request
if hero_dataf.is_file():
    hero_data_cached = True
    with open(hero_dataf, "r") as f:
        hero_data = jload(f)
else:
    r = re_get(f"{OPENDOTA_API}/heroes")
    if r.status_code != 200:
        print(f"Error pre-fetching hero data (code: {r.status_code})")
    hero_data_cached = False
    hero_data = r.json()


@register_command
async def osfrog(msg, mobj):
    """
    Patch 7.02: help string was removed from Captain's Mode 
    """
    osfrogs = [
        "Added Monkey King to the game",
        "Reduced Lone Druid's respawn talent -50s to -40s",
    ]
示例#15
0
def get_url(url):
    return re_get(url).json()
示例#16
0
 def get_url(self, url):
     if self.requests_installed:
         return re_get(url).json()
     return json_load(urlopen(url).read().decode('utf-8'))