Added GPL notice to Python code.
[doldaconnect.git] / lib / python / dolcon / __init__.py
CommitLineData
92f3b0d7
FT
1# Dolda Connect - Modular multiuser Direct Connect-style client
2# Copyright (C) 2007 Fredrik Tolf <fredrik@dolda2000.com>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
fbe30a6d 18from dolmod import *
c5de778c 19import os
fbe30a6d 20
21def login(useauthless = True, **kw):
ff076c0a 22 """A convenience function for loginasync.
23
24 This function will initiate an asynchronous login per the
25 loginasync command, and then run a select loop while waiting for
26 it to complete. It will return a tuple (res, reason), where res is
27 the result code, and reason is an explanatory text for any error.
28
29 res can be any of the following:
30 * success: Login completed successfully
31 * nologin: No authentication mechanism could be negotiated
32 * server: An error occurred on the server
33 * user: An error occurred in the library
34 * conv: The password conversation mechanism failed
35 * authfail: The server refused the login (due to e.g. bad credentials)
36 """
fbe30a6d 37 result = [None]
38 def mycb(*v):
39 result[0] = v
40 loginasync(mycb, useauthless, **kw)
41 while result[0] is None:
42 select()
43 return result[0]
44
9cbeb60c 45def mustconnect(host, revision = latest):
ff076c0a 46 """A convenience function for connect.
47
48 This function will connect to the given host, perform a select
49 loop, and ensure that the server approves of the connection. If
50 any of these steps fail, an exception is raised. If successful,
51 the file descriptor for the server connection is returned.
52 """
9cbeb60c 53 fd = connect(host)
fbe30a6d 54 while True:
55 resp = getresp()
56 if resp is not None and resp.getcmd() == u".connect":
57 break
58 select()
9cbeb60c 59 if resp.getcode() != 201:
fbe30a6d 60 raise RuntimeError, resp.intresp()[0][0]
9cbeb60c 61 if not checkproto(resp, revision):
62 raise RuntimeError, resp
00ea2039 63 return fd
fbe30a6d 64
9cbeb60c 65def cnl(host = None, useauthless = True, revision = latest, **kw):
ff076c0a 66 """A convenience function for connect and loginasync.
67
68 This function will connect to the given server, or the server in
17537706 69 the environment variable $DCSERVER if none is given, or, if that
70 fails, localhost, and authenticate to the server. If any of the
71 steps fail, an exception is raised.
ff076c0a 72 """
c5de778c 73 if host is None:
74 host = os.getenv("DCSERVER")
75 if host is None:
17537706 76 host = "localhost"
9cbeb60c 77 fd = mustconnect(host, revision)
fbe30a6d 78 err, reason = login(useauthless, **kw)
79 if err != "success":
80 raise RuntimeError, (err, reason)
00ea2039 81 return fd
fbe30a6d 82
83def ecmd(*args):
ff076c0a 84 """A convenience function for qcmd.
85
86 This function will queue the given command, and then wait in a
87 select loop until the command has been carried out. The return
88 value is a Response object, corresponding to the reponse from the
89 server.
90 """
fbe30a6d 91 tag = qcmd(*args)
92 while True:
93 resp = getresp(tag)
94 if resp is not None:
95 break;
96 select()
97 return resp
98
99def ecmda(code, *args):
ff076c0a 100 """A convenience function for ecmd.
101
102 This function does essentially the same as ecmd, but it will also
103 check so that the response has the given numerical code. If not,
104 an exception is raised.
105 """
fbe30a6d 106 resp = ecmd(*args)
107 if resp.getcode() != code:
108 raise ValueError, resp.getcode()
109 return resp
194d48ea 110
111def ecmds(*args):
112 """Another convenience function for ecmd.
113
114 Like ecmda, but will fail on all 5xx codes, and succeed on all
115 others.
116 """
117 resp = ecmd(*args)
118 if resp.getcode() >= 500 and resp.getcode() < 600:
f04b2c3c 119 raise ValueError, tuple(resp.extract()[0])
194d48ea 120 return resp
54b4a861 121
122def getresps():
123 """A generator function which will iterate over all responses from
124 getresp.
125 """
126 while True:
127 resp = getresp()
128 if resp is None:
129 break
130 else:
131 yield resp