2012年12月13日木曜日

PythonとFlaskとMongoDBで後輩のお手伝いをした話

昨日はJOI(情報オリンピック)の予選の模擬試験を後輩(@kagamiz)がやるのをお手伝いしました

システム側の運営をやった感じです。(@kagamizは問題を作りました)

今回もMongoDB+Flaskで頑張りました。

実装

今回の主な実装となったのは
1. ログイン処理
2. 解答の提出処理
3. 採点スクリプト

の3つです。

1つ目はlogin用の使いまわしやすいモジュールを自分で書いてあるのでそれをクローンしてくるだけで瞬殺でした。

MongoDBで {_id: int, username: string, passwd: string} みたいな感じのコレクションを用意しておいて 以下のように

!python

import functools
from flask import session

def require_login(func):
@functools.wraps(func)
def wrapeer(*args, **kwargs):
    if (session.has_key("username") == True and
    session.has_key("passwd") == True):
        user = g.db.users.find_one({"username": session["username"]});
        if (user == None):
            return ("Invalid User");
        kwargs["user"] = user;
    else:
        path = request.path;
        get_request = urllib.urlencode({
            "redirect": path
        });
        return (redirect("/login?" + get_request));

    return func(*args, **kwargs);
return wrapeer;

こんな感じで書いてこれをViewのデコレータにしてあげればデコレータをつけたViewに入るときにloginしていなければログイン画面へリダイレクトするという処理がかけます(うーん便利だなーデコレータは!) Pythonのデコレータはすごく便利なので後日まとまって記事がかけるといいな〜と思っています。

2つ目はフォルダのパーミッションに気をつけさえすればそんなに難しいことではありません。

3つ目は頑張って書きました。 正直データベースからデータを引っ張ってきてゴニョゴニョするだけです。

参加状況

最初はICT委員会(僕の入ってる部活のようなものです)内でやる厳かなものだと思ってたのですが@kagamizくんがTwitterで一般の人にも告知したところ。なんと128人も参加者が来ました(切りが良い!) なんか、落としたらどうしようって感じで怖かったです。

トラブル

  1. ソースファイルの提出が一時間できなくなった(そこまで致命的ではない)
  2. 登録処理が5分間ほどできなくなった(致命的)
  3. 採点する際に空ファイルを提出された時に正解と出してしまっていた(致命的)

1に関しては些細なミスが招いたものですでに他の解凍ファイルを提出した状況下でしかテストをおこなっていなかったことに起因します。これからはテストをもっとしっかりやりたい。

2に関しては登録した時の確認メールを送る処理の中でこけていました。原因の究明も大事なのですがかなり致命的な場所でのエラーだったので、一旦メール確認の機能を切ることにより対処しました。

3は解答ファイルのほうが小さかった場合の処理のbrakeの前にフラグを折ってなかったことに起因しました。

まあ、致命的な奴は5分くらいで対処できたので初めてにしては上出来なのではないでしょうか?

まとめ

正直、短時間で100人以上が同時に参加するサイトを管理するという。経験が少なかったので短い間でしたけどその体験ができてよかったです。

まあ、いくつかトラブルがありましたが無事終了させることがあってよかったです。

0 件のコメント:

コメントを投稿