Skip to content

Instantly share code, notes, and snippets.

@chiro
Last active August 29, 2015 14:06
Show Gist options
  • Save chiro/bf6fd46fa65cbc56b5d1 to your computer and use it in GitHub Desktop.
Save chiro/bf6fd46fa65cbc56b5d1 to your computer and use it in GitHub Desktop.
#! /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