Browse Source

Add DB-based system manager server. New simple XML parser.

master
Maurizio Porrato 8 years ago
parent
commit
214cb07962

+ 4
- 4
frn/manager/__init__.py View File

@@ -8,16 +8,16 @@ from zope.interface import Interface
8 8
 
9 9
 class IManager(Interface):
10 10
 
11
-    def serverLogin(user):
11
+    def serverLogin(server):
12 12
         """Logs server on"""
13 13
 
14
-    def serverLogout(user):
14
+    def serverLogout(server):
15 15
         """Logs server out"""
16 16
 
17
-    def clientLogin(user):
17
+    def clientLogin(server, user):
18 18
         """Logs client in"""
19 19
 
20
-    def clientLogout(user):
20
+    def clientLogout(server, user):
21 21
         """Logs client out"""
22 22
 
23 23
     def getClientList():

+ 127
- 14
frn/manager/database.py View File

@@ -5,33 +5,146 @@
5 5
 
6 6
 from zope.interface import implements
7 7
 from frn.manager import IManager
8
-from frn.userstore.database import DatabaseUserStore
8
+from twisted.python import log
9
+from twisted.python.failure import Failure
10
+from twisted.mail.smtp import sendmail
11
+import random, string, uuid
12
+from frn.user import FRNUser
9 13
 
14
+def rndpasswd():
15
+    return ''.join([random.choice(string.ascii_uppercase) for i in range(8)])
10 16
 
11 17
 class DatabaseManager(object):
12 18
 
13 19
     implements(IManager)
14 20
 
15
-    def __init__(self, store):
16
-        self._store = store
21
+    def __init__(self, pool):
22
+        self._pool = pool
23
+        self._pool.runOperation("""
24
+            CREATE TABLE IF NOT EXISTS frn_users (
25
+                _id VARCHAR(32) NOT NULL PRIMARY KEY,
26
+                _ea VARCHAR(30) UNIQUE NOT NULL,
27
+                _pw VARCHAR(20) NOT NULL,
28
+                _on VARCHAR(20) NOT NULL,
29
+                _bc VARCHAR(20) NOT NULL,
30
+                _nn VARCHAR(20) NOT NULL,
31
+                _ct VARCHAR(20) NOT NULL,
32
+                _nt VARCHAR(20),
33
+                _ds VARCHAR(20) NOT NULL,
34
+                _ip VARCHAR(20),
35
+                registration TIMESTAMP NOT NULL DEFAULT current_timestamp,
36
+                lastlogin TIMESTAMP,
37
+                server VARCHAR(20),
38
+                port INTEGER
39
+            );
40
+            """)
41
+        self._pool.runOperation("""
42
+            CREATE TABLE IF NOT EXISTS frn_servers (
43
+                _vx VARCHAR(7) NOT NULL,
44
+                _sn VARCHAR(20) NOT NULL,
45
+                _pt INTEGER NOT NULL,
46
+                _bn VARCHAR(20),
47
+                _bp integer,
48
+                _ow VARCHAR(30) NOT NULL,
49
+                registration TIMESTAMP NOT NULL DEFAULT current_timestamp,
50
+                PRIMARY KEY(_sn, _pt)
51
+            );
52
+            """)
17 53
 
18
-    def serverLogin(self, user):
19
-        pass
54
+    def serverLogin(self, server):
55
+        def checkauth(res):
56
+            if not isinstance(res, Failure):
57
+                if res[0] > 0:
58
+                    return self._pool.runOperation("""
59
+                        INSERT INTO frn_servers
60
+                            (_vx, _sn, _pt, _bn, _bp, _ow) VALUES
61
+                            (?,?,?,?,?,?)
62
+                        """, (server.VX, server.SN, server.PT,
63
+                            server.BN, server.BP, server.OW)).addCallbacks(
64
+                                lambda x: 0, lambda x: -1)
65
+            else:
66
+                return -1
67
+        return self._pool.runQuery("SELECT count(*) FROM frn_users WHERE _ea=? AND _pw=?",
68
+            (server.OW, server.PW)).addBoth(checkauth)
20 69
 
21
-    def serverLogout(self, user):
22
-        pass
70
+    def serverLogout(self, server):
71
+        self._pool.runOperation("UPDATE frn_users SET server=NULL, port=NULL, _nt=NULL WHERE server=? AND port=?",
72
+            (server.SN, server.PT))
73
+        self._pool.runOperation("DELETE FROM frn_servers WHERE _sn=? AND _pt=?",
74
+            (server.SN, server.PT))
23 75
 
24
-    def clientLogin(self, user):
25
-        pass
76
+    def clientLogin(self, server, user):
77
+        def userfound(data):
78
+            log.msg("Client login: %s" % repr(data))
79
+            if data:
80
+                u = dict(zip(
81
+                    ('ID', 'EA', 'PW', 'ON', 'BC', 'NN', 'CT', 'NT', 'DS', 'IP', 'registration', 'lastlogin', 'server', 'port'),
82
+                    data[0]))
83
+                if u['server']:
84
+                    log.msg("Duplicate client %s" % repr(user))
85
+                    return "DUPL"
86
+                self._pool.runQuery("""
87
+                    UPDATE frn_users SET
88
+                        _bc=?, _nn=?, _ct=?, _nt=?, _ds=?, _ip=?, server=?, port=?,
89
+                        lastlogin=current_timestamp
90
+                    WHERE _id=?
91
+                """, (user.BC, user.NN, user.CT, user.NT, user.DS, user.IP, server.SN, server.PT, u['ID']))
92
+                log.msg("Authenticated client %s" % repr(user))
93
+                return str(u['ID'])
94
+            else:
95
+                log.msg("Wrong client %s" % repr(user))
96
+                return "WRONG"
97
+        return self._pool.runQuery("SELECT * FROM frn_users WHERE _ea=? AND _on=? AND _pw=?",
98
+            (user.EA, user.ON, user.PW)).addCallbacks(userfound, lambda x: "WRONG")
26 99
 
27
-    def clientLogout(self, user):
28
-        pass
100
+    def clientLogout(self, server, user):
101
+        log.msg("Logging out client %s" % repr(user))
102
+        return self._pool.runOperation("UPDATE frn_users SET server=NULL, port=NULL, _nt=NULL WHERE _id=?",
103
+            (user.ID,)).addBoth(lambda x: "OK")
29 104
 
30 105
     def getClientList(self):
31
-        pass
106
+        def buildlist(tr):
107
+            tr.execute("SELECT _sn, _pt FROM frn_servers")
108
+            servers = tr.fetchall()
109
+            r = {}
110
+            for sn, sp in servers:
111
+                r[(sn,sp)] = {}
112
+                tr.execute("SELECT DISTINCT _nt FROM frn_users WHERE server=? AND port=?", (sn,sp))
113
+                networks = tr.fetchall()
114
+                for (n,) in networks:
115
+                    r[(sn,sp)][n] = []
116
+                    tr.execute("SELECT _id, _on, _bc, _ds, _nn, _ct FROM frn_users WHERE server=? AND port=? AND _nt=?",
117
+                        (sn, sp, n))
118
+                    clients = tr.fetchall()
119
+                    for c in clients:
120
+                        cu = FRNUser(**dict(zip(['EA','ON','BC','DS','NN','CT'],c)))
121
+                        r[(sn,sp)][n].append(cu)
122
+            return r
123
+        return self._pool.runInteraction(buildlist)
32 124
 
33 125
     def registerUser(self, user):
34
-        pass
35
-
126
+        def fetchdata(is_new):
127
+            def maildata(data):
128
+                u = dict(zip(
129
+                    ('ID', 'EA', 'PW', 'ON', 'BC', 'NN', 'CT', 'NT', 'DS', 'IP', 'registration', 'lastlogin', 'server', 'port'),
130
+                    data[0]))
131
+                log.msg("Mailing password to user %s" % str(u))
132
+                with open('mailtemplate.txt','r') as tplfile:
133
+                    tpl = tplfile.read()
134
+                    mailbody = string.Template(tpl).safe_substitute(u)
135
+                    sendmail('127.0.0.1',
136
+                        'admin@gnuradionetwork.org',
137
+                        [u['EA']],
138
+                        mailbody, port=2525)
139
+                return "OK"
140
+            return self._pool.runQuery(
141
+                "SELECT * FROM frn_users WHERE _ea=?", (user.EA,)
142
+                ).addCallback(maildata).addErrback(lambda x: "ERROR")
143
+        return self._pool.runOperation("""
144
+            INSERT INTO frn_users (_id, _ea, _pw, _on, _bc, _ds, _nn, _ct)
145
+            VALUES (?,?,?,?,?,?,?,?)
146
+            """, (uuid.uuid4().get_hex()[:20], user.EA, rndpasswd(),
147
+            user.ON, user.BC, user.DS, user.NN, user.CT)
148
+            ).addBoth(fetchdata)
36 149
 
37 150
 # vim: set et ai sw=4 ts=4 sts=4:

+ 5
- 5
frn/manager/dummy.py View File

@@ -16,20 +16,20 @@ class DummyManager(object):
16 16
     def _randId(self):
17 17
         return '.'.join([str(randint(1,254)) for i in range(4)])
18 18
 
19
-    def serverLogin(self, user):
19
+    def serverLogin(self, server):
20 20
         return defer.succeed(0)
21 21
 
22
-    def serverLogout(self, user):
22
+    def serverLogout(self, server):
23 23
         return defer.succeed(None)
24 24
 
25
-    def clientLogin(self, user):
25
+    def clientLogin(self, server, user):
26 26
         return defer.succeed(self._randId())
27 27
 
28
-    def clientLogout(self, user):
28
+    def clientLogout(self, server, user):
29 29
         return defer.succeed('OK')
30 30
 
31 31
     def getClientList(self):
32
-        return defer.succeed([])
32
+        return defer.succeed({})
33 33
 
34 34
     def registerUser(self, user):
35 35
         return defer.succeed('OK')

+ 6
- 6
frn/manager/remote.py View File

@@ -55,23 +55,23 @@ class RemoteManager(object):
55 55
     def doConnect(self):
56 56
         self.reactor.connectTCP(self.server, self.port, self.factory)
57 57
 
58
-    def serverLogin(self, user):
59
-        self.factory = CustomManagerClientFactory(user)
58
+    def serverLogin(self, server):
59
+        self.factory = CustomManagerClientFactory(server)
60 60
         self.doConnect()
61 61
         return self.factory.deferred
62 62
 
63
-    def serverLogout(self, user):
63
+    def serverLogout(self, server):
64 64
         if self.factory.client is not None:
65
-            return self.factory.client.sendServerLogout(user)
65
+            return self.factory.client.sendServerLogout(server)
66 66
 
67
-    def clientLogin(self, user):
67
+    def clientLogin(self, server, user):
68 68
         if self.maskParrot and user.BC == 'Parrot':
69 69
             u = user.copy(BC='PC Only')
70 70
         else:
71 71
             u = user.copy()
72 72
         return self.factory.client.sendClientLogin(u)
73 73
 
74
-    def clientLogout(self, user):
74
+    def clientLogout(self, server, user):
75 75
         if self.maskParrot and user.BC == 'Parrot':
76 76
             u = user.copy(BC='PC Only')
77 77
         else:

+ 26
- 5
frn/protocol/manager.py View File

@@ -112,12 +112,16 @@ class FRNManagerServer(LineOnlyReceiver):
112 112
     def connectionMade(self):
113 113
         log.msg("Manager client connected from %s" % self.transport.getPeer().host)
114 114
         self._phase = "CONNECTED"
115
+        self.serverInfo = None
115 116
         self.kp = makeRandomChallange()
116 117
 
117 118
     def connectionLost(self, reason):
118 119
         log.msg("Manager client disconnected from %s: %s" %
119 120
             (self.transport.getPeer().host, reason))
120
-        self.manager.serverLogout(None) # FIXME
121
+        if self.serverInfo:
122
+            self.manager.serverLogout(self.serverInfo)
123
+            self.serverInfo = None
124
+            self._phase = "DISCONNECTED"
121 125
 
122 126
     def _authOnly(self):
123 127
         if self._phase != "AUTHENTICATED":
@@ -129,6 +133,8 @@ class FRNManagerServer(LineOnlyReceiver):
129 133
         if self._phase == "CHALLANGE":
130 134
             if sline == responseToChallange(self.kp):
131 135
                 self._phase = "AUTHENTICATED"
136
+                self.serverInfo = self.tmpServerInfo
137
+                log.msg("Auth success: %s" % repr(self.serverInfo))
132 138
             else:
133 139
                 self.transport.loseConnection()
134 140
         else:
@@ -146,8 +152,19 @@ class FRNManagerServer(LineOnlyReceiver):
146 152
                     handler(xbody)
147 153
 
148 154
     def sendClientList(self):
155
+        def gotClientList(cl):
156
+            self.sendLine(str(len(cl)))
157
+            for sn, sp in cl:
158
+                self.sendLine("%s - Port: %d" % (sn, sp))
159
+                self.sendLine(str(len(cl[(sn,sp)])))
160
+                for nt in cl[(sn,sp)]:
161
+                    self.sendLine(nt)
162
+                    self.sendLine(str(len(cl[(sn,sp)][nt])))
163
+                    for u in cl[(sn,sp)][nt]:
164
+                        self.sendLine(u.asXML('EA','ON','BC','DS','NN','CT'))
149 165
         log.msg("SM")
150
-        self.sendLine('0') # TODO
166
+        return self.manager.getClientList().addCallback(gotClientList)
167
+
151 168
 
152 169
     def unimplemented(self, cmd, body):
153 170
         log.err("Unimplemented command %s: %s" % (cmd, str(body)))
@@ -156,13 +173,17 @@ class FRNManagerServer(LineOnlyReceiver):
156 173
         def sendManagerInfo(res):
157 174
             if versions.manager > 2009004:
158 175
                 self._phase = "CHALLANGE"
176
+                self.tmpServerInfo = FRNUser(**body)
159 177
             else:
160 178
                 self._phase = "AUTHENTICATED"
179
+                self.serverInfo = FRNUser(**body)
180
+                log.msg("Auth success: %s" % repr(self.serverInfo))
161 181
             self.sendLine(formatSimpleXML([
162 182
                 ('SV', versions.server),
163 183
                 ('CV', versions.client),
164 184
                 ('MC', versions.manager),
165
-                ('AL', res['al']),
185
+#                ('AL', res['al']),
186
+                ('AL', res),
166 187
                 ('KP', self.kp)
167 188
             ]))
168 189
         log.msg("SC: %s" % str(body))
@@ -172,13 +193,13 @@ class FRNManagerServer(LineOnlyReceiver):
172 193
     def decodeCC(self, body): # Client login
173 194
         log.msg("CC: %s" % str(body))
174 195
         self._authOnly()
175
-        self.manager.clientLogin(FRNUser(**body)).addCallback(
196
+        self.manager.clientLogin(self.serverInfo, FRNUser(**body)).addCallback(
176 197
             self.sendLine)
177 198
 
178 199
     def decodeCD(self, body): # Client logout
179 200
         log.msg("CD: %s" % str(body))
180 201
         self._authOnly()
181
-        self.manager.clientLogout(FRNUser(**body)).addCallback(
202
+        self.manager.clientLogout(self.serverInfo, FRNUser(**body)).addCallback(
182 203
             self.sendLine)
183 204
 
184 205
     def decodeIG(self, body): # Account creation

+ 17
- 13
frn/protocol/server.py View File

@@ -32,20 +32,19 @@ class FRNServer(BufferingLineReceiver, TimeoutMixin):
32 32
 
33 33
     def connectionLost(self, reason):
34 34
         log.msg("Client disconnected: %s" % self.clientAddress.host)
35
-        self.stopPinging()
36
-        if self.user is not None:
37
-            if self.user.ID:
38
-                log.msg("Logging out client %s" % self.user.ID)
39
-                self.factory.manager.clientLogout(self.user)
40
-                self.factory.tracker.logout(self)
35
+        self.disconnect()
41 36
         BufferingLineReceiver.connectionLost(self, reason)
42 37
 
38
+	def timeoutConnection(self):
39
+		log.msg("Client dead: disconnecting %s" % self.user)
40
+		self.disconnect()
41
+
43 42
     def lineReceived(self, line):
44 43
         self.resetTimeout()
45 44
         sline = line.strip()
46 45
         if self.waitingKey:
47 46
             if responseToChallange(self.kp) != sline:
48
-                self.transport.loseConnection()
47
+                self.disconnect()
49 48
                 return
50 49
             else:
51 50
                 self.waitingKey = False
@@ -59,7 +58,7 @@ class FRNServer(BufferingLineReceiver, TimeoutMixin):
59 58
                     self.sendAccessFlags(ac,tx)
60 59
                     self.sendAccessList(self.factory.tracker.getAcl(self.user.NT))
61 60
                 if self.role not in ['OK', 'ADMIN', 'OWNER']:
62
-                    self.transport.loseConnection()
61
+                    self.disconnect()
63 62
                     return
64 63
                 self.startPinging()
65 64
                 self.setTimeout(10.0)
@@ -72,7 +71,7 @@ class FRNServer(BufferingLineReceiver, TimeoutMixin):
72 71
         else:
73 72
             command, body = sline.split(':', 1)
74 73
         if command != 'CT' and self.user is None:
75
-            self.transport.loseConnection()
74
+            self.disconnect()
76 75
             return
77 76
         handler = getattr(self, 'decode'+command, None)
78 77
         if body[0] == '<' and body[-1] == '>':
@@ -110,7 +109,12 @@ class FRNServer(BufferingLineReceiver, TimeoutMixin):
110 109
             return succeed(("BLOCK", ""))
111 110
 
112 111
     def disconnect(self):
113
-        self.transport.loseConnection()
112
+        self.stopPinging()
113
+        if self.user is not None:
114
+			log.msg("Logging out client %s" % self.user)
115
+			self.factory.manager.clientLogout(self.user)
116
+			self.factory.tracker.logout(self)
117
+		self.transport.loseConnection()
114 118
 
115 119
     def decodeCT(self, body):
116 120
         def authReturned(result):
@@ -135,7 +139,7 @@ class FRNServer(BufferingLineReceiver, TimeoutMixin):
135 139
             self.sendLine(
136 140
                 self.factory.serverAuth.asXML('MT','SV','AL','BN','BP','KP'))
137 141
             if self.role not in ['OK', 'OWNER', 'ADMIN']:
138
-                self.transport.loseConnection()
142
+                self.disconnect()
139 143
             else:
140 144
                 self.sendNetworkList(self.factory.tracker.getNetworkList())
141 145
                 self.transport.setTcpNoDelay(True)
@@ -307,14 +311,14 @@ class FRNServer(BufferingLineReceiver, TimeoutMixin):
307 311
         log.msg("Sending ACL to %s: %s" % (self.user.ON, str(clients)))
308 312
         self.transport.write(chr(7))
309 313
         self.sendLine(str(len(clients)))
310
-        for c in clients: # FIXME
314
+        for c in clients:
311 315
             self.sendLine(c.asXML('AI','NN','CT','BC','ON','ID'))
312 316
 
313 317
     def sendAccessFlags(self, access, talk):
314 318
         log.msg("Sending ACL flags to %s: %s" % (self.user.ON, str((access, talk))))
315 319
         FV = {True: '1', False: 'o'}
316 320
         self.transport.write(chr(10))
317
-        self.sendLine('2') # TODO
321
+        self.sendLine('2')
318 322
         self.sendLine(FV[access])
319 323
         self.sendLine(FV[talk])
320 324
 

+ 0
- 9
frn/userstore/__init__.py View File

@@ -1,9 +0,0 @@
1
-# -*- coding: utf-8 -*-
2
-#
3
-# Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>
4
-# See LICENSE.txt for copyright info
5
-
6
-class FRNUserNotFound(StandardError): pass
7
-
8
-
9
-# vim: set et ai sw=4 ts=4 sts=4:

+ 0
- 84
frn/userstore/database.py View File

@@ -1,84 +0,0 @@
1
-# -*- coding: utf-8 -*-
2
-#
3
-# Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>
4
-# See LICENSE.txt for copyright info
5
-
6
-from twisted.python import log
7
-from twisted.enterprise.adbapi import safe
8
-from frn.userstore import FRNUserNotFound
9
-from frn.user import FRNUser
10
-
11
-
12
-def _asDict(curs, *args, **kw):
13
-    log.msg("Running query %s %s" % (str(args), str(kw)))
14
-    curs.execute(*args, **kw)
15
-    result = curs.fetchall()
16
-    columns = [d[0] for d in curs.description]
17
-    d = [dict(zip(columns, r)) for r in result]
18
-    log.msg("Query returned: %s" % str(d))
19
-    return d
20
-
21
-
22
-def _returnId(curs, *args, **kw):
23
-    log.msg("Running query %s %s" % (str(args), str(kw)))
24
-    curs.execute(*args, **kw)
25
-    rowId = curs.lastrowid
26
-    log.msg("Query returned: %s" % str(rowId))
27
-    return rowId
28
-
29
-
30
-class DatabaseUserStore(object):
31
-
32
-    def __init__(self, pool):
33
-        self._pool = pool
34
-
35
-    def _query(self, *args, **kw):
36
-        return self._pool.runInteraction(_asDict, *args, **kw)
37
-
38
-    def getByName(self, name, email):
39
-        try:
40
-            return self._query("""
41
-                SELECT * FROM frn_users
42
-                WHERE "on"=? AND "ea"=?""",
43
-                (name, email)).addCallback(
44
-                    lambda x: FRNUser(**x[0]))
45
-        except IndexError:
46
-            raise FRNUserNotFound
47
-
48
-    def getById(self, userId):
49
-        return self._query("""
50
-            SELECT * FROM frn_users
51
-            WHERE "id"=?""",
52
-            (int(userId), )).addCallback(
53
-                lambda x: FRNUser(x[0]))
54
-
55
-    def update(self, userId, **kw):
56
-        assignments = ','.join(["\"%s\"='%s'" % (k,safe(v))
57
-            for k,v in kw.items()])
58
-        op = "UPDATE frn_users SET "+assignments+" WHERE \"id\"=?"
59
-        self._pool.runOperation(op, (int(userId),))
60
-
61
-    def create(self, user):
62
-        return self._query(
63
-            """INSERT INTO frn_users ("on","ea") VALUES (?,?)""",
64
-            (user.ON, user.EA)).addCallback(lambda x: "%015s" % x)
65
-
66
-    def list(self):
67
-        return self._query("SELECT * FROM frn_users").addCallback(
68
-            lambda x: [FRNUser(y) for y in x])
69
-
70
-    def login(self, user):
71
-        def gotUser(u):
72
-            log.msg("Got user %s" % u.ID)
73
-            if u.PW == user.PW:
74
-                return u.ID
75
-            return "WRONG"
76
-        log.msg("Authenticating %s (%s)" % (user.ON, user.EA))
77
-        return self.getByName(user.ON, user.EA).addCallbacks(
78
-            gotUser, lambda x: "WRONG")
79
-
80
-    def logout(self, userId):
81
-        pass
82
-
83
-
84
-# vim: set et ai sw=4 ts=4 sts=4:

+ 3
- 38
frn/utility.py View File

@@ -3,7 +3,7 @@
3 3
 # Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>
4 4
 # See LICENSE.txt for copyright info
5 5
 
6
-from HTMLParser import HTMLParser
6
+import re
7 7
 from random import choice
8 8
 
9 9
 
@@ -19,45 +19,10 @@ def makeRandomChallange():
19 19
     return ''.join([choice('0123456789') for i in range(6)])
20 20
 
21 21
 
22
-class SimpleXMLParser(HTMLParser):
23
-    """Dirty FRN-specific hack to handle bogus one-level nesting only
24
-    XML-like syntax"""
25
-
26
-    def handle_starttag(self, tag, attrs):
27
-        if not hasattr(self, 'fields'):
28
-            self.fields = {}
29
-            self.next_field = None
30
-            self.next_data = ''
31
-        if self.next_field is None:
32
-            self.next_field = tag
33
-            self.next_data = ''
34
-        else:
35
-            if attrs:
36
-                a = ' '+' '.join(['%s="%s"' % (k,v) for k,v in attrs])
37
-            else:
38
-                a = ''
39
-            self.next_data += "<%s%s>" % (tag,a)
40
-
41
-    def handle_data(self, data):
42
-        if self.next_field is not None:
43
-            self.next_data += data
44
-
45
-    def handle_endtag(self, tag):
46
-        if tag == self.next_field:
47
-            self.fields[self.next_field] = self.next_data
48
-            self.next_field = None
49
-            self.next_data = ''
50
-        else:
51
-            self.next_data += "</%s>" % tag
52
-
53
-    def get_fields(self):
54
-        return self.fields
55
-
22
+re_tag = re.compile(r"<([A-Z]{2})>(.*)</\1>")
56 23
 
57 24
 def parseSimpleXML(xml):
58
-    p = SimpleXMLParser()
59
-    p.feed(xml)
60
-    return p.get_fields()
25
+    return dict(re_tag.findall(xml))
61 26
 
62 27
 
63 28
 def formatSimpleXML(elements):

+ 22
- 16
manager.py View File

@@ -9,25 +9,31 @@ from frn.protocol.manager import FRNManagerServer, FRNManagerServerFactory
9 9
 from twisted.enterprise.adbapi import ConnectionPool
10 10
 from frn.manager.dummy import DummyManager
11 11
 from frn.manager.remote import RemoteManager
12
+from frn.manager.database import DatabaseManager
12 13
 from frn.user import FRNUser
13 14
 from twisted.python import log
14 15
 
15 16
 if __name__ == '__main__':
16
-    import sys
17
-
18
-    log.startLogging(sys.stderr)
19
-
20
-    def standardManagerFactory():
21
-        log.msg("Building Manager")
22
-        return RemoteManager(reactor)
23
-
24
-    reactor.listenTCP(10025, FRNManagerServerFactory(
25
-#        DatabaseUserStore(
26
-#            ConnectionPool("sqlite3", "frn_users.sqlite3",
27
-#                check_same_thread=False)),
28
-#        DummyManager()
29
-        standardManagerFactory
30
-    ))
31
-    reactor.run()
17
+	import sys
18
+
19
+	log.startLogging(sys.stderr)
20
+
21
+	def dummyManagerFactory():
22
+		log.msg("Building DummyManager")
23
+		return DummyManager()
24
+
25
+	def remoteManagerFactory():
26
+		log.msg("Building RemoteManager")
27
+		return RemoteManager(reactor)
28
+
29
+	def databaseManagerFactory():
30
+		log.msg("Building DatabaseManager")
31
+		return DatabaseManager(
32
+			ConnectionPool("sqlite3", "/tmp/frnmanager.sqlite3", cp_noisy=True))
33
+
34
+	reactor.listenTCP(10025, FRNManagerServerFactory(
35
+		databaseManagerFactory
36
+	))
37
+	reactor.run()
32 38
 
33 39
 # vim: set et ai sw=4 ts=4 sts=4:

Loading…
Cancel
Save