#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright (C) 2012 by Atzm WATANABE # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License (version 2) as # published by the Free Software Foundation. It is distributed in the # hope that it will be useful, but WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. See the GNU General Public License for more details. # # $Id$ # from __future__ import with_statement import os.path import sys import cgi import json import fcntl import urllib import ConfigParser class ScoreBoard(object): def __init__(self, path, limit): self._path = path self._limit = limit self._data = [] self._fp = None def get(self): return self._data[:] def open(self, mode='a+', lock=fcntl.LOCK_EX): self._fp = open(self._path, mode) fcntl.flock(self._fp, lock) return self def close(self): self._fp.close() return self def read(self): self._fp.seek(0, 0) raw = self._fp.read() if raw: self._data = json.loads(raw) return self def write(self): raw = json.dumps(self._data, ensure_ascii=False).encode('utf-8') self._fp.seek(0, 0) self._fp.truncate(0) self._fp.write(raw + '\n') return self def insert(self, name, value, stime, etime): self._data.append({ 'name': name, 'value': value, 'stime': stime, 'etime': etime, }) self.sort() if self._limit < len(self._data): self._data.pop(-1) return self def sort(self): self._data.sort(lambda a, b: cmp(a['value'], b['value']), reverse=True) return self def main(): config = ConfigParser.SafeConfigParser() config.read('score.conf') path = os.path.abspath(os.path.expanduser(config.get('DEFAULT', 'path'))) limit = config.getint('DEFAULT', 'limit') board = ScoreBoard(path, limit) form = cgi.FieldStorage() try: stime = int(form.getfirst('stime')) etime = int(form.getfirst('etime')) score = int(form.getfirst('value')) name = urllib.unquote(form.getfirst('name')).decode('utf-8') if 20 < len(name): raise ValueError('name is too long') board.open().read().insert(name, score, stime, etime).write().close() except: board.open().read().close() sys.stdout.write('Content-type: application/json; charset=UTF-8\r\n\r\n') print(json.dumps(board.get(), ensure_ascii=False).encode('utf-8')) if __name__ == '__main__': main()