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

« back to all changes in this revision

Viewing changes to ivle/chat.py

  • Committer: William Grant
  • Date: 2009-02-23 23:47:02 UTC
  • mfrom: (1099.1.211 new-dispatch)
  • Revision ID: grantw@unimelb.edu.au-20090223234702-db4b1llly46ignwo
Merge from lp:~ivle-dev/ivle/new-dispatch.

Pretty much everything changes. Reread the setup docs. Backup your databases.
Every file is now in a different installed location, the configuration system
is rewritten, the dispatch system is rewritten, URLs are different, the
database is different, worksheets and exercises are no longer on the
filesystem, we use a templating engine, jail service protocols are rewritten,
we don't repeat ourselves, we have authorization rewritten, phpBB is gone,
and probably lots of other things that I cannot remember.

This is certainly the biggest commit I have ever made, and hopefully
the largest I ever will.

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