Last active
November 20, 2019 15:09
-
-
Save kierendavies/80f5e22969bbb5dade2374c91e280d73 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import collections | |
import datetime | |
import itertools | |
import logging | |
import shelve | |
import requests | |
import requests.adapters | |
import tqdm | |
import urllib3.util.retry | |
SUMMONER_NAME = "Zenhoth" | |
API_KEY = "RGAPI-84848378-8dcf-4bda-aa47-94ac28baf9f7" | |
ENDPOINT = "https://euw1.api.riotgames.com" | |
logging.basicConfig(level=logging.INFO) | |
logger = logging.getLogger("rofl") | |
# From the docs at https://developer.riotgames.com/docs/portal | |
# The rate limit for a personal keys is by design very limited: | |
# - 20 requests every 1 second | |
# - 100 requests every 2 minutes | |
class Retry(urllib3.util.retry.Retry): | |
def __init__(self, **kwargs): | |
kwargs["total"] = 2 | |
kwargs["status_forcelist"] = {429} | |
super().__init__(**kwargs) | |
def get_backoff_time(self): | |
consecutive_errors_len = len( | |
list( | |
itertools.takewhile( | |
lambda x: x.redirect_location is None, | |
reversed(self.history) | |
) | |
) | |
) | |
if consecutive_errors_len < 1: | |
return 0 | |
elif consecutive_errors_len == 1: | |
return 1 | |
else: | |
return 120 | |
session = requests.Session() | |
session.mount("https://", requests.adapters.HTTPAdapter(max_retries=Retry())) | |
session.headers.update({"X-Riot-Token": API_KEY}) | |
with shelve.open("roflcache", writeback=True) as cache: | |
def request(path): | |
if path not in cache: | |
response = session.get(ENDPOINT + path) | |
response.raise_for_status() | |
cache[path] = response.json() | |
return cache[path] | |
logger.info("Getting summoner") | |
summoner = request(f"/lol/summoner/v4/summoners/by-name/{SUMMONER_NAME}") | |
logger.info("Getting match list") | |
matches = {} | |
begin_index = 0 | |
with tqdm.tqdm() as t: | |
while True: | |
match_list = request( | |
"/lol/match/v4/matchlists/by-account/{}?beginIndex={}".format( | |
summoner["accountId"], | |
begin_index, | |
) | |
) | |
if not match_list["matches"]: | |
break | |
for match in match_list["matches"]: | |
match_id = int(match["gameId"]) | |
if match_id not in matches: | |
matches[int(match["gameId"])] = match | |
t.update() | |
begin_index = match_list["endIndex"] | |
first_match_timestamp = min(m["timestamp"] for m in matches.values()) | |
first_match_datetime = datetime.datetime.fromtimestamp(first_match_timestamp / 1000) | |
logger.info(f"Match history available from {first_match_datetime.date()}") | |
logger.info("Getting match details") | |
seen_summoners = collections.Counter() | |
seen_accounts = collections.Counter() | |
for match_id in tqdm.tqdm(matches.keys()): | |
match_info = request( | |
f"/lol/match/v4/matches/{match_id}" | |
) | |
for p in match_info["participantIdentities"]: | |
# Skip bots. | |
if p["player"]["accountId"] == "0": | |
continue | |
seen_summoners[p["player"]["summonerName"]] += 1 | |
seen_accounts[p["player"]["accountId"]] += 1 | |
most_seen_summoners = list(itertools.takewhile(lambda kv: kv[1] > 1, seen_summoners.most_common())) | |
count_width = max(len(str(count)) for name, count in most_seen_summoners) | |
for name, count in most_seen_summoners: | |
print(f"{count:{count_width}} {name}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment