~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/chat.py

  • Committer: mattgiuca
  • Date: 2008-07-15 07:19:34 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:875
Added "migrations" directory, which contains incremental database update
    scripts.
Updated users.sql, uniqueness key on offering table.
Added migration matching this update to the migrations directory. Mm handy!

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# IVLE - Informatics Virtual Learning Environment
2
 
# Copyright (C) 2007-2008 The University of Melbourne
3
 
#
4
 
# This program is free software; you can redistribute it and/or modify
5
 
# it under the terms of the GNU General Public License as published by
6
 
# the Free Software Foundation; either version 2 of the License, or
7
 
# (at your option) any later version.
8
 
#
9
 
# This program is distributed in the hope that it will be useful,
10
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
# GNU General Public License for more details.
13
 
#
14
 
# You should have received a copy of the GNU General Public License
15
 
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
 
 
18
 
# Module: Chat
19
 
# Author: Thomas Conway
20
 
# Date:   5/2/2008
21
 
 
22
 
import cjson
23
 
import cStringIO
24
 
import md5
25
 
import sys
26
 
import os
27
 
import socket
28
 
import traceback
29
 
 
30
 
class Terminate(Exception):
31
 
    """Exception thrown when server is to be shut down. It will attempt to sned 
32
 
    the final_response to the client and then exits"""
33
 
    def __init__(self, final_response=None):
34
 
        self.final_response = final_response
35
 
 
36
 
    def __str__(self):
37
 
        return repr(self.final_response)
38
 
 
39
 
 
40
 
def start_server(port, magic, daemon_mode, handler, initializer = None):
41
 
    # Attempt to open the socket.
42
 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
43
 
    s.bind(('', port))
44
 
    s.listen(1)
45
 
 
46
 
    # Excellent! It worked. Let's turn ourself into a daemon,
47
 
    # then get on with the job of being a python interpreter.
48
 
    if daemon_mode:
49
 
        if os.fork():   # launch child and...
50
 
            os._exit(0) # kill off parent
51
 
        os.setsid()
52
 
        if os.fork():   # launch child and...
53
 
            os._exit(0) # kill off parent again.
54
 
        os.umask(077)
55
 
 
56
 
        try:
57
 
            MAXFD = os.sysconf("SC_OPEN_MAX")
58
 
        except:
59
 
            MAXFD = 256
60
 
 
61
 
        # Close all file descriptors, except the socket.
62
 
        for i in xrange(MAXFD):
63
 
            if i == s.fileno():
64
 
                continue
65
 
            try:
66
 
                os.close(i)
67
 
            except OSError:
68
 
                pass
69
 
 
70
 
        si = os.open(os.devnull, os.O_RDONLY)
71
 
        os.dup2(si, sys.stdin.fileno())
72
 
 
73
 
        so = os.open(os.devnull, os.O_WRONLY)
74
 
        os.dup2(so, sys.stdout.fileno())
75
 
 
76
 
        se = os.open(os.devnull, os.O_WRONLY)
77
 
        os.dup2(se, sys.stderr.fileno())
78
 
 
79
 
    if initializer:
80
 
        initializer()
81
 
 
82
 
    while True:
83
 
        (conn, addr) = s.accept()
84
 
        try:
85
 
            # Grab the input
86
 
            buf = cStringIO.StringIO()
87
 
            blk = conn.recv(1024)
88
 
            while blk:
89
 
                buf.write(blk)
90
 
                try:
91
 
                    blk = conn.recv(1024, socket.MSG_DONTWAIT)
92
 
                except:
93
 
                    # Exception thrown if it WOULD block (but we
94
 
                    # told it not to wait) - ie. we are done
95
 
                    blk = None
96
 
            inp = buf.getvalue()
97
 
            env = cjson.decode(inp)
98
 
            
99
 
            # Check that the message is 
100
 
            digest = md5.new(env['content'] + magic).digest().encode('hex')
101
 
            if env['digest'] != digest:
102
 
                conn.close()
103
 
                continue
104
 
 
105
 
            content = cjson.decode(env['content'])
106
 
 
107
 
            response = handler(content)
108
 
 
109
 
            conn.sendall(cjson.encode(response))
110
 
 
111
 
            conn.close()
112
 
 
113
 
        except Terminate, t:
114
 
            # Try and send final response and then terminate
115
 
            if t.final_response:
116
 
                conn.sendall(cjson.encode(t.final_response))
117
 
            conn.close()
118
 
            sys.exit(0)
119
 
        except Exception:
120
 
            # Make a JSON object full of exceptional goodness
121
 
            tb_dump = cStringIO.StringIO()
122
 
            e_type, e_val, e_tb = sys.exc_info()
123
 
            traceback.print_tb(e_tb, file=tb_dump)
124
 
            json_exc = {
125
 
                "type": e_type.__name__,
126
 
                "value": str(e_val),
127
 
                "traceback": tb_dump.getvalue()
128
 
            }
129
 
            conn.sendall(cjson.encode(json_exc))
130
 
            conn.close()
131
 
 
132
 
 
133
 
def chat(host, port, msg, magic, decode = True):
134
 
    sok = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
135
 
    sok.connect((host, port))
136
 
    content = cjson.encode(msg)
137
 
    digest = md5.new(content + magic).digest().encode("hex")
138
 
    env = {'digest':digest,'content':content}
139
 
    sok.send(cjson.encode(env))
140
 
 
141
 
    buf = cStringIO.StringIO()
142
 
    blk = sok.recv(1024)
143
 
    while blk:
144
 
        buf.write(blk)
145
 
        try:
146
 
            blk = sok.recv(1024, socket.MSG_DONTWAIT)
147
 
        except socket.error, e:
148
 
            if e[0] != 11:
149
 
                raise
150
 
            # Exception thrown if it WOULD block (but we
151
 
            # told it not to wait) - ie. we are done
152
 
            blk = None
153
 
    inp = buf.getvalue()
154
 
    sok.close()
155
 
 
156
 
    if decode:
157
 
        return cjson.decode(inp)
158
 
    else:
159
 
        return inp
160