Last active
August 29, 2015 14:06
-
-
Save chiro/bf6fd46fa65cbc56b5d1 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
#! /usr/bin/env python | |
# -*- coding:utf-8 -*- | |
import codecs | |
import csv | |
import urllib | |
import urllib.request | |
import urllib.parse | |
import os | |
import sys | |
import time | |
import http.cookiejar | |
import shlex | |
import gspread | |
class Write2Spread(object): | |
def __init__(self, username, password, url, sheetnum): | |
try: | |
gc = gspread.login(username, password) | |
self.ws = gc.open_by_url(url).get_worksheet(int(sheetnum)) | |
except gspread.exceptions.AuthenticationError: | |
print("Oops! Incorrect username or password. Please try again.", | |
file=sys.stderr) | |
def append_row(self, values): | |
""" | |
値のリストをスプレットシートの最後の列として追加する. | |
:param values: 書き込みたい値のリスト.長さはスプレットシートのカラムを超えなければよい. | |
""" | |
self.ws.append_row(values) | |
class Atcoder(object): | |
def __init__(self, contest_name): | |
cookie = http.cookiejar.CookieJar() | |
self.opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookie)) | |
self.contest_name = contest_name | |
def login(self, username, password): | |
post = { | |
'name': username, | |
'password': password | |
} | |
data = urllib.parse.urlencode(post).encode('UTF-8') | |
self.opener.open(self.__contest_url() + "login", data) | |
def get_standings(self): | |
res = self.opener.open(self.__contest_url() + "standings/csv/") | |
lines = res.read().decode("Shift-JIS").splitlines() | |
reader = csv.reader(lines) | |
# Skip header | |
next(reader) | |
return [team_score for team_score in reader] | |
def __contest_url(self): | |
return "http://" + self.contest_name + ".contest.atcoder.jp/" | |
def get_old_csv(): | |
res = "" | |
with codecs.open(OLD_STANDINGS_FILE_NAME, 'r') as f: | |
reader = csv.reader(f) | |
res = [team for team in reader] | |
return res | |
def update_csv(new_content): | |
with codecs.open(OLD_STANDINGS_FILE_NAME, 'w') as f: | |
f.seek(0) | |
writer = csv.writer(f) | |
for row in new_content: | |
writer.writerow(row) | |
f.truncate() | |
def find_score(teamid, standings): | |
for score in standings: | |
if len(score) > 3 and score[2] == teamid: | |
return score | |
return [] | |
def get_diff(score1, score2): | |
length = len(score1) | |
res = [] | |
for idx, s1, s2 in zip(range(0, length-5), score1[4:], score2[4:]): | |
if s1 != s2: | |
res.append(idx) | |
return res | |
def get_updates(atcoder): | |
standings = atcoder.get_standings() | |
old_standings = get_old_csv() | |
res = [] | |
for team in standings: | |
if len(team) < 3: | |
continue | |
teamname = team[1] | |
teamid = team[2] | |
score = find_score(teamid, standings) | |
old_score = find_score(teamid, old_standings) | |
d = list(map(lambda x: PROBLEM_IDS[int(x / 3)], | |
[x for x in get_diff(score, old_score) | |
if x % 3 == 0 and x / 3 < len(PROBLEM_IDS)])) | |
if len(d) > 0: | |
res.append([teamid, teamname, d]) | |
return (res, standings) | |
PROBLEM_IDS = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"] | |
OLD_STANDINGS_FILE_NAME = "old.csv" | |
def update_spreadsheet(w2s, updates): | |
try: | |
for update in updates: | |
print(update) | |
if len(update) > 0: | |
for problem in update[2]: | |
w2s.append_row([update[0], update[1], problem]) | |
except: | |
raise | |
def say(updates): | |
for update in updates: | |
os.system('say -v Victoria ' + quote(update[0]) | |
def main(): | |
google_user_name = 'a@b.c' | |
google_password = 'your google password' | |
spreadsheet_url = 'URL of the spreadsheet' | |
spreadsheet_sheetnum = 0 | |
w2s = Write2Spread(google_user_name, google_password, spreadsheet_url, | |
spreadsheet_sheetnum) | |
atcoder = Atcoder('') | |
atcoder_user_name = 'atcoder user id' | |
atcoder_password = 'atcoder password' | |
atcoder.login(atcoder_user_name, atcoder_password) | |
interval = 3 | |
while True: | |
try: | |
updates, standings = get_updates(atcoder) | |
update_spreadsheet(w2s, updates) | |
say(updates) | |
update_csv(standings) | |
print(".", end="", flush=True) | |
time.sleep(interval) | |
except KeyboardInterrupt: | |
print("Bye") | |
sys.exit() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment