├── .gitignore └── chesscom-games.py /.gitignore: -------------------------------------------------------------------------------- 1 | venv/ 2 | -------------------------------------------------------------------------------- /chesscom-games.py: -------------------------------------------------------------------------------- 1 | from codecs import open 2 | from datetime import date 3 | import os.path 4 | import requests 5 | 6 | def main(user, where): 7 | print("Downloading %s's games to %s:" % (user, where)) 8 | for archive in get('https://api.chess.com/pub/player/%s/games/archives' % user)['archives']: 9 | download_archive(archive, where) 10 | 11 | def download_archive(url, where): 12 | games = get(url)['games'] 13 | d = date.fromtimestamp(games[0]['end_time']) 14 | y = d.year 15 | m = d.month 16 | filename = os.path.join(where, "%d-%02d.pgn" % (y, m)) 17 | print('Starting work on %s...' % filename) 18 | # XXX: If a file with this name already exists, we'll blow away the old 19 | # one. Possibly not ideal. 20 | with open(filename, 'w', encoding='utf-8') as output: 21 | for game in games: 22 | print(game['pgn'], file=output) 23 | print('', file=output) 24 | 25 | def get(url): 26 | return requests.get(url).json() 27 | 28 | if __name__ == '__main__': 29 | import argparse 30 | parser = argparse.ArgumentParser(description="Download a user's games from chess.com") 31 | parser.add_argument('user', metavar='USER', help='The user whose games we want') 32 | parser.add_argument('where', metavar='PATH', help='Where to create the PGN files', 33 | default=".", nargs='?') 34 | args = parser.parse_args() 35 | main(args.user, args.where) 36 | --------------------------------------------------------------------------------