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

« back to all changes in this revision

Viewing changes to ivle/chat.py

Dispatch now generates an index for each plugin type, allowing plugins to
be written which are aware of other plugins, and other plugin types.

All view plugins now subclass from ivle.webapp.base.plugins.ViewPlugin,
as opposed to subclassing BasePlugin directly. This will allow us to
easily re-write console as an OverlayPlugin, and allow future new
plugins types to be created.

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
    if initializer:
 
57
        initializer()
 
58
 
 
59
    while True:
 
60
        (conn, addr) = s.accept()
 
61
        try:
 
62
            # Grab the input
 
63
            buf = cStringIO.StringIO()
 
64
            blk = conn.recv(1024)
 
65
            while blk:
 
66
                buf.write(blk)
 
67
                try:
 
68
                    blk = conn.recv(1024, socket.MSG_DONTWAIT)
 
69
                except:
 
70
                    # Exception thrown if it WOULD block (but we
 
71
                    # told it not to wait) - ie. we are done
 
72
                    blk = None
 
73
            inp = buf.getvalue()
 
74
            env = cjson.decode(inp)
 
75
            
 
76
            # Check that the message is 
 
77
            digest = md5.new(env['content'] + magic).digest().encode('hex')
 
78
            if env['digest'] != digest:
 
79
                conn.close()
 
80
                continue
 
81
 
 
82
            content = cjson.decode(env['content'])
 
83
 
 
84
            response = handler(content)
 
85
 
 
86
            conn.sendall(cjson.encode(response))
 
87
 
 
88
            conn.close()
 
89
 
 
90
        except Terminate, t:
 
91
            # Try and send final response and then terminate
 
92
            if t.final_response:
 
93
                conn.sendall(cjson.encode(t.final_response))
 
94
            conn.close()
 
95
            sys.exit(0)
 
96
        except Exception:
 
97
            # Make a JSON object full of exceptional goodness
 
98
            tb_dump = cStringIO.StringIO()
 
99
            e_type, e_val, e_tb = sys.exc_info()
 
100
            traceback.print_tb(e_tb, file=tb_dump)
 
101
            json_exc = {
 
102
                "type": e_type.__name__,
 
103
                "value": str(e_val),
 
104
                "traceback": tb_dump.getvalue()
 
105
            }
 
106
            conn.sendall(cjson.encode(json_exc))
 
107
            conn.close()
 
108
 
 
109
 
 
110
def chat(host, port, msg, magic, decode = True):
 
111
    sok = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
112
    sok.connect((host, port))
 
113
    content = cjson.encode(msg)
 
114
    digest = md5.new(content + magic).digest().encode("hex")
 
115
    env = {'digest':digest,'content':content}
 
116
    sok.send(cjson.encode(env))
 
117
 
 
118
    buf = cStringIO.StringIO()
 
119
    blk = sok.recv(1024)
 
120
    while blk:
 
121
        buf.write(blk)
 
122
        try:
 
123
            blk = sok.recv(1024, socket.MSG_DONTWAIT)
 
124
        except socket.error, e:
 
125
            if e[0] != 11:
 
126
                raise
 
127
            # Exception thrown if it WOULD block (but we
 
128
            # told it not to wait) - ie. we are done
 
129
            blk = None
 
130
    inp = buf.getvalue()
 
131
    sok.close()
 
132
 
 
133
    if decode:
 
134
        return cjson.decode(inp)
 
135
    else:
 
136
        return inp
 
137